Category:Elena: Difference between revisions
Line 67: | Line 67: | ||
The assigning value can be an expression itself: |
The assigning value can be an expression itself: |
||
program = |
public program = |
||
[ |
[ |
||
console writeLine("Hello!"); writeLine("How are you?"). |
console writeLine("Hello!"); writeLine("How are you?"). |
||
Line 75: | Line 75: | ||
ELENA is a dynamic language and in normal case we may not specify the variable type: |
ELENA is a dynamic language and in normal case we may not specify the variable type: |
||
program = |
public program = |
||
[ |
[ |
||
var s := "Hello". |
var s := "Hello". |
||
Line 91: | Line 91: | ||
But it is still possible to specify the variable expected type: |
But it is still possible to specify the variable expected type: |
||
T<LiteralValue> s := "Hello". |
|||
console writeLine(s). |
console writeLine(s). |
||
Line 104: | Line 104: | ||
literal s := "Hello". |
literal s := "Hello". |
||
s := 2. |
s := T<literal>(2). |
||
Why? ELENA is a dynamic language and in most cases resolves the types in run-time. So our code will be actually |
Why? ELENA is a dynamic language and in most cases resolves the types in run-time. So our code will be actually |
||
Line 110: | Line 110: | ||
literal s := "Hello". |
literal s := "Hello". |
||
s := |
s := T<literal>(2) |
||
It is guaranteed that the result of |
It is guaranteed that the result of the cast message is an instance of LiteralValue, so if the object supports the message the conversion will be done quietly. |
||
int n := 3. |
|||
n := 3.4r. |
|||
The output will be: |
The output will be: |
Revision as of 08:55, 14 June 2018
This programming language may be used to instruct a computer to perform a task.
Official website |
---|
Execution method: | Compiled (bytecode) |
---|---|
Garbage collected: | Yes |
Type safety: | Safe |
Type strength: | Strong |
Type expression: | Implicit |
Type checking: | Dynamic |
See Also: |
ELENA is a general-purpose, object-oriented, polymorphic language with late binding. It features message dispatching/manipulation, dynamic object mutation, a script engine / interpreter and mix-ins.
The simplest program
To create a simple console program we have to declare the program symbol in the project root namespace:
public program = [ ].
Everything in ELENA is an object. To interact with it we have to send a message. The simplest (generic, i.e. without an explicit signature) message consists of an action and a parameter list.
The statement should be terminated by a dot (ELENA is inspired by Smalltalk and uses its syntax notations).
public program = [ console writeLine("Hello!"). ].
In our example the action is writeLine and the parameter list consists of a single literal constant. The message target is console object (implementing input / output operations with a program console).
Several message operations can be done in a single statement separated by a semicolon:
public program = [ console writeLine("Hello!"); writeLine("How are you?"). ].
The result will be:
Hello! How are you?
We may read a user input by sending readLine message without parameters:
public program = [ console write("What is your name:"); writeLine("Hello " + console readLine). ].
The result will be:
What is your name:Alex Hello Alex
Console::write method is similar to writeLine except that it writes to the output screen without a new line character.
Declaring a variable
A variable can be declared in an assignment statement starting with var attribute:
var myVariable := "A text".
where we declare a variable myVariable and initialize it with a literal constant value.
The assigning value can be an expression itself:
public program = [ console writeLine("Hello!"); writeLine("How are you?"). var s := console readLine. ].
ELENA is a dynamic language and in normal case we may not specify the variable type:
public program = [ var s := "Hello". console writeLine(s).
s := 2. console writeLine(s). ].
The output will be:
Hello 2
But it is still possible to specify the variable expected type:
T<LiteralValue> s := "Hello". console writeLine(s).
where system'LiteralValue is a class representing text as a sequence of UTF-8 characters.
We may use a class alias to simplify the code:
literal s := "Hello". // literal is a LiteralValue alias console writeLine(s).
Note that despite it we may still assign the objects of different types without a compile-time error:
literal s := "Hello". s := T<literal>(2).
Why? ELENA is a dynamic language and in most cases resolves the types in run-time. So our code will be actually compiled as follow:
literal s := "Hello". s := T<literal>(2)
It is guaranteed that the result of the cast message is an instance of LiteralValue, so if the object supports the message the conversion will be done quietly.
The output will be:
system'RealNumber : Method $system'IntNumber not found Call stack: system'Exception#class.new$system'LiteralValue[1]:exceptions.l(125) system'MethodNotFoundException#class.new$system'Object$system'Message[2]:exceptions.l(213) system'#inline1BF.start[1]:win32_app.l(252) mytest'program.#invoke[0]:test.l(5) system'BaseFunction.eval[0]:control.l(172) system'#inline1BF.start[1]:win32_app.l(37) system'startUp(5)
Basic Types
The Boolean Type
Boolean type is used in conditional operations and may accept only two Boolean literals - true and false.
import extensions. program = [ bool b1 := true. bool b2 := false. console printLine(b1,"==",b1," is ",b1==b1). console printLine(b2,"==",b2," is ",b2==b2). console printLine(b1,"==",b2," is ",b1==b2). console printLine(b2,"==",b1," is ",b1==b2). ].
Note that implicit extension method - extensions'outputOp.printLine[] - was used to simplify the output operations.
The output is:
true==true is true false==false is true true==false is false false==true is false
The Numeric types
The most used numeric types in ELENA are 32-bit signed integer number (represented by **IntNumber**), 64-bit signed integer number (represented by **LongNumber**) and 64-bit floating-point number (represented by **RealNumber**):
import extensions. program = [ int n := -234. long l := 1235456765l. real r := 2.3456r. console printLine("Integer number - ",n). console printLine("Long integer number - ",l). console printLine("Real number - ",r). ].
The output is:
Integer number - -234 Long integer number - 1235456765 Real number - 2.3456
The string Type
LiteralValue is used to store the text encoded in UTF-8. LiteralValus is read-only collection of CharValue classes each representing UTF-32 symbol. Note that one character may be encoded with more than one byte!
import extensions. program = [ var s := "Hello". console printLine("The first character of ",s," is ", s[0]). console printLine("The last character of ",s," is ", s[s length - 1]). ].
The output is:
The first character of Hello is H The last character of Hello is o
The same code for example with a Russian text will not work. Because every character is encoded with a two bytes and this should be taken into account.
import extensions.
program = [ var s := "Привет". console printLine("The first character of ",s," is ", s[0]). console printLine("The last character of ",s," is ", s[s length - 1]). ].
The output is:
The first character of Привет is П An index is out of range Call stack: system'Exception#class.new$system'LiteralValue[1]:exceptions.l(125) system'OutOfRangeException#class.new[0]:exceptions.l(149) system'LiteralValue.getAt$system'IntNumber[1]:memory.l(1191) mytest'program.#invoke[0]:test.l(8) system'BaseFunction.eval[0]:control.l(172) system'#inline1BF.start[1]:win32_app.l(37) system'startUp(5)
We may use another class representing UTF-16 text (WideLiteralValue) to solve this problem:
import extensions. program = [ var s := "Привет"w. // UTF-16 string console printLine("The first character of ",s," is ", s[0]). console printLine("The last character of ",s," is ", s[s length - 1]). ].
The output will be correct this time:
The first character of Привет is П The last character of Привет is т
But this code will not work with Chinese text or any other requiring more than 2 bytes per symbol. So instead we may use enumerators:
import system'routines. import extensions. program = [ var s := "Привет". console printLine("The first character of ",s," is ", s enumerator; firstMember). console printLine("The last character of ",s," is ", s enumerator; lastMember). ].
The output will be correct for any UTF-8 text:
The first character of Привет is П The last character of Привет is т
Array type
It is possible to declare a dynamic or static array.
import extensions. program = [ var staticArray := (1,2,3). var dynamicArray := Array new(3). dynamicArray[0] := 1. dynamicArray[1] := "b". dynamicArray[2] := 2.3r. console printLine("static array ",staticArray). console printLine("dynamic array ",dynamicArray). ].
The output is:
static array 1,2,3 dynamic array 1,b,2.3
Basic arithmetic operations
ELENA supports basic arithmetic operations with integer and floating-point numbers:
import extensions.
program = [ var n1 := 12. var n2 := 5. var n3 := -3. var r1 := 2.3r. console printLine(n1, " + ", n2, " = ", n1 + n2). console printLine(n1, " - ", n2, " = ", n1 - n2). console printLine(n1, " * ", n3, " = ", n1 * n3). console printLine(n1, " / ", n2, " = ", n1 / n2).
console printLine(n1, " + ", n2, " * ", r1 ," = ", n1 + n2 * r1). ].
The result is:
12 + 5 = 17 12 - 5 = 7 12 * -3 = -36 12 / 5 = 2 12 + 5 * 2.3 = 23.5
Conditions, Multi-select, Loops
Conditional statement in ELENA are defined as follows:
if(<Boolean expression>) [ /* doSomething if TRUE*/ ]; [ /*doSomehting if ELSE*/ ].
We could omit else part
if(<Boolean expression>) [ /*doSomehting if TRUE*/ ].
Usually Boolean expression is a result of a comparison operation:
program = [ console writeLine("Hello!"); writeLine("How are you?"). var s := console readLine. if(s == "good") [ console writeLine("Me too") ]; [ console writeLine("What happends?") ] ].
Several conditions can be checked:
program = [ console writeLine("Hello!"); writeLine("How are you?"). var s := console readLine. if((s == "good") || (s == "fine")) [ console writeLine("Me too") ]; [ console writeLine("What happens?") ] ].
A switch statement can be implemented using => operator:
program = [ console writeLine("Hello!"); writeLine("How are you?"). var s := console readLine. s => "good" [ console writeLine("Me too") ]; "fine" [ console writeLine("Glad to hear") ]; "bad" [ console writeLine("What's wrong?") ]; "so so" [ console writeLine("It happens") ]; ! [ console writeLine("What happens?") ]. ].
We could declare *while* loop which will be repeated until the condition is true:
program = [ console writeLine("Hello!"); writeLine("Guess what?"). var s := console readLine. while (s != "nothing") [ console writeLine("Guess what?"). s := console readLine ] ].
Alternatively *until* loop is executed until the condition is met :
program = [ console writeLine("Hello!"); writeLine("Guess what?"). var s := console readLine. until (s == "nothing") [ console writeLine("Guess what?"). s := console readLine ] ].
Classes, Fields Methods, Constructors
Everything in ELENA is a class. So to implement some tasks we will have to declare our own classes.
Declaring a simple class
Let's create a simple class :
import extensions. class MyClass { // a field literal myString. // a constructor constructor new(literal s) [ myString := s. ] // a method printString [ console printLine(myString). ] } program = [ // creating a class instance by sending new message to the class var myClass := MyClass new("This is printed by my class."). myClass printString. ].
The output will be:
This is printed by my class.
Note that in ELENA a class is an object itself and can be used by like any other object.
Class Inheritance
We may inherit our class. When the parent is not explicitly declared - the class inherits system'Object super class
import extensions. class MyParent { constructor new [ console printLine("Parent Constructor.") ] print [ console printLine("I'm a Parent Class.") ] } class MyChild :: MyParent { constructor new <= new; // calling the parent constructor [ console printLine("Child Constructor.") ] print [ // calling the parent method $super print. console printLine("I'm a Child Class.") ] } program = [ var myClass := MyChild new. myClass print. ].
The output is:
Parent Constructor. Child Constructor. I'm a Parent Class. I'm a Child Class.
Private methods
It is possible to declare the private methods which cannot be called outside the class.
import extensions. class MyClass { private printPrivate [ console printLine("private print.") ] printPublic [ console print("Calling from public print - "). // $self is a reference to the current object self printPrivate. ] } program = [ // Note that if the constructor explicitly is not declared // the system'Object one (without input parameters) is inherited var myClass := MyClass new. myClass printPublic. myClass printPrivate. ]. The output is:
Calling from public print - private print. mytest'MyClass : Method mytest#printPrivate not found Call stack: system'Exception#class.new$system'LiteralValue[1]:exceptions.l(125) system'MethodNotFoundException#class.new$system'Object$system'Message[2]:exceptions.l(213) system'#inline1BF.start[1]:win32_app.l(252) mytest'program.#invoke[0]:test.l(24) system'BaseFunction.eval[0]:control.l(172) system'#inline1BF.start[1]:win32_app.l(37) system'startUp(5)
Properties
In normal case the class fields cannot be accessed outside the class. That's why we may declare a special method to access it:
import extensions. class MyClass { int _x. int x = _x. // get accessor set x(int o) // set accessor [ _x := o. ] } program = [ var myClass := MyClass new. myClass x := 2. console printLine("MyClass.x=", myClass x). ].
The output is:
MyClass.x=2
We may simplify our code if we will use prop attribute:
import extensions. class MyClass { int prop x :: _x. } program = [ var myClass := MyClass new. myClass x := 2. console printLine("MyClass.x=", myClass x). ].
Exception Handling
We may use try-catch statement to handle the possible exceptions:
import extensions. import system'io. program = [ try(console printLine(File new("notexistingfile.txt"); content)) { on(Exception ex) [ console printLine("Unknown error - ",ex). ] on(IOException ex) [ console printLine("I/O error - ",ex). ] } ].
The output is :
I/O error - Cannot open the file Call stack: system'Exception#class.new$system'LiteralValue[1]:exceptions.l(125) system'io'IOException#class.new$system'LiteralValue[1]:io\ioexceptions.l(10)system'io'FileStream#class.new$system'WideLiteralValue$system'IntNumber$system'IntNumber$system'IntNumber$system'IntNmber[5]:io\win32_files.l(52) system'io'FileStream#class.openForRead[1]:io\win32_files.l(29) system'io'StreamReader#class.new[1]:io\win32_files.l(207) system'io'fileControl.reader[1]:io\win32_files.l(269) system'io'File.read$system'text'TextBuilder[1]:io\files.l(59) system'io'File.content[0]:io\files.l(33) mytest'program.#invoke[0]:test.l(6) system'BaseFunction.eval[0]:control.l(172) system'#inline1BF.start[1]:win32_app.l(37) system'startUp(5)
See also
Subcategories
This category has the following 3 subcategories, out of 3 total.
@
- Elena examples needing attention (empty)
- Elena Implementations (1 P)
- Elena User (2 P)
Pages in category "Elena"
The following 200 pages are in this category, out of 241 total.
(previous page) (next page)2
A
- A+B
- ABC problem
- Abstract type
- Abundant, deficient and perfect number classifications
- Accumulator factory
- Ackermann function
- Add a variable to a class instance at runtime
- AKS test for primes
- Amb
- Amicable pairs
- Anagrams
- Anonymous recursion
- Apply a callback to an array
- Arithmetic evaluation
- Arithmetic/Integer
- Array concatenation
- Array length
- Arrays
- Associative array/Creation
- Associative array/Iteration
- Averages/Arithmetic mean
- Averages/Median
- Averages/Mode
- Averages/Root mean square
- Averages/Simple moving average
B
C
- Caesar cipher
- Calendar - for "REAL" programmers
- Call a function
- Call an object method
- Case-sensitivity of identifiers
- Catamorphism
- Character codes
- Check that file exists
- Classes
- Closures/Value capture
- Collections
- Combinations
- Command-line arguments
- Comments
- Compare a list of strings
- Compound data type
- Conway's Game of Life
- Copy a string
- Create a file
- Create a two-dimensional array at runtime
D
E
F
G
H
I
J
L
M
P
R
- Random number generator (included)
- Random numbers
- Read a file line by line
- Real constants and functions
- Reflection/List methods
- Reflection/List properties
- Remove duplicate elements
- Repeat a string
- Respond to an unknown method call
- Return multiple values
- Reverse a string
- Reverse words in a string
- Roman numerals/Decode
- Roman numerals/Encode
- Rot-13
- Run-length encoding
- Runtime evaluation
- Runtime evaluation/In an environment
S
- Search a list
- Search a list of records
- Send an unknown method call
- Sequence of primes by trial division
- Set of real numbers
- Short-circuit evaluation
- Simple windowed application
- Singleton
- Singly-linked list/Element definition
- Singly-linked list/Element insertion
- Singly-linked list/Traversal
- Sleep
- Sockets
- Sort an array of composite structures
- Sort an integer array
- Sort disjoint sublist
- Sort three variables
- Sort using a custom comparator
- Sorting algorithms/Bogosort
- Sorting algorithms/Bubble sort
- Sorting algorithms/Cocktail sort
- Sorting algorithms/Comb sort
- Sorting algorithms/Counting sort
- Sorting algorithms/Gnome sort
- Sorting algorithms/Insertion sort
- Sorting algorithms/Pancake sort
- Sorting algorithms/Quicksort
- Sorting algorithms/Selection sort
- Sorting algorithms/Sleep sort
- Sorting algorithms/Stooge sort
- Stack
- Stack traces
- String append
- String case
- String comparison
- String concatenation
- String interpolation (included)
- String length
- String matching
- String prepend
- Strip a set of characters from a string
- Strip whitespace from a string/Top and tail
- Substring
- Substring/Top and tail