Friday, October 29, 2010

ELENA 1.5.6 released

What's new in 1.5.6

Despite my promise in the previous post I released a new version early and it is a major one. Once again the method calling routine was overhauled.
So what's the point of it? After the subject concept was introduced the number of subjects increased at very high speed. Practically any new functionality brought new subjects as well. So I realized that proposed solution is not ideal and there is a question of subject reusing. So the next step was to start to use it for different patterns. But this contradicted with the original goal of subjects - to prevent possible name conflicts. As a result I separated generic subjects from domain oriented. Instead of "aControl control'items" I use "aControl control items" (where items is a generic subject and control is a part of gui dictionary). Thus the code was simplified (both compiler and source ones) and several ideas were dropped (property, nested subjects and so on).
Another very important change deals with nil'ifnot. Actually "if" or "ifnot" verbs require a parameter. "is" does not need is. So Instead of "nil'ifnot" - "nil'if" is used (and this is more logical than the previous message, only nil symbol should support it)
And of course all these changes broke the compatibility with the previous versions (but I hope this will not require any significant efforts).

Here the comparison between 1.5.5.x and 1.5.6 code samples:
  • aControls @ connector'SecondPlayerID control'items control'selected'index'set:0.
  • aControls @ connector'SecondPlayerID items selected'set:0.
  • #var aPlayerInfo := aControl control'items control'selected control'tag.
  • #var aPlayerInfo := aControl items selected tag.
  • #if aValue nil'ifNot [self write:aValue. ].
  • #if aValue nil'is | [self write:aValue. ].

Thursday, October 21, 2010 weekly release release is out now.

There are several enhancement over method calling: it is now possible to use nested secondary subjects, #property keyword is introduced (yet not fully tested).

Several major bugs were fixed, including
#00057 (read a long string from the console) and a one with 64bit integer constants.

Small changes in ELENA API: ctrl'IndexBackwarding is no longer supported, a new symbols - std'patterns'Loop, std'patterns'IndexLoop, std'patterns'IndexBackLoop and std'patterns'IndexerLoop should be used

Work on linux migration and x-project is continued

A major release is sheduled on mid of novermber ( actually it will be one of normal weekly release ).

Tuesday, October 12, 2010 weekly release

ELENA is out.

The release features a new control - gui'controls'Menu ( look at notepad sample to learn how to use it ).

Several new methods were added:
- std'collections'List
* clear - clears the list;
- win32'controls'edit / win32'controls'memo
* edit'selection'get - returns the edit cursor position and the selection length
* edit'selection'set - sets the edit cursor position and the selection length

For example
#var aPosition := theEdit edit'selection edit'selection'starting. // the cursor position
#var aSelection := theEdit edit'selection edit'selection'length. // the selection length or 0 if the text is not selected.

A #00056 bug is fixed: when the default encoding is unicode there were problems with ansi files

ELENA Project code is moved to gcc4 (it took me some time before I was able to compile the code, I even started to think over moving to MSVS Express)

Monday, October 4, 2010

Method Calling tutorial

From the first programming languages procedures (or functions) play very important role. Introduction of object-oriented paradigm increase this role even more. So it is not possible to program a language without learning the way how it handles procedures. This tutorial will show that this is not so trivial in ELENA.

When ELENA programming language was designed I made an important decision - to limit the number of method parameters to just one (concept of the limited object interface). It was done to make the object interface (or protocol if you wish) as much polymorphic as possible (selecting one set of parameters over others implies the way how it will be used; anyone who tried to add another method with the same name in the C++ base class knows that it could be a painful process).

