I suspect creating even more terse syntax around this feature will only make the code less and less readable.
--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
On Sun, Aug 4, 2013 at 2:49 AM, Alexei Sholik <alcos...@gmail.com> wrote:
Support for &1/shell("%{rm} *.o") will allow one to generate an arbitrary function of N arguments that does nothing with them. Will the language benefit from it?
Yes, I believe it will, because it is orthogonal. &(...)
creates a function. Right now it guesses the arity from the presence of &n
in the capture. But there‘s no way to create a function of zero arity. (There’s a slightly amusing compilation error involving &0
:
iex(2)> f=&[&0,&1]
** (CompileError) iex:2: capture &0 cannot be defined without &1
So at a minimum, I'd strongly support &(expression without &n)
generating a zero airty function, rather that the current error(s) (compare &(42)
and &(:atom)
). Note that the parentheses are required here. &1 is a deprecated way of generating a function that returns its argument, and &(1) is a proposed way of generating a zero arity function that returns 1.
Then there‘s the issue of generating functions of greater arity than would be suggested by the placeholder &ns. This is still useful (but less so that the case of fn/0, I think). I think Alex’s example is a good example. If this were to be supported, I'd suggest the syntax
&/1(expr)
If expr
contains placeholders, then the highest numbered must be <= the number after the &/
. Gaps would be allowed. So
&/4(&1+&3) → fn a, _, b, _ -> a+b end
As I said, I think this is more esoteric than the zero arity case, but it is still useful.
Dave
Yes, I believe it will, because it is orthogonal.
&(...)
creates a function. Right now it guesses the arity from the presence of&n
in the capture. But there‘s no way to create a function of zero arity. (There’s a slightly amusing compilation error involving&0
:iex(2)> f=&[&0,&1] ** (CompileError) iex:2: capture &0 cannot be defined without &1
So at a minimum, I'd strongly support
&(expression without &n)
generating a zero airty function, rather that the current error(s) (compare&(42)
and&(:atom)
). Note that the parentheses are required here. &1 is a deprecated way of generating a function that returns its argument, and &(1) is a proposed way of generating a zero arity function that returns 1.
Then there‘s the issue of generating functions of greater arity than would be suggested by the placeholder &ns. This is still useful (but less so that the case of fn/0, I think). I think Alex’s example is a good example. If this were to be supported, I'd suggest the syntax
&/1(expr)
If
expr
contains placeholders, then the highest numbered must be <= the number after the&/
. Gaps would be allowed. So&/4(&1+&3) → fn a, _, b, _ -> a+b end
>
> Elixir makes no distinction in between &(1) and &1 at the AST level. Maybe we could support expression without &n as long as it is an explicit call but I don't think we should add it now. I would like to remove the old syntax and wait the current one get more stable before doing additions.
Of course, the issue is that we use & for both the capture operator and the placeholders. If say we were to use , $ or \ for the capture, then the issue would go away…
I agree to a point. But the more I think about it, the more I think the issue here is the overloading of &
to mean both capture function and here's a parameter placeholder.
To me, being able to write
Enum.map list, λ(&1+1)
just seems nicer than
Enum.map list, fn element -> element + 1 end
Extending it to faking out arity is slightly ugly, but powerful. It could look like λ/1(42)
, which equates to the current fn _ -> 42 end
.
OK, you say, but I don't have λ on my keyboard, to which I say “buy a bigger keyboard, or use Ukelele” :). (Or, more realistically, we could use \, which is currently unambiguous in this context. This would look like
Enum.map list, \(&1+1) and \/1(42)
For the 90% use case, fn a, b -> a + b end
seems noisy and verbose. &1+&2
was very nice, but clearly ambiguous and unworkable in the general case. &(&1+&2)
removes some of the ambiguity, but at the cost of overloading &
, which means that &(42) can't work. It also leads to constructs such as & &1
, which makes my eyes tear up a little.
So I'm simply suggesting taking the next evolutionary step and changing the capture operator to \ (maybe aliased to λ, just because…), which removes the ambiguity and supports proper function capture.
Dave (channelling Mr Wall) Thomas
--
I agree to a point. But the more I think about it, the more I think the issue here is the overloading of
&
to mean both capture function and here's a parameter placeholder.To me, being able to write
Enum.map list, λ(&1+1)
just seems nicer than
Enum.map list, fn element -> element + 1 end
Extending it to faking out arity is slightly ugly, but powerful. It could look like
λ/1(42)
, which equates to the currentfn _ -> 42 end
.OK, you say, but I don't have λ on my keyboard, to which I say “buy a bigger keyboard, or use Ukelele” :). (Or, more realistically, we could use \, which is currently unambiguous in this context. This would look like
Enum.map list, \(&1+1) and \/1(42)
...
--
Hugs