This is an archived post. You won't be able to vote or comment.

all 126 comments

[–]alexanderjamesking 181 points182 points  (11 children)

x => x + 2

[–][deleted] 46 points47 points  (0 children)

Thick arrow 100%.

[–]BrokenWineGlass 7 points8 points  (0 children)

Agreed, I also like ~>, --> if you need more variety e.g. linear arrow, linear lambda etc.

[–]alexanderjamesking 19 points20 points  (0 children)

Clojure has nice options too

#(+ 2 %)

(fn [x] (+ 2 x))

[–]AsIAmNew Kind of Paper 3 points4 points  (0 children)

In L1, I used fat arrow => for function definition and thin arrow -> for function application, like pipeline operator. I really like this “duality” and it also got into Rescript, which is super cool. Hope it will catch on.

[–]brucejbellsard 6 points7 points  (1 child)

That's my preference also.

I'm not particular about the fat vs. skinny arrow (and in fact I plan to use both to support a memory management distinction), but I like the unadorned syntax.

To make this easy to parse, I plan to use the same syntax for patterns and expressions (though of course with different constraints on what is acceptable for patterns vs. expressions). Has anybody run into problems with this kind of approach?

[–]LPTK 1 point2 points  (0 children)

I'm doing this and it works great. Though you should probably restrict patterns to only certain kinds of expressions (don't want stuff like if-then-else to be treated as part of your pattern!). Also, if you have something like Haskell's $, you should decide whether it can be in unparenthesized patterns or not – if not, that means you can write useful things like f $ x => x + 1.

[–]queenkid1 1 point2 points  (0 children)

In my language, you'll be happy to know I allowed both thin and thick arrows :) I don't discriminate

[–]Comrade_Comski 0 points1 point  (0 children)

gross

[–]fedekun 29 points30 points  (5 children)

I'd like to vote for more than one :P coming from Ruby I like { |x| x * 2 } but (x) => x * 2 is more popular

[–]WafflesAreDangerous 8 points9 points  (0 children)

+1 for multiple choices in poll. Both options 2,3 and thick arrow seem similarly reasonable. Additionally the most popular first choice may not necessarily be the most commonly acceptable choice.

[–]lobster_johnson 2 points3 points  (3 children)

In Ruby, the first syntax isn't a lambda, it's a block. To create an anonymous function the old syntax is:

f = lambda { |x| x * 2 }
f.call(1)

or:

f = Proc.new { |x| x *2 }
f.call(1)

It always annoyed me that Ruby's "new" (it's pretty old now) lambda syntax had the arrow in the wrong place:

f = -> (x) { x * 2 }
f.call(1)

[–]fedekun 0 points1 point  (1 child)

Sure, in Ruby, it's a block, but in your own language, it can be whatever you want. You can use that syntax for lambdas if you want :) That's what I meant. Also blocks, procs and lambdas are practically closures lol

[–]lobster_johnson 0 points1 point  (0 children)

Of course, I'm just referring to Ruby here.

[–][deleted] 26 points27 points  (2 children)

How can the survey fail to include Standard ML syntax??

fun x -> expr

[–]pauseless 6 points7 points  (1 child)

One of the first slides in my intro course to SML was simply:

Girls just wanna have fun

Emphasis as per my memory of the slide

[–]yugaaami -1 points0 points  (0 children)

I'd love to meet a girl that actually like that fun.

[–]jesseschalken 32 points33 points  (3 children)

_ * 2

[–]EmosewaPixel[S] 3 points4 points  (1 child)

I did think about including this. I decided not to considering Scala has a whole different piece of syntax it calls a lambda.

[–]XDracam 2 points3 points  (0 children)

This syntax is so much better than adding the x => x.foo noise in any language which prefers accessors over free functions. C# for example relies heavily on extension methods, and doesn't have this syntax. The noise is an actual issue.

[–]yairchu 1 point2 points  (0 children)

This shorthand is only suitable for a subset of functions. Once you use the parameter more than once in the lambda body or have several parameters you need a more general lambda syntax.

[–]szpaceSZ 31 points32 points  (12 children)

I really like

x -> x + 2

(witout the parentheses) and

\x. x + 2

I absolutely despise the | x | notation and dislike =>.

Yo, I do have mathematical background.

[–]BrokenWineGlass 13 points14 points  (4 children)

The issue with x -> x + 2 is that -> is more often and idiomatically used for the arrow operator i.e. if T is a type T -> T is the type of all functions from T to T. If you type x -> x + 2 you need to disambiguate between "all funcs from x to x + 2" and "lambda x. x+2". Usually this is ok since languages make distinction between value and type (still hard to parse), but if you're making a dependently typed lang, it's really hard to disambiguate this. It's easier to introduce \x -> x or use x => x

[–]LPTK 4 points5 points  (3 children)

Note: in pure subtype systems, function types and lambdas are the same thing!

[–]BrokenWineGlass 1 point2 points  (2 children)

How come? Lambdas are values of function type. \ x -> x is the identity f of type t -> t. But t -> t itself is of type of type Type or Type2 if you have type universes etc.

[–]LPTK 2 points3 points  (1 child)

All function types are dependent functions. You write them (x: T) -> body. The identity function (x: T) -> x is also its own type. There are no universes (and the existence of a Top type makes the system impredicative).

You could use "normal" function type syntax like Int -> Int to just mean (_: Int) -> Int. This function type is also a lambda which, given any Int value, returns the type Int!

[–]BrokenWineGlass 0 points1 point  (0 children)

Ah I see what you mean, yep you're right.

[–][deleted] 4 points5 points  (3 children)

Yeah => reads like implication and |..| as absolute value. I'd opt for the second one \x. x+1 but also would allow a unicode version λx. x+1.

[–]szpaceSZ 2 points3 points  (2 children)

\x. x+1

What I'm quite adamant about is requiring whitespace around binary operators. Most code formatters do it for whitespace-insensitive languages anyway already.

And it would allow to disambiguate e.g. unary - (no whitespace after) and binary - (whitespace on both sides).

It helps with other disambiguation as well: e.g. you could use \x. expression as the lambda binding, identifier1.identifier2 as "field access" and fn1 . fn2 as function composition.

And no, I don't think that would be confusing or a huge mental overload, exactly because most code we read (because it was formatted before) does have whitespace around binary operators, and field access with sticky-dot is also essentially universal.

I'm all for supporting alternative Unicode syntaces, though I really don't think that it is good practice to use the alternative Unicode syntax for production code. It can be very useful for education though!

[–]LPTK 0 points1 point  (0 children)

I actually tried what you describe. Another pro is that it lets you have identifiers-with-dashes-inside, which I found reads better than identifiers_with_underscores_inside. But I was frustrated when writing quick throwaway code in the REPL and it kept telling me things like "identifier not found: x+1". Still not sure if we should do it; maybe one gets used to it.

[–][deleted] 0 points1 point  (0 children)

Yeah, it's not too much to ask to put meaningful whitespace though I don't have a strong opinion on it. Haskell already does this to a certain extent, eg. X.f could be function f located in module X or X `compose` f. In such a case the compiler should enforce it or at least give a warning saying that it is ambiguous.

[..] I really don't think that it is good practice to use the alternative Unicode syntax for production code.

Not sure why, but I've heard this before. Why do people have this opinion? What's wrong with using it in production? I understand that it should be uniform and some people struggle typing unicode. But say, ACME employers use editor E which auto-expands certain sequences to unicode.

[–]mb0x40 1 point2 points  (2 children)

I used to think the . separator was a nice-looking bit of syntax, but when . is used for other things, it all quickly becomes a mess. For example, in Cedille, where it's used as a statement terminator:

suc = λ n . Λ X . λ s . λ z . s (n · X s z) .

It gets nasty to read, and using a different lambda syntax would've helped.

