librelist archives

« back to archive

Efene documentation nits

Efene documentation nits

From:
Brian Candler
Date:
2011-02-07 @ 16:44
Hi,

I've been reading efene documentation, and noticed a few minor things which
I think are errors.

http://marianoguerra.com.ar/efene/docs/reference/expressions/literals.html
--------------------------------------------------------------------------

    A term holding a value, it must start with a lower case letter

I think you mean an *upper* case letter?

    >>> P = (adam,24,(july,29)).
    (adam,24,(july,29))
    >>> element(1,P).
    adam

There are extra erlang-style dots at the end of each line.

    >>> element(3,P).
    (july,29)
    >>> P2 = setelement(2,P,25).
    (adam,25,(july,29))

These actually print tuples with braces, e.g. {july,29}. However I suspect
that's a bug in the implementation, and the documentation shows intended
behaviour, since {july,29} is not accepted by efene.

    >>> tuple_size(P).
    3
    >>> tuple_size(()).
    0

The last one should be: tuple_size((,))

    >>> <[10,20]>
    <<10,20>>
    >>>  <["ABC"]>
    <<"ABC">>

efene actually prints return values enclosed in <[ ]> not erlang << >>,
e.g. <[10,20]>

    >>> <[1:1,0:1]>
    <<2:2>>

In this case the documentation is correct, but I think the efene
implementation is wrong.  That value should be <[2:2]> if you want to be
able to paste it back into efene.

http://marianoguerra.com.ar/efene/docs/reference/expressions/add.html
---------------------------------------------------------------------

    -    substraction

should say "subtraction"

http://marianoguerra.com.ar/efene/docs/reference/expressions/struct.html
------------------------------------------------------------------------

    >>> Person = {name: "mariano", "age": 25}
    {name: "mariano", "age": 25}

Console output is actually:
{name: [109, 97, 114, 105, 97, 110, 111], "age": 25}
This might be either a documentation or implementation bug.

https://github.com/marianoguerra/efene
--------------------------------------
Under "Participate", links to
https://github.com/marianoguerra/efene@librelist.com
instead of
mailto:efene@librelist.com

General
-------
The compiler seems to get very confused if you give it source code with
a .efn rather than .fn extension. That was my mistake of course.

Anyway, I just thought I'd note these down. efene looks very interesting. I
started trying to hack erlang into a ruby-type syntax, but gave up after not
getting very far :-)

Regards,

Brian.

P.S. I also had your idea of using the -> operator, passing the left-hand
value as an argument.  However, looking at the standard library, it seemed
to me that in most cases that this value should be passed as the *last*
argument not the first, e.g.

       mapfoldl(Fun, Acc0, List1) -> {List2, Acc1}
       member(Elem, List) -> bool()
       nth(N, List) -> Elem

For example: I would prefer this syntax

>>> [10,11,12]->lists.nth(1)
exception throw: function_clause
  in function  lists:nth/2
     called as lists:nth("\n\v\f",1)

but actually efene requires

>>> 1->lists.nth([10,11,12])
10

I also observe that many functions take an auxiliary function as the first
argument, which means you could shift a ruby-style block into the first
argument.  e.g.

    [1,2,3]->lists.map() { |X| X*2 }

would become

    Tmp1 = [1,2,3],
    Tmp2 = lists:map(fun(X) -> X*2 end, Tmp1)

Anyway, just a thought :-)

Re: [efene] Efene documentation nits

From:
Mariano Guerra
Date:
2011-02-07 @ 17:24
On Mon, Feb 7, 2011 at 1:44 PM, Brian Candler <B.Candler@pobox.com> wrote:
> Hi,
>
> I've been reading efene documentation, and noticed a few minor things which
> I think are errors.
>
> http://marianoguerra.com.ar/efene/docs/reference/expressions/literals.html
> --------------------------------------------------------------------------
>
>    A term holding a value, it must start with a lower case letter
>
> I think you mean an *upper* case letter?

fixed

>    >>> P = (adam,24,(july,29)).
>    (adam,24,(july,29))
>    >>> element(1,P).
>    adam
>
> There are extra erlang-style dots at the end of each line.

fixed

>    >>> element(3,P).
>    (july,29)
>    >>> P2 = setelement(2,P,25).
>    (adam,25,(july,29))
>
> These actually print tuples with braces, e.g. {july,29}. However I suspect
> that's a bug in the implementation, and the documentation shows intended
> behaviour, since {july,29} is not accepted by efene.

yes, that's a bug in the shell implementation

>    >>> tuple_size(P).
>    3
>    >>> tuple_size(()).
>    0
>
> The last one should be: tuple_size((,))

fixed

>    >>> <[10,20]>
>    <<10,20>>
>    >>>  <["ABC"]>
>    <<"ABC">>
>
> efene actually prints return values enclosed in <[ ]> not erlang << >>,
> e.g. <[10,20]>
>
>    >>> <[1:1,0:1]>
>    <<2:2>>
>
> In this case the documentation is correct, but I think the efene
> implementation is wrong.  That value should be <[2:2]> if you want to be
> able to paste it back into efene.

