Scoty

Scoty

Can I check if value is in range in a guard clause

Hey,

I am currently reading Programming Elixir and I am doing one of the exercises where you should write a solution to the “I’m thinking of a number between 1 and 1000”

I have made it work, but I wanted to add a simple guard clause: I want to check if the passed number is actually in the passed range. As far as I have read only handful of functions and operators are allowed in guard clauses, but the ‘in’ is one of them.

So 1st I tried this:

def guess(actual, range) when (actual not in range), do: IO.puts "actual #{actual} is not in #{range}"

But I got: (ArgumentError) invalid args for operator “in”, it expects a compile-time proper list or compile-time range on the right side.

2nd I tried to make a list from the range:

def guess(actual, range) when (actual not in (Enum.to_list range), do: IO.puts "actual #{actual} is not in #{range}

And again I got the same error, this time saying that I the right side is the function itself instead the evaluation of it, which should be proper list ?!?

But this works(when the range is defined in the guard clause) :

def test(x) when(x not in 1..100) …

Most Liked

NobbZ

NobbZ

Well, at the point, where you already matched on min and max, and you can make it a compiletime range again for the guard:

iex(1)> defmodule M do
...(1)>   def guess(n, min..max) when n in min..max, do: "Yeah, you won!"
...(1)>   def guess(_, _), do: "There is no try!"
...(1)> end
iex(2)> M.guess 4, 1..1000
"Yeah, you won!"
iex(3)> M.guess 4, 1..3   
"There is no try!"

I consider this slightly more readable than n > min and n < max (which I generally would prefer to write as min < n and n < max.

lpil

lpil

Creator of Gleam

How about something like this?

def guess(actual, min..max) when actual < min or actual > max

Guards are very limited, and much of the fancy properties of in in guards is done at compile time using macros; because of this a compile time range literal can be used, but a runtime range value cannot.

NobbZ

NobbZ

Which is quite less readable and you have to remember to do it that way, while using the n in a..b approach just works.

NobbZ

NobbZ

Also I just realise, that there is a very big difference between using comperators and using in range:

iex(1)> defmodule M do
...(1)>   def f(n, a..b) when n in a..b, do: "Yeah!"
...(1)> 
...(1)>   def g(n, a..b) when a <= n and n <= b, do: "Yeah"
...(1)>   def g(_, _), do: "WTF?"
...(1)> end
iex(2)> M.f(5, 10..1)
"Yeah!"
iex(3)> M.g(5, 10..1)
"WTF?"
OvermindDL1

OvermindDL1

Sounds like a good use for a defguard (especially with OTP21’s new map_get guards as then you could make a in_range/2, but otherwise an in_range/3 would work regardless, though an in-range/2 could be made if my original defguard proposal was made instead…).

Where Next?

Popular in Chat/Questions Top

William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
xgilarb
Hi there, I’m interested in using Elixir because of the rumors about the reliability of the Phoenix framework, and surprisingly, Elixir’...
New
Yoga
Or at least, in the works? All I can find are bits and pieces but not a single project from start to finish. Including things like i18n,...
New
New
tom_s
Hello Elixir Community! I’m new to functional programming in general and to Elixir in particular but I’m very intrigued and would like t...
New
TwistingTwists
I want to learn DSL. Don’t know how to write one. What;s the best introductory resource? I see some macro being used here. Is DSL only ...
New
woohaaha
I’m coming from Ruby and Rails. I have read some Elixir and Phoenix books. They shed a lot of light about building applications in Elixir...
New
miguelsrrobo
hi i was wondering if it is necessary to learn erlang to learn elixir
New
imanuelgittens
Hey all! Just joined the forum and I’m very excited to learn the language. I just finished reading the documentation and I was wondering ...
New
Fl4m3Ph03n1x
Background I am trying to do the typical Ceaser cypher exercise in Elixir. The description of the exercise is as follows: Create an impl...
New

Other popular topics Top

pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
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 49522 488
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
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
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New

We're in Beta

About us Mission Statement