Sunday, November 11, 2018

Inheritance with chakracore-delphi

I've just pushed some updates to chakracore-delphi.

A new feature worth mentioning is support for inheritance (I mean Javascript-style, "prototypical inheritance") in both directions. Suppose the following hierarchy:

First, here is Shape the "superclass", defined in Javascript:



Next comes Circle, a "subclass" of Shape, defined in Javascript as well:



The following is Rectangle, defined in Pascal, as a "subclass" of Shape:



Here's Square, defined in Javascript again, as a "subclass" of Rectangle:



And finally here are the tests, demonstrating that
- (Javascript) Circle descends from (Javascript) Shape
- (Pascal) Rectangle descends from (Javascript) Shape
- (Javascript) Square descends from (Pascal) Rectangle



As always, you can grab the latest code on GitHub. Cheers!

Monday, October 29, 2018

My Lazarus External Tools

Similar to My Delphi Tools blog post (wow, many years ago), here's my Lazarus External Tools configuration.

Linux (Mint)

Title: Explore to Source Directory
Program Filename: caja
Parameters: $Path($EdFile())
Working Directory:

Title: Explore to Target Directory
Program Filename: caja
Parameters: $Path($TargetFile())
Working Directory:

Title: Console in Source Directory
Program Filename: mate-terminal
Parameters: --working-directory=$Path($EdFile())
Working Directory:
Show console: True

Title: Console in Target Directory
Program Filename: mate-terminal
Parameters: --working-directory=$Path($TargetFile())
Working Directory:
Show console: True

Import link: lazarus-external-tools-linux-mint.xml

Windows

Title: Explore to Source Directory
Program Filename: explorer.exe
Parameters: /e,/select, "$EdFile()"
Working Directory:

Title: Explore to Target Directory
Program Filename: explorer.exe
Parameters: /e,/select,"$TargetFile()"
Working Directory:

Title: Console in Source Directory
Program Filename: cmd.exe
Parameters: /k cd "$Path($EdFile())"
Working Directory:
Show console: True

Title: Console in Target Directory
Program Filename: cmd.exe
Parameters: /k cd "$Path($TargetFile())"
Working Directory:
Show console: True

Import link: lazarus-external-tools-windows.xml

Sunday, September 16, 2018

Project Page IDE extension for RAD Studio XE

In a response to this question on G+, I just published projpage-xe, an IDE extension for RAD Studio XE (Delphi and C++Builder) as open source on GitHub.

This IDE extension is targeting RAD Studio XE version (ie. BDS 15.0 released in August 2010) specifically. It can hopefully serve as a work-around for the problem that the official Project Page IDE functionality mysteriously disappeared in that particular release, reappearing in later releases again.
It's implemented as a design-only package which can be simply installed in the IDE in the usual way.

From README.md, here's what it does:
This extension listens for the active project change events. If the currently activated project contains an HTML file with the name 'index.htm' or 'index.html' it will open and show it in the IDE's internal embedded browser.

A small demonstration:

Thursday, July 19, 2018

Delphi Free for Some - Lazarus Free for Everyone!

Embarcadero has announced the Community Edition releases for Delphi and C++Builder. Sounds like a reason to celebrate. But reading the "fine print" is rather sobering, as the license agreement practically excludes anyone but some students and hobbyists, perhaps:
"The Community Edition license applies solely if Licensee cumulative annual revenue (of the for-profit organization, the government entity or the individual developer) or any donations (of the non-profit organization) does not exceed USD $5,000.00 (or the equivalent in other currencies) (the "Threshold"). If Licensee is an individual developer, the revenue of all contract work performed by developer in one calendar year may not exceed the Threshold (whether or not the Community Edition is used for all projects). For example, a developer who receives payment of $5,000.00 for a single project (or more than $5,000.00 for multiple projects) even if such engagements do not anticipate the use of the Community Edition, is not allowed to use the Community Edition. In addition, a developer building solely an app store application would not be allowed to use the Community Edition once the app store revenue reaches a revenue of $5,000.00 or more in a year. If Licensee is a company that has a cumulative annual revenue which exceeds the Threshold, then Licensee is not allowed to use the Community Edition, regardless if the Community Edition is used solely to write applications for the business' internal use or is seen by third parties outside the company or has a direct revenue associated with it."

I think there's no need to be so excited about it. Consider this: you mustn't have more than $5000 a year (or $416.67 a month), regardless of what tools you're using. Mind you, revenue, not profit, and even donations count. That makes the offer unusable even for most start-ups, students or hobbyists. So in case you make a bit more than that ;-) and still don't want to pay the full price for a Professional or Enterprise Edition, you're back to

Free Pascal and Lazarus


  • Truly free (both as in beer and as in speech) Object Pascal compilers and tools supporting multiple target platforms, including Windows, Mac OS X and Linux, Intel 32-bit, 64-bit, ARM and more. (I haven't tried the mobile platforms, Android or iOS, yet.)
  • A nice, stable and capable IDE, itself a great example of its own multi-platform support (screenshots).
  • LCL (Lazarus Component Library) - cross-platform, with many components, extensible with your own. (Just a few days ago, I realised there's an LCL port of Virtual TreeView which I can use in my projects on all the three major operating systems. I'm eager to try it out!)

All free and open, with full source code. Licensed under GPL/LGPL.

OK, Embarcadero still considers Delphi as the Swiss Army Knife of software development and Swiss Army Knives don't come cheap. Maybe not everybody shares that point of view and some may not feel like paying to find out (30 days trial is just not enough for such a complex tool.) For those, Free Pascal and Lazarus are still a working and probably the best solution.

UPDATE:

The Community Edition FAQs suggest it's fine for anyone to use it for "their own personal use":

Q: If I work for a company with more than US $5,000 in revenue, can I still download Delphi Community Edition or C++Builder Community Edition for my own personal use?

A: Yes. You can download Delphi Community Edition or C++Builder Community Edition as an individual and use it to develop applications for your personal use and use it to create software for you to sell (up to US $5,000 in revenue, see License Agreement for details).

After all, this sounds more permissive than the EULA itself for company employees.

Saturday, June 23, 2018

FastText follow-up

Just a quick follow-up for those of you who showed interest.

My proof-of-concept with FastText has been a success. The C# class library has been integrated with a product and staged for a future release.

The product provides a web-based conversational user interface, accepting natural language as user input and performing configurable actions, possibly interacting with other (external or internal) software products and services. For example, "How's the weather in Tokyo?" will send a request to a weather service and return the response, or "Show me the current sequence of application xyz" will query another product's database and display the results (prompting the user in case of uncertainty). Therefore the initial use case is supervised text classification, and FastText has proven to be fit for the purpose.

The FastText functionality I've exposed to .NET so far includes:
- all training methods (cbow, skipgram, supervised) and their parameters
- file persistence
- text classification
- partial word representation, "nearest neighbour" queries, "analogies"
- accessing dictionary and model data

The top two points open the possibility to re-train based on new user input, ie. continuous learning.

Additionally, I've implemented database persistence of the dictionaries and trained models so they can be queried directly in SQL code. For example, the classic "king - man + woman" (using cosine similarity):

Sunday, May 20, 2018

One of my favourite ways of multi-threading on Windows

Having blogged about a few bugs in multi-threading libraries recently, I want to show an easy and convenient alternative. It's minimalistic but it works.

On Windows, the I/O completion port offers a way to use a thread pool for your multi-threaded application. Designed primarily for efficient processing of asynchronous I/O, it supports files, named pipes, sockets and device control.

In addition to that, you can post your own packets to the port. Quoting from the documentation:
The PostQueuedCompletionStatus function allows an application to queue its own special-purpose completion packets to the I/O completion port without starting an asynchronous I/O operation.
An example of this is shown in the worker demo project (which uses no async I/O at all).

Saturday, April 28, 2018

Another Bug

So you've put in the time and effort to refactor your code and data for parallel execution and are eager to see some parallel action. Unfortunately, you might be disappointed; in some cases your tasks might get serialized, performed sequentially in a single thread. With the overhead you've just introduced, your code probably performs a little bit worse than before.

If you thought TParallel.Join was a nasty bug, things can apparently get even worse. Reading further in Primož Gabrijelčič's book Delphi High Performance, Chapter 7, "Exploring Parallel Practices":


There's a nasty bug in the System.Threading code that was introduced in Delphi 10.2 Tokyo. I certainly hope that it will be fixed in the next release, as it makes the Parallel Programming Library hard to use. It sometimes causes new threads not to be created when you start a task. That forces your tasks to execute one by one, not in parallel.

(Interestingly, I'm able to reproduce it reliably in XE7, too.)

The ParallelTasks sample project demonstrates the issue.
If you run the "Check primes 2" code with four tasks first, then two tasks, and finally one task, you'll get the expected result:


However, running the code with one task first, then two tasks, and finally four tasks will give you this:


The author offers two different workarounds:
- insert a little delay after each call to TTask.Run (in the sample code, uncomment the Sleep(1) call in btnCheckPrimes2Click method), or
- create your own thread pool and limit the minimum number of running threads in it (in the sample code, see btnCustomThreadPoolClick method).

Sunday, April 22, 2018

Don't lose time with a known Delphi bug affecting TParallel.Join

Writing multi-threaded code is hard and takes a lot of time. That's why it's especially annoying to waste time with bugs like this.

Reading (and enjoying) Primož Gabrijelčič's book Delphi High Performance, I've come across this paragraph in Chapter 7: Exploring Parallel Practices:
There's not much to say about Join, except that in current Delphi it doesn't work correctly. A bug in the 10.1 Berlin and 10.2 Tokyo implementations causes Join to not start enough threads. For example, if you pass in two tasks, it will only create one thread and execute tasks one after another. If you pass in three tasks, it will create two threads and execute two tasks in one and one in another.
The code accompanying the book is available on Github: PacktPublishing/Delphi-High-Performance

Related:
G+ discussion
TParallel,Join does not create enough threads (Embarcadero's Quality Portal RSP-19557)

The author offers a simple workaround by starting a dummy task (which does nothing) first; you can see an example here.

Some time ago (using Delphi XE7), I wrote a library with my own TThreadPool class using and encapsulating the Windows IOCP. The result turned out well, it was rock-solid. Reading about bugs like this in the latest-and-greatest Delphi version makes me glad I chose to write my own implementation from scratch and saved a lot of time hunting for bugs like this in Delphi's runtime library (in addition to my own).

Sunday, April 15, 2018

Artificial Intelligence Transgender: Kings and Queens

Researching for some Natural Language Processing tasks for a .NET application recently, I've come across Facebook's FastText library.

FastText is an open-source, free, lightweight library that allows users to learn text representations and text classifiers. It works on standard, generic hardware. Models can later be reduced in size to even fit on mobile devices.
It's written in C++ and builds on modern Mac OS and Linux distributions. Since it uses some C++11 features, it requires a compiler with good C++11 support. Python bindings are included.

Using this library, you can train models which represent words as multi-dimensional vectors. The models can be queried to find correlations between these vectors in the multi-dimensional space. Depending on the volume and quality of your input data, as well as the training parameters you specify, you can obtain better or worse results to your queries. An introductory explanation of how it works: king - man + woman is queen; but why?

An unofficial FastText fork for Windows is available on GitHub. I'm using this as a starting point to create a DLL in Visual Studio, exposing the C++ classes in a "flattened" C-style API as described in the article Using C++ objects in Delphi by Rudy Velthuis. Such a DLL can also be used from .NET via platform invoke.

As a result, when it's done I'll be able to use this library from Python, .NET, Delphi/Free Pascal and JavaScript (by embedding ChakraCore).

Some examples of console output from my experiments:

King - Man + Woman = ? (JavaScript)

C:\Code\fasttextConsole\chakra\Win64\Debug>ftcc ft.js
Loading file "C:\Data\fasttext\wiki\enwik9.bin"...
done.
Computing vectors...
done.
positive words:
king woman
negative words:
man
"queen": 0.7796817421913147
"regnant": 0.7554017305374145
"consort": 0.7433754205703735
"daughter": 0.7231032848358154
"throne": 0.721994161605835

Berlin - Germany + Argentina = ? (C#)

C:\Code\fasttextConsole\cs\ftcs\bin\x64\Debug>ftcs
Loading file "C:\Data\fasttext\wiki\enwik9.bin"...done.
Computing vectors...done.
positive words:
berlin argentina
negative words:
germany
"aires": 0.8183396
"buenos": 0.8142648
"argentinan": 0.7616609
"argentinas": 0.7580159
"caracas": 0.740073

Berlin - Germany + Slovakia = ? (Free Pascal)

C:\Code\fasttextConsole\fpc\bin\x86_64-win64\Debug>ftc
Loading file 'C:\Data\fasttext\wiki\enwik9.bin'...done.
Computing vectors...done.
positive words:
berlin slovakia
negative words:
germany
'zagreb': 0.81 (Oops! ;-))
'bratislava': 0.79 (Yeah!)
'budapesti': 0.79
'slavonski': 0.79
'podgorica': 0.78

Playstation - Sony + Nintendo = ? (JavaScript)

C:\Code\fasttextConsole\chakra\Win64\Debug>ftcc ft.js
Loading file "C:\Data\fasttext\wiki\enwik9.bin"...
done.
Computing vectors...
done.
positive words:
playstation nintendo
negative words:
sony
"gamecube": 0.8729094862937927
"nintendogs": 0.8490696549415588
"playstationjapan": 0.840140163898468
"snes": 0.8312469720840454
"sega": 0.822517454624176

Here are some code examples:

1. C-style API (DLL exported functions)
2. Imports for .NET
3. Wrapper class for .NET
4. C# usage
5. Imports for Pascal
6. Pascal usage
7. Pascal class for ChakraCore host
8. JavaScript usage

Monday, April 02, 2018

First steps with Lazarus Qt5 interface

Steps for building and installing Qt5 for Lazarus

Using a quick test project with relevant code shown here: unit1.pas
I'm using Qt 5.6.2 because that's the version with which Lazarus qt5 interface has been tested. You can experiment with later versions, too.

Windows 32-bit

Using MinGW

$(LazarusDir): C:\fpcupdeluxe\lazarus
$(QtDir): C:\Qt\Qt5.6.2

- download: qt-opensource-windows-x86-mingw492-5.6.2.exe
- install
- open command prompt in the bindings directory $(LazarusDir)\lcl\interfaces\qt5\cbindings
set PATH=$(QtDir)\5.6\mingw49_32\bin;$(QtDir)\Tools\mingw492_32\bin;%PATH%
qmake
mingw32-make
mingw32-make install
$(FpcDir)\bin\i386-win32\strip.exe $(QtDir)\5.6\mingw49_32\bin\Qt5Pas1.dll



Windows 64-bit

Using Visual Studio 2015

$(LazarusDir): C:\fpcupdeluxe\lazarus
$(QtDir): C:\Qt\Qt5.6.2

- download: qt-opensource-windows-x86-msvc2015_64-5.6.2.exe
- install
- fix the binding sources in the bindings directory $(LazarusDir)\lcl\interfaces\qt5\cbindings to be able to compile with Visual Studio: patch
- open command prompt in the bindings directory $(LazarusDir)\lcl\interfaces\qt5\cbindings
set PATH=$(QtDir)\5.6\msvc2015_64\bin;%PATH%
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
qmake

- edit the Makefile to remove -Wfatal-errors from CXXFLAGS
nmake
nmake install



OSX 64-bit

$(LazarusDir): ~/fpcupdeluxe/lazarus
$(QtDir): ~/Qt5.6.2

- download: qt-opensource-mac-x64-clang-5.6.2.dmg
- install
- open terminal in the bindings directory $(LazarusDir)/lcl/interfaces/qt5/cbindings
PATH=$(QtDir)/5.6/clang_64/bin:$PATH
qmake
make
sudo make install



Linux 64-bit (Mint 18.3 Sylvia)

$(LazarusDir): ~/fpcupdeluxe/lazarus
$(QtDir): ~/Qt5.6.2

- make sure OpenGL headers are installed:
sudo apt install mesa-common-dev
sudo ln -s /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1 /usr/lib/libGL.so
sudo ldconfig

- download: qt-opensource-linux-x64-5.6.2.run
- install
Modify the system-wide config in /usr/lib/x86_64-linux-gnu/qt-default/qtchooser/default.conf to point to your Qt5 directories:
$(QtDir)/5.6/gcc_64/bin
$(QtDir)/5.6/gcc_64/lib

- open terminal in the bindings directory $(LazarusDir)/lcl/interfaces/qt5/cbindings
qmake
make
sudo make install
sudo strip $(QtDir)/5.6/gcc_64/lib/libQt5Pas.so.1.2.6



Happy Easter!

Sunday, February 11, 2018

Not interested in improving your product?

This morning I've found some sad news over at The Wiert Corner.

Apparently, Jeroen Wiert Pluimers - a valued member of the Delphi community, whose work I appreciate a lot - got his MVP status and technical partner licenses revoked. Jeroen won't be able to support Delphi community and open source projects as much as before because the latest licenses of his own are Delphi 2007 and XE4.

Jeroen's been a very active member of the Delphi community over the years, providing countless articles, blog posts, comments, bug reports and constructive participation in technical discussions. His contributions were always standing out as helpful, to the point, clearly with the aim and wish to improve Delphi, to provide value to the people involved, to support the community, and, need I really say it, thus also the company selling the product.

What happened, Embarcadero? Care to comment on this? Since this might be interpreted as "constructive criticism not welcome here".

I hope this could still come out as a misunderstanding which can be sorted out and forgotten soon.

Friday, January 12, 2018

chakracore-delphi initial release

The initial release of chakracore-delphi is out, published under the MIT license.

Short summary:



Comments, ideas and of course pull requests are very welcome. Cheers!

Saturday, January 06, 2018

chakracore-delphi

With the initial release coming up soon, here are a few teaser screenshots of chakracore-delphi, a new opensource library with Delphi and Free Pascal bindings and classes for Microsoft's ChakraCore Javascript engine:


FPC 3.0.4 and Lazarus 1.8 build (win64):

FPC 3.0.4 and Lazarus 1.8 build (linux64):

FPC 3.0.4 and Lazarus 1.8 build (macosx64):

Delphi XE 10.2 Tokyo build (win64):

Delphi 2009 build (win32):

Delphi 7 build (win32):

and a tiny code snippet showing an example of embedding the Javascript engine and exposing some native methods to it: