I wanted to revisit this conversation and see if I can address any concerns. https://roc.zulipchat.com/#narrow/stream/304641-ideas/topic/tuples.20for.20function.20arguments
I think supporting at most one argument would be beneficial to ROC long term as it would simplify the parsing and (i think) remove some ambiguity issues.
I will try to address the concerns in the post above:
Tags would have at most one type Tag a, but could manually be destructured like Tag (a,b)
Lambdas would always have at most one argument, and use destructuring as needed
\a -> a.0 + a.1 or \(a,b) -> a + b
Example of how this impacts the map function signature
#Tuple - Parenthesis would be required here to show it's one type with a nested tuple
map : (List a, ( a -> b )) -> List b
result = List.map ( [1,2,3], \num -> num * 2 )
vs
#function currying
# different order to support piping
map: (a -> b) -> List a -> List b
result = List.map (\num -> num * 2) [1,2,3]
# another example with piping
result = [1,2,3] |> List.map (\num -> num * 2)
Only supporting at most one argument should simplify the parsing a lot, reduce ambiguity, and the standard library would probably need to use function currying more often when wanting to use piping.
You would need to explicitly destructure tuples or records as needed, but a single value by itself should infer its type based on the function body.
Your thoughts?
Can you clarify what the gain here is? Roc parsing is currently functional and I don't think it has any parsing ambiguities around function arguments (at least not to a computer. Might be kinda ambiguous to humans).
Aside, roc has other reasons for not supporting currying: https://www.roc-lang.org/faq.html#curried-functions
I guess the only advantage is simplified parsing and AST, but clearly it has downsides with piping used as the last argument and common mistakes. Definitely see how Roc prefers using it as the first argument so it works like function chaining.
I missed the info in the FAQ.
Last updated: Jun 16 2026 at 16:19 UTC