again, bug in the shell code

> http://marianoguerra.com.ar/efene/docs/reference/expressions/add.html
> ---------------------------------------------------------------------
>
>    -    substraction
>
> should say "subtraction"

done

> http://marianoguerra.com.ar/efene/docs/reference/expressions/struct.html
> ------------------------------------------------------------------------
>
>    >>> Person = {name: "mariano", "age": 25}
>    {name: "mariano", "age": 25}
>
> Console output is actually:
> {name: [109, 97, 114, 105, 97, 110, 111], "age": 25}
> This might be either a documentation or implementation bug.

since strings are list of numbers sometimes the output appears like
that, I will see if I can fix those cases.

> https://github.com/marianoguerra/efene
> --------------------------------------
> Under "Participate", links to
> https://github.com/marianoguerra/efene@librelist.com
> instead of
> mailto:efene@librelist.com

fixed

> General
> -------
> The compiler seems to get very confused if you give it source code with
> a .efn rather than .fn extension. That was my mistake of course.

I reported it here:

https://github.com/marianoguerra/efene/issues/issue/32

> Anyway, I just thought I'd note these down. efene looks very interesting. I
> started trying to hack erlang into a ruby-type syntax, but gave up after not
> getting very far :-)
>
> Regards,
>
> Brian.
>
> P.S. I also had your idea of using the -> operator, passing the left-hand
> value as an argument.  However, looking at the standard library, it seemed
> to me that in most cases that this value should be passed as the *last*
> argument not the first, e.g.
>
>       mapfoldl(Fun, Acc0, List1) -> {List2, Acc1}
>       member(Elem, List) -> bool()
>       nth(N, List) -> Elem
>
> For example: I would prefer this syntax
>
>>>> [10,11,12]->lists.nth(1)
> exception throw: function_clause
>  in function  lists:nth/2
>     called as lists:nth("\n\v\f",1)
>
> but actually efene requires
>
>>>> 1->lists.nth([10,11,12])
> 10

for that I created the d.ifn and l.ifn modules in efene lib, just to
give the arguments the correct order and provide better names, I don't
know if those libs will keep those names but I don't want to clash
with other modules so I name my modules with short names :)

I think that is a common convention to place the variable that
contains the information that will be manipulated as first argument
(almost all languages do that), and I want to keep that convention.

> I also observe that many functions take an auxiliary function as the first
> argument, which means you could shift a ruby-style block into the first
> argument.  e.g.
>
>    [1,2,3]->lists.map() { |X| X*2 }

the problem there is that both the list and the fun will try to be
inserted as first parameter :)

> would become
>
>    Tmp1 = [1,2,3],
>    Tmp2 = lists:map(fun(X) -> X*2 end, Tmp1)
>
> Anyway, just a thought :-)

I like the idea of ruby blocks, I have to think if I want to add yet
another notation for functions.

thanks for all the reports I will work on improving the shell pretty
printing and compiler error messages

Re: [efene] Efene documentation nits

From:
Brian Candler
Date:
2011-02-07 @ 18:00
On Mon, Feb 07, 2011 at 02:24:43PM -0300, Mariano Guerra wrote:
> I think that is a common convention to place the variable that
> contains the information that will be manipulated as first argument
> (almost all languages do that), and I want to keep that convention.

All except erlang stdlib :-)

To be fair there are some exceptions:

       erlang:append_element(Tuple1, Term) -> Tuple2
       atom_to_binary(Atom, Encoding) -> binary()    %% and friends
       is_function(Term, Arity) -> bool()
[re] - most functions

But it seems to me the more common case is for the 'receiver' to be last
when dealing with data structures:

       element(N, Tuple) -> term()
       erlang:make_tuple(Arity, Default, InitList) -> tuple()

[lists]
       all(Pred, List) -> bool()
       any(Pred, List) -> bool()
       delete(Elem, List1) -> List2
       ... many more

[proplists]
       append_values(Key, List) -> List
       delete(Key, List) -> List
       expand(Expansions, List) -> List
       get_all_values(Key, List) -> [term()]
       ... many more, although not normalize and split

[dict]
       append(Key, Value, Dict1) -> Dict2
       append_list(Key, ValList, Dict1) -> Dict2
       erase(Key, Dict1) -> Dict2
       fetch(Key, Dict) -> Value
       ... many more

[queue]
       in(Item, Q1) -> Q2
       in_r(Item, Q1) -> Q2
       split(N, Q1) -> {Q2,Q3}
       ... etc

> >    [1,2,3]->lists.map() { |X| X*2 }
> 
> the problem there is that both the list and the fun will try to be
> inserted as first parameter :)

True, if you have already decided that the first argument must be the
receiver.  In that case the block could become the last argument - which is
also opposite to the stdlib :-)

[lists]
       dropwhile(Pred, List1) -> List2
       flatmap(Fun, List1) -> List2
       foldl(Fun, Acc0, List) -> Acc1
       foreach(Fun, List) -> void()
       ... etc

Anyway, thank you for your rapid reply.

Regards,

Brian.