Click here to Skip to main content
13,295,192 members (70,076 online)
Click here to Skip to main content


49 bookmarked
Posted 15 Feb 2011

Ela, functional programming language

, 5 Jul 2012
Description of an interpreted functional programming language implemented solely in .NET/C#.
Test.ela of Ela 0.9.5 op code is now decomissioned (it wasn't emitted by compiler anyway). improvemenet in thunk calculation. Performance for thunks is increased, also thunk calculation cannot cause stack overflow anymore in a case of long recursion spree. and Popelemi op codes are now decomissioned. operator (<->) is now decomissioned. of Ela 0.9.4 bug fixed in lazy list comprehension - variable references inside generator expressions weren't correctly resolved. bug fixed in call stack generation - function names weren't always determined correctly. it is possible to open module with a qualified access only using new 'qualified' keyword, e.g. 'open qualified Foo'. routines for ElaValue/ElaObject are refactored in order to be more extensible. ElaLinker has an AddArgument method. This method simulates arguments using an implicit $Args module. engine is decomissioned (arg tokens are removed from the language as well as corresponding op codes). didn't work at all. of Ela 0.9.3 corrections in implementation of Show by ElaFunction. lists support structural comparison. bug in ElaList.GetLength and ElaList.GetValue fixed. They used to raise actual exceptions instead of reporting about errors through execution context (could cause Ela VM to crush). linker generates a 'ModuleResolve' event when it can't find a module (without the DLL specified). In this case user code has an ability to manually supply an instance of a module. in Ela linker - all 'AddModule' methods of CodeAssembly are not internal. Also public interface for the ModuleReference is cleaned up. compiler is able to recognize builtin functions (and inline) them when they are declared using 'et' (mutual recursion). fixes in generation of debug info for variable declarations. are decomissioned.'ExportVars' now has a public constructor. of Ela 0.9.2 'base' is decomissioned. of pattern matching with guards optimized. redefinition of variables is not allowed in pattern matching. rules for mutual recursive declarations are relaxed. The work for any declarations but for regular strict binding an error will be generated if a particular bindings refer to a non-initialized value. bug fixed in declaration of mutually recursive functions. Ela supports custom attribute both on module and on 'let' binding level. The first are serialized to object files and preserved in run-time, the latter can be used by external tools such as documentation generators. in parsing of lazy expressions. Now both '(& expr )' and '( & expr)' are valid. declaring operator in infix form it is possible to use parenthesis around operator name (or to omit parenthesis as is worked before), e.g. both 'let + x = ...' and 'let (+) x = ...' are valid. it is not possible to omit a variant name and to match any variant. variant names don't have to be prepended with an apostrophe however all variants should start with an uppercase letter. all regular variables (except of modules and variants) should start from the lowercase letter. when applying a function using infix form, e.g. x `fun` y, one can writen any literal expression (not just identifier) inside apostrophes. parenthesis around head/tail pattern are required everywhere except regular match construct. one can declare functions in both infix and postfix forms. one can use symbolic names in patterns (by enclosing them in parenthesis, e.g. 'fun (+) x y' is now valid'. one can reference a symbolic name declared in a module (or a symbolic field in a record) using syntax 'Module.(op)'. of Ela 0.9.1 refactoring in strict range compilation logic.'InvalidLazyListDefinition' run-time exception wasn't generated correctly (it cause VM to crush). of parameters wasn't always done correctly when compiling partial applications of built-in functions. and prefix calls for custom operators was compiled incorrectly.'NotEqual' operation for ElaTuple was implemented incorrectly. printer didn't generate 'inline' modifier for bindings with 'inline' modifier. compiler doesn't generate 'InlineOnlyFunctions' error. it is possible to use 'inline' modifier on non-global functions as well.'Not' op code (and 'not' built-in function) worked correctly only with boolean types (e.g. it didn't work correctly with tuples). now no longer support bitwise operations (which was of low use anyway). when function is formatted to a string function name is enclosed in parenthesis if it is an operator. Ela function can determine its name even if there is no source code available and a module was read from an object file (works only for global functions). of Ela 0.9.0 functions fst, snd, fst3 and snd3 are implemented as built-in functions. built-in functions tag and untag are implemented (when applied to a variant they return a variant tag and tagged value respectively). of Ela machine after errors in interactive mode wasn't always done correctly. symbol '_' was compiled with an error. call on a left-hand side could cause VM stack corruption (compilation logic error). Ela supports inline functions through an 'inline' modifier. flags are decomissioned. Instead ElaPatterns flags will be used. functions 'typeid' and 'show' are decomissioned. Function 'show' will now be defined as a partially applied 'showf'. are now not transparent. behavior for Newfun op code was calculated incorrectly. was incorrectly compiled when a single tuple element was used as a match expression. linker didn't correctly process situations when an object file wasn't coupled with a source code file. for Ela functions passed from external context (such as .NET code) were passed in a wrong order. bug fixed in head/tail pattern compilation logic. stage and linking stage are now overlapping. All incudles are processed exactly after an include node is found by compiler. Compiler uses metadata from compiled imported modules to decide whether it is possible to inline some of the operators. now has a setting that allows to specify the name of a module used as a Predule module (in this case no explicit import is required). ability to define/redefine any operator added. All standard operators now will be added through 'Prelude' module. redesign in Ela parser and grammar. Now instead of specific operators Ela defines several tokens for operators. Priorioty and precendence is controlled by the first character (similar to OCaml/F#). Ela doesn't have built-in operators anymore except of special forms. of Ela operators now uses a different evaluation order (from right to left) and are no more than regular functions. Because of that sequencing operator that requires left to right order is no longer a function, but a special form. multiline strings now have '<[ ... ]>' syntax. '<|' and '<<' are not right associative, but '>>' is not. refactoring in parsing of comprehensions (potential LL conflict in grammar is removed, no syntax changes). implicit naming of record fields is supported when records elements are variable references, e.g. '{x,y}'. ability to use negative numerics in pattern matching is (probably temporary) disabled. it is possible to declare non-global operators and to pair operators with other declarations using 'et' keyword. engine is decomissioned (it is no longer needed with the new automatic module open procedure) along with corresponding op code and data structures. Custom operators are not treated like regular functions. compiler doesn't track undefined variables. Linker does. all module variables are imported automatically. An explicit import list is decomissioned. critical bug in VM fixed - pervasives (such as operators) were initialized only for the first module that referenced a module with pervasives. Ela linker generates a warning if there is an referenced argument that wasn't supplied. critical bug with pervasives fixed - VM crushed in pervasives (such as operators) were used not in a main module. traits (with no corresponding logic) 'Int' and 'Real' are added to denote integer and real numbers. 'Fold' trait renamed to 'Seq'. verification of pattern match is decomissioned. According to the language sematics all possible combinations of patterns are correct. previous warnings and hints that were generates in a case when an irrefutable pattern was used before other patterns are decomissioned. warning message now displays the pattern that will never match. error now made into warning. for overlapping match entries is implemented (experimental). printer for Ela AST is completely redesigned to support indented output. bug in type check of patterns in pattern matching construct is fixed (string pattern and list pattern could be considered as invalid when this is a valid combination). now doesn't have any special treatment for unary operators. They are treated in the same way as binary. Unary notiation is allowed using "partial application" syntax. It changes almost nothing with the only exception that unary operators can be called using postfix notation. application for operators as well as operator referencing as functions now don't require braces. 'and' is not replaced by keyword 'et'. it is required to write function name before each function body. for 'binding' pattern changed. 'where' clause is correctly processed when it is attached to another 'where' clause (which e.g. is a regular variable binding). refactorings in Ela parser. corrections in Ela parser error messages. 'F' (or 'f') prefix is supported by Ela numeric literals to denote single precision floating numbers. critical error in compilation logic of comprehensions is fixed - multiple generators used to crash Ela machine. ForeignModule has a Close method that is called when Ela machine is disposed (Ela machine implements IDisposable for that and now it is mandatory to dispose it). sequencing operator '$' is now a function. rules for 'match' and 'try' expressions are changed. Now they are not 'simple' expressions anymore and cannot be used in function application without parenthesis. enhancements in parser error reporting. bug in parser fixed - parser could crash if you try to use an operator as a function when an operator is not a function but is a special form. Ela linker can accept files with no extension, files with .ela extension and files with .elaobj extension as primary module. It will always first try to read object file and only then - to compile a file. error in object file reader and writer is fixed that could cause a linker crush or incorrect module deserialization because of an error in they way how module references were processed. supports optional "no layout" mode when semicolons are used as a replacement for indentation (will be useful in interactive mode). now supports entering expressions directly at the top level. new layout based syntax is implemented. Keyword 'end' is not longer required for 'let' and 'where' bindings (as well as for 'match' and 'try' expressions). Also semicolons are not required between match entries. bug in functional literal compilation logic fixed - it could cause stack corruption when used on a left side of an expression. could crush on a syntax error binding pattern. bug in range compilation logic fixed - it didn't take into account situations when range is used at the left hand side and as a result generate code could cause stack corruption. critical bug fixed in compilation logic of guards in pattern matching constructs. critical bug fixed in compilation logic of head/tail pattern. in error message for 'TraitFieldSet' run time error. warning ELA400 (UnitAlwaysFail) could be generated in an incorrect case (when applying 'Eq' trait to unit which is legal). one can write expressions directly in the global scope. for 'module open' directive is changed from 'open Foo[dllname] as MyFoo with x,y' to 'open Foo#dllname@MyFoo with x,y'. fixes in implementation of 'Show' trait for ElaList. imperative cycles including 'for-to', 'for-downto', 'for-in' and 'while' are decomissioned. Also 'return', 'break' and 'continue' keywords are removed. for mutable record fields changed from '{mutable x=...}' to '{!x=...}'. compiler mode is decomissioned (it only enforced errors on global mutable variables which are useless as soon as there are no mutable variables at all). doesn't support mutable variables anymore. One should use reference cells to achieve the same effect, e.g. '{!value=...}'. could crash on a binding expression without initialization block, e.g. 'let foo'. corrections in compiler error messages. code refactorings in order to support .NET 2.0 as a minimum requirement (C# 3.0 is still a minimum version of compiler that is needed to build Ela projects). ElaModule supports trait 'FieldGet'. printing infinite lists (using 'show' trait and built-in formatter helper) cannot cycle - looping through the list will always stop after first 50 elements. If one needs to show more elements than these elements should be explicitely taken from list before that ('take'). function 'cout' (along with corresponding op code) is decomissioned. One should should use Con module for console output. fully refactored. Now it doesn't inherit ElaTuple. Also support for 'Ord' and 'Num' traits is dropped. However records still provide structural equality. matching in bindings ('let' and 'where') has changed. Now all patterns except of variant pattern can be used without extra parenthesis. 'Cons' extended with a 'Nil' method that can be used to get a 'nil' instance of an entity. Also a new built-in 'nil' function is added to is mapped to this action. is is possible to create pervasives (such as custom operators) from foreign modules (modules written in .NET). new built-in function 'ref' added (along with new op code Ceqref). This function can be used to test two given object using reference equality. bug fixed in compilation logic of head/tail pattern for patterns that are combined from two nested patterns. A typical example of a case when this bug could be reproduced is when you have a head/tail pattern that ends with (xs@n) - in such as case 'n' variable wasn't declared at all. 'Seq' renamed to 'Ix'. new public 'Concatenate' method added to ElaList (method can be used from .NET code to concatenate two lists). reflection API is fully refactored. Left and Some added to ElaVariant to simplify construction of 'Either' variant (for operation in .NET code). for comparison (ElaObject.Compare) can now be overriden by the types defined outside of Ela core assembly. ElaString supports 'Seq' trait (which supported by string as soon as it represents an ordered structure of elements). information corrected for the literal patterns. type check logic corrected in according to the recent type system changes (it used to generate errors for the correct cases). corrections in Ela AST pretty printing logic. all Ela types expose a GetTypeName method that is used internally by Ela machine to determine type name. of function application at compile time is enhanced - it will now generate warning for all attempts to call something different than function if it was directly initialized with a literal. now moved from the built-in types to the standard library. Arrcons op code, array literal, array pattern, etc. are decomissioned.'Tagval' op code renamed to 'Untag'.'Tag' trait didn't have a full implementation. The direct casting to ElaVariant still took place for the 'untag' operation. A new 'Untag' method added to the trait 'Tag' to avoid this. class made public so it can be used when implementing 'Show' trait for custom types. lazy lists can be fully used from .NET code - ElaList.Next correctly processes a situation when a list is lazy and forces thunk evaluation. of Ela 0.8.6 name wasn't preserved when using incremental linker (and as a result didn't show up in call stack). critical error in built-in 'flip' function fixed - it corrupted functions when applied to external functions. is decomissioned. Instead new ElaRuntimeException should be used by external methods (it allows to specify an exception category that is translated by Ela into variant tag). Ela types implement 'Compare' method (which is exposed to public through implementation of IComparable<> interface in ElaValue). standard 'Equals' function is implemented in ElaValue (it delegates to 'Eq' trait implementation of a particular type). hashing function ('GetHashCode') is implemented for all Ela types where it is reasonable to have one.'Seq' trait makes its return. It is used to mark a type as a one that supports a sequential access to its elements (and is normally coupled with 'Get'). of 'trait check' pattern is changed from '<Foo,Bar>' to '?(Foo,Bar)'. of 'Eq' trait in ElaVariant now correctly processes a situation when both compared values are variants (previously a comparison like '`Foo 42 == `Bar 42' would result to 'true'. ElaValue.FromObject doesn't fail if a provided value is a null reference. An ElaUnit value is used in such case. fix in a conversion method - a conversion used to fail when target and source types were the same. now has static methods 'Some' and 'None' that simplify creation of Option-type variants. ElaValue exposes all trait methods that can be used to operate with traits supported by a wrapped object. 'Call' method that supports 'Call' trait made protected internal as all other trait methods. new 'Is<T>' and 'As<T>' methods added to ElaValue that can be used to test type of a wrapped object and convert it directly. 'ReferenceEquals' method added to ElaValue that can be used to perform fast reference comparison (without the need to convert to object first). bug in type conversion logic for ElaValue has fixed - it didn't correctly processes all the possible values for the target type and as a result conversion from ElaObject to a comparible type wasn't supported. type conversion for ElaValue can correctly handle a situation when a requested conversion is from ElaValue to ElaValue. check pattern now has syntax '?typename' instead of 'x ? typename'. This syntax is used in all constructs, e.g. 'x is ?typename' (used to be 'x ? typename', the '?' operator was used for both 'short match' expression and type check pattern). '?' is now replaced by 'is'. printing is corrected for type check pattern when check is done against traits. new 'Tag' trait added and now operations with polymorphic variants are performed through this trait. Ela allows to use '[]' pattern in the middle of head/tail pattern (e.g. 'x[]xs'). This is a completely legal situation (nil list beign an element of another list) but was treated as an error. built-in function 'ignore' is decomissioned. of Ela 0.8.5 syntax for comprehension is changed, now '\\' operator is used instead of '@', e.g. [x \\ x <- [1..10]]. ElaValue can be created from both arrays and IEnumerable implementations. The first creates ElaArray, the second - ElaList. ElaValue.GetType method can convert Ela objects to arrays (in the same manner as to IEnumerable<>). ElaValue.GetType method can convert Ela objects to IEnumerable<T> type where T can be a native .NET type (e.g. char or int). This also affect marshalling of data types performed by ForeignModule when registering delegates as Ela functions. 'open' directive syntax changed. Instead of 'open Foo at "Directory" with x' we have 'open Directory.Foo x'. 'open' directive now correctly works in both Windows and Unix when a path element is specified. cleanups and enhancements in parser error reporting logic. 'as' clause didn't work in 'open' module directive. incorrect warning could be generated for an expression like so 'x <- ()'. ToString in ElaObject prints '<unknown>' if a value cannot be determined (which happens for stack based values). didn't correctly process a situation when one tried to use 'Gen' trait with it (it doesn't support Gen but error was raised). operator '@@' can now be used for ranges as well as for comprehensions. of Ela 0.8.4 application (in the form '(@@ [x,x<-seq])') for the comprehension operator has added. ability to use guards (multiple, with mandatory 'else' guard) in 'let' and 'where' bindings added. ElaString supports 'Cons' trait (can be constructed using list construction operator). comprehension operator '@@' is added. (With comprehension operator you can use comprehensions for any type that supports 'Gen' trait). ElaLinker raises an exception when a module reference is used in sandbox mode. bug fixed in compilation logic of 'while true do...' expression. Invalid optimization for this pattern was causing VM to crush. ability to executed Ela scripts in a limited trust environment added. Now ElaLinker has a Sandbox option (disabled by default) that allows it. of Ela 0.8.3 internal type name for function is changed from 'function' to 'fun'. in the form 'x * -y' is now recognized as invalid (the correct one is 'x * -y'). reference in variable declaration was always allowed for regular declarations as well that could cause VM to crush in certain cases. new public Convert method that accepts ObjectType and execution context added to ElaValue. ElaFunction supports a set of static Create method that allow to create an Ela function from Func<> delegates. didn't scan files in the folder where 'elac.exe' is located. binding using 'where' didn't always create a lexical scope. bug in implementation of 'length' function for lists is fixed - it could crash in a case of lazy lists or cycle forever. bug fixed in enumeration of lazy lists. bug fixed in parser that could case parser to crash in semantic action for a match entry with guards. of Ela 0.8.2 'Seq' trait is decomissioned. ability to test if a given value supports specified traits is added to pattern matching, i.e. 'x ? <Num,Eq>'). 'succ' and 'pred' didn't work correctly with 'tuples' - the length of a result tuple wasn't calculated correctly. ('Neg' op code) operation didn't work correctly for 'single' data type. string support 'Ord' trait - comparison operations such as greater, lesser, etc. fixes in 'match' pretty printing logic. 'end' is required for the 'where' construct. Logic that allowed to omit it in certain cases caused error prone code. of Ela 0.8.1 bug in 'lazy' data type behavior when it acts as a tail of a lazy list is fixed (this bug was reproducible on certain types of lazy lists). bug in enumeration of certain types of lazy lists is fixed. bug fixed in compiler that could cause compiler to crush when an initialization is missing in a variable declaration (should result in a regular error message instead). bug fixed in error formatting code in Ela Console that could cause console to crush in certain cases. all record fields are immutable by default. To declare a mutable field one should write 'mutable', i.e. '{mutable x = 0}'. critical bug in stack size calculation fixed - compilation logic for the head/tail pattern is rewritten. types 'single' and 'double' support 'Enum' trait (successor/predecessor operations).'Arrcons', 'Tupcons' and 'Lrev' op codes are decomissioned. Now new op codes 'Gen' and 'Genfin' (to finalize generation) are used instead for all data structures. A new trait 'Gen' is added to support it. logic for comprehensions and ranges is refactored and now is more generic. logic for comprehensions and their representation in Ela DOM is redesigned. to string of tuples is changed for the case of single element tuples, now a comma is added at the end to match literal and to denote that this a tuple, not just grouped expression. bug fixed in implementation of 'pred' trait for integers (used to work in the same manner as 'succ'). type 'char' supports trait 'Ord' (comparison operations - greater, lesser, etc.). of 'Show' trait in variant is corrected and now prints only the tag if it was created without the tagged value like so `None. new 'Thunk' trait added. Now Ela 'lazy' type implements this trait and operations with lazy (force) are not hardcoded for the particular type, but for the trait (now once can implement his own lazy type). in output of value in runtime error message (in certain case the value wasn't printed). the name of 'memory' module (in interactive mode) is always printed in brakets like so '<memory>' when an error is printed to output. corrections in Ela compiler error messages. now supports delegates from Func family through methods like Add(string name,Func<T1,T2> fun). ElaValue generate standard InvalidCastException instead of ElaCastException. ElaParameterTypeException is decomissioned as well. generic ChangeType method added to ElaValue. This method can be used for conversions. of Ela 0.8 it is possible to use negative integers and reals in literal patterns like so '--1' or '--.25'. it is not possible to declare a cycle variable as mutable (e.g. for let mutable x in...). The cycle variables are still kind of mutable but their value is changed only by the cycle itself. (Basically you can notice this only if you capture this variable using closure). bug fixed in partial application of functions using 'operator' syntax. pretty printing functionality is added to Ela AST. Some of the compiler error message now shows the body of an errorneous expression. Ela allows to declare custom operators with any number of arguments (they can be called in infix, prefix and postfix forms). error reporting logic is refactored and enhanced. 'Cont' and 'Insert' used to define a mutable container such as ElaArray are removed as welll as corresponding built-ins and op codes. Now ElaArray directly exposes functions to operate with its contents like it used before. types are fully refactored. Now variant is a type that holds a tag and an instance of an object of any other type. It provide transparent operations with the wrapped object, e.g. you can write '`Some 3 + 5' and this will be a perfectly valid code with the result '8'. Pattern matching for variants is refactored as well.'Show' trait now supports format strings (all numeric types implement them). Also new built-ins 'show' (with default format) and 'showf' (with a format as a first argument) are added with corresponding op codes. minus and 'bitwise not' are now normal unary operators with their own precedence (less tight than function application). Partial application is also supported. Functions 'negate' and 'bitnot' are decomissioned. logic for pipe operators is fully refactored. Now these operators a not functions but a pure syntax and only exist in parse time and are translated to regular function application AST node. logic for PM as a function definition (check whether patterns for all function parameters are provided) is corrected. It didn't recognize errorneous situations in some cases. expressions (PM without patterns and 'match with' block) are (probably temporary) decomissioned. bug in compilation logic of head/tail pattern was fixed. This bug could cause stack corruption (unused data could be left on a stack). expression decomissioned. One shoudl use sequencing operator '$' instead. now no longer can be used as the comprehension syntax. variable declaration syntax changed from "var x = ..." to "let mutable x = ...". 'or' pattern (written using '||' operator) is now decomissioned. One can use closures to achieve the similar effect. it is possible to use string literals when specifying record field names in record pattern. bug fixed in code for cloning external function (an array that holds partially applied parameters wasn't cloned and a new function copy used the pointer to the same array). bug fixed in compilation logic of 'if' expression (wrong lexical scoping, both 'if' and 'else' clauses had the same lexical scope which could cause VM to crush in some rare cases). one can use string literal to specify field names in record literal if a field name doesn't comply with identifier rules, e.g. {"text-decoration"="underline"}. 'field test' pattern (the one that doesn't binding a value of record field but simply checks if this field is present) is decomissioned. logic for record patterns is refactored. 'where' binding support function definition by PM and multiple binding using 'and' but has a required 'end' terminator. new 'Call' trait is implemented (this trait is supported by 'function' data type). ability to reload an opened module added to Ela linker and VM (this feature is used by interactive console). VM and type system are seriously refactored to gain a better type flexibility. Also performance is tuned for certain cases.'Eq' trait now has both methods Equals and NotEquals. 'Ord' traits now have methods additional methods 'GreaterEquals' and 'LesserEquals'. most of trait operations return 'ElaValue' and not a concrete value, e.g. Equals, Greater, etc. return ElaValue, not a boolean value as they used to. One can use 'Bool' trait to obtain boolean.'Invalid' type is decomissioned and is no longer used internally by VM to signal an incorrect operation. 'Show' trait is extended with extendable ShowInfo structure that can be used to provide display options. Ela supports only implicit conversion from int to long and from single to double, int to double, long to single, etc. are prohibited. 'traits' system is fully refactored. Now all binary operations accept two parameters for both left and right operands - now expressions 'Foo + x' and 'x + Foo' will have the same result type. lazy list comprehension is implemented that can be used to generate lazy linked lists using the same syntax as with regular lists comprehensions. tuples support comparisons (based on their elements), arithmetic and bitwise operations. new 'where' binding implemented (in Haskell style). This binding can be scoped to guards and can be quite useful in pattern matching. lambdas support guards but don't support multiple body definition. syntax has changed and guards are enhanced - now they can be used in PM without patterns (in such case either the previous pattern is considered or none). Match compilation logic has changed to support this. new 'Lazycall' op code added that is used to optimize lazy values creation and execution when a body of a lazy value is a function application. codes 'Brptr' and 'Pushptr' are removed a long with the special stack 'pointer' data type as soon as these staff is no longer needed by Ela interpreter. it is possible to use guards in method formal parameter list. in Haskell style added (including support for infinite lists). op code deserialization logic was incorrect and caused linker to crush. logic for verification of date stamps of Ela object files (in Ela linker) was incorrect and generated a warning when it wasn't needed. bug fixed in interactive mode - user defined operators didn't work at in incremental compilation mode. new 'Trait' op code is added that allow to check whether an object support provided traits. new 'Tag' trait is added that potentially allows other data types (not only records and tuples) to be 'tagged'. of polymorphic variants has changed. Now variant constructors are not literals but functions. In fact a 'tag' built-in function that accepts a string tag and an object is used for construction of variants. Older syntax is just a sugar for it - e.g. `Some (x, y) is equivalent to tag "Some" (x, y). Constructors for variants are also removed from the language. Now regular functions can be used to construct variants with the same success. of simple cases for the pattern head/tail (which are the most common cases) is seriously optmized. New op codes are used for this - 'Skiptl' and 'Skiptn'. 'open' expressions can be used only as top level expressions. alternative (closer to Set-Builder notation) list and array comprehension syntax added. for expression and while expression use a do/end block as their body therefore the 'end' token is required for them. a global scope can either contains a single expression (can be useful in interactive mode) or only let/do expressions. All other expressions are prohibited. Semicolons are no longer used to separate declarations. The only place where semicolons can be used are do/end expressions. and until expressions are removed. Also unless expression (a version of when expression) is removed. new do/end expression is introduced to simplify writing imperative code. Expressions inside do/end block should be separated with semicolons. This construct doesn not define a lexical scope. support for lazy lists is added. Now lists allow to have a 'thunk' as a next element. Therefore a second argument of a cons operator can simply contains a lazy value. function (or so called 'static functions') are fully removed from the language along with 'Newfuns', 'Callcc', 'Checkcc', 'Yield' and many other related op codes. Also built-in functions 'iter' and 'next' are removed and for/in construct is rewritten to use 'Fold' trait. reflection API is refactored according to the new changes in Ela object model. Exceptions are now records with a 'Type' tag. new 'Convert' trait is added that can be used to control how objects convert to each other. routine is again refactored. Now ElaValue doesn't implement IConvertible but defines methods that exactly corresponds to Ela types and perform exact type marshalling and no conversion. new 'Show' trait that controls formatting of objects to a string added. Now string conversion and string representation are two different things. now implements 'Fold' trait and can be analysed using pattern matching (specifically head/tail pattern). new 'Fold' and 'Cons' traits are added that allow to fully similate linked lists by other data structures. new exception handling mechanism for objects that support traits is implemented. Exception handling is done through the ExecutionContext instance and allows to preserve full stack trace if an error object originates from the Ela code (e.g. executed in another worker thread). all virtual machine operations are based on traits, including atomic operations such as 'add', 'sub', 'del' and more complex operations. built-in functions 'add', 'remove', 'clear' and 'insert' are added instead of built-in functions of array. These new functions however are polymorphic. object model fully refactored. A new 'traits' concept is introduced. All standard functions are groups into categories (traits) and external objects can fully extend object model and can be used with Ela standard operators. Now objects don't have any built-in attributes at all. of lazy values is refactored.'Typeid' op code now checks if a value is unevaluated lazy and pushes lazy type ID, if it is an evaluated lazy and pushes ID of an actual value or acts as normal in other case. new 'force' built-in function (and corresponding 'Force' op code) added that can be used to explicitly force lazy values. id, sub, key and rec are no longer built-in. They will be moved to the library. 'AmbiguousUnary' parser error added that rejects expressions in the form 'n-1' (without spaces). Previously they were considered to be function applications. logic for list pattern is fixed (it worked correctly only for the first two elements). compilation logic fixed (nested comprehensions didn't work correctly). bug fixed in compilation logic of variants and in compilation logic of variants call. shortcut syntax for record pattern is now available, one can write '{foo}' as an equivalent to '{foo=foo}'. bug in indexer logic of lists is fixed. compiler disallows implicit tupling of function arguments when PM is used in function definition and an irrefutable pattern (such as 'x') is specified while not providing the full argument list. This behavior could cause unintuitive runtime errors. bug fixed in comparison logic ('Br_eq' and 'Br_neq') of boolean values. each function has its own stack which size is defined statically, therefore the need to dynamically check and resize stack is eleminated which causes noticeable performance improvements. Ela compiler statically calculates the size of the stack for functions and global scope. level verification of variants is disabled (probably will be removed in future). with exceptions is fully redesigned, new syntax introduced ('raise' and 'fail'), new op code for rethrowing exceptions without chaing call stack ('Rethrow'), ElaError object is redesigned as well. Now polymorphic variants are used to present exceptions. it is not possible to skip linking stage. One should run Ela machine only after linker, not after compiler. routines rewritten for all Ela types and ElaValue. Now conversion behavior can be extended by custom types. Also lazy values acts as proxies, therefore the need to force them when passing to external methods is eliminated.'Throw' op code splitted into two op codes - 'Throw' to generate user exceptions and 'Failwith' to generate system exceptions (these two op codes have different stack behavior). codes 'Newfund' and 'Calld' removed. Now calling and creating a function with statically unknown number of parameters is not supported.'Newtup' op code changed. Tuple literal compilation rewritten to use new op code 'Tupcons' that allows to statically calculate stack size.'Newrec' op code changed. Record literal compilation rewritten to use new op code 'Reccons' that allows to statically calculate stack size.'Newarr' op code changed. Array literal and array comprehension compilation rewritten to use new op code 'Arrcons' that allows to statically calculate stack size.'Lgen' op code removed. List literal and list comprehension compilation rewritten to use new op codes 'Lconsr' and 'Lrev' that allow to statically calculate stack size. op codes 'Popelemi' and 'Pushelemi' added to optimize work with indexers (experimental). bug fixed in compilation logic for the field reference (in some cases an instruction 'Popfld' may be incorrectly generated instead of 'Pushfld' which will lead to VM crush). warnings about calling a function with incorrect number of parameters are removed - now this case cannot be verified statically. and compilation logic optimized for functions with tupled parameters, e.g. f(x, y). New op code 'Tupex' is added to support that. bug fixed in tail recursion optimization - it could be incorrectly applied in the case if a function with the same name (but not the same function) is tail called. curried functions are always called with exactly one parameter, e.g. fun x y will be compiled into two function calls ((f x) y). type removed with op codes 'Pushseq', 'Newseq' and 'Convseq'. Appropriate changes in compiler, VM and value formatter are made. of 'Throw' op code was calculated incorrectly during byte code serialization. bug in eval stack trim procedure fixed (used in exception handling) - could cause parasite entries on eval stack. logic for pipes is optimized for the cases when builtin functions are used with pipes (functions are now inlined). bug fixed in compilation logic of 'try' expression - it didn't pop value when used as a left hand expression. with memoization makes its return but now has a full transparency for the client code (no need to manually force lazy values). for mutually recursive functions (using 'and' keyword in declarations) added. fun sym (in debug info) is generated for composition if a composition is at the right hand side of a variable declaration. instead of sigma '$' for arguments a dedicated argument literal is used in parser (e.g. '$ arg' is not valid anymore, but '$arg' is valid). priorities are corrected for better usability (closer to Haskell). '+' is valid only for numeric types, for string/list, etc. concatenation a new '++' operator is used. A corresponding 'Concat' op code added. in AST and compiler - now assignment operators ('<-' and '<->') are presented as a binary operator and not a separate AST node. bug fixed in tail call (Callt op code) - in certain cases it could cause VM to crush. Ela doesn't have unary operators (both standard and custom). 'Bitwise not' replaced with 'bitnot' function, boolean not - with 'not', etc. 'let' binding now can be used to start a lexical scope by adding 'in' after the binding (in the Haskell/OCaml style). application (for both left and right arguments) implemented for standard operators. flip built-in function (both regular and inline) implemented. Function flips first two parameters of a supplied functions. It works through the new op code Flip. ability to define multiple function bodies added (used for pattern matching sugar in Haskell style). bug fixed in optimization logic for compilation of endless cycle, e.g. 'while true'. bug fixed in 'as' pattern (binding was done only if a pattern was matched successfully which could cause a VM crash). new type enforcement pattern (that actually converts an object to a supplied type) implemented. bug in 'is' patten fixed (binding were never done correctly). bug fixed in refresh logic for inner state of virtual machine (could cause VM to crash when opening module in interactive session). new 'Swap' op code added that swaps two values on the top of the stack (e.g. making left right and right left). operator '<-' now yields unit instead of operation result. most of Ela operators are functions and can be used in the same way as regular functions (compiler tries to inline them however wherever possible). bug with recursive variable declaration was fixed. Now recursive references only allowed in function declarations. of types for functions changed to use notation 'a->'a->'a. Formatting also shows partial applied functions as a pair of signatures. 'typeof', 'ignore' and 'cout' are removed and replaced by special buil-in functions ('typeof' renamed to 'typeid') that can be inlined in certain cases. an incorrect warning generation for the case when a unit type function is used in a pipe chain. bug fixed in error generation logic when a call to Ela function was done through virtual machine using Call method (the case for built-in object functions). all functions accepts at least one parameter. Function without parameters can be simulated using unit pattern '()' instead of parameters list., decrement, post increment and post decrement operators are removed. minus operator is removed. Minus now has a syntax '~' is a regular function call. pattern as well as And pattern are removed from pattern matching. redesign of language syntax in ML style. of Ela 0.7.20. bug fixed fixed in compilation logic of custom operators (wrong parameter order for operators were used). bug fixed in parsing logic of the backward composition operator. bug fixed in parsing logic of the forward pipe operator. bug fixed in compilation logic of generators (execution of generators could fail because of unneccarry stack manipulation code). of pervasives (e.g. custom operators) is completely rewritten and is now much more effecient. bug fixed in literal pattern (it wasn't possible to use negative integers and reals). logic for automatically generated polymorphic variants fully refactored. Now it doesn't create a constructor function but generates a variant in place. sequence pattern, list pattern and array pattern support a 'dot-dot' operator that allows to use 'relaxed' check of a corresponding sequence size (equal or greater to the number of arguments in the pattern instead of strictly equals by default). and constructor pattern AST nodes and parsing logic refactored. bug fixed in a VM state refresh procedure that is used by interactive mode (the memory layouts didn't properly resize). 'long' data type didn't correctly convert to 'double' during implicit conversions. bug fixed in compilation logic of function - function handle was calculated incorrectly, different handles can be used for the same function in symbols and in byte code. variants related bug fixed - variants were accidentally exported as a part of visible global scope which could VM to fail through introspection. bug fixed in compilation logic of contructor pattern (didn't correctly process situations when formal parameter list wasn't specified at all). bug fixed in compilation logic of variants (incorrect variable address calculation for storing generated constructors). bug fixed in ElaLazy computation logic that cause unnecessary stack operations. bug fixed in interactive mode of VM - it didn't correctly recover after errors. removed from the function memory frame because of redundancy. didn't work for records (but worked for tuples). bug fixed in the record indexer implementation (didn't work correctly for the numeric indices). bug fixed in the Pushfld op code for the case a standard record attribute (such as length) was queried. ElaList inherits ElaIndexedObject and supports an indexer operator as well as array. compiler raises an error for the casts to non-supported types, previously such situations were completely ignored. bug in optimization of tail calls for binary operators including pipe operators. critical bug fixed in implementation of async calculation (the result of value of calculation was never persisted). reporting for the cases when a field of an object is immutable enhanced in a virtual machine. bug fixed in compilation logic of function composition. bug fixed in tail recursion - VM crushed when a function called to itself without supplying full argument list. bug fixed in stack clear logic of ExecuteThrow routine in Ela VM. bug/design leak fixed in compilation logic for the polymorphic variants. Compilation logic fully redesigned. Also now variants are scoped as regular variables. bug in Callt op code fixed (bug cause VM to crash when a tail call was done to the function in another module). new setting added to linker that allows to specify a name of a standard library. Stdlib is now preloaded and it is also possible to use shorter open declarations for standard modules (expiremental). clean-ups in Ela parser grammar. handling logic refactored in virtual machine and parser. Now each Ela component generates its own exception type (e.g. ElaParserException). match patterns can be used inside functions formal parameter list, e.g. \([x,y]) { ... }. new syntax for anonymous functions implemented instead of (x, y) -> expr now \(x, y) expr. fixes in operations affinity table in virtual machine (several types such as 'int' and 'double' were always incompatible). of Ela 0.7.19. bug fixed that could cause an error when calling a function with empty body. bug fixed in compilation logic of variants (wrong argument order). bug fixed in compilation logic for short version of match expression. compiler supports separate 'debug' (generate debug info) and 'optimize' (perform optimizations) flags. call optimization disabled inside try/catch and for generators. composition compilation logic optimized. tail call (non-recursive) is now optimized. A call is performed using new op code 'Callt' (experimental). bug fixed in currying logic in virtual machine. warning is now generated when a function is partially applied during composition. changes in composition grammar - order of evaluation for '>>>' and '<<<' operators is exchanged. function call verification is performed against composed functions (using function composition operators). function call verification is performed against curried functions as well. new FunctionZeroParams warning is now generated with a function with non-zero argument list is tried to call with empty argument list. new mechanism implemented in compiler that allows expression compiler to return additional metadata about compilation results which can be used for code verification and optimization. bug in function composition fixed (number of arguments for the first function were incorrectly determined which caused VM to crush). shortcut syntax (e.g. fun(x, y,)) with a trailing comma added for tuple creation inside a function call expression (as an alternative to fun((x,y))). new static verification added - compiler now tries to determine if a function call operation is performed against function and generates an appropriate warning if needed. new static verification added - compiler now tries to check if a correct number of arguments are specified in a function call and generates an appropriate warning if needed. match compilation logic optimized, new diagnostic warnings added. compilation logic optimized for the cases when pattern matching is used in cycles. reporting completely refactored for parser, compiler, linker and Ela runtime. new ElaRecordInfo class added to the reflection API. This class is used to describe 'record' data types and exposes method to operate with record fields. type system was refactored in the part that is responsible for the reflection support, redundant code removed. handling in virtual machine enhanced for all indexer related operations (Popelem, Pushelem, Popfld, Pushfld). new ElaIndexedObject type was added Ela type system.This type is now used as a base type for all types that support indexer operation. changes 'IsIndexed' field is removed. changes 'IsTagged' field is replaced by the 'Tag' field that returns a tag value. Comparison logic is updated as well. bug fixed in the parser production for the sequence match pattern that was creating nested sequences instead of processing them a solid sequence. new 'Len' op code was added. This op code is used when compiling match instead of manually pushing "length" field. validation (typing of match patterns) is fully redesigned, both AST and match compilation logic have changed. AST refactored in the part that represents elements of match expression. refactoring in Ela code model (parser AST). placeholder expression ('_') is correctly processed when used inside casts, 'typeof' and 'is' expressions. bug fix in functions with multiple parameters created using partial application. op didn't correctly check the type of an argument when a sequence was created from a static function (regular function could be used with no errors). added to reflection API (can be obtained through ElaTuple and ElaRecord instances). refactoring in Ela type system. added to reflection API (can be obtained through ElaSequence instance). refactorying and enhancements in ElaSequence type. added to reflection API (can be obtained through ElaLazy instance). refactoring in ElaLazy type. methods (that are usable from both Ela code and .NET) added to Ela reflection classes. default ToString implementation return type name in Ela notation added to all Ela types. now has a getValue method exposed to Ela code that returns a variable value. added to reflection API (it is accessible through ElaModuleInfo instance). coroutine is executed using the same Call procedure as a regular function. Also regular Call procedure is now able to correctly process static functions. implemented for both native and external functions (experimental for now). refactoring in ElaFunctionInfo and ElaFunction object as well as in function call code in ElaMachine. of Ela 0.7.18. new reflection API that is usable from both Ela and .NETis implemented. ElaObject has a protected virtual EnumerateFields method that returns all fields exposed by an object. ElaObject has a GetValue(int) method that can be used by indexed derivations such as ElaTuple or ElaArray. in Ela type system organization - now ElaTuple, ElaString and ElaRecord don't inherit ElaArray. public constructors added to ElaList to simplify array creation from .NET code. public constructors added to ElaTuple to simplify array creation from .NET code. in grammar. Now it is possible to obtain fields from primitives literals, i.e. "1.getType()". it is possible to create a tuple with one argument using (x,) notation and to match against such a tuple. public constructors added to ElaArray to simplify array creation from .NET code. bug fixed in ElaString - it couldn't obtain the very first character through the indexer. bug fixed in 'ctor' and 'any ctor' patterns for the case when a variant contains only a single element. of Ela 0.7.17. performance tweaks in ElaMachine for 64 bit. object refactored. Now native function is implemented through internal ElaNativeFunction class and ElaFunction is an abstract base class. tail call optimization is done when last expression in function is a pipe (|> or <|) operator. it is possible to create external Ela function with an unlimited number of parameters (used for String.format currently). clean-ups in runtime code. fixed in ElaLinker that was causing some error messages to be lost. new method 'ToModule' was added to the RuntimeValue structure.'Module' type is implemented through 'ElaModule' class that has a module handle and a reference to ElaMachine. class now has a public EnumerateNames method that allows to iterate through all variable names. format for the call stack is changed. ElaDebugger and not ElaMachine is responsible for building call stack for errors. unneccessary 'Cache' hint removed from compiler. fixes in error reporter for parser, enhanced error reporting for match syntax errors. clean-ups in compiler code and internal compiler object model. in CodeFrame implementation, change work with module references., work with module names, handles and arguments was fully redesigned. bug fixed that was causing VM to fail if there is a return from a function from another module. didn't correctly handle situations when different modules have the same name (only one module was actually saved). wasn't cleared when an exception is raised from the VM. now catches situations when cases of 'or' patterns don't match in number of variable declarations. compiling 'as' pattern an existing variable can be used instead of forcing to declare a new variable. in parser for pattern matching - sequences, tail and head, 'as' patterns are now processed more correctly. of Ela 0.7.16 fixes in exception handling, error messages moved to the Strings table. lookup table OpHelper.OpSize was added in order to determine the size of op codes, object file read/write logic modified to use new op code size lookup table. op code removed. op code removed (replaced by Pushfld "length"). op code removed (replaced by Pushfld "length"). in Ela type system, better public API for interoperability with .NET. file format reading/writing is enabled again. in parser (language grammar). refactoring in AST(now it is possible to construct AST outside of Ela library).,int) public method added. made public (but with internal setter). structure made public (also added public read-only properties VariableAddress and VariableFlags). Scope.GetVariable and Scope.Clone made public. property made public (but with internal setter). property made public and changed type to IReadOnlyMap<>.<> and IReadOnlyMap<> added for use by compiler for imports, pervasives, etc. class was added (can be helpful for writing user code). protected CodeAssembly.AddModule method added. This method allows to add new CodeFrame instances to the module list. and PushI4_2 op codes removed. and Call_2 op codes removed. op code removed. Now Throw is used for both cases (system and user exceptions). op code removed. 'is' operator can be used to check if an expression is unit using unit literal (). op code removed and replaced by Listlen op code. Cin op code removed. fix in EIL generation logic (0 was printed for opcodes without argument). refactoring in op codes naming. 'yield' presence is determined through expression flags, not through HasYield virtual property. syntax sugar for the generators was removed. an empty tuple (unit literal) is recognized as a 'unit' type expression when performing static code analysis. warning is raised when one of the expression in binary expression always returns 'unit'. 'yield', 'return', 'break' and 'continue' are not allowed in binary expression (previously they caused 'Stack corrupted' error). new 'BreaksExecution' hint added to the AST (for 'yield', 'return', 'break', 'continue'; can be used for code analysis). new 'ReturnsUnit' hint added to the AST (can be used for static code analysis). refactoring in parser. are now generic classes (compiler and parser can be specified via generic parameters). of Ela 0.7.15 codes encoding/decoding (parser and vm optimization, less memory consumption). fix in record data type (unable to change values of fields). until and do/until cycles (similar to while and do/while cycles). fix in while cycle (always executed as an endless cycle). of Ela 0.7.14

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


About the Author

Basil Voronkov
Russian Federation Russian Federation
Ph.D. in philosophy
Work as a software consultant, Microsoft, Russia.
Main specialization: .NET
Interested in: functional programming

You may also be interested in...

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171207.1 | Last Updated 5 Jul 2012
Article Copyright 2011 by Basil Voronkov
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid