Added list comprehensions and standard List, Option, Func, Pair, and Triple library #596

Merged
zxq9 merged 19 commits from github/fork/radrow/list-comprehension into master 2019-08-14 20:53:58 +09:00
zxq9 commented 2019-07-10 01:08:03 +09:00 (Migrated from gitlab.com)

Created by: radrow

New syntax

Example test file

contract ListComp =

    entrypoint sample1() = [1,2,3]
    entrypoint sample2() = [4,5]

    entrypoint l1() = [x | x <- sample1()]
    entrypoint l1_true() = [1,2,3]

    entrypoint l2() = [x + y | x <- sample1(), y <- sample2()]
    entrypoint l2_true() = [5,6,6,7,7,8]

    entrypoint l3() = [x ++ y | x <- [[":)"] | x <- [1,2]]
                              , y <- [[":("]]]
    entrypoint l3_true() = [[":)", ":("], [":)", ":("]]

    entrypoint l4() = [(a, b, c) | let is_pit(a, b, c) = a*a + b*b == c*c
                                 , let base = [1,2,3,4,5,6,7,8,9,10]
                                 , a <- base
                                 , b <- base, if (b >= a)
                                 , c <- base, if (c >= b)
                                 , if (is_pit(a, b, c))
                                 ]
    entrypoint l4_true() = [(3, 4, 5), (6, 8, 10)]

Standard library

Standard libraries are included automatically. They take priority over user defined files and any attempt to redefine them will lead to an error.

Developing

They are written as inlined strings in aeso_stdlib.erl, however in the future they should (IMO) be kept as separate aes files and at best compiled during aesophia build time.

If standard library wants to import another one it just needs to be mentioned in dependencies/1 function. The keyword include should not be used in stdlib code.

To preserve compatibility with existing tests all functions in stdlib should have explicitly defined types.

Other changes

expand_includes in aeso_parse has yet another argument – Included which is a set of already included files that are going to be skipped. They are encoded as pairs of their filenames and hashes of their contents. This solution solves most problems with cyclic and transitive imports and allows to safely mix them up.
This argument is also included in parse in aeso_compiler.

I have added one more compiler option – no_implicit_stdlib which stops standard library being included automatically. This helps a bit with includes inside of the stdlib and fixes compatibility issues of already existing tests that didn't expect additional includes and is very handy in tests that just don't require stdlib which has really bad impact on overall compilation performance (it increases build time by about 1 second of a single contract on my PC).

TODO

  • Move Sophia code out of the erl files++
  • Optimizations: for instance [f(x) | x <- l] could be replaced by Lists.map
*Created by: radrow* ## New syntax Example test file ```haskell contract ListComp = entrypoint sample1() = [1,2,3] entrypoint sample2() = [4,5] entrypoint l1() = [x | x <- sample1()] entrypoint l1_true() = [1,2,3] entrypoint l2() = [x + y | x <- sample1(), y <- sample2()] entrypoint l2_true() = [5,6,6,7,7,8] entrypoint l3() = [x ++ y | x <- [[":)"] | x <- [1,2]] , y <- [[":("]]] entrypoint l3_true() = [[":)", ":("], [":)", ":("]] entrypoint l4() = [(a, b, c) | let is_pit(a, b, c) = a*a + b*b == c*c , let base = [1,2,3,4,5,6,7,8,9,10] , a <- base , b <- base, if (b >= a) , c <- base, if (c >= b) , if (is_pit(a, b, c)) ] entrypoint l4_true() = [(3, 4, 5), (6, 8, 10)] ``` ## Standard library Standard libraries are included automatically. They take priority over user defined files and any attempt to redefine them will lead to an error. ### Developing They are written as inlined strings in `aeso_stdlib.erl`, however in the future they should (IMO) be kept as separate `aes` files and at best compiled during aesophia build time. If standard library wants to import another one it just needs to be mentioned in `dependencies/1` function. The keyword `include` should not be used in stdlib code. To preserve compatibility with existing tests all functions in stdlib should have explicitly defined types. ## Other changes `expand_includes` in `aeso_parse` has yet another argument – `Included` which is a set of already included files that are going to be skipped. They are encoded as pairs of their filenames and hashes of their contents. This solution solves most problems with cyclic and transitive imports and allows to safely mix them up. This argument is also included in `parse` in `aeso_compiler`. I have added one more compiler option – `no_implicit_stdlib` which stops standard library being included automatically. This helps a bit with includes inside of the stdlib and fixes compatibility issues of already existing tests that didn't expect additional includes and is very handy in tests that just don't require stdlib which has really bad impact on overall compilation performance (it increases build time by about 1 second of a single contract on my PC). ## TODO - Move Sophia code out of the `erl` files++ - Optimizations: for instance `[f(x) | x <- l]` could be replaced by `Lists.map`
zxq9 commented 2019-07-10 16:52:16 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

  • Lack of List.aes include will cause compiler crash missing flat_map function – proper message should be written

A perhaps nicer alternative is to import it implicitly.

  • Compile standard library during build time

We have no machinery for separate compilation and I don't see that there would be any tangible benefits from it.

*Created by: UlfNorell* > - Lack of List.aes include will cause compiler crash missing flat_map function – proper message should be written A perhaps nicer alternative is to import it implicitly. > - Compile standard library during build time We have no machinery for separate compilation and I don't see that there would be any tangible benefits from it.
zxq9 commented 2019-07-10 16:53:09 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

