Friday, December 24, 2010

Up'N'Down 0.1 is released

After more then two years I managed to release the first version of Up'N'Down game, the first "real" program written with ELENA.

http://sourceforge.net/projects/upndown/files/0.1/upndown-bin-0.1.zip/download

Monday, December 20, 2010

Weekly release: 1.5.6.4

There were several critical bug fixes (disabled debug mode crashes executable file, cirtical fix in $next keyword implementing, cirtical fix in the long integer constant implementation), a new class std'collections'dictionary and some minor changes in the language itself.

First, I'm continuing to re-factor ELENA API code. As you probably know the language features some formal rules regarding the method names. They consist of subject and verb. The number of verbs are limited and should be well-defined. As it appeared there is a two ambiguous verbs - do and run. So starting from 1.5.6.3 the code review is proceeding and as a result some of subjects were dropped (like literalinfo, memoryinfo and so on). The main goal is to make sure that the subject defines the method parameter (with exception for 'do' verb) rather then the operation. Another goal is to make sure that the subjects are reusable (which is not the case for the subject like literalinfo).

Second bug change deals with operators. The operators are normal methods with custom parsing order. The expression '2 + 3 * a int' is parsed like 2 + (3 * (a int)).
Because of they nature it was not possible to provide the operator with the subject.
As a result the use of operators was limited. Starting from 1.5.6.4 the operators are synonyms to 'normal' verbs:
'==' <=> 'equal'
'!=' <=> 'notequal
'+' <=> add
'?' <=> is

and so on.

Thursday, December 9, 2010

ELENA Programming Language: The Next Big Thing

I've started the project more than 10 years ago. I've made a decision to create my one language in the summer of 1999. I had a quite vague idea what it would be except the idea that it will be a pure object-oriented language with late binding (dynamic one). So at first I was occupied with technical tasks implementing the compiler. The syntax was not important (due to a LALR parser which gave me total freedom over it). Compiler-free linker was created and since that I was able to concentrate on the language itself. ELENA is a frame language actually, it doesn't implement the "real" code (like adding numbers, comparing strings and so on). So I was free from this as well and concentrated on experiments with different language models (still in object-oriented frames). In 2006 I published the project on the sourceforge site and since that the work was accelerated. In 2007 the modern-like syntax was introduced. In 1.2.0 (2008) the first dynamic features were introduced (context-dependant roles). In 1.2.5 the dynamic inheritance was introduced. The latest version 1.5.6 introduced the final version of method calling routine (subjects and verbs). So what will be a next big thing?

Starting from 1.5.7 I will start so-called "y project". It's main goal is to create a special meta language which will be a high level abstraction script for the language virtual machine (elenavm). Unlike "traditional" scripts it will be not imperative. In ideal case it should be set of instructions how to assemble (self-assemble) the set of objects (symbols in ELENA terms) which will be able to solve the problem (objects themselves are written in normal way). The test bed will be opencalc sample. With the help of vmconsole the programmer will be able to interact with the system by entering the script (actually recombining existing ones).

One could say, is it real or just a pipe dream? At the current moment it is hard to say. It is actually a manifest or declaration of intent. The direction I'm going to work on. But I hope the first result (probably very early) will be already seen in the 1.5.7 release. Time will say

Saturday, December 4, 2010

Weekly release: 1.5.6.3

What's new since 1.5.6.1:

1.5.6.2

- changed inline class implementation
- new symbol ext'io'TextReading
- fixed std'basic'memory:bugs with memory operations
- fixed critical bug with long number constant
- new project template - guivm
- new : std'patterns'Validation symbol
- new : sys'groups'StaticBroadCaster
- dynamic symbol loading
- new symbol sys'vm'loader

1.5.6.3
- drop support of streamable subject
- fixed matrix sample
- enum verb is obsolete, use run
- indexerloop symbol is obsolete - use index
- loop subject is obsolete
- new verb:rewind
- control-evaluate should be used intead of control-run
- control-run / control-rewind repeats the action while the result is true / false
- canvas: possible to select color and font

It is now possible to load dynamically symbols by their name (for vm clients)

Starting with 1.5.6.3 the work on ELENA API refactoring is started. The main focus would be methods named like xx'run and xx'do. At the moment there are too many such names.

As I wrote before ELENA introduces an original concept of method naming. Unlike many other languages the language proposes a formal rule for method naming. The normal method name consists of the subject and the verb. As it appeared there are too many methods with subject which in fact a gerund rather then a noun. So I will rename such methods to make the subjects more resusable. And some form of subject morphology is introduced: [subject]+ing <=>[subject] + for + action (e.g. range and ranging, list and listing).

So bsort sample is changed:
1.5.6.2:
- ctrl'IndexerLoop backwardloop'run &from:aLastIndex &till:0 &for:anArray &action:
1.5.6.3 (a new verb rewind):
- ctrl'IndexIterator ranging'rewind &for:anArray &till:aLastIndex &action

1.5.6.2:
- ctrl'IndexEnum loop'run &for:anArray &action:
1.5.6.3:
- ctrl'IndexEnum listing'run &for:anArray &action:

The subject loop is obsolete ( it is in fact a process rather then an object )

Monday, November 8, 2010

Weekly release: 1.5.6.1

I spent the last week fixing number of bugs, including several critical ones:
- fixed the issue with the focus in upndown sample
- fixed int64 division
- fixed int64 subtraction
- add possibility to import subjects on the level of the module
- critical bug with nested conditional statements
- critical bug with GC

Most of the work was done with upndown sample which is now more stable. I plan to release the first alpha version of the game during the current month

x-project reached a significant milestone: young generation garbage collection routine is tested for console applications, next will be gui ones. After that I will start to implement multi-threading routine

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.
Or
  • #var aPlayerInfo := aControl control'items control'selected control'tag.
  • #var aPlayerInfo := aControl items selected tag.
Or
  • #if aValue nil'ifNot [self write:aValue. ].
  • #if aValue nil'is | [self write:aValue. ].

Thursday, October 21, 2010

1.5.5.11 weekly release

1.5.5.11 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

1.5.5.10 weekly release

ELENA 1.5.5.10 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

1.5.5.9 weekly release

After a false start, ELENA 1.5.5.9 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

Saturday, September 25, 2010

1.5.5.8 weekly release

A new weekly version is out now.

After a long delay it is now possible to debug elena vm clients. IDE Project settings were changed. There are three debug modes: disabled, enabled and enabled in vm. To debug vm client the third option should be selected.

The work on upndown, dtcalculator and eldoc samples continues.

