As detailed in my previous reply, when discussing such extensions to the
language, it is very important to go beyond the trivial examples. The
examples above look obvious because we all know how String.downcase/1
behaves. We know it expects one argument. So looking at examples we can
"guess" how we want the code to behave

But if I look at this code:

&SomeModule.some_function

It actually has two possible interpretations:

fn -> SomeModule.some_function end
fn x -> SomeModule.some_function(x) end

None of them are possible in the language today, but once we do allow the
proposed syntax, we are introducing this ambiguity. Sure, the compiler will
know which one to pick, but for every person reading the code, your brain
now has to parse it, interpret it, and resolve it accordingly.

I have given more examples in an earlier reply so I won 't repeat those,
but in a nutshell we are not adding more ambiguity to the language. The
cost it has on reading the code is not worth saving 2-3 characters.


*José Valim*
www.plataformatec.com.br
Skype: jv.ptec
Founder and Director of R&D


On Wed, Jul 3, 2019 at 3:01 PM Alexis Brodeur <[email protected]>
wrote:

> Opps, I read too fast.
>
> No, the form would need to explicitly match `&function` or
> `&function(...)`, meaning `&(...)` would not be treated differently and
> current use of the form `&function(...)` must use capture arguments or it
> will not compile, meaning no breaking changes.
>
> On Wednesday, July 3, 2019 at 8:59:13 AM UTC-4, Alexis Brodeur wrote:
>>
>> No, since a capture argument is used in `&(&1)`, it would not be affected.
>>
>> On Wednesday, July 3, 2019 at 8:56:12 AM UTC-4, Tyson Buzza wrote:
>>>
>>> Would this mean
>>>
>>> &(&1) == &()
>>>
>>> On Wed, Jul 3, 2019, 8:45 PM Alexis Brodeur <[email protected]> wrote:
>>>
>>>> Let me reformulate that,
>>>>
>>>> If no capture arguments (i.e.: `&1`, `&2`, etc.) are used in a capture
>>>> function and the capture function is simply a function call (of the form
>>>> `&my_function(...)` or `&my_function`, `&1` will automatically be inlined
>>>> as the first argument of the captured function, thereby removing the need
>>>> to know arity at compile time.
>>>>
>>>> Meaning (pseudocode warning):
>>>> &identity == &identity(&1)
>>>> &role?(:admin) == &role?(&1, :admin)
>>>>
>>>> &role?(&2) != &role?(&1, &2) # capture argument, so no inlined first
>>>> argument
>>>>
>>>> If we go in this direction, why not add something like lens, a capture
>>>> structured like a property access.  `&.my_property` could translate to
>>>> `&(&1.my_property)` ?
>>>>
>>>> I think this is an interesting feature proposal, and both changes are
>>>> backward compatible.
>>>> On Tuesday, July 2, 2019 at 9:27:52 PM UTC-4, Rich Morin wrote:
>>>>>
>>>>> Thanks for all the thoughtful responses.  Also, apologies for the
>>>>> ambiguities and
>>>>> omissions in my original note.  As so often happens, some of the
>>>>> things I had in
>>>>> mind didn't make it into my email.  (sigh)
>>>>>
>>>>> In this note, I'm only considering the case of named functions that
>>>>> are explicitly
>>>>> handed other named functions as arguments, via function capture.  So,
>>>>> for example,
>>>>> we don't have to worry about dealing with variables which are bound to
>>>>> a function.
>>>>>
>>>>> # Inferring arity of captured functions
>>>>>
>>>>> When a captured function (&bar) is being used as an argument to
>>>>> another function
>>>>> (foo), it may be possible to infer bar's arity.  In the case of
>>>>> library functions,
>>>>> this information should be available from the function's typespec.
>>>>> For example,
>>>>> https://hexdocs.pm/elixir/Enum.html#group_by/3 tells us that key_fun
>>>>> and value_fun
>>>>> both have arity 1:
>>>>>
>>>>>   group_by(enumerable, key_fun, value_fun \\ fn x -> x end)
>>>>>
>>>>>   group_by(t(), (element() -> any()), (element() -> any())) :: map()
>>>>>
>>>>> So, we should be able to write something like this:
>>>>>
>>>>>   list = ~w{ant buffalo cat dingo}
>>>>>
>>>>>   list |> Enum.group_by(&String.length)
>>>>>   # %{3 => ["ant", "cat"], 5 => ["dingo"], 7 => ["buffalo"]}
>>>>>
>>>>>   list |> Enum.group_by(&String.length, &String.first)
>>>>>   # %{3 => ["a", "c"], 5 => ["d"], 7 => ["b"]}
>>>>>
>>>>> To clarify my motivation, I'm not trying to save the effort of typing
>>>>> the arity
>>>>> information.  Rather, I'm trying to cut down on the amount of clutter
>>>>> on the page
>>>>> and (perhaps) the effort of reading it.  I also want to get the "/1"
>>>>> syntax out
>>>>> of the way to allow for the following notion.
>>>>>
>>>>> # Adding arguments to captured functions
>>>>>
>>>>> Many named functions take multiple arguments, so they can't be used in
>>>>> function
>>>>> captures.  Allowing arguments could extend their reach and reduce the
>>>>> need for
>>>>> special-purpose lambdas.  Here is some proposed syntax:
>>>>>
>>>>>   list = [
>>>>>     { :status, 2, "This is a minor problem." },
>>>>>     { :status, 1, "This is a major problem." }
>>>>>   ]
>>>>>
>>>>>   list |> Enum.sort_by(&elem(1))
>>>>>
>>>>> which could replace complected horrors such as:
>>>>>
>>>>>   list |> Enum.sort_by(fn {_, x, _} -> x end)
>>>>>   list |> Enum.sort_by(fn x -> elem(x, 1) end)
>>>>>
>>>>> https://hexdocs.pm/elixir/Enum.html#sort_by/3 tells us that its
>>>>> mapper function
>>>>> needs to have arity 1: "(element() -> mapped_element)".  Although
>>>>> we're using
>>>>> elem/2, we're also handing it an argument, so the arity math comes out
>>>>> even...
>>>>>
>>>>> -r
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>> 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 [email protected].
>>>> To view this discussion on the web visit
>>>> https://groups.google.com/d/msgid/elixir-lang-core/54d0dc1b-241e-4ed0-a76b-b6d8c828e86f%40googlegroups.com
>>>> <https://groups.google.com/d/msgid/elixir-lang-core/54d0dc1b-241e-4ed0-a76b-b6d8c828e86f%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>> .
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>> --
> 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 [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/ca1cc996-414c-473e-ad75-6d799ccb4d82%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/ca1cc996-414c-473e-ad75-6d799ccb4d82%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4LAa8o_r2t-TF1AyATfUfZW1oP6akibZreYev5Rxa1kKw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to