I'm failing to see how they're not isomorphic.
However, as the article outlines, there are differences (both positive and negative) to using functions with these types. Curried functions allow for partial application, leading to elegant definitions, e.g., in Haskell, we can define a function that sums over lists as sum = foldl (+) 0 where we leave out foldl's final list argument, giving us a function expecting a list that performs the behavior we expect. However, this style of programming can lead to weird games and unweildy code because of the positional nature of curried functions, e.g., having to use function combinators such as Haskell's flip function (with type (A -> B -> C) -> B -> A -> C) to juggle arguments you do not want to fill to the end of the parameter list.
From a theoretical perspective, a tuple expresses the idea of "many things" and a multi-argument parameter list expresses the idea of both "many things" and "function arguments." Thus, from a cleanliness perspective for your definitions, you may want to separate the two, i.e., require function have exactly one argument and then pass a tuple when multiple arguments are required. This theoretical cleanliness does result in concrete gains: writing down a formalism for single-argument functions is decidedly cleaner (in my opinion) than multi-argument functions and implementing a basic interpreter off of this formalism is, subsequently, easier.
From a systems perspective, there is a clear downside in this space. If tuples exist on the heap (as they do for most functional languages), you induce a heap allocation when you want to pass multiple arguments! This pitfall is evident with the semi-common beginner's mistake with OCaml algebraic datatype definitions where the programmer inadvertently wraps the constructor type with parentheses, thereby specifying a constructor of one-argument that is a tuple instead of a multi-argument constructor (see https://stackoverflow.com/questions/67079629/is-a-multiple-a... for more details).
The distinction is mostly semantic so you could say they are the same. But I thought it makes sense to emphasize that the former is a feature of function types, and the latter is still technically single-parameter.
I suppose one real difference is that you cannot feed a tuple into a parameter list function. Like:
fn do_something(name: &str, age: u32) { ... }
let person = ("Alice", 40);
do_something(person); // doesn't compile
The article is about programmer ergonomics of a language. Two languages can have substantially different ergonomics even when there is a straightforward mapping between the two.
Then there's an implication of 'sure, but that doesn't actually help much if it's not standar' and then it's not addressed further.
The article draws a three way distinction between curried style (à la Haskell), tuples and parameter list.
I'm talking about the distinction it claims exists between the latter two.
args = (a, b, c)
f args
…and that will have the effect of binding a, b, and c as arguments in the called function.In fact many “scripting” languages, like Javascript and Python, support something close to this using their array type. If you squint, you can see them as languages whose functions take a single argument that is equivalent to an array. At an internal implementation level this equivalence can be messy, though.
Lower level languages like C and Rust tend not to support this.
1) "performance is a bit of a concern"
2) "curried function types have a weird shape"
2 is followed by single example of how it doesn't work the way the author would expect it to in Haskell.It's not a strong case in my opinion. Dismissed.
I think you are focusing on the theoretical aspect of partial application and missing the actual argument of the article which having it be the default, implicit way of defining and calling functions isn't a good programming interface.
I wrote a non-trivial lambda program [1] which enumerates proofs in the Calculus of Constructions to demonstrate [2] that BBλ(1850) > Loader's Number.
[1] https://github.com/tromp/AIT/blob/master/fast_growing_and_co...
[2] https://codegolf.stackexchange.com/questions/176966/golf-a-n...
They are not equally easy for me to use when I'm writing a program. So from a software engineering perspective, they are very much not the same.