I finally fixed the problem with helloworld sample (#00053) (it is shame that it took so many time to find out that I forgot to change the method name from 'do' to 'evaluate').

New symbols: sys'dates'today (theoretically it should return only date without time), ext'patterns'printingln (will print the line and moves the cursor to the new line).

I modified textfile reader implementation. The reader no longer returns trailing %r%n characters.

New methods:
std'patterns'indexenum search'run &from
(e.g ctrl'indexenum search'run &from:a@3 &value:b
- compare with ctrl'indexenum search'run &for:a &value:b)

sts'basic'literalindexer literalinfo'create &till
(e.g a@i literalinfo'create &till:a@j
- compare with a@i literalinfo'create &length:(j - i))

Monday, September 20, 2010

ELENA Programming Language: Object model


ELENA is a general-purpose, object-oriented, polymorphic language with late binding. It features multiple dispatching, context-dependent roles, dynamic inheritance and group object support.


The language treats any program as a set of objects (class instances). The program flow is a process of interaction between objects by sending each other messages. A message may have attached information (a message parameter). An object may react on message if it has an appropriate message handler (a method). If the object reacts on the message it is treated as successful otherwise unsuccessful. In its turn the method may send messages to other objects and so on until the flow reaches the method written by external tools (meta method). If the message is unsuccessful the flow is considered to be broken. It's possible to declare alternative flow which are executed if previous ones are broken. The method has only one input parameter and one output parameter (if the method returns itself it may be considered as an input one).
Every object may be formed up with other objects characterizing its internal state. They in turn may be formed with others and so on until meta objects which internal states are considered as raw data.
All referring entities in the language are objects. A variable is a reference to the object allocated in the program heap. The literal and numeric constants are references to the objects allocated in the static memory.


Any object is an instance of one or another class. The classes form the hierarchy tree on the principle of inheritance. There is the common super class - Object. The class parent may be explicitly declared. When the parent is not specified, the class inherits Object.


A class is an abstract concept which means that no operations can be done with it except a declaration. So to create the object its symbol should be referenced. There are explicit and implicit, static and dynamic symbols.
When a new class is declared simultaneously the appropriate implicit symbol is declared as well. The explicit symbol should be declared explicitly. In general the implicit symbol is the object in the initial state and the explicit one is the object in the particular state.
A static symbol is the class instance which state is preserved. A static symbol is always explicit one. There could be only one instance of static symbol.
The class declaration can be named or unnamed (inline declaration) public or private (when the class name is a private name). Its body contains member declarations: fields, roles and methods.


The fields can be accessed only within the class and its descendants. They can be a normal ones (references to another objects) or meta ones (raw data).
The roles are alternative sets of methods which could be used to implement context-dependent object behavior. When it is applied the role overrides the appropriate object methods with its own ones (static mutation).


Methods maybe private or public depending on their name (public or private). All class methods are considered to be polymorphic. It is possible to dispatch the method call depending on its parameter (declarative multi-dispatching). The method has only one input (or nil) and output (or it should return itself) parameters. If the method requires several parameters a special proxy argument list object can be used.


It is possible to declare a special "Any" handler. It is a method which redirects any unhandled message (i.e. messages which are not mapped in the class or its base classes) to the specified target. The target could be a single object (actually mutation) or collection (group object). A group object is a collection of the objects accessible through the common instance reference. The content of the group can be changed dynamically during the object life time (self-modification). The member objects can be a part of different groups or be single. The group can be persistent or temporally created to solve the particular task. The group objects are treated like "normal" ones and no special routines are required to work with them. If two or more members have duplicate methods either the first message mapping is resolved (exclusive mode) or all duplicate methods are executed (broadcast mode) depending on the group type.

Sunday, September 19, 2010

1.5,5,7 weekly release

Several new symbols were added to ELENA API:
sys'io: BinaryFile, NewBinaryFile
ext'text: HexAdapter, EIntFormatter, ELiteralFormatter

BinaryFile and NewBinaryFile are adapters to work with binary files.

#var reader := BinaryFile::"file.dat" reader'get.
#var writer := NewBinaryFile::"newfile.dat" writer'get.

Returned reader and writer support basic reader / writer protocol to work with data.

HexAdapter will allow to convert hexadecimal literal constant to the integer and back:
#var S := ext'text'HexAdapter literal'of:2Dh. // -> "2D"
#var N := ext'text'HexAdapter int'of:S. // -> 2D

The work on upndown example continues. It is now possible to play basic rounds (without joker).

New binary corex.bin will contain an enhanced GC implementation supporting multi-threading.

Some settings were moved from elc.cfg to the specific templates (like console.cfg)

On the next week I will start a debugger redesign (to support elenavm client debugging), continue slow migration to Linux and a lot of other things.

I'm planning to start my first real open architecture application - opencalc.

So that's all for this week

Tuesday, September 7, 2010

ELENA Programming Language: Paradigm

As a general purpose programming language ELENA is able to support various programming paradigms. But there is a special one the language was made for: open architecture paradigm (OA).
OA paradigm presumes that the system consists of the number of relative simple objects actively interacting with each other and forming object groups. The content of the group can be modified (self-modified) depending on its state or functionality. Typical group consists of several members representing different implementation layers. Let's presumes that we develop the card game. The main system actors will be: a game master, a player and a representer. We could define several layers: basic, game logic and multiplayer ones. A basic layer will implement the common functionality which will be used in any game. A game logic layer will care about implementing the game rules and a multiplayer one will support a chosen transport protocol. Additional layers can be applied to any game actors, like AI one for the player. Testing environment can also modify the system to set up some test scenario and so on. A group content will be modified to be more suitable for the current game stage (for example a computer player may change it content for implementing different strategies, if the game has different stages the game master will be self-modified to lead the appropriate game stage). At the game start the main groups will be self-assembled depending on the user choice.
In general OA paradigm tends to change the accent from a vertical inheritance to a horizontal one. It will make the program implementation more decentralized, limiting the number of "super" objects. The main advantage of this approach is the possibility to extend / modify system more easily, sometimes even without need to recompile it.

Friday, September 3, 2010

1.5,5,4 weekly release

A new version is available - 1.5.5.4

It contains mostly ELENA API bug fixes and a new symbol - gui'dialogs'errorbox

Thursday, September 2, 2010

Method calling in ELENA: overhaul, part 2

First of all, I would like to announce changes in the project release practice. Now there will be two types of releases: official and weekly ones. Official release will happens once per several months (version number x.x.x) as it was before. But additionally every several week I will publish weekly release (version numbers x.x.x.x) and they will be located in http://sourceforge.net/projects/elenalang/files/ELENA/Weekly.

The first such weekly release happened yesterday - http://sourceforge.net/projects/elenalang/files/ELENA/Weekly/elena-1.5.5.3.zip/download
The main purpose of that release was publishing the changes in method call syntax. Apart from this I did several small enhancements. First of all I decided to get rid of message subject prefix "gui". Though it is still possible to use it in most cases now it is recommended to omit it. So the old style code like this - self set &gui'location'x:50 &y:50 set &gui'size'width:700 &height:520 gui'control'caption'set:"Caption" - will look a bit better -
self location'set &x:50 &y:50 size'set &width:700 &height:520 control'caption'set: "Caption".
The same for event handler - on'control'Click'do has to be converted to on'Click'do.

Here the list of changes:
  • LiteralType and ArrayType "create" methods are now obsolete. LiteralType literalinfo'create &length and ArrayType arrayinfo &count should be used instead. If you wish to initialize the array during its creation you should use the same method - basic'ArrayType arrayinfo'create &count:10 &action: => (basic'Integer <<0)
  • ctrl'IndexEnum run &enum'in &action and ctrl'Enum run &enum'in &action are no longer supported - ctrl'IndexEnum pattern'run&for &action and ctrl'Enum pattern'run&for &action should be used instead.
  • gui'control'items'get => control'items'get
  • Event handlers "on'control'Paint'do" and " control'IndexChanged'do " should be converted into - on'Paint &canvas and on'IndecChanged &index
  • ext'patterns'ArrayType is no longer supported. Use std'basic'ArrayType instead
  • ext'io'textfile and ext'io' LogTextFile are no longer supported. They were moved into sys package. So use sys'io'textfile and sys'io' LogTextFile
  • std'patterns'Loop is refactored. Repeater pattern'run &for &action should be used instead
The old style syntax will be kept until 1.5.6 release. If you have any questions or problems with converting feel free to ask.

Friday, August 20, 2010

Method calling in ELENA: overhaul

As I already told several times ELENA is developed in "evolutional" mode (which is quite suitable for an open source project where there are no major releases and new versions are released often). It has its pros and cons but it is fun because you never know what will be next (except the pain from rewriting the whole code again and again).

When I introduced a new syntax for sending messages in 1.5.5 I had no idea that already in 1.5.6 it will be overhauled once again (though this time I will try hard to keep backward compatibility).

Before I will outline what will be new in 1.5.6 I will shortly describe the history of the problem.

I told this hundred times but it's worth repeating it again. ELENA is a highly dynamic language. This means that many approaches which are suitable and easy in the world of static languages may be problematic in the dynamic one. One of them is sending messages. You may ask what problem may be with calling a method? Yes, in a statically typed language it is not a problem (though with typecasting you may shoot your feet easily) but in a dynamic one there is a chance that message meaning was overloaded (after all human languages are very ambiguous). You send "or" message supposing the bit wise operation while a receptor treats it like Boolean one. So you either check the object type or pray that this time it will be ok. In ELENA it is even worse. A group object may consist of several objects many of them were not designed to work with each other so the chance of name conflict are quite high. After trying several other techniques I proposed the concept of a message namespace (though it was designed for other purpose).

In 1.5.5 this concept gets final implementation (I hoped so but the time proved that I was wrong). Every message consists of a subject and a verb. The number of verbs are limited (like in many human languages) and well defined (in a theory, in reality it is more or less defined :)). The subject have to be defined in the program and usually belongs to the program use case. For example "or" is a verb. "Int" and "bool" are subjects (representing integer and Boolean values). So if you need bitwise "or" - "int'or" should be used, otherwise "bool'or".

