torimus

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

peerreynders

https://groups.google.com/d/msg/elixir-lang-core/3HVYGqimS9o/8x9L6PNeHewJ


https://github.com/pragdave/elixir-fx

rodrigues

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

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

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.

Where Next?

Popular in Discussions Top

PragTob
Hey everyone, this has been on my mind for some time and I’d love your input on it! TLDR: I feel like maps are superioer for storing and...
New
rms.mrcs
A couple of days ago I was discussing with a friend about different approaches to write microservices. He said that if he was going to w...
New
acrolink
How does the two languages compare when it comes to server side application development? Any experiences or ideas? Thank you.
New
mikl
I wanted to capitalize a string, and tried using String.capitalize(). That generally works well, until you try to capitalize a word like...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
matthias_toepp
I’d love to hear what people think about Wisp, the new Gleam web framework started by Gleam’s primary creator Louis Pilfold. Gleam, alon...
New
arcanemachine
https://nitter.net/josevalim/status/1744395345872683471 https://twitter.com/josevalim/status/1744395345872683471
New

Other popular topics Top

baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New

We're in Beta

About us Mission Statement