ashneyderman

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

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

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

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*

Where Next?

Popular in Questions Top

beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; somethi...
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&amp;query=perfume&amp;page=2, I would like to get: ...
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
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31013 112
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52673 488
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New

We're in Beta

About us Mission Statement