It appeared that the concept of subjects may be used not only for calling methods but for implementing multi-dispatching as well. std'basic'Integer and std'basic'LongInteger may support "int" subject, std'basic'Boolean, std'basic'True and std'basic'False support "bool" one. So if the receptor is dispatchable (it means the object support mutli-dispatching) the operation - receptor or:parameter - will produce different results depending on the parameter subject (in contrast to polymorphism where the result depends on the receptor type). If a parameter is an integer number - "int'or" will be executed. If a parameter is a boolean value - "bool'or". And so on.

Moreover I found that the subject may help me with another problem. ELENA is a language with a limited operational set. It means that the object method may have only one parameter. Actually it is not a big problem. If you need to pass several parameters you may use something like this - control location'set: gui'common'Point { location'x'get = 0. location'x'get = 0} (where x and y are second level subjects). But the resulting code is quite clumsy. So with the help of the subject I was able to simplify it (though keeping original concept) - control set &location'x:0 &y:0.
This approach made me happy until I started to migrate the code. It appeared that as a result I was forced to have two set of methods to support both of these expressions. And finally in 1.5.6 I found the way how to avoid it.

So the new version of the code will look like this - control location'set &x:0 &y:0. Not a big difference you may say. In fact it is. This could will be translated by the compiler to the following one - control location'set:#hint[subj:location]{ location'x'get = 0. location'y'get = 0. }. Which is equivalent to the original one. So no need to duplicate. And "location'set" method may look like this - #method location'set &x:anX &y:anY [ ... ]. This method will be able to support both type of passing multiple parameters and multi-dispatching one as well - control set:point .
Moreover I found that (once again :)) it may resolve another problem. Every time inline object was used the compiler create an appropriate VMT. As a result the code contains several duplicate VMTs. To resolve this some complex logic should be involved. Subject will fix this problem. Every time a subject with secondary items are declared the compiler will create a VMT. So no need to create them in place.