Is this type no longer valid?

*Created by: UlfNorell* Is this type no longer valid?
zxq9 commented 2019-07-10 16:55:25 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

🤨

*Created by: UlfNorell* 🤨
zxq9 commented 2019-07-10 17:11:34 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

This isn't right. iter(2 ^ n, f) == f. You want the recursive call to be

    else iter_(n / 2, comp(f, f), if(n mod 2 == 0) acc else comp(f, acc))

However I don't think this is really a function that we should put in the standard libarary.

*Created by: UlfNorell* This isn't right. `iter(2 ^ n, f) == f`. You want the recursive call to be ```suggestion:-0+0 else iter_(n / 2, comp(f, f), if(n mod 2 == 0) acc else comp(f, acc)) ``` However I don't think this is really a function that we should put in the standard libarary.
zxq9 commented 2019-07-10 17:12:18 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

is_empty?

*Created by: UlfNorell* `is_empty`?
zxq9 commented 2019-07-10 17:13:11 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

head?

*Created by: UlfNorell* `head`?
zxq9 commented 2019-07-10 17:18:16 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

To make these option-valued functions convenient to use, we should should also have some standard functions on options (but let's leave that for another PR)

*Created by: UlfNorell* To make these `option`-valued functions convenient to use, we should should also have some standard functions on options (but let's leave that for another PR)
zxq9 commented 2019-07-10 17:20:42 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

We probably want short-cut behaviour for these.

*Created by: UlfNorell* We probably want short-cut behaviour for these.
zxq9 commented 2019-07-17 00:56:15 +09:00 (Migrated from gitlab.com)

Created by: radrow

emacs for the win :p fixed

*Created by: radrow* emacs for the win :p fixed
zxq9 commented 2019-07-17 00:56:27 +09:00 (Migrated from gitlab.com)

Created by: radrow

undeleted

*Created by: radrow* undeleted
zxq9 commented 2019-07-17 00:57:57 +09:00 (Migrated from gitlab.com)

Created by: radrow

What do you mean?

*Created by: radrow* What do you mean?
zxq9 commented 2019-07-17 00:58:41 +09:00 (Migrated from gitlab.com)

Created by: radrow

That's good idea. Maybe we should start an issue for it?

*Created by: radrow* That's good idea. Maybe we should start an issue for it?
zxq9 commented 2019-07-17 01:02:15 +09:00 (Migrated from gitlab.com)

Created by: radrow

I know your point, but imo first will look more clear for a random user

*Created by: radrow* I know your point, but imo `first` will look more clear for a random user
zxq9 commented 2019-07-17 01:02:24 +09:00 (Migrated from gitlab.com)

Created by: radrow

fixed

*Created by: radrow* fixed
zxq9 commented 2019-07-17 01:04:11 +09:00 (Migrated from gitlab.com)

Created by: radrow

My bad, sorry, fixed. I believe it can be used in some iterative algorithms and we don't gain much if we remove it

*Created by: radrow* My bad, sorry, fixed. I believe it can be used in some iterative algorithms and we don't gain much if we remove it
zxq9 commented 2019-07-18 00:35:00 +09:00 (Migrated from gitlab.com)

Created by: radrow

Maybe I should consider cases of comprehension_bind and comprehension_if, @UlfNorell what do you think?

*Created by: radrow* Maybe I should consider cases of `comprehension_bind` and `comprehension_if`, @UlfNorell what do you think?
zxq9 commented 2019-07-20 03:18:15 +09:00 (Migrated from gitlab.com)

Created by: radrow

I have added some support

*Created by: radrow* I have added some support
zxq9 commented 2019-07-27 01:28:03 +09:00 (Migrated from gitlab.com)

Created by: radrow

  • Compile standard library during build time

We have no machinery for separate compilation and I don't see that there would be any tangible benefits from it.

Tests are radically longer because all that code needs to be processed every time. On the other hand I have provided option to skip stdlib – we may use it in tests that don't use it

*Created by: radrow* > > * Compile standard library during build time > > We have no machinery for separate compilation and I don't see that there would be any tangible benefits from it. Tests are radically longer because all that code needs to be processed every time. On the other hand I have provided option to skip stdlib – we may use it in tests that don't use it
zxq9 commented 2019-08-05 16:08:40 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

That all only evaluates p until it gets a false, in the same way that false && x doesn't evaluate x.

*Created by: UlfNorell* That `all` only evaluates `p` until it gets a `false`, in the same way that `false && x` doesn't evaluate `x`.
zxq9 commented 2019-08-05 23:19:52 +09:00 (Migrated from gitlab.com)

Created by: radrow

fixed

*Created by: radrow* fixed
zxq9 commented 2019-08-13 16:09:16 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

Review: Approved

*Created by: UlfNorell* **Review:** Approved
zxq9 commented 2019-08-14 15:46:04 +09:00 (Migrated from gitlab.com)

Created by: hanssv

Review: Approved

Looks great!

*Created by: hanssv* **Review:** Approved Looks great!
zxq9 commented 2019-08-14 20:53:58 +09:00 (Migrated from gitlab.com)

Merged by: hanssv at 2019-08-14 11:53:58 UTC

*Merged by: hanssv at 2019-08-14 11:53:58 UTC*
Sign in to join this conversation.
No description provided.