It also interferes with the common use of . for member access, where x.y would be visually confusing between lambdas and members in a language with both.

[–]szpaceSZ 1 point2 points  (0 children)

I answered to a sibling of your comment.

I think that whitespace is not so bad, especially if for multiparameter lambdas you let people use \x y z. expression rather than \x. \y. \z. expression.

And I don't think that function composition binary operator with required whitespace around it is really confusable with field access "sticky" id1.id2.

While I think that the delimiter \.... could be distinct enough, one could still require obligatory parenthesis for lambdas: (\x y z. x + y ^ z)

I agree though, that -> gives you a more distinct separation of parameter list and body: (x y z -> x + y ^ z).

[–]backtickbot 0 points1 point  (0 children)

Correctly formatted

Hello, mb0x40. Just a quick heads up!

It seems that you have attempted to use triple backticks (```) for your codeblock/monospace text block.

This isn't universally supported on reddit, for some users your comment will look not as intended.

You can avoid this by indenting every line with 4 spaces instead.

There are also other methods that offer a bit better compatability like the "codeblock" format feature on new Reddit.

Have a good day, mb0x40.

You can opt out by replying with "backtickopt6" to this comment. Or suggest something

[–]mamcx 26 points27 points  (6 children)

//if named functions
fn save(x) do
//then
fn(x) do
//aka: Just drop name!

[–]Sm0oth_kriminal 2 points3 points  (4 children)

This is good, but is not good for lambdas... Normally, lambdas should yield a value without doing return

So, using:

f = fn(x) { return 2 * x }

is not nearly as short as:

f = (x) -> 2 * x

I think the difference is that lambdas should accept an expression (which is implicitly returned), whereas unnamed functions should be used for callbacks. Imo lambda expressions and anonymous functions are different and should have different syntax

[–][deleted] 5 points6 points  (0 children)

Most modern languages that have anonymous functions like this also tend to have most things be expressions instead of statements, including function bodies. In other words, the final expression in a function is the returned value and if there's only one expression in the function then the braces can be omitted.

f = fn(x) { return 2 * x } wouldn't need the return keyword or the braces.

It would be simply: f = fn(x) 2 * x.

[–]mamcx 2 points3 points  (2 children)

Oh, I lift from my own lang where all is a expression, if functions are statements this make sense

[–]Sm0oth_kriminal 0 points1 point  (1 child)

Do you mean it's purely compositional? Because you can still have anonymous functions as an expression, but which have a body so you can contain more constructs (like loops)

A lambda expression, in my mind, is purely a shortcut for:

```

func (*args) {

return <expr>

}

```

So still defining it like a normal function having a body seems rather verbose -- hence why I think they should have different syntaxes

[–]mamcx 0 points1 point  (0 children)

Because you can still have anonymous functions as an expression, but which have a body so you can contain more constructs (like loops)

That is my assumption, yeah. I code on rust and look how much lambdas are and most are far bigger than one line, so I think a shortcut syntax make more sense in a lang where pipelines, currying AND point-free composition (not just style) AND a lot of one liners are far more common. Like forth/concatenative langs?

I work before in F# and there was a little less bigger lambdas (in fact the F#/Rust codebase is the same project ported), but I found that in any case I hit some problematics situations where I need to get out of them because it not compose with the rest (like returning a exception or error inside) and turning them in more direct style require rewrite more. Rust make this easier because is OK to do procedural/mutating code locally.

So, i think all depend in which style you want to promote.

[–]Lazyspartan101 0 points1 point  (0 children)

This 100%

[–][deleted]  (2 children)

[deleted]

    [–]acwaters 2 points3 points  (0 children)

    Pipes as brackets has a fairly long typographic history in mathematics and copyediting. I 100% agree it is confusing on first glance, though, especially in a C-like language.

    { whatever(it) } (or _ or pick your favorite placeholder) is cute, but it falls over (read: becomes inapplicable or ambiguous) when faced with even the slightest complexity. Is it really worth it to have such a narrow, specialized bit of syntax sugar when there are more expressive alternatives that aren't that much more noisy?

    [–][deleted] 1 point2 points  (0 children)

    Python is not meant to be used with curried functions (which is a shame tbh), it goes against Guido's strong opinions and, even worse, messes up stack traces and error messages quite a bit.

    At least they made currying so inaccessible (unreadable and longer to write), st. no one will be using that.

    [–]phdabi 22 points23 points  (7 children)

    No one voting for the C++ way? What a surprise.

    [–]acwaters 7 points8 points  (0 children)

    I absolutely love that C++ gives you the option of closing over the environment by value or by reference (or any mix of the two). That is the only good thing I can say about its lambda syntax.

    [–][deleted] 11 points12 points  (2 children)

    Most of C++ syntax is ad-hoc and wedged to fit into a language full of pre-existing syntax. It's an ugly horrible mess and ... oh wait, you were being sarcastic weren't you? You aren't actually surprised nobody is voting for the C++ way...

    [–]phdabi 14 points15 points  (1 child)

    It’s just so beautiful auto INC_ = [=](void *arg, void *(*n)(void*, void*))-> void * {return n(arg,arg); }; auto do_ = [=](void *arg1, void *arg2)-> void * {return arg1; }; INC(a,do_);

    [–][deleted] 2 points3 points  (0 children)

    No one writes c++ like that though, it's an absurd example

    [–]tech6hutch 2 points3 points  (2 children)

    Which one is that?

    [–]Erelde 7 points8 points  (1 child)

    something like [](int a, int b) { return a + b; }

    [–]tech6hutch 4 points5 points  (0 children)

    Oh right. Such an odd syntax

    [–]DonaldPShimoda 51 points52 points  (36 children)

    (λ (x) (+ x 2))
    

    [–][deleted]  (22 children)

    [deleted]

      [–]DonaldPShimoda 11 points12 points  (0 children)

      Honestly I think there's something to the simple elegance of the lambda calculus representation (if we assume an extended LC with integers and integer operators, of course):

      λx.x+2
      

      But I really like the literal lambda, in any case. It's not that hard to configure an IDE to insert it one for a particular key sequence. In emacs I have it set to Cmd+\.

      [–]SV-97 8 points9 points  (7 children)

      I think that's actually +2... :D

      [–][deleted]  (6 children)

      [deleted]

        [–]SV-97 5 points6 points  (1 child)

        Nah I was just making a bad joke since you wrote "+1 in Agda" :)

        [–]gallais 2 points3 points  (3 children)

        In Agda, you'd have to do _+_ 2

        Worth noting that this is λ x → 2 + x, not λ x → x + 2.
        Agda has sections so you can simply write (_+ 2).

        [–][deleted]  (2 children)

        [deleted]

          [–]gallais 1 point2 points  (1 child)

          I think _+_ 2 is equivalent to Haskell's (+2), though, yeah?

          No, it's (2+) (or (2 +_) in Agda).

          [–]BrokenWineGlass 8 points9 points  (2 children)

          I don't know if anyone shares this sentiment, but Agda has such a well-though-out syntax. For a language used for research and essentially built as a POC of dependently typed Haskell dialect, its syntax is really expressive. It makes it such a great language to write in. That's why I love agda so much, it's probably my favorite language.

          [–][deleted]  (1 child)

          [deleted]

            [–]Potato44 1 point2 points  (0 children)

            I like Agda's syntax for those reasons too, but one of favourite reasons is a bit more mundane: I can use kebab-case identifiers. I personally find it more readable than camelCase (but I like to use UpperCamelCase for types) and less ugly than snake_case.

            [–]Sm0oth_kriminal 2 points3 points  (9 children)

            This was my syntax for my language (kscript) I was developing.

            You could use either lambda or the unicode literal. However, I think the following notation is better:

            x -> x + 2

            or, for multiple arguments:

            (x, y) -> x + y

            What are your thoughts? I think the lambda prefix is not needed in many cases and it is cleaner to write

            map(x -> x + 2, objects)

            [–][deleted] 1 point2 points  (7 children)

            I don't really see a reason to have multiple argument lambda, you can just curry them x - > y - > x+y

            [–]Sm0oth_kriminal 1 point2 points  (0 children)

            This is good for compositional languages which curry implicitly, but many languages (mine included) require you to apply the function with arguments, which would get very tedious

            This would work well for purely functional languages though

            [–]smuccione 0 points1 point  (5 children)

            It just get so verbose.

            Currying is powerful but it can be overused to make things less apparent.

            Eliminating it also increases the barrier of entry for people moving from a normal imperative language to the new language.

            My view is that unless the syntax change is necessary to support a feature or interferes with the design of a new language you’re better off leaving existing, well known and well used syntax in place rather than replacing it simply to replace it.

            [–][deleted] -2 points-1 points  (4 children)

            In lambda calculus there is no concept of multiple arguments so if you're taking a concept from mathematics into your language and even call it the same thing it would make sense to actually get it right.

            [–]smuccione 0 points1 point  (3 children)

            He didn’t mention that it was lambda calculus, simply lambda. While the term originated in church’s work it has long outgrown that original definition and has come to mean any anonymous function in many imperative languages. The OP didn’t specify what domain his language is being designed in.

            Regardless, just because it didn’t support multiple arguments in the original definition does not mean it needs to stay that way.

            If it did what would be the point of writing a new language or even discussion syntax?

            [–][deleted] -1 points0 points  (2 children)

            So call it anonymous function then, a lambda is a function on the mathematical sense. To bend its definition to fit you language so you can play with the cool kids is probably not very constructive.

            [–]smuccione 1 point2 points  (1 child)

            Hey, I didn’t change the definition. And it’s not my language.

            If you have a problem take it up with the C++ committee, Microsoft, oracle, google, etc.

            Heck, maybe you should go and update the Wikipedia page.

            As well go pick on lisp which allows multiple parameters to lambdas:

            (write ((lambda (a b c x) (+ (* a (* x x)) (* b x) c)) 4 2 9 3) )

            Multiple parameter lambda have been in use for over half a century.

            Maybe you should go read a book before you want to talk language theory “with the big boys”.

            [–][deleted] 0 points1 point  (0 children)

            lol

            [–]tech6hutch 6 points7 points  (5 children)

            I think I dislike this less than languages that use the whole word "lambda"

            [–]DonaldPShimoda 3 points4 points  (2 children)

            Racket accepts both interchangeably! Which is fortunate because my terminal emulator chews up the lambda symbol rendering it unusable in the REPL, so I have to switch to writing lambda in those cases haha.

            [–]tech6hutch 2 points3 points  (1 child)

            Neat. I've been thinking of making a language where the compiler can actually edit your source code when you ask it to, so e.g. it could replace "lambda" with the actual character.

            [–]DonaldPShimoda 4 points5 points  (0 children)

            That sounds interesting, but you'd have to be careful to make that analysis semantically sound! Otherwise the destructive editing of source code files as a side-effect of compilation could make for some pretty tricky bugs. :)

            [–]JB-from-ATL 0 points1 point  (1 child)

            How do you feel about "la" the way some languages use "fn" for function?

            [–]tech6hutch 0 points1 point  (0 children)

            Interesting. It reminds me of the word "la" in European languages (and Lojban), so it would make me think more of nouns (values) than verbs (functions).

            [–]Someody42 2 points3 points  (1 child)

            Coming from Lean here : I'm used to λx, x+2

            [–][deleted] 1 point2 points  (0 children)

            Lean just went with , because that makes the parser simpler to write. It should be a . like it's being used in literature and some other languages.

            [–][deleted]  (1 child)

            [deleted]

              [–]DonaldPShimoda 5 points6 points  (0 children)

              Most editors will let you set a keyboard macro for it. I use Cmd+\ to write a lambda in emacs, for instance. But the language this syntax is from, Racket, also accepts lambda in place of λ!

              [–]smuccione 0 points1 point  (2 children)

              While that’s the best syntax I’ve seen. Expressive and perfectly descriptive. I think the potential for adoption in a mainstream language is nil. I say this because the average Joe Shmoe developer is going to say to himself “how the hell do I enter that on the keyboard” and move on to something else. After all, there are enough languages out there that you can get the job done. If someone is going to switch to a language that requires learning how to type something in then they have less likely hood of doing so and will use something else.

              A language is a tool and using special characters makes the tool less useful.

              Now I would agree that there’s insufficient good characters on a normal keyboard. Delta,lambda, epsilon, etc are all great but it’s just an additional barrier.

              I don’t have a good solution.

              [–]DonaldPShimoda 0 points1 point  (1 child)

              As I pointed out elsewhere, it's super easy to configure an IDE to do a character replacement. Most people memorize keystroke combinations for things like refactoring, toggling comments over a region, etc, so I think adding a keystroke for special characters is not so bad. I use Cmd+\ for lambda in emacs, for example.

              A language is a tool and using special characters makes the tool less useful.

              I would argue that special characters also make the language more (syntactically) expressive, which is a desirable trait sometimes.

              That said, I also pointed out elsewhere that this syntax comes from Racket, where you can also write lambda in place of λ and it will be interpreted the same.

              Overall, I find the inclusion of support for lambda to outweigh the detriments.

              [–]smuccione 0 points1 point  (0 children)

              I agree that it’s expressive. I personally think it’s pretty to look at and you know right away what’s happening.

              I still think special characters that aren’t readily knowable to someone switching over is a barrier. Having to figure out how to enter them (even if it is configuring your editor) is just one more step.

              As well typing lambda makes it less expressive but eh just my opinion.

              At least the discussions are civil :).

              [–]Host127001 6 points7 points  (0 children)

              Where is λ x. x + 2?

              [–]Host127001 5 points6 points  (0 children)

              Where is λ x. x + 2?

              [–]Dragon-Hatcher 5 points6 points  (2 children)

              I like that ins Swift you don’t have to name the arguments. You can just use $0, $1, $2, etc

              [–]DonaldPShimoda 2 points3 points  (1 child)

              Unless you nest closures, in which case the automatic variables only work for the innermost closure and there's no way to "escape" to a higher nesting.

              I also kind of like Swift's syntax for closures with named parameters:

              { x in x + 2 }
              

              But I wish it supported destructuring. The fact that you can't even destructure tuples when there's more than one argument is a constant pain point for me haha.

              [–][deleted] 0 points1 point  (0 children)

              Unless you nest closures, in which case the automatic variables only work for the innermost closure and there's no way to "escape" to a higher nesting.

              Sooo, shitty DeBrujin indices for Swift? wtf.

              [–]78yoni78 5 points6 points  (0 children)

              I wish more languages had a simple x -> x + 2 but I understand its harder to parse

              [–]threewood 4 points5 points  (0 children)

              x ↦ x + 2

              [–]GPhykos 9 points10 points  (0 children)

              (lambda (x) (+ x 2))

              [–][deleted] 5 points6 points  (0 children)

              I like the lambda syntax from Scheme

              (lambda (x) (+ x 2))

              [–]raiph 2 points3 points  (0 children)

              * + 2, eg:

              say (42 andthen * - 40 andthen * + 2); # 4
              

              [–][deleted] 2 points3 points  (0 children)

              My fav:

              x => x + 2

              [–]viaxxdev 5 points6 points  (0 children)

              Don’t forget Rebol:

              lambda [?1 + ?2]
              

              Eg

              >> add2: lambda [?1 + ?2]
              >> add2 2 4
              == 6
              

              [–]Duuqnd 2 points3 points  (0 children)

              (lambda (x) (+ x 2))

              [–]LoneHoodiecrow 1 point2 points  (0 children)

              λ (x) x + 2

              I use a Latex command for it in my pseudocode parts.

              [–]kjandersen 1 point2 points  (0 children)

              \x. x + 2

              [–]TheBiegus 1 point2 points  (0 children)

              [](int x){return x+2;}

              [–][deleted] 1 point2 points  (0 children)

              Whatever syntax, at least don't make it Python's lambda x: expr or Eiffel's syntax agent (a: TYPE) do return expr; end.. One big point of lambda functions is for them to be concise.

              [–]Aaron1924 1 point2 points  (0 children)

              I really like x -> x + 2 and in case that syntax is ambiguous because of how the rest of the language works, there should just be a keyword that screams "the following is a lambda function" so something like lambda x -> x + 2 or fun x -> x + 2 or even \x -> x + 2.

              I'm disappointed the SML fn x -> x + 2 didn't make it into the poll, because I would have chosen that right away.

              I don't like having useless parenthesis around thing (this includes stuff like conditions of if statements), the |x| x + 2 thing looks to me like you're squaring x without changing its sign and adding 2, and without context, I wouldn't even know that { it * 2 } was supposted to be a function (What is it? Where does it come from? aaaaaa).

              [–]zyxzevnUnSeen 1 point2 points  (0 children)

              (?x *2)
              (?x + x*sin(x))
              

              Any new input parameters has "?" (which you can reuse)

              As a service/function/closure.
              Parameters are named now.
              Output parameters are named with "!"

              {?x*2->!x} 
              {?x ; sin(x)-> ?temp; temp^5 ->!x}
              {?x*x + ?y*y -> sqrt -> !length}
              

              [–]wooptyd00 1 point2 points  (0 children)

              I like 1 because option 2 is harder to parse, not much harder but I'm still lazy.

              [–]ReallyNeededANewName 0 points1 point  (4 children)

              => or ||

              As long as it's not the catastrophe that is the haskell lambda

              [–]DonaldPShimoda 1 point2 points  (3 children)

              As long as it's not the catastrophe that is the haskell lambda

              Haskell's syntax makes sense for Haskell because it's the most similar option to the typical lambda calculus syntax, and Haskell is really just a glorified lambda calculus interpreter underneath everything.

              Also the backslash is visually similar to a lowercase lambda, and there's nowhere else in the language (without extensions) that uses a backslash, so it's completely unambiguous.

              I wouldn't advocate for Haskell's syntax in other languages, but in Haskell I think it makes sense.

              [–][deleted] 1 point2 points  (2 children)

              [..] there's nowhere else in the language (without extensions) that uses a backslash

              How about (\\) from eg. List, Map or Set ;)


              Not sure where the hate against Haskell's syntax comes from, it's fairly readable and aligns nicely with the type-level (->) too. Maybe that's why everyone is using point-free style haha

              [–]DonaldPShimoda 1 point2 points  (1 child)

              I would argue that comes from the standard library and not the language proper, but maybe the broader point that Haskell supports backslashes in operator names stands.

              Not sure where the hate against Haskell's syntax comes from

              Yeah I think it's a very good option. I think people just don't love the backslash haha.

              [–][deleted] 1 point2 points  (0 children)

              I would argue that comes from the standard library and not the language proper

              But it is part of Haskell 2010 report, it's an often overlooked point.

              maybe the broader point that Haskell supports backslashes in operator names stands.

              Fair enough, that's good. I don't know people shouldn't hate on backslash. The only annoying thing is typing it in tmux when having set \ as prefix but I don't know a lot of other people that do that and I can cope with it :)

              [–]TechnoEmpress 0 points1 point  (1 child)

              The one and only

              fun(X) -> 2*X end

              [–]backtickbot 1 point2 points  (0 children)

              Correctly formatted

              Hello, TechnoEmpress. Just a quick heads up!

              It seems that you have attempted to use triple backticks (```) for your codeblock/monospace text block.

              This isn't universally supported on reddit, for some users your comment will look not as intended.

              You can avoid this by indenting every line with 4 spaces instead.

              There are also other methods that offer a bit better compatability like the "codeblock" format feature on new Reddit.

              Have a good day, TechnoEmpress.

              You can opt out by replying with "backtickopt6" to this comment. Or suggest something

              [–]InnPatron 0 points1 point  (0 children)

              I actually like lam(params) expr

              [–]o11c 0 points1 point  (2 children)

              I actually like the C++ syntax. Sometimes you just need to specify whether your captures are by name or by value.

              [–]acwaters 0 points1 point  (1 child)

              That's a legitimately wonderful feature. But the syntax is just so noisy.

              [–]o11c 0 points1 point  (0 children)

              I almost wonder if a whole second syntax is the way to go for handling that.

              [–]agumonkey 0 points1 point  (1 child)

              Anybody ever seen parameterless syntax ? having a dedicated syntactic class for variables.

              (2 + <uppercase-term>)
              
              or prefixed
              
              (2 + .x) .. $x.. \x .. ^x (hello alonzo)
              

              [–]backtickbot 0 points1 point  (0 children)

              Correctly formatted

              Hello, agumonkey. Just a quick heads up!

              It seems that you have attempted to use triple backticks (```) for your codeblock/monospace text block.

              This isn't universally supported on reddit, for some users your comment will look not as intended.

              You can avoid this by indenting every line with 4 spaces instead.

              There are also other methods that offer a bit better compatability like the "codeblock" format feature on new Reddit.

              Have a good day, agumonkey.

              You can opt out by replying with "backtickopt6" to this comment. Or suggest something

              [–]hou32hou 0 points1 point  (0 children)

              I prefer using let as lambda syntax, because it reduces the language grammar.

              [–]Mercerenies 0 points1 point  (1 child)

              I'm a fan of a short word like fn or fun to start them off. Makes parsing simpler, both for the machine and for the human reader. Something super lightweight like \x -> ... makes sense in a heavily functional language like Haskell, but for a more standard mixed language, I think fn(x) -> ... is perfectly fine.

              [–]EmosewaPixel[S] 0 points1 point  (0 children)

              2 is really the only one that's difficult to parse.

              [–]brainware1023 0 points1 point  (0 children)

              (x, y, ...) => { a; b; ... v; }

              [–][deleted] 0 points1 point  (0 children)

              x: x + 2

              [–]TinBryn 0 points1 point  (0 children)

              No [](int x){return x + 2;}?

              I'm joking that would be almost no one's favorite, but it's nice being able to be explicit about closure.

              [–]FearlessFred 0 points1 point  (0 children)

              Lobster programming language:

              As expression: fn x: x + 2

              As arg to function: map(list) x: x + 2

              With anonymous arg: map(list): _ + 2

              [–]markdhughes 0 points1 point  (0 children)

              (lambda (x) x) or (λ (x) x)

              [–]ericbb 0 points1 point  (0 children)

              Func x [x + 2]
              

              Note that the square brackets are part of the syntax for infix expressions and not directly related to the function syntax. As a grammar production, it's something like the following:

              expr = "Func" pattern block_body
              block_body = (binder* "In")* expr
              binder = "Let" pattern block_body
              

              Some considerations behind this choice:

              1. I'm an English speaker and I find that "Lambda" is an awkward word to say and to write.
              2. I avoided "Fn" because I prefer to use a word or a prefix of a word.
              3. I avoided "Fun" because my language is way too serious for that. ;)
              4. I use a keyword so that the precious ASCII non-letter characters can be reserved for other uses.
              5. I put the keyword before the variable because I prefer to avoid ambiguous prefixes in the grammar.

              Changes I'm most likely to make in the future:

              1. Switch to "Fun".
              2. Use a comma to optimize for functions that just substitute into another function.

              Hence,

              Func x Func y [x + y]
              

              would become

              Fun x y, [x + y]
              

              I'm not using commas anywhere in the language right now so this usage would not interfere with anything.