efene programming language

new domain, we moved!

today is the day of the 0.9 release and the first day in society of our new domain:

http://efenelang.org

follow us on the new blog, this blog is kept for historical purposes only

see you there!


fnt - jquery-like templates for the erlang platform

About fnt - efene templates

first the most important, fnt code is hosted at github here:

https://github.com/marianoguerra/fnt—efene-templates

the documentation is here:

http://marianoguerra.com.ar/fnt/

you are invited to contribute by testing it, reporting bugs, improving the documentation, spreading the word and the most awesome of all, by helping with the development.

fnt (efene templates) is an erlang module that allows to compile text templates into erlang modules to be used in the erlang platform (erlang, efene, reia, LFE, etc.)

fnt uses the syntax of jquery templates , this has several advantages, first you have to learn only one template syntax for server and client side templates, second you can reuse the templates to create server and client generated pages, to improve page crawling by search engines and provide non javascript versions of your site without duplicating effort. Also, you have the benefit of more documentation and examples of the template syntax.

fnt templates are compiled into bytecode, you get fast page generation since the template is translated into an optimized function that avoids string concatenations.

your next step should be following the fnt tutorial

Frequently Asked Questions

why the name if it’s written in erlang?

I don’t want to push efene as a forced dependency to everyone wanting to use fnt in languages like erlang, reia and LFE.

also because it will be in the efene standard library and I’m really bad at names ;)

that said efene is awesome so go and check it out!

license?

BSD

more resources


really nice DSL for configuration and more…

yesterday reading something about coffeescritpt (an awesome language btw) y decided to try something I saw on the coffeescript page.

after a slight modification of the parser I was able to write the following:

@public
run = fn ()
    Awesome =
        me:
            name: "Mariano",
            age: 25,
            language: efene

        ,bob:
            name: "SpongeBob",
            age: idontknow,
            languaje: english

    io.format("~p~n", [Awesome])

this is possible only in ifene, in efene you would have to write the curly brackets, since that’s how it works. I hope you like it


congratulations to djui!

djui requested a pull from his repo today, I just pushed the changes to efene master.

with this simple action he became the first official contributor of efene.

when we reach our secret goal* of conquering the world he will be able to point to this blog post with pride ;)

* not *that* secret any more

thanks to him and hurry up! you can be the second contributor!


a little more object oriented

I added the ability to call methods inside structs.

a call to a function inside a struct will pass the struct as first parameter implicitly.

with this we get a behaviour similar to python where methods are just functions that receive an object as first parameter (normally called self).

here are some examples:

@public

present = fn (Self)

    io.format("Hi!, I'm ~s ~s, my email is ~s~n",

        [@Self.firstname, @Self.lastname, @Self.email])



@public

new = fn (Firstname, Lastname, Email)

    New = {

        firstname: Firstname,

        lastname: Lastname,

        email: Email,

        show: fn struct.print:1,

        present: fn present:1}



    New



@public

run = fn ()

    P = new("mariano", "guerra", "foo@bar.com")

    @P.show()

    @P.present()

as you can see, the instantiation of the new struct is similar to javascript.

running the program displays:

<struct firstname="mariano" lastname="guerra" email="foo@bar.com"/>

Hi!, I'm mariano guerra, my email is foo@bar.com


I also added pretty printing of structs in the erlang shell and some more functions to the struct module

>>> P = person.new("mariano", "guerra", "foo@bar.com")

<struct firstname="mariano" lastname="guerra" email="foo@bar.com"/>

>>> @P.firstname

"mariano"

>>> struct.print(P)

<struct firstname="mariano" lastname="guerra" email="foo@bar.com"/>

ok

>>> S = {foo: 1, bar: "asd", baz: true, show: fn struct.print:1}

<struct foo=1 bar="asd" baz=true/>

>>> @S.show()

<struct foo=1 bar="asd" baz=true/>

ok

>>> struct.print(S, true)

<struct foo=1 bar="asd" baz=true show=#Fun<struct.print.1>/>

ok

more on efene’s structs

I’ve decided that structs are the way to go for efene and removed all traces of “objects” from the code.

The reasons to do this:

  • structs are a real data structure and not a closure trick to look like a data structure.
  • You can introspect them, operate on them, dump and see what’s inside. This allow people to write code that interact with structs in ways I can’t imagine now. “objects” were hard to modify.
  • structs allow nested structs
  • friendly syntax to access and modify a struct
  • meaningful and simple error messages
  • syntax to define structs ad-hoc
  • map 1:1 with JSON
  • look like JSON

of course if you liked objects they are 100%  implemented as a library so you can get the source from some commits ago and use it.

now some code using new functions in the struct module.

>>> Me = {firstname: "mariano", lastname: "guerra", location: {city: "cordoba", country: "argentina"}}
{struct,[{firstname,"mariano"},
         {lastname,"guerra"},
         {location,{struct,[{city,"cordoba"},{country,"argentina"}]}}]}
>>> struct.fields(Me)
[firstname,lastname,location]
>>> struct.has(Me, firstname)
true
>>> struct.has(Me, email)
false

efene now JSON friendly - introducing structs

if I describe efene as “a javascript like syntax” then it should plain nice with JSON right?

well, from now I can say it does…

introducing structs:

>>> Me = {firstname: "mariano", lastname: "guerra", location: {city: "cordoba", country: "argentina"}}
{struct,[{firstname,"mariano"},
         {lastname,"guerra"},
         {location,{struct,[{city,"cordoba"},{country,"argentina"}]}}]}

>>> @Me.firstname
"mariano"

>>> @Me.location
{struct,[{city,"cordoba"},{country,"argentina"}]}

>>> @Me.location.city
"cordoba"

>>> @Me.firstname := "Mariano"
{struct,[{firstname,"Mariano"},
         {lastname,"guerra"},
         {location,{struct,[{city,"cordoba"},{country,"argentina"}]}}]}

>>> Me1 = @Me.firstname := "Mariano"
{struct,[{firstname,"Mariano"},
         {lastname,"guerra"},
         {location,{struct,[{city,"cordoba"},{country,"argentina"}]}}]}

>>> Me2 = @Me1.location.country := "Argentina"
{struct,[{firstname,"Mariano"},
         {lastname,"guerra"},
         {location,{struct,[{city,"cordoba"},{country,"Argentina"}]}}]}

>>> @Me.location.country
"argentina"

>>> @Me.email
exception throw: {attribute_error,"Me struct has no attribute 'email'"}
  in function  struct:get/3

>>> @Me.firstname.something
exception throw: {value_error,"firstname doesn't seem to be a struct"}
  in function  struct:get/3

>>> @Me.location.state
exception throw: {attribute_error,"location struct has no attribute 'state'"}
  in function  struct:get/3

>>> Me = {firstname: "mariano", lastname: "guerra", location: {city: "cordoba", country: "argentina"}}
{struct,[{firstname,"mariano"},
         {lastname,"guerra"},
         {location,{struct,[{city,"cordoba"},{country,"argentina"}]}}]}

>>> Json = mochijson.encode(Me)
[123,"\"firstname\"",58,"\"mariano\"",44,"\"lastname\"",58,"\"guerra\"",44,
 "\"location\"",58,
 [123,"\"city\"",58,"\"cordoba\"",44,"\"country\"",58,"\"argentina\"",125],
 125]

>>> io.format("~s~n", [Json])
{"firstname":"mariano","lastname":"guerra","location":{"city":"cordoba","country":"argentina"}}
ok

>>> Data = mochijson.decode(Json)
{struct,[{"firstname","mariano"},
         {"lastname","guerra"},
         {"location",{struct,[{"city","cordoba"},{"country","argentina"}]}}]}

>>> @Data.firstname
"mariano"

>>> io.format("~s~n", [mochijson.encode(@Data.firstname := "Mariano")])
{"firstname":"Mariano","lastname":"guerra","location":{"city":"cordoba","country":"argentina"}}
ok

from the example you can see that the object notation has the same syntax then JSON and python dictionaries.

you should also see that are serialized to and from json without any extra step using mochijson.

also the syntax to access and modify the “structs” is similar to an OO syntax

last but not least, check the descriptive error messages!

let me know what you think. My idea is to put efene “objects” to rest and focus on structs, since they are data structures (not closures), have a nice and friendly syntax and play really nice with JSON


flattr button for efene

I added a flattr button to efene pages so people can “flattr” me if they found my work interesting.

if you have a project, join to flattr, if I find it useful I will contribute (my first flatter was for dpkg :)


Getting legal

I decided to get legal and add all the changes in the code to release efene under the 3 clause BSD license.

this are some needed steps to stabilize the project so people can be sure that efene won’t eat their lunch.

next step, define a naming strategy to avoid efene modules colliding with existing and future modules of erlang.


fat arrows - some syntactic sugar for “dicts”

I was thinking on how to make some kind of dict like structure on efene with the things provided by erlang.

I identified a pattern and decided to have some syntactic sugar for it.

a common thing in erlang is to “tag” something with a two item tuple that contains the “tag” that represent what the second item is, and the value.

Things like {error, Reason}, {ok, Value} are really common in erlang.

Another pattern is using lists of two item tuples to represent “dicts”, you can see this here:

http://erldocs.com/R14A/stdlib/lists.html?i=0&search=lists:key

here

http://erldocs.com/R14A/stdlib/dict.html?i=0&search=dict:fro#from_list/1

and here

http://erldocs.com/R14A/stdlib/orddict.html?i=1&search=dict:fro#from_list/1

for some examples.

we can say that the list of two item tuples is used often, also the “tagged value” pattern, so why don’t do something about it? well, I did something…

I introduce to you: fat arrow expression!

it’s a simple expression that provides a nice looking way to state that we are doing a kind of “dict” or “tagged value”, it also allows some nice looking DSLs build on top of efene, let’s see some examples:

>>> Nums = [one => 1, two => 2, fourtytwo => 42]
[{one,1},{two,2},{fourtytwo,42}]
>>> lists.keyfind(two, 1, Nums)
{two,2}
>>> lists.keymember(two, 1, Nums)
true
>>> lists.keymember(nine, 1, Nums)
false
>>> lists.keysearch(two, 1, Nums)
{value,{two,2}}
>>>

>>> error => "you fail at failing"
{error,"you fail at failing"}
>>> throw(error => "something bad happened")
exception throw: {error,"something bad happened"}
>>> ok => "hi"
{ok,"hi"}
>>> SomeValue = ok => "Value"
{ok,"Value"}
>>> switch SomeValue { case ok => Value { Value }; }
"Value"

>>> Nums = [one => 1, two => 2, fourtytwo => 42]
[{one,1},{two,2},{fourtytwo,42}]
>>> dict.from_list(Nums)
{dict,3,16,16,8,80,48,
      {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
      {{[],[],[],[],[],
        [[one|1]],
        [],[],[],[],[],[],[],[],[],
        [[two|2],[fourtytwo|42]]}}}




sorry for some one liners there, fn shell needs some improvements :)

as you can see you can do lot of operations using fat arrows.

if you don’t like creating dicts from list of tuples at run time you can do it at compile time if the values are known at compile time:




@public
run = fn ()
    Nums = $[dict.from_list([one => 1, two => 2, fourtytwo => 42])]
    io.format("~p~n", [Nums])




translating to erlang with fnc -t erl test.ifn




-module(test).

-export([run/0]).

run() ->
    Nums = {dict, 3, 16, 16, 8, 80, 48,
            {[], [], [], [], [], [], [], [], [], [], [], [], [], [],
             [], []},
            {{[], [], [], [], [], [[one | 1]], [], [], [], [], [],
              [], [], [], [], [[two | 2], [fourtytwo | 42]]}}},
    io:format("~p~n", [Nums]).




PS: I wont be adding syntactic sugar to everything I find in efene, I just thought that this case deserved special treatment :D

so there you go, complex and nice looking data structures with no overhead at run time, all thanks to fat arrows and efene meta programming


14
To Tumblr, Love Metalab