torimus
Capture containing at least one argument - CompileError
Hello.
I’m relatively new to Elixir, but not to programming generally.
In the learning process I’ve been recently struck with following inconsistency, at “capturing” an anonymous function with & operator:
iex> &(:just_return_this_atom)
** (CompileError) iex:350: invalid args for &, expected an expression in the format of &Mod.fun/arity, &local/arity or a capture containing at least one argument as &1, got: :just_return_this_atom
I’ve read the docs, where the limitation is stated:
The only restrictions when creating anonymous functions is that at least one placeholder must be present, i.e. it must contain at least
&1, and that block expressions are not supported:
What is the rationale behind this limitation ? I’ve already searched some mailing lists but so far no satisfactory explanation has been found.
I’m aware by choosing unary ampersand operator for converting both - normal expression and function name with arity - to Function instance, already did introduced ambiguity itself. In addition, by choosing slash operator both - for arithmetic division and separator between function name and its arity, only made it worse.
As far as I know, function_name/arity_num is not even valid token itself and does exist only for the sole purpose of capturing with &. Just in this single special case.
Are there some plans, work in core dev to fix above described inconsistency in some major release, like 2.0 ? Or find it as unsolvable problem without breaking backward compatibility and accepting damage has been already done ?
I’d probably need dive deeper into Elixir’s parser, but so far I’d imagine it could be handled with fixing operators precedence incl. parens and capturing function_name/arity_num would always require explicit enclosing in parens.
Most Liked
peerreynders
rodrigues
Hi @torimus, welcome to the forum!
I don’t know why it’s like this, if there’s any technical reason, but I suspect it’s intentional, a language design choice.
For some time I also liked the idea of the capture operator working without &1, but now I see it potentially bringing confusion, this ends up helping to bring clarity and consistency to elixir code IMO.
Some meta examples where I see it becoming cryptic or misleading:
# this "lispy wrapping" could become very confusing, specially for beginners
[&(42), &(nil), &([]), &(:foo), &(@foo), &(foo), ...]
# & easily unnoticeable
[&%{foo: :bar}, &"wut", &[1, 2, 3]]
&fun(1) # easy to mistake with fun(1) or &fun(&1)
&Mod.fun() # easy to confuse with Mod.fun(), &Mod.fun/0 wins IMO
&Mod.fun(a, b) # easy to confuse with Mod.fun(a, b)
hauleth
name/num is perfectly valid and token and can be used for division. Which mean that in situation like:
f = &(a/2)
The compilation need to “deduce” whether a is a function or not.
Another reason can be the fact that &foo(1) and &foo(&1) can be easily confused one with another and could lead to strange bugs.
Last Post!
hauleth
& operator when used as a sugar for generating lambda has more limitations, for example this is illegal:
fun = &(&2)
As you need to use all arguments within such lambda body. So no, there is no exception to the rule as &function/arity is something completely different from & &1 lambda as these will behave differently. First one will cause call to function/arity while second will expand to fn a -> a end which will expand even further to generate function with generated name, for example :'-lambda-line-1-arity-1'/0 which will be internally used by the compiler. So yes, there is huge difference between these two.
Popular in Discussions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









