Erlang/OTP Forums

Author Message

<  Erlang  ~  == vs =:=

wallink
Posted: Thu Dec 13, 2007 9:29 pm Reply with quote
Joined: 01 Dec 2007 Posts: 5 Location: Göteborg
Hello everybody, I'm pretty new to erlang and reading the book "Programming Erlang" written by Joe Armstrong.

He writes that in 99 of 100 cases I should use the =:= instead of the ==. I think I know what they do and i don't understand why I shouldn't use ==.

As I understand it: The only difference is that when you comepare integers and floats you can get different results like:

5==5.0 => true
5=:=5.0 => false

And in this case I usally want it to be true...so why is =:= better? is there any other difference between them???

THANKS!
View user's profile Send private message MSN Messenger
wolfgke
Posted: Thu Dec 13, 2007 10:07 pm Reply with quote
User Joined: 16 Sep 2007 Posts: 16
=:= will also compare whether the arguments have the same type while == will convert integer to float when one of the 2 arguments is an integer and the other one is a float (read the book page 106-107).

So =:= helps to avoid the bug that an argument type which is not intended is used.
View user's profile Send private message
dsmith
Posted: Mon Feb 04, 2008 10:57 am Reply with quote
User Joined: 08 Aug 2007 Posts: 36 Location: Toronto
I don't get it either.

Using =:= will not producer a compile-time or runtime-time error/warning if the number types are different, so it won't help identify a bug, it will just evaluate to false.

When comparing float to integers, I almost always want to do the value comparison after the integer is converted to a float( ie. the == semantics). In this case accidentally using =:= would produce be a bug.

I'm not sure if I'm just slow. If someone can give a clear example of how I might run into trouble using ==, that would be greatly appreciated.
View user's profile Send private message
francesco
Posted: Tue Feb 05, 2008 7:27 pm Reply with quote
User Joined: 07 Jul 2006 Posts: 238 Location: London
Joe has a programming style (Joeism) which does not often match with what the masses do. This might change if everyone reads his book Smile

I have been using Erlang for 15 years, and always use == unless I need an exact match (Which has never happened).

Another interesting Joeism is spawn(Fun) which is also rarely used in production systems because you can not upgrade the code in the function you have spawned. Use spawn(Module, Function, Args), which Joe mentions, but forgets to add that Function must be exported.

Other than the above, I love his book. It has really raised the profile of Erlang.

Francesco
View user's profile Send private message Visit poster's website
happi
Posted: Wed Feb 06, 2008 7:07 am Reply with quote
Joined: 07 Nov 2005 Posts: 6 Location: Sweden
There are a number of reasons to use =:= instead of ==.

1. It is a bit faster.
2. It gives more information to the compiler and to tools like Dialyzer. (The type on both sides of =:= will be known.)
3. It is exactly the same test which is used in pattern matching, you can easily convert code using =:= comparison to pattern matching and back.

francesco wrote:
Quote:

spawn(Fun) which is also rarely used in production
systems because you can not upgrade the code in the
function you have spawned.


This is so wrong on so many levels.
You should always use spwan(Fun) nowadays in order to not have to expose your process entry point through an export.

First of all code loading with funs works fine if you use the fun Module:Function/Arity version.
Secondly, you don't have to loop over the fun, in fact you seldom do, you just use the fun to start the code:

Code:

 start(State) -> spawn(fun () -> loop(State) end).

 loop(State) ->
   ...
   ?MODULE:loop(State).


The closure will be thrown away as soon as the function loop is entered and code loading will again work fine.

(Ok, so in this example you will have to export loop/1 anyway, but in general it is a good principle.)
View user's profile Send private message Visit poster's website
dsmith
Posted: Thu Feb 07, 2008 8:18 am Reply with quote
User Joined: 08 Aug 2007 Posts: 36 Location: Toronto
Quote:

2. It gives more information to the compiler and to tools like Dialyzer. (The type on both sides of =:= will be known.)

Fair enough. You are right, dialyzer does produce warnings when the =:= comparison evaluates to false, but does not for ==. For me this is a good enough reason to use the former. I'm not sure, however, why dialyzer does not do comparison checks on ==. If for example I have an expression {}==2, dialyzer does not report an error. It seems to me it could and it should.
Quote:

3. It is exactly the same test which is used in pattern matching, you can easily convert code using =:= comparison to pattern matching and back.

To your 3rd point, perhaps a refactoring tool can use this difference to determine whether a refactoring is safe. But beyond that I'm not so convinced.

Unfortunately, the =:= is just plain ugly. Smile
View user's profile Send private message
francesco
Posted: Sun Feb 24, 2008 10:18 am Reply with quote
User Joined: 07 Jul 2006 Posts: 238 Location: London
Quote:
1. It is a bit faster.


First make it work. Then make it beautiful. And if you really really have to, make it fast while keeping it beautiful. I agree with others on this thread. =:= is *plain ugly*. Use it only if you need to shave off the odd microsecond in execution time.

Quote:
2. It gives more information to the compiler and to tools like Dialyzer. (The type on both sides of =:= will be known.)


Fair enough.

Quote:
3. It is exactly the same test which is used in pattern matching, you can easily convert code using =:= comparison to pattern matching and back.


You are testing for equality, not pattern matching. I am not sure I buy into this one.


In regards to spawn, I agree that having to export a funciton you are spawning is not elegant. This is a flaw in the language (there for historical reasons) which most of us have learnt to live with. Using funs will not solve the problem, because as you say, in both

Code:
start(State) -> spawn(fun () -> loop(State) end).

 loop(State) ->
   ...
   ?MODULE:loop(State).


and

Code:
First of all code loading with funs works fine if you use the fun Module:Function/Arity version.


you still need to export the function. If so, use it as intended.

Code:
The closure will be thrown away as soon as the function loop is entered and code loading will again work fine.


Will it? You can only have two versions of a module in the runtime system at any one time (Yet another Erlang design flaw, as unlimited versions of modules should have been allowed and just be GCed when no longer in use). With your example, I am faily sure the process will crash when you load the third module.

Bottom line, do not use funs when spawning. Your code might appear more elegant at first, but the underlying mechanism will not handle it correctly.

Francesco
--
http://www.erlang-consulting.com
View user's profile Send private message Visit poster's website

Display posts from previous:  

All times are GMT
Page 1 of 1
Post new topic

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum