Why am I getting a FunctionClauseError ("lack of function matching function") in this Elixir program translated from Erlang?

** So, I used to work with Erlang, and it is very convenient for me. I'm just trying to find out the elixir.

Recently, I tried to translate the example of “lazy kitchens” into an elixir, and I am puzzled by why it either does not compile or compiles with a warning and does not work. What I am missing is here; Any ideas? The erlang code and "run" are as follows: **

jps@GRASSKEET ~/dev/erlang $ cat cater.erl -module(cater). -export([cater/1]). cater(0) -> 1; cater(N) when N>0 -> N + cater(N-1). jps@GRASSKEET ~/dev/erlang $ erl Eshell V6.3 (abort with ^G) 1> c("cater.erl"). {ok,cater} 2> cater:cater(10). 56 3>* 

When I write Cater.ex like this, it gets an error that doesn't make sense to me:

 jps@GRASSKEET ~/dev/elix $ cat Cater.ex defmodule Cater do def cut(0), do: 1 def cut(N) when N>0, do: N + cut(N-1) end jps@GRASSKEET ~/dev/elix $ iex Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> c("Cater.ex") Cater.ex:1: warning: redefining module Cater Cater.ex:3: warning: this expression will fail with ArithmeticError [Cater] iex(2)> Cater.cut(10) ** (FunctionClauseError) no function clause matching in Cater.cut/1 Cater.ex:2: Cater.cut(10) iex(2)> 
+6
source share
1 answer

Just to expand the problem and why you received the error message:

Header identifiers are considered aliases for atoms. For instance:

 iex(1)> N == :Elixir.N true 

So, if you have the following code:

 iex(1)> defmodule Test do ...(1)> def foo, do: IO.puts "testing" ...(1)> end iex(2)> Test.foo testing 

This is the same as saying

 iex(3)> :Elixir.Test.foo testing 

Since uppercase identifiers are treated as characters, you essentially wrote the following program:

 defmodule Cater do def cut(0), do: 1 def cut(:Elixir.N) when :Elixir.N>0, do: :Elixir.N + cut(:Elixir.N-1) end 

This is valid because you can match the pattern by atoms in the argument list, and :Elixir.N > 0 is a valid expression.

 iex(1)> N > 0 true 

Consider the following program and Elixir output:

 iex(1)> defmodule Cater do ...(1)> def cut(0), do: IO.puts "cut(0)" ...(1)> def cut(N) when N > 0, do: IO.puts "cut(N)" ...(1)> end iex(2)> Cater.cut(0) cut(0) iex(3)> Cater.cut(N) cut(N) iex(4)> Cater.cut(:Elixir.N) cut(N) iex(5)> Cater.cut(1) ** (FunctionClauseError) no function clause matching in Cater.cut/1 iex:2: Cater.cut(1) 

So, the reason you got the strange no function clause matching in Cater.cut/1 error message is because there is technically nothing wrong with your program (except the actual body of the cut(N) -it function will raise an ArithmeticError , which Elixir warns you during compilation); he’s totally believable, he just doesn’t do what you wanted him to do / what you thought he did.

+7
source

Source: https://habr.com/ru/post/989041/


All Articles