Thomas Browne
Thomas Browne

Reputation: 24928

Why can't I pipe directly into Elixir String.length. Why do I have to wrap it in another function?

Why doesn't this work:

iex(2)> Enum.map(["the", "huge", "elephant"], String.length)
** (UndefinedFunctionError) function String.length/0 is undefined or private. 

But this does:

iex(2)> Enum.map(["the", "huge", "elephant"], fn x -> String.length(x) end) 
[3, 4, 8]

I mean, String.length is a function, right? Just like my anonymous wrapper one? Or is it some kind of scoping issue as per the error message?

My only experience with another functional(ish) language, is R, and this would work fine:

> sapply(c("the", "huge", "elephant"), nchar)
     the     huge elephant 
       3        4        8 
> sapply(c("the", "huge", "elephant"), function(x) nchar(x))
     the     huge elephant 
       3        4        8 

Upvotes: 1

Views: 305

Answers (1)

Dogbert
Dogbert

Reputation: 222368

String.length is a function but as Elixir allows calling a function without parentheses, you're not actually getting a function back when you type String.length, but the result of calling that function with 0 arguments. You'll have to use the &module.function/arity syntax:

iex(1)> Enum.map(["the", "huge", "elephant"], &String.length/1)
[3, 4, 8]

Upvotes: 5

Related Questions