News for hackers. Stuff that matters.
Re:Dave Herman’s contributions to Rust by devit on Monday May 03, 2021 @09:17AM (#27024649)
That would imply that "foo(x: int)" is a string rather than a function.

Haskell doesn't use that notation either, it uses -> both for the parameter list and for the return type, and separates argument names (arguably, these are poor choices, since currying is not an efficient CPU-native operation and not intuitive so distinguishing between multiple arguments and returning closures is useful, and argument names are useful for documentation).

Re:Dave Herman’s contributions to Rust by willtim on Monday May 03, 2021 @09:34AM (#27024878)
> That would imply that "foo(x: int)" is a string rather than a function

But foo(x : int) is a string! It literally reads "foo applied to x". In the function definition, it appears to be used as a left-hand-side pattern which is "matched". The definition is written as if to say, whenever the term foo(x) is encountered, use this definition here. At least, that was my expectation.

> Haskell doesn't use that notation either

OCaml does and Haskell once had a proposal to add it. Haskell type signatures are normally written separately, but it does support annotating patterns with the right extensions.

Re:Dave Herman’s contributions to Rust by gpm on Monday May 03, 2021 @11:10AM (#27026077)
No, foo(x: int) is not a string, it's not even an expression, it's not even an AST node. It's a fragment of the larger ast node

    fn foo(x: int) -> ReturnType {
        body
    }
The ast here splits into

    Function {
        name: foo
        signature: (x: int) -> ReturnType
        body: body
    }
I.e. the arrow binary op binds more tightly than the adjacency between foo and x: int. And the type of foo is a function, not a string.

A "better" way to write this (in that it breaks down the syntax into the order it is best understood) might be

    static foo: (Int -> ReturnType) = {
        let x = arg0;
        body
    }
Or to put it another way. Reading foo(x: int) as "foo applied to x" in this case is a mistake, because that's now how things bind. You should read that "foo is a (function that takes Int to String)". It's a syntactic coincidence that foo and x are beside eachother, nothing more.
Re:Dave Herman’s contributions to Rust by willtim on Monday May 03, 2021 @11:36AM (#27026427)
That's a nice explanation of what's going on. My point remains that I found the syntax confusing though.
Re:Dave Herman’s contributions to Rust by gpm on Monday May 03, 2021 @11:47AM (#27026576)
Ya, I'm not really going to defend the current syntax past "function syntax is hard".

It's mixing up assigning a global variable, specifying that variables type, and destructuring an argument list into individual arguments, in one line. I've played at making my own language, and this is one part that I've never been satisfied with.

Personally I'd probably at least go with a `foo = <anonymous function>` syntax to split out the assigning part. But that's spending "strangeness budget" because that's not how C/Python/Java do it, and I can understand the decision to not spend that budget here...

Re:Dave Herman’s contributions to Rust by ZoomZoomZoom on Monday May 03, 2021 @10:20AM (#27025404)
> But foo(x : int) is a string!

Can you say so decisively for a language with first-class functions?

Re:Dave Herman’s contributions to Rust by willtim on Monday May 03, 2021 @11:34AM (#27026402)
You are quoting me out of context. In many languages, the term and/or pattern foo(x : int) is a string, if foo : int -> string.
Re:Dave Herman’s contributions to Rust by kaba0 on Monday May 03, 2021 @10:01AM (#27025172)
Just a nitpick, but currying is a language detail, one can potentially create an efficient implementation with or without them.
Re:Dave Herman’s contributions to Rust by willtim on Monday May 03, 2021 @10:07AM (#27025255)
Yes and of course Haskell is quite capable of supporting uncurried functions too, e.g.

foo :: (Int, Int) -> Int

foo (x, y) = ...

Re:Dave Herman’s contributions to Rust by valenterry on Monday May 03, 2021 @09:34AM (#27024872)
I don't think that would be the implication, because we are in the context of a function. Otherwise, we should also not write foo(x: int) but foo: int -> ?