No one can stop me from continuing :). If a subject is declared with VMT I may customize get method. So it may help to reuse some common patterns. E.g. in location'set I have to call int'get for x and y every time I used them (don't forget a parameter may be a group or proxy object). Instead of this I will be able to write something like this - #xsubject location ( x => x int'get, y => y int'get ) (#xsubject will be used instead of #subject for backward compatibility with 1.5.5).

And finally (at least at the moment) I decided to simplify another thing. If you wish to return an object field you usually use the get method with secondary subject - point location'x'get. From 1.5.6 it will be possible to ommit get (and set) verb - point location'x (a subject cannot have a name coinciding with verb).

If you ask me what will be in 1.5.7? I will honestly answer - no idea :)

Monday, August 2, 2010

ELENA 1.5.5 released

I would like to inform about a new release of ELENA Programming Language.

It took me almost 3 months to finish the work (I actually refactored ELENA library code twice). The changes are everywhere and unfortunately it means that the 1.5.5 is not compatible with 1.5.4 (now I do understand some software firms which do not like to support previous versions :)).

Just short overview of the changes:

1) hints:
Instead of old style compiler hints - #class[...] Edit (Control) - the special keyword has to be used #hint[...] #class Edit (Control)

2) messages:
several messages (actually message verbs) like proceed, continue, ifnotnil are no longer supported, the new ones are evaluate, do, nil'ifnot

3)Multiple dispatching mechanism is refactored and optimized. I will discuss this later in more details.

4) A new type of group object is introduced - #union. I will discuss this later in more details.

5) elena byte codes (ecodes) are redesigned, I continue to optimize the virtual machine command set

6) context'get is no more supported, use instead enum'content'get (for enumerations) or indexer'content'get (for indexers)