So how String.Insert(index, value) method could be implemented if you cannot provide another parameter? There are general several ways how to do this. First way would be to introduce a special class (in this case std'basic'LiteralIndexer) which will be a mediator (agent) between string and the piece of code where the substring is inserted. So in ELENA it will look like this anStr@index insert:value ( @ operator will return an indexer pointing to specified position). One good thing with this that it is a code pattern. So every time we would like to insert something into an indexable collection we will use this way. But sometimes we have to set several peer parameters (like x and y coordinates). Of course we could set them independently but if it is important to set them simultaneously the second way could be used - aControl location'set: { location'x = 20. location'y = 20. }. The good thing is that location'set is a polymorphic method ( no change in the method interface have to be made if we decided to use three-dimensional or polar coordinates). The bad thing that the expression is quite big. So a special simplified version could be used - aControl location'set &x:20 &y:20. If the method requires no parameters a special nil symbol is passed to it - aControl control'open ( <=> aControl control'open:nil).

Being dynamic ELENA does not allow to implement a method overload a la C++. Instead the polymorphic nature of method parameter can be used. For example std'patterns'IndexEnum::pattern'run could use two set of parameters - ctrl'IndexEnum &for:anArray &action: => [ .. ] and ctrl'IndexEnum &from:anArray@2 &action: => [ ... ]. std'basic' LiteralIndexer :: literalinfo'create method is another example. If we would like to copy a substring from the specific position till the end we could omit parameter at all - aStr@2 literalinfo'create. If we wish to provide a substring length - aStr@2 literalinfo'create &length:10. If we are interested in copying a substring from one indexer till another - aStr@0 literalinfo'create &till:(aStr@1 literal'seek:" ").

Note that in all examples above a single method body was used. If we need a specific implementation for different parameters multi-dispatching routine should be used. In ELENA multi-dispatching is similar to traditional polymorphism with the only difference that executing code depends on a parameter rather than the object. For example if the method parameter is an integer - an integer operation should be executed. If it is a real number - real one and so on. e.g. - aWriter write:2 write:2.3r write:"literal" should correctly write to the stream an integer, a real and a literal values.

How could we achieve this on the language with the late binding (no compiler magic like in static languages)? Several ways could be used. One of them would be to ask the parameter to do the operation itself (after all who knows how to handle the object better than the object itself?). The problem with these approach (which is used in ELENA as well) that the object should know all possible operation with it. In ELENA a method naming limitation makes the things even worse (It is not possible to call the method copyToInteger, lessThenInteger as it would be discussed later). So as an alternative the concept of the subject was introduced.

The subject could be considered as a declarative type (a unique token). For example std'basic'Literal, std'basic'String and gui'control'Edit are all implement literal subject (note that they do not share common code with each other except a generic super class). The subject should be declared before use. It is inherited but the class may support only one subject (it is done with a special compiler hint - #hint[subj:literal] before a class or symbol declaration).

Before continuing let's consider another topic where a subject is used - method naming. As opposed to many main stream languages ELENA limits the way how a method can be named. Any public message may consist of subject and verb (generic messages have only verb part of the name). The number of verbs are limited and well defined (e.g. and, get, set, read, write, start, run and so on). The subject is defined by the user and could represent an actor or type (bool'and, int'add, literal'read, indexer'get; see above). The subject may represent the process as well (pattern'run, process'start and so on).

So let's return to multi-dispatching mechanism. If our class (stream writer for example) handles a particular subject (integer, real or literal values) the method name should contain the appropriate subject (int'write, real'write and literal'write). This approach allows the object to notify any potential user of expecting parameter type (note that in a language with late binding like ELENA the mismatch type errors can be found only in run-time) or returning value (literal'get) or expected operation - (process'stop). As a plus this helps us with multi-dispatching as well. If we mark our class as dispatchable (#hint[dispatchable]) when the expression aWriter write:2 write:2.3r write:"literal" will actually invoke int'write, real'write and literal'write respectively.

Saturday, October 2, 2010 weekly release

After a false start, ELENA is out.

This release contain a new sample notepad which uses a new class gui'common'LayoutManager designed to auto adjust control location when the form is resized.

on'resize event is now raised after the control size is changed.

The work on linux migration and x project continued