Skip to content

Lambdas: |args| syntax should facilitate manually-curried functions. #2760

@bblum

Description

@bblum

I brought up manually-currying functions with @eholk and @brson, and we discussed the relative merits/demerits of the new lambda syntax. I think everyone agrees that the braces shouldn't be required, so you can write stuff like:

|a||b||c| a+b+c;

Edit: NOTE: My opinion has changed from what's written below - look in the comments.

But I think it'd be better if they bound forever instead of stopping at the first semicolon. The downsides of binding forever:

  • You can't write "for ... |i| { block }; after_loop();" (you have to stick with the current braces-before syntax). Personally, I like the current syntax better anyway.
  • You have to use either braces or parens most of the time, like "map2((|x,y|x+y),[1,2,3],[4,5,6])".

The benefit is the following idiom for manually-curried functions.

fn zipWith<A,B,C>(f: fn(A,B) -> C) -> fn@([A]) -> fn@([B]) -> [C] {|list1||list2|
    ... apply f to list1 and list2 with multiple statements ...
}

It expresses multi-staged computation really well to boot:

fn foo(x: X) -> fn@(Y) -> fn~(Z) {
    stage0(x);
|y|
    stage1_partA(x,y);
    stage1_partB(x,y);
|z|
    stage2(x,y,z);
}

Foo does stage0, returns a @-callback which awaits y before performing stage1 and then returning a ~-callback which etc etc. If we require braces to get multi-statement lambdas, you won't be able to write this sort of thing without rightward drift.

Even apart from this 'staged' pattern, I think we should make manually currying easier. It'd be good to have curried versions of map and fold, so you could write for example "foldl(0, sum)" and hand it to someone else who has a list of numbers.

Lambdas bind forever in haskell, in SML, in all renderings of lambda calculus I've seen. Brian says they only bind one expression in C#. In C++ they require braces, so that could go either way.

Also, I suspect every functionally-seasoned programmer will trip up over lambdas not binding forever. I realise our target audience is more the C++ crowd, but that's still an issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-grammarArea: The grammar of Rust

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions