Efene is a programming language that runs on the erlang virtual machine.
the idea is to provide an alternative syntax to Erlang that is most suitable for people coming from languages like Java, C, C++, C#, Javascript, or Python.
Efene comes in two language dialects: Efene (Javascript style) and Ifene (Python style).
The language is almost 100% compatible with Erlang (and will be), the compiler allows to translate an Efene source file into a readable Erlang one or compile it directly to BEAM bytecode. It also adds some syntactic sugar in some places to make some tasks easier.
To see how it looks you can go to the examples dir.
# public will allow accessing this function from other modules
@public
run() {
io.format("hello world!")
}
fnc hello.fn
fnc -r hello run
# public will allow accessing this function from other modules
@public
run()
io.format("hello world!")
fnc hello.ifn
fnc -r hello run
# if statement
compare = fn (A, B) {
if A < B {
lt
}
else if A > B {
gt
}
else {
eq
}
}
# switch statement and multiline expressions
compare_to_string = fn (Result) {
switch Result {
case lt {
"lower than"
}
case gt {
"greater than"
}
case eq {
"equal to"
}
else {
"invalid value '" ++
atom_to_list(Result) ++
"'"
}
}
}
# multiple function definition and guards
compare_to_string_guards = fn (Result) when Result == lt {
"lower than"
}
fn (Result) when Result == gt {
"greater than"
}
fn (Result) when Result == eq {
"equal to"
}
fn (Result) {
"invalid value '" ++
atom_to_list(Result) ++
"'"
}
# try/catch expression and tuples
fail = fn (Fun) {
try {
Fun()
}
catch error Error {
("error", Error)
}
catch throw Throw {
("throw", Throw)
}
catch Type Desc {
(atom_to_list(Type), Desc)
}
}
# pattern match
do = fn (add, A, B) {
A + B
}
fn (mul, A, B) {
A * B
}
fn (div, _A, 0) {
invalid_division
}
fn (div, A, B) {
A / B
}
# main function, made public to access it outside the module
@public
run = fn () {
# lambda functions
Print = fn (Expr) { io.format("~p~n", [Expr]) }
Print(compare(1, 2))
Print(compare(2, 1))
Print(compare(2, 2))
Print(compare_to_string(lt))
Print(compare_to_string(gt))
Print(compare_to_string(eq))
Print(compare_to_string(this_is_an_invalid_value))
Print(compare_to_string_guards(lt))
Print(compare_to_string_guards(gt))
Print(compare_to_string_guards(eq))
Print(compare_to_string_guards(this_is_an_invalid_value))
# call fail with a function that will fail in different ways
Print(fail(fn () { throw("throw here") }))
Print(fail(fn () { erlang.error("error here") }))
Print(fail(fn () { exit("exit here") }))
Print(do(add, 10, 2))
Print(do(mul, 10, 2))
Print(do(div, 10, 2))
Print(do(div, 1, 0))
}
fnc demo.fn
fnc -r demo run
# if statement
compare = fn (A, B)
if A < B
lt
else if A > B
gt
else
eq
# switch statement and multiline expressions
compare_to_string = fn (Result)
switch Result
case lt
"lower than"
case gt
"greater than"
case eq
"equal to"
else
"invalid value '" ++
atom_to_list(Result) ++
"'"
# multiple function definition and guards
compare_to_string_guards = fn (Result) when Result == lt
"lower than"
fn (Result) when Result == gt
"greater than"
fn (Result) when Result == eq
"equal to"
fn (Result)
"invalid value '" ++
atom_to_list(Result) ++
"'"
# try/catch expression and tuples
fail = fn (Fun)
try
Fun()
catch error Error
("error", Error)
catch throw Throw
("throw", Throw)
catch Type Desc
(atom_to_list(Type), Desc)
# pattern match
do = fn (add, A, B)
A + B
fn (mul, A, B)
A * B
fn (div, _A, 0)
invalid_division
fn (div, A, B)
A / B
# main function, made public to access it outside the module
@public
run = fn ()
# lambda functions
Print = fn (Expr) { io.format("~p~n", [Expr]) }
Print(compare(1, 2))
Print(compare(2, 1))
Print(compare(2, 2))
Print(compare_to_string(lt))
Print(compare_to_string(gt))
Print(compare_to_string(eq))
Print(compare_to_string(this_is_an_invalid_value))
Print(compare_to_string_guards(lt))
Print(compare_to_string_guards(gt))
Print(compare_to_string_guards(eq))
Print(compare_to_string_guards(this_is_an_invalid_value))
# call fail with a function that will fail in different ways
Print(fail(fn () { throw("throw here") }))
Print(fail(fn () { erlang.error("error here") }))
Print(fail(fn () { exit("exit here") }))
Print(do(add, 10, 2))
Print(do(mul, 10, 2))
Print(do(div, 10, 2))
Print(do(div, 1, 0))
fnc demo.ifn
fnc -r demo run
A mailing-list is available at librelist just send a mail to [email protected] to subscribe.
As first mail you may send a hello world program in Efene and present yourself by saying your name, where you are, how did you heard about Efene and anything else you would like to say.
$ git clone git://github.com/marianoguerra/efene.git
$ cd efene
$ ./build.sh
The build instructions create the Efene compiler, compile the Efene source and some libraries. To compile Efene source code, a binary of fnc
(the Efene compiler) is provided for Linux (32 bits) and Windows. If you are on different OSor architecture (e.g. OSX) you first will need to compile fnc
under ./tools
for your needs.
$ git clone git://github.com/marianoguerra/efene.git
$ cd efene
$ pushd tools ; make ; popd
$ pushd src ; ./build.sh ; popd
$ pushd lib ; ./build.sh ; popd
Additionally you can build and run the examples:
$ cd examples
$ ./build.sh
$ ./run.sh
To create the Efene compiler you will need a C compiler like GCC or LLVM-GCC. For the main purpose you will need any recent Erlang/OTP release.
- Erlang
- (GCC or LLVM-GCC)