Smart Mobile Studio
  • News
  • Forums
  • Download
  • Store
  • Showcases
    • Featured demos
    • The Smart Contest 2013, Round 1 – Graphics
  • Documentation
    • Get the book
    • System requirements
    • Prerequisites
    • Getting started
      • Introduction
      • Application architecture
      • The application object
      • Forms and navigation
      • Message dialogs
      • Themes and styles
    • Project types
      • Visual project
      • Game project
      • Console project
    • Layout manager
    • Networking
      • TW3HttpRequest
      • TW3JSONP
      • Loading files
  • About

Using external JS libraries with Smart Mobile Studio

Posted on 15.01.2016 by Smart Mobile Studio Team Posted in Developers log, News and articles
Neuron groups, ZEISS-Microscopy, CC

Neuron groups, ZEISS-Microscopy, CC

In the forums there was a discussion about how to wrap existing libraries transparently and with a minimum of overhead. In that discussion an example was given about how to wrap the neural network library brain. To avoid posting the same text here as well, this blog post is about translating another neural network library called ‘Synaptic‘.

Getting Started

When starting, it’s useful to have a look at the JS libraries homepage or GitHub page. In this case both exist and are worth a closer look. The homepage contains 6 demos, which are interesting enough to get us hooked. Beside the demos it contains a link to the documentation, which redirects us to the corresponding GitHub page.

The documentation is divided into 5 different sections, where each section documents a certain JS file. In this context we only have a look at the first section. The other sections/files can be translated in the same manner.

Now let’s start by having a look at the ‘Neurons’ documentation. As you can see there’s not much to read, but at the same time there is no code snippet that looks like a class definition in the first place. Still we can wrap it into a class nicely.

With the sentence

“A Neuron can perform basically 4 operations: project connections, gate connections, activate and propagate”

we can easily imagine a class called “Neuron” with 4 methods. Something like this:

type
  TNeuron = class
    procedure project;
    procedure gate;
    procedure activate;
    procedure propagate;
  end;

In fact – as external code is only interfaced – this is not a real class, but an external class. This means that we only need the definition while the implementation is done by the external JavaScript code.

External Classes

Since external classes are the glue between the Object Pascal and the JavaScript world it is important to mention that these classes are case sensitive. This means that the method ‘project’ will become a ‘project’ in the JavaScript output. Alternatively, you can also use any other favorite naming style, but specify the JavaScript separately. It could look like this then:

  TNeuron = class external
    procedure Project; external 'project';
    procedure Gate; external 'gate';
    procedure Activate; external 'activate';
    procedure Propagate; external 'propagate';
  end;

What remains missing are the parameters of the methods. These can be gathered by taking a closer look at the documentation for each method. Let’s start by looking at ‘project’ https://github.com/cazala/synaptic/wiki/Neurons#project

We can find the following code snippet:

var A = new Neuron();
var B = new Neuron();
A.project(B); // A now projects a connection to B

This makes clear that the method ‘project’ has at least one parameter, which is another neuron. The sentence ‘The method project returns a Connection object, that can be gated by another neuron.’ also makes it clear that it outputs a ‘connection’.
Now it’s not really clear what a connection is. So we can only specify this as Variant (can be anything).

Our class looks like this now:

type
  TConnection = Variant;
  TNeuron = class
    function project(value: TNeuron): TConnection;
    [...]
  end;

Next, let’s have a look at the gate method. By the code snippet:

var A = new Neuron();
var B = new Neuron();
var connection = A.project(B);
var C = new Neuron();
C.gate(connection); // now C gates the connection between A and B

It got clear that the parameter for the gate method is a connection, so it can be written as:

procedure gate(value: TConnection);

For the method ‘activate’ the following documentation snippet:

var A = new Neuron();
var B = new Neuron();
A.project(B);
A.activate(0.5); // 0.5
B.activate(); // 0.3244554645

hints for a method that can accept either one or no parameter. This can be expressed in Object Pascal with the ‘overload;’ directive.

Thus it becomes to:

procedure activate(value: Float); overload;
procedure activate; overload;

Last but not least we have the method ‘propagate’. Its documentation code snippet is a bit bold to print in total, so let’s only focus on the use of the method propagate:

var learningRate = .3;
[...]
B.propagate(learningRate, 0);

From this you get that it has two parameters (numbers). In the example it remains unclear whether both are of type float or whether the second one is an integer. In case of doubt just always use floats. You can narrow this later at anytime when you have a confirmation that the parameter is really only limited to integer values.

Now we have all methods specified, so the class looks like this now:

type
  TConnection = Variant;
  TNeuron = class external
    function project(value: TNeuron): TConnection;
    procedure gate(value: TConnection);
    procedure activate(value: Float); overload;
    procedure activate; overload;
    procedure propagate(learningRate: Float; value: Float);
  end;

This can already be used on existing Neuron objects. Unfortunately, we haven’t specified a constructor so far and thus we can’t easily translate the existing code snippets from the documentation in Object Pascal.

Constructor

A basic constructor is always exposed by DWScript, it’s just not explicitly clear how this looks like. Luckily we have the ‘constructor’ keyword to specify a constructor in Pascal. DWScript typically ignores the specified name (in particular if it is ‘Create’) and uses the class name instead. However, out of convenience we can still use the ‘Create’ name. Thus a constructor can look something like this:

type
  TNeuron = class external
    constructor Create;
    [...]
  end;

Now if one calls:

TNeuron.Create

it will be translated to

new TNeuron()

which is just slightly different to the

new Neuron();

from the example.

However, this already looks promising, except for the fact that the name is still wrong. It can be fixed by either renaming the class to the JS name or by supplying an external name for the class or for the constructor.

Renaming the class is probably not the best idea as it should fit into the naming scheme. In Smart Mobile Studio a ‘J’ has been picked instead of the ‘T’ for Object Pascal types. This leaves the option to supply a dedicated external name (either for the class or for the constructor)

The example below shows both (only one would be really necessary)

type
  JNeuron = class external 'Neuron'
    constructor Create; external 'Neuron';
    [...]
  end;

With this you can already write all the documentation code snippets in Object Pascal.

Final thoughts

If this isn’t enough, you can always go deeper with the header translation by looking at the JavaScript source code. There you can discover whether there are further overloads to the functions or hidden return values. Also you can spot fields, which are mostly used internal, but might become useful if you want to extend the supplied class.

In case of the Synaptic library there are 4 more sections that needed a header translation until it is fully usable. Consider this as homework until the next beta (to be released soon) will contain all translated headers. You can find it in the library path (under ‘Synaptic’).

HTML5 javascript Neuronal Networks Object Pascal
« Smart Mobile Studio 2.2 (beta-4)
Telling a 32bit float from a 64bit float »

Pages

  • About
  • Feature Matrix
  • Forums
  • News
  • Release History
  • Download
  • Showcases
    • The Smart Contest 2013, Round 1 – Graphics
  • Store
  • Documentation
    • Creating your own controls
    • Debugging, exceptions and error handling
    • Differences between Delphi and Smart
    • Get the book
    • Getting started
      • Introduction
      • Local storage, session storage and global storage
      • Application architecture
      • The application object
      • Forms and navigation
      • Message dialogs
      • pmSmart Box Model
      • Themes and styles
    • Layout manager
    • Networking
      • Loading files
      • TW3HttpRequest
      • TW3JSONP
    • Prerequisites
    • Real data, talking to sqLite
    • System requirements
    • Project types
      • Visual project
      • Game project
      • Console project

Archives

  • December 2019
  • December 2018
  • November 2018
  • July 2018
  • June 2018
  • February 2018
  • September 2017
  • April 2017
  • November 2016
  • October 2016
  • September 2016
  • April 2016
  • March 2016
  • January 2016
  • October 2015
  • September 2015
  • July 2015
  • April 2015
  • January 2015
  • December 2014
  • October 2014
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • November 2013
  • October 2013
  • August 2013
  • July 2013
  • June 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • November 2011
  • October 2011
  • September 2011

Categories

  • Announcements (25)
  • Developers log (119)
  • Documentation (26)
  • News (104)
  • News and articles (16)

WordPress

  • Register
  • Log in
  • WordPress

Subscribe

  • Entries (RSS)
  • Comments (RSS)
© Optimale Systemer AS