7) special type of messages is introduced to simplify passing the multiple parameters to the method (It took me so many years to invent the wheel but I'm quite happy with this implementation).

So instead of - theEdit gui'size'set:gui'Size{ gui'size'Width'get = 200. gui'size'Height'get = 24. } more simplified version could be used - theEdit set &gui'size'width:200 &height:24. I will discuss this later in more details.

Here the link - http://sourceforge.net/projects/elenalang/files/ELENA/1.5.5/elena-1.5.5.zip/download

Sunday, July 25, 2010

Group Objects Example

Let's consider the use of group objects.

In the next example I will demonstrate how to extend and customize code using branch-free self modifying code.
(Note that 'project' should be replaced with a name of the source file)

// --- namespace shortcuts ---
#define basic'* = std'basic'*.
#define ctrl'* = std'patterns'*.
#define list'* = std'collections'*.

#symbol Printing = anItem =>
[
// prints a parameter
'program'output << eshownext =" anItem">
[
// replace itself with ESkipNext
#inline elena'172 (self, $self, project'ESkipNext).
].

#symbol ESkipNext = anItem =>
[
// redirects the call to the next group item
$next proceed:anItem.

// replace itself with EShowNext
#inline elena'172 (self, $self, EShowNext).
].

#symbol Program =>
[
#var aList := list'List.
aList += 1 += 2 += 3 += 4 += 5 += 6.

// extending
'program'output << "All items:%n".
#group(ctrl'EEnum, aList) run:Printing.

// customizing
'program'output << "Every second item (1,3,...):%n".
#group(ctrl'EEnum, aList) run:#group(ESkipNext, Printing).

'program'output << "Every second item (2,4,...):%n".
#group(ctrl'EEnum, aList) run:#group(EShowNext, Printing).
].

The program start in Program symbol. Firstly we have to create a collection.

#var aList := list'List.
aList += 1 += 2 += 3 += 4.

In the code below we will enumerate every member of the collection and print it.

// extending
'program'output << "All items:%n".
#group(ctrl'EEnum, aList) run:Printing.

aList is extended with ctrl'EEnum adapter. EEnum is a FOR EACH pattern, executing the action for every member of the collection it is combined with. Printing is a simple action which prints a provided parameter. In combination this code prints every member of the collection.

Let's consider how could we customize it to print only every second item without if statement.

// customizing
'program'output << "Every second item (1,3,...):%n".
#group(ctrl'EEnum, aList) run:#group(ESkipNext, Printing).

Printing action is combined with a special adapter ESkipNext. ESkipNect redirects the flow to the next group item and modify the group by replacing itself with EShowNext. So during the next call EShowNext will be executed. EShowNext in its turn replaces itself with ESkipNext and so on. As a result we will print every second item of the collection. A voila.

To be continued...

Thursday, July 22, 2010

Group Objects

Let us define a group object as a collection of the objects accessible through the common instance reference. The member objects may or may not have any relations with each other. They may or may not have intersecting message mapping. The content of the group can be changed dynamically during the object life time (self-modification). The member objects can be a part of different groups or be single. They may not even notice they become a part of the group (dynamic overriding). The group can be persistent or temporally created to solve the particular task. In general the group objects are treated like "normal" ones and no special routines are required to work with them. If two or more members have duplicate methods either the first message mapping is resolved (exclusive mode) or all duplicate methods are executed (broadcast mode) depending on the group type.
So how may group objects be used? Let us consider several possible use cases: code customization, "branching-free" / self-modifying algorithms and horizontal inheritance.

Customizing / Extending existing code


The concept of the group object may be used for modifying the existing code. Sometimes only minor changes should be applied to the code to be reused. Commonly we may override the class. Or we could combine it with the special adapter class containing only the methods we would like to change (actually dynamically override it, see horizontal inheritance). Though this two patterns are quite equivalent, the group can be formed with any object implementing a particular protocol at a run time. And in contrast to an aggregation we have to implement only the methods we would like to change without affecting others (which is quite important for the dynamic language where we do not always know the object type). Moreover in some cases we will not need to write a new code at all, only combining well-defined components. In general it allows us to inject the code into the complex system without big modifications and this injection may be invisible for other parts of it.

"Branching-free" algorithms


The content of the object group may be changed during its life time and it gives us quite an interesting feature: every time the group internal state is changed its actual content may be changed as well. Though the total number of the different states is quite big we can always select several extreme ones (empty list, unassigned reference, read-only collection and so on), place the code related to them into a separate control object (or several ones) and combine it with the main code. So when the group state is changed the control object replaces itself with the appropriate one instead of checking the state every time (alternatively the control object may have a several set of VMTs). Self modifying group can be used as well in many cycle algorithms where the first or the last action are different from the main ones. The real "branch free" code is unlikely to be feasible but the moderate usage can still simplify the code.

Horizontal inheritance


Group object can be used as an alternative to a multiple inheritance as well. Common satellite classes can be included in different groups allowing them to share the code without actually inheriting it, helping us to reduce the depth of inheritance tree.

Having looked at several use cases let us examine the possible implementation of the group object concept.

Possible implementation


Being born as a part of the dynamic language study the group object definitely requires a pure polymorphic language with a late binding. For implementation simplicity the concept of limited object interface was introduced. We presume that any class method may have only one input and one output parameters. If the method does not require any parameter a special void parameter is passed (e.g. nil constant). If the method does not require to return anything it returns itself (e.g. self variable). As a result we have a system with relatively big number of "simple" classes actively interacting with each other to resolve any task (so we can say that the number of inter-class calls tends to be higher than the number of inner-class ones). Finally let us introduce a proxy handler concept. The proxy handler is a special kind of a method which is executed every time there is no message mapping in the class VMT. It may redirect the call to the specific target.
Summering all above any group object consists of the array of group members and a VMT containing only a special proxy handler. Depending on the type of the group it redirects the call to the first object handling the appropriate message (exclusive mode) or to all members (broadcast mode). Every time a member method is called the reference to the group is passed to it rather than to the object itself. So when the method calls another object method it is in fact redirected to the group (dynamic overriding).
The only problem with this approach (except performance of course) is an access to the object fields. To solve it we need to keep the reference to the object as well. In a standalone mode both variables refer to the object. In fact having two object references allows the programmer to decide whether the method call might be overridden or not.

Name conflicts


But how predictable could such groups be? After all we combine the objects which are not always well known to us. Will there be any message conflict leading to unexpected results? To ease this problem we may introduce the concept of the message namespace. The words in a human language are quite ambiguous and as a result the message names may be ambiguous too. "AND" could be bitwise or Boolean operation, "GET" may return any value and so on. So let us introduce a special language entity of a message scope which describes well-defined term (e.g. "integer", "boolean") and list possible operations with it (e.g. "get", "and" ,...). Any message used by the group member should belong to one or another message scope (which has to exist physically). As a result the chance that the different members of the group will use occasionally similar messages is quite small.

Critical review


Though the scheme above seem a bit complex it costs not so much: an extra check per message call and an additional object variable (if we compare it with the cost of transition from a static call to a dynamic one). But in any case we are facing a bigger concern - redundancy. It is easy to show that most of the possible features could be implemented without groups (after all any high level programming language is translated to the machine codes and by definition cannot be more powerful than the assembler).

So is the introduction of the new entity really justified? And though there is no simple answer to this question several reasons can be mentioned. First of all it promotes more polymorphic and extendable code. The possibility to customize the object behavior without actually knowing much about it (except supporting protocols) will give a programmer more flexible way to deal with existing / reusable code. Secondly this approach reshapes the system structure. Instead of multifunctional classes we will get plenty of rather simple ones with limited functionality which can be easily tested and reused. And finally combining them into super entities makes the system more open and configurable.
To summarize this type of redundancy may be a key factor how to build and maintain more powerful and complex systems with an open architecture. And though it is too early to say if the concept of the group object makes the difference it can give a boost to active use of more structural self-modifying collaborative code.

Wednesday, July 21, 2010

General language overview

In the next several posts I will try to describe the language general overview, proposed programming paradigm and basic code patterns. So let's begin.

ELENA is an object-oriented programming language with the late binding. It means that it belongs to the same class as Smalltalk rather than C# or Java. It is a non-mainstream language and is used as a testbed for experiments with the language design, dynamic and self-modifying code and so on. So don't expect it will be easy to learn. Probably someone may say it is weird but I like its dynamic nature. It has weak sides but it DOES work. And finally it is a live language in the process of developing.

Let's consider several major language features which I will discuss in more details later.

ELENA is a language with the reduced class interfaces. It assumes that there is only limited way to interact with the object on the base of protocols supported by it. Any class method should perform an atomic operation, be quite small and support only one parameter. Moreover the strong concept of reduced class interfaces limits the possible operations between classes (belonging to different modules) to the small list of well-defined messages - verbs (though it is possible to provide "subject" for each verb, i.e. with "get" verb we can use several distinct messages: int'get or game'player'get). The method cannot have more than one parameter. As a result the method parameter tends to become an active partner. The method has to ask the parameter to return the required information, so the method caller has some control of the method work (in combination with dynamic mutation we could have some kind of two-way interaction).

ELENA is a language with a reduced operational set. Practically the only supported operation is sending a message to the object with a parameter. Conditional (#if) statement extends this operation with possibility to use multi-statement blocks and loop (#loop) one just repeats it until it fails. The only way to control the flow is message chaining. An ELENA program code is a sequence of actions (sending a message) enclosed in square brackets (Unlike Smalltalk the sub code is a sequence of action as well). The execution of every next action happens only if the previous one was successful. Otherwise the control goes to the closest alternative action and the flow continues. Alternative message chains are used in ELENA not only for handling exceptional situation but (and mostly for) conditional branching. The program code could explicitly break the execution (by sending fail message) to indicate the negative result of the method.

ELENA is a dynamic language supporting different run-time code manipulations. One of them is a static mutation. It is presumed that an object may have several alternative sets of VMTs (roles) and switch between them depending on its state. Though the total number of these states can be big enough we could always select several extreme ones (such as an empty string, unassigned container). Such cases could be implemented as class roles containing the code which is applicable only in the particular state. Only in the place where it could be changed (copying the value, assigning the object) we will check the situation and switch between roles. In most cases the bulk of the code would not be affected so there could be only several quite simple roles. But in some situation the whole code is divided between roles. E.g. Boolean variable could have two (or three) roles: true, false values (and undefined one).

ELENA supports a dynamic mutation as well. It means that we can dynamically override any public object method. This mutation could be either stable or temporal (if it is included into the temporal object group) and be accessible both inside and outside the mutated object (though inside the object we can explicitly decide if we allow overriding). It is possible either extends the object with some custom code or combine it with the number of other objects (so called object satellites) into a group object (will be described in the next post).

Concept of the group objects is one of the most interesting ELENA feature and I will continue to investigate it hoping that it will help to create self-modifying systems with truly open architecture (that in my opinion may lead to creating a very complex highly adaptive autonomous programs).

Yet another programming language

Probably every person hearing about a new language asks this question: why yet another programming language? I cannot say about all but me. When I decided 10 years ago to create a new programming language I had several reasons. First of all it was a perfect way to learn C++ (as many Russians I came from Pascal & Delphi world). But most of all I was interested in object-oriented programming. For me it was a perfect chance to learn more about it. I was fascinated with Smalltalk and decided to do something similar. Writing the compiler is a quite challenging task but it cannot be compared with the task of creating a language or a programming paradigm (after all the most valuable things in our world are ideas). So after several attempts to invent / create something original I decided to follow other way: implement something simple and gradually modify it in hope to find something interesting. So step by step the language grew (practically any part of the compiler / language was rewritten / refactored at least several times) and now it has nothing common with the one I decided at the beginning. And though many of its ideas which I thought were original are used in other languages ELENA has its own individuality and style.

So how could I answer on this question? Is ELENA yet another programming language. The answer is not simple. Yes, ELENA may be considered as another amateur language with small source code base and lack of bug tracking functionality. And no, ELENA is a conceptual language. It is designed to examine / prove feasibility of several basic concepts. From the beginning I tried to make the language as dynamic as possible. My ultimate goal is to create the programming systems with truly open architecture, the systems which can be modified / extended in run time, the system where a big number of "simple" objects actively cooperate with each other forming group objects, able to self-modify. Will the language become something more than experimental one? Only time will show. Honestly I have no idea where the language will be in the next several years. One thing I may say definitely - it will be different.

In this blog I will try to show my current ideas and the state where the language is.