This idea is just for increased readability. Would it be nice to require & in front of function types when passing as an argument, so it's obvious they are being passed by reference instead of being called? I guess () already shows a function is being called with or without arguments, but nothing to show a variable function name is being passed by reference?
main! =
store_email!(Path.from_str("url.txt")) ? &handle_err!
store_email! = |path|
url = File.read_utf8!(path)?
user = Http.get!(url, Json.utf8)?
dest = Path.from_str("${user.name}.txt")
File.write_utf8!(dest, user.email)?
Stdout.line!("Wrote email to ${Path.display(dest)}")
handle_err! = |err|
when err is
HttpErr(url, _) -> Stderr.line!("Error fetching URL ${url}")
FileReadErr(path, _) -> Stderr.line!("Error reading from ${Path.display(path)}")
FileWriteErr(path, _) -> Stderr.line!("Error writing to ${Path.display(path)}")
It also makes it obvious if the variable name is a function, or some other type
I understand the goal here, but it isn't pass by reference. So I wouldn't call it that.
It also might be very odd for inline lambdas
(deleted)
I wouldn't think inline needs & because it's not a variable
What is it called when a function is passed in as an argument like List.map for example?
List.map(list, |x| x + 1)
That is an inline lambda
addOne = |x| x + 1
List.map(list, &addOne)
Yeah, those two are exactly the same in roc. So likely they should be treated the same in syntax (but they don't strictly have to be)
Yeah, the & would only be required on variable names with type function.
I think it makes it obvious which arguments for the map function are data types / array / obj vs a function
Brian Teague said:
What is it called when a function is passed in as an argument like List.map for example?
No special name. Just passing a function. Reference or not is an implementation detail that roc users don't interact with
When I see List.map(list, &addOne) I immediately know addOne is a function without knowing the implementation details for addOne.
That's fair. I understand the idea. I don't particularly see a reason to make functions special, but I get that they can do more than regular data types. That said, what about a record of functions or a list of functions?
I guess those would just pass like regular records or lists?
Cause a record of functions can do a lot more than a single function but is not particularly more special than any other record.
{a: &doStuff, b: anInt} # Obvious a has a function type
vs
{a: doStuff, b: anInt} # current version
&[doStuff1, doStuff2] # arrays have strict types, so maybe only need 1 &
vs
[&doStuff1, &doStuff2] # still like this better
vs
[doStuff1, doStuff2] #current version
vs
[anInt1, anInt2]
(&doStuff, anInt) #tuple example, first arg is a function
Yeah, I think & in front of functions makes it obvious which are functions and which are normal data types.
Fair enough. I don't particularly find this compelling, but I understand it. Curious to hear other opinions.
To me it is extra noise that I almost never need (but very minor noise)
When learning more complicated functional programming that use functions as arguments, I have thought to myself, "man, I wish I knew that was a function type" ahead of time (mainly in JavaScript)
Devils advocate, I guess the verb in the variable name usually gives that away too.
Humans are very good at pattern recognition.
And this makes it explicitly obvious, () means the variable is being invoked, and & means the function variable is being passed as an argument.
callFunc1(a, b, &c, callFunc2(d, &e))
When looking at this which variables are functions, and which variable are being called, and which variables are values like int, str, array, or obj?
But yeah, the new syntax ROC is currently using is just pure AWESOME!!!
What if callFunc2 returns a lambda?
Still same syntax?
In the IDE with type on hover it's pretty easy to see what's a function if it's not already clear from the name.
From my own experience I believe I rarely pass a function that isn't an inline lambda.
I think that if we ever introduced a syntax like this, to Anton’s point, it should be for something like partial application - probably for a static dispatch call
And to be clear I’m not arguing in favor of us introducing that syntax
Brendan Hansknecht said:
Still same syntax?
That is a really good edge case I did not see. I think & in front of callFunc2 would be useful information to tell the user it returns a function. In this example the function call () still has a higher precedence then &, and & is just informational to show the return type of callFunc2.
callFunc1(a, b, &c, &callFunc2(d, &e))
Anton said:
In the IDE with type on hover it's pretty easy to see what's a function if it's not already clear from the name.
I'm not for this suggestion, but in general, I don't think that LSPs are enough here if you want a feature like this. The LSP requires interaction to see the info. This is info that @Brian Teague looks to want at a glance. An LSP will not give you that over a larger function. So I think there is a clear distinction here.
For myself, I think naming is enough general. Also, I am just so familiar with the various functions in my code that take lambdas that none are surprising. I know that map, walk, etc all take a lambda.
I imagine if Richard's original dream of making the Roc editing experience easily extendable ever comes true it should be possible write a plug-in in Roc to add inlay hints to the IDE that show which values are lambdas. For now you would have to fork a Roc extension to add it.
Note: Syntax highlighting (such as with Eli's tree-sitter-roc and my rocwise-editor-themes) should color function identifiers with a distinct color, even when referenced in function arguments.
"The LSP requires interaction to see the info". This is entierly up to the editor configuration no? Emacs with eglot LSP integration displays type information inline by default in rust for example.
Yeah that's what I was talking about earlier, vscode calls them "inlay hints"
IMO this should be LSP function - and let the editor differntiate variables tha hold functions with different colors.
I don't really think having the symbol prefixes for everything is a good idea - it will get annoying to type
In C# we have different colors for local variables, class fields etc - you can take it to the extreme with theming.
Last updated: Jun 16 2026 at 16:19 UTC