calebh / Juniper

https://www.juniper-lang.org/
MIT License
79 stars 9 forks source link

Tuple Syntactic Sugar #22

Closed Qata closed 2 weeks ago

Qata commented 2 weeks ago

Realised too late that my comment in #17 was pretty off-topic compared to what you were talking about.

I was thinking of special-cased syntactic sugar that essentially auto-names a tuple arg to something like tup, then inserts let (name1, name2, name3) = tup, as a post-type check but pre-compilation step.

So the former gets rewritten to the latter, then compiled:

(_, snd) => snd
(tup) => {
    let (_, snd) = tup
    snd
}

Feel free to close if it would be tedious to implement a rewriting step within the compiler. It’d be nice to have but it is just sugar.

calebh commented 2 weeks ago

Under the proposal in #17, you would be able to pattern match tuples in the argument list. For instance, if you wanted to map over a list of tuples, and return a list of only the second elements, you could do:

List:map(((a, b)) => b, mylst)

This is different from a function with two arguments, ie:

(a, b) => b

This function takes in two arguments and returns the second.

Under your proposal, how would we be able to tell the difference between a two argument lambda and a one argument lambda that takes a tuple?

Note:

For quickly accessing the first and second elements of a pair (two element tuple), you can already use the fst and snd functions defined in Prelude. For example:

List:map(snd, mylst)

or

let mytup = (true, 1u32)
// "a" gets bound to true
let a = fst(mytup)

In many other functional programming languages, a function can only take one argument. Multiargument functions often have syntax sugar for automatic currying (which is why I mentioned currying in #17). This doesn't work as well with Juniper, since I wanted to stay close to the C++ language where functions can have multiargument functions, and currying with stack allocated closures can be expensive.

Qata commented 2 weeks ago

Ah so my first instinct was right in that #17 will allow destructuring a tuple in a closure argument? Excellent. That's more than adequate.

Under your proposal, how would we be able to tell the difference between a two argument lambda and a one argument lambda that takes a tuple?

Good point, closing this out.