--
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.
I'd vote for (3): require () for parameterless calls only.
All the solutions have a little associated inconsistency. To me, this solution minimizes the impact.
The most common use of a function with no parameters will be to create something to pass to map and friends, and there you are -passing- the function, not calling it, so there's no impact.
Dave
--
The inconsistency lies in the fact we can't invoke an anonymous functions that takes no arguments without parentheses (because that simply means accessing a variable):iex> print = fn -> IO.puts "hello" endiex> print#Function<...>iex> print()hello
I'd vote for (3): require () for parameterless calls only.
Am I the only one who likes the current way to call an anonymous function and the clarity it provides?The only reason it's confusing is because people are trying to mind map other language semantics onto Elixir.
In Scala, invoking anonymous function requires parentheses.
I suggest keeping the new anonymous function syntax, and requiring
that invoking anonymous function requires parentheses.
--
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.
I'm with Dave on this one. Using () for all 0-arity function calls is better IMO. It makes the code clearer both for beginners (is `self` a variable or a function?) and veterans.
parent = self() # this is now the only way to _call_ selfself_fn = self # error? or perhaps this is equal to &self/0? I'm suggesting the latterLikewise,Enum.map col, one_arg_func# orEnum.map(col, one_arg_func)If it's clear in the grammar that `one_arg_func` above is not a call (I think it's clear enough for humans), then it can be treated as if it was `&one_arg_func/1`).
--
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.
I agree with Dave and Alexei. Please keep 0-arity remote function invocation syntax the same. Having to write `file.mtime()` for record fields wouldn't be very nice.
We can't do this because functions are recognized by name and arity. So if you have foo/1, foo/2 and foo/3 and simply call "foo", how would we know which one of the three do you want?
Our compiler cannot figure that out and even if it did, it is perfectly fine for a function to accept anonymous functions with 1, 2, 3 or more arguments.
--
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.
We can't do this because functions are recognized by name and arity. So if you have foo/1, foo/2 and foo/3 and simply call "foo", how would we know which one of the three do you want?I was half-joking, but I don't think it's an entirely lost cause. For instance, Enum.map always expects a function of 1 argument. That could be encoded in the type spec and used by compiler. It doesn't matter what the arity of the given function is, because this is valid code in Elixir:Enum.map col, &div/2Enum.map col, &Nonexistent.func/1So the only thing that matters is what Enum.map expects.
Our compiler cannot figure that out and even if it did, it is perfectly fine for a function to accept anonymous functions with 1, 2, 3 or more arguments.I can't come up with an example of such a function. But I don't see as a problem anyway.
Wait. We already have a syntax for that.
So what is wrong with this approach? Why has no one commented on this?
That wouldn’t work. We need special syntax for invocation of anonymous functions because elixir is a dynamic language. Imagine you have the following expression: var. Should we generate code for function invocation or for variable access? We don't know because at compile time we don’t know if var is an anonymous function or any other type.
On 11/05/2013 10:30 AM, Eric Meadows-Jönsson wrote:
> I agree with Dave and Alexei. Please keep 0-arity remote function
> invocation syntax the same. Having to write `file.mtime()` for record
> fields wouldn't be very nice.
>
>
> On Tue, Nov 5, 2013 at 10:15 AM, José Valim <jose....@plataformatec.com.br
Where the `def` macro when seeing `@prop` would add the function atom to
a module property and the compiler would look in that property to see if
the call should be allowed or denied.
Again, the problem here is that elixir is a dynamic language. We have the same issue with typespecs that someone talked about above. How can the compiler look for @prop when it doesnt know the module at compile time: mod = Foo; mod.bar?
On 11/05/2013 10:30 AM, Eric Meadows-Jönsson wrote:
> I agree with Dave and Alexei. Please keep 0-arity remote function
> invocation syntax the same. Having to write `file.mtime()` for record
> fields wouldn't be very nice.
>
>
> On Tue, Nov 5, 2013 at 10:15 AM, José Valim <jose....@plataformatec.com.br
On 11/05/2013 10:30 AM, Eric Meadows-Jönsson wrote:
> I agree with Dave and Alexei. Please keep 0-arity remote function
> invocation syntax the same. Having to write `file.mtime()` for record
> fields wouldn't be very nice.
>
>
> On Tue, Nov 5, 2013 at 10:15 AM, José Valim <jose....@plataformatec.com.br
1. What will happen with imported modules?import MyModule...fun_from_my_module # imported from MyModuleIn particular, this is important for autoimported functions from Kernel (e.g. self)
3. I expect pipelines should work without parens, but I'd just like to verify:var|> fun|> another_fun
Even if it was possible, I really dislike this approach because it is poorly extensible. For example, a simple property like name may be changed later to be the concatenation of first and last names. The cost of such computation is very likely irrelevant to the app but now I need to update all invocations to account the change. There is a lot of theory coming from Eiffel (uniform access principle iirc) detailing why this is not desired.
Local, anonymous and imported functions with zero arity will require parentheses.
3. I expect pipelines should work without parens, but I'd just like to verify:var|> fun|> another_funVery good question. As there is no ambiguity in this case, I can see an argument for it not being required. But I can also see an argument for consistency as well.
1. What will happen with imported modules?import MyModule...fun_from_my_module # imported from MyModuleIn particular, this is important for autoimported functions from Kernel (e.g. self)
3. I expect pipelines should work without parens, but I'd just like to verify:var|> fun|> another_fun
On 11/05/2013 10:30 AM, Eric Meadows-Jönsson wrote:
> I agree with Dave and Alexei. Please keep 0-arity remote function
> invocation syntax the same. Having to write `file.mtime()` for record
> fields wouldn't be very nice.
>
>
> On Tue, Nov 5, 2013 at 10:15 AM, José Valim <jose....@plataformatec.com.br
Best regards
Alexei Sholik
--
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.
Ah, thanks Alexei (and sorry Peter)! I thought it worked as JavaScript (where the issue I described exists).
Am I the only one who likes the current way to call an anonymous function and the clarity it provides?The only reason it's confusing is because people are trying to mind map other language semantics onto Elixir.
On Mon, Nov 4, 2013 at 6:16 PM, TR NS <tran...@gmail.com> wrote:
On Monday, November 4, 2013 4:42:35 PM UTC-5, José Valim wrote:
The inconsistency lies in the fact we can't invoke an anonymous functions that takes no arguments without parentheses (because that simply means accessing a variable):iex> print = fn -> IO.puts "hello" endiex> print#Function<...>iex> print()hello
If the goal is to have annonymous functions behave like local methods, why not make the exception that anonymous functions require a special syntax to access them as a variable. e.g.
iex> print = fn -> IO.puts "hello" endiex> print
helloiex> \print#Function<...>
Of course the trick then becomes finding a good syntax for that.
--
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.
Local, anonymous and imported functions with zero arity will require parentheses.So calling any fun with arity > 0 will work without parens? In particular, it will not be necessary to use parens when calling macros (unless of course it accepts no argument)?
3. I expect pipelines should work without parens, but I'd just like to verify:var|> fun|> another_funVery good question. As there is no ambiguity in this case, I can see an argument for it not being required. But I can also see an argument for consistency as well.The complete consistency is not guaranteed in any case, since we can call external funs without parens, and we can call funs with arities > 0 without parens. In that sense, there are subtle syntax differences for the same thing (calling a fun). Which is why I start to wonder are the benefits of dropping current lambda call syntax really worth it.
In any case, having to writevar|> fun()|> another_fun()would in my opinion uglify the code a bit.
Well, the DSL argument is what drives the compromise for me.Removing parentheses and dots will just make DSLs more expressive and for that I would be willing to live with slight inconsistencies.So my vote would be for required parentheses on /0 anonymous functions (for higher arity functions not using parentheses should be OK), removal of the dot and maintaining the ability to call (named) functions without parentheses.Which I guess means I'm repeating what the majority say :PV.-
Hello everyone,This is a small discussion about removing the dreaded dot from the anonymous function invocation syntax. The current:iex> sum = fn a, b -> a + b endiex> sum.(1, 2)
1 + 2
Will become:iex> sum = fn a, b -> a + b endiex> sum(1, 2)1 + 2The consequence of this change is that anonymous functions can now shadow local function calls. If this is a good thing or not is being discussed literally for decades, as seen in the Lisp-1 vs Lisp-2 discussions. The change is mostly straight-forward except by one inconsistency that would be introduced into the language which I want to discuss.Today, in order to invoke a local function, parentheses are not required:do_something 1, 2, 3Parentheses are not required even if the function expects no arguments:do_something #=> translated as do_something() as long as there is no do_something varAnd we want anonymous functions to behave the same:iex> sum = fn a, b -> a + b endiex> sum 1, 2
The inconsistency lies in the fact we can't invoke an anonymous functions that takes no arguments without parentheses (because that simply means accessing a variable):iex> print = fn -> IO.puts "hello" endiex> print#Function<...>iex> print()hello
That is very inconsistent. Since the whole point of removing the dot is to allow shadowing, invoking anonymous and local functions should be bound by the same syntax. That said, we have two options:1. Give up on the new anonymous function syntax.2. Deprecate (during a long, long period) invocation of local functions without parentheses. That said, if you have `foo` in your code calling a local function foo/0, a warning asking parentheses to be explicitly added will now be issued. In case you choose 2, should this rule also apply to remote calls on functions with no args? I.e. should `MyModule.foo` also emit the same warning or the warning should only apply to local functions?So which option do you choose and why?
I agree with Devin and Yurri in that the current state of things is quite balanced and I find my own Elixir code uses anonymous functions much less often than imported and local module functions. Given this usage pattern, I actually prefer/don't mind the dot invocation since it explicitly shows what is going on, namely, it's invoking an anonymous or captured function. Optional parens for local functions is a must for me since it makes composing DSLs much nicer so I plead that we don't go the #2 route.It appears that abandoning the removal of the dot invocation is actually the clearest approach and avoids introducing new inconsistencies, at the cost of a special case for anon funcs and newcomers learning the "dot syntax". For me, this is a pleasant tradeoff and swings my vote towards leaving the current state as is.
--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-core" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-core/_kEBXO0NRDY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-co...@googlegroups.com.
--
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.
The more I think about it, the more I'm inclined to side with Yurii.
1) keep as is2) remove the dot and require parentheses for non-qualified 0-arity calls
3) remove the dot but keep optional parentheses
--
Wait. We already have a syntax for that.
So what is wrong with this approach? Why has no one commented on this?
That wouldn’t work. We need special syntax for invocation of anonymous functions because elixir is a dynamic language. Imagine you have the following expression:
var. Should we generate code for function invocation or for variable access? We don't know because at compile time we don’t know ifvaris an anonymous function or any other type.
The more I think about it, the more I'm inclined to side with Yurii.I believe I’m coming around to this perspective as well.
why not simply use the "/" sign at the end to mean "function as a value" without the need of a leading "&":ModuleFoo.ModuleBar.func/When there is no ambiguity, simply use the slash sign ("/"): foo/. It might mean foo/0 in priority. If there is ambiguity, use foo/1, foo/2, foo/3...
There could be another syntax that would fit nicely with partially applied functions: the "_" sign as a placeholder. This way any function "called" with "_" would return a partially applied function.
So `foo _` would be the same than `foo(_)`, and the same than `foo/1
If we consider piping as a succession of 1-arity functions as values, we could
do things like this:2|> times _, 2|> times 3, _|> divides _, 4|> modulo _, 2# result is 11|> add_two/1|> divides &1, _# returns a 1-arity function that divides by 3