ashneyderman
Compiler tells me anonymous functions can not have default parameters
So something like this fails to compile:
def streamfun_from_string(str) do
fn(skip_headers \\ true) ->
..
end
end
I am wondering why is this a restriction? I do not quite understand the reason for it. Is there a work-around?
Most Liked
OvermindDL1
To sum up:
Functions are named by their atom name and their arity. There is no such thing as an arity-less function. There is such a thing as an atom-less function, those are anonymous functions, notice it still has an arity however. Thus every function always absolutely has an arity. Now considering that a default argument actually creates two function of one with the full arity and one of less that just calls the one with more, and considering function pointers only reference a single function and not multiple, that means it can’t encode both, just not possible.
peerreynders
Google Groups elixir-lang-talk (2014): Default arguments on anonymous functions
i.e.
defmodule Demo do
def identity(x \\ :ok), # ONE function definition
do: x
defp info(fun) do
fun
|> Function.info()
|> IO.inspect()
end
def run do
info(&identity/0) # TWO functions
info(&identity/1) #
end
end
Demo.run()
$ elixir demo.exs
[
pid: #PID<0.89.0>,
module: Demo,
new_index: 0,
new_uniq: <<135, 214, 25, 143, 240, 101, 78, 237, 14, 92, 136, 181, 46, 33, 8,
18>>,
index: 0,
uniq: 71217356,
name: :"-run/0-fun-0-",
arity: 0,
env: [],
type: :local
]
[
pid: #PID<0.89.0>,
module: Demo,
new_index: 1,
new_uniq: <<135, 214, 25, 143, 240, 101, 78, 237, 14, 92, 136, 181, 46, 33, 8,
18>>,
index: 1,
uniq: 71217356,
name: :"-run/0-fun-1-",
arity: 1,
env: [],
type: :local
]
An anonymous function is a single function value.
Is there a work-around?
Probably not what you had in mind:
defmodule Demo do
def makeFun() do
fn options ->
{skip_headers, _options} = Keyword.pop_first(options, :skip_headers, true)
skip_headers
end
end
def run do
f = makeFun()
IO.inspect(f.([]))
IO.inspect(f.(skip_headers: false))
end
end
Demo.run()
$ elixir demo.exs
true
false
OvermindDL1
The common erlang idiom is to do {module, function, [postargs]} where postargs are useful for carrying additional state (I.E. the closure part). So you can do something like {Blah, :blorp, [1, 2, 42]} then call it like {mod, fun, args} = {Blah, :blorp, [1, 2, 42]}; apply(mod, fun, [:prefix, :args | args]).
This is also why you tend to see so many erlang functions designed to take their most useful state at the end (same pattern as piping, which, again, Elixir does backwards), and it fit is so fantastically with Tuple Calls as it basically made this pattern a full callable instead (like anonymous functions)! But that’s gone now *grumble*grumble*…
Popular in Questions
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
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









