Erlang/OTP Forums

Author Message

<  Erlang  ~  Simple loops

Jigar Gosar
Posted: Wed Oct 24, 2007 4:02 pm Reply with quote
Joined: 09 Oct 2007 Posts: 9
here is the code i came up with for printing numbers from 1 to Count.

using guards
Code:

print(Count) -> print(1,Count).
print(X,Count) when (X < Count) or (X == Count) ->
       io:fwrite("~p~n",[X]),
       print(X+1,Count);
print(X,Count) -> [].


using if
Code:

print2(Count) -> print(1,Count).
print2(X,Count) ->
  if
    (X < Count) or (X == Count) ->
       io:fwrite("~p~n",[X]),
       print2(X+1,Count)
  end.


is there a better way or am I on the right track?

this is the smallest code I came up with, but this has problem of stack overflow, am I correct?

Code:

print3(0) -> [];
print3(Count) ->
    print3(Count-1),
    io:fwrite("~p~n",[Count]).


Please advise on any any other better alternative. and please comment on the merits of the solutions provided above.

I am new to erlang, and looking for better way of doing things.
View user's profile Send private message
Adam
Posted: Fri Oct 26, 2007 3:24 pm Reply with quote
User Joined: 23 Aug 2006 Posts: 71 Location: London
The last version is the most Erlang-like implementation, but you are correct that it will produce a large stack given high numbers. A better implementation requires a single change:

Code:
print3(0) -> [];
print3(Count) ->
    io:fwrite("~p~n",[Count]),
    print3(Count-1).


This way, the last line will not be saved on the stack as the Erlang compiler recognizes and optimizes tail recursion.

The problem is that print3 counts backwards. If you must count starting from 1 your first implementation is the most correct one. It can be made a little prettier like this:
Code:
print4(Count) ->
    print4(1, Count).

print4(Count, Count) ->
    ok;
print4(X, Count) ->
    io:fwrite("~p~n", [X]),
    print4(X + 1, Count).

_________________
Adam
Erlang Training & Consulting
View user's profile Send private message Visit poster's website MSN Messenger ICQ Number
Jigar Gosar
Posted: Fri Oct 26, 2007 8:33 pm Reply with quote
Joined: 09 Oct 2007 Posts: 9
thanks,

The problem with print4 is that it doesn't print count. i.e. if I pass 3, only 1 and 2 will be printed and not 3. Thats the reason I came up with such convoluted alternatives using guards and if.

But now looking at your solution, by just making a small change 3 can also be printed.

heres the mod.

Code:

print4(Count+1, Count) ->
    ok;


But, its still more code than that of other imperative languages.

Functional languages take pride in conciseness of the code, and typical cases like quick sort are given to sell functional languages to imperative programmers.

I think this proves that there does exist a common case where functional code tends to become longer (although marginally) than the imperative counterpart.

I do acknowledge that there are many instances where functional code will beat the crap out of imperative languages in terms of LOC.

thanks for the reply.
View user's profile Send private message
Adam
Posted: Mon Oct 29, 2007 4:09 pm Reply with quote
User Joined: 23 Aug 2006 Posts: 71 Location: London
Well, compared to something imperative like:

Code:
function print4(Count) {
    int i;
    for(i = 0; i > Count; i++)
        print i;
    return true;
}


It's five lines, about the same as print4 in Erlang (print4/1 is just syntactic sugar). Not such a big difference, yes?

Coding Erlang I don't even think about for-loops any more. Recursion becomes part of your mindset. Most problems people seem to have is when they haven't gotten used to a new mindset yet.

_________________
Adam
Erlang Training & Consulting
View user's profile Send private message Visit poster's website MSN Messenger ICQ Number
Jigar Gosar
Posted: Wed Oct 31, 2007 4:17 pm Reply with quote
Joined: 09 Oct 2007 Posts: 9
I agree its just 4 lines, but the syntactic sugar of print4/1 is necessary to make it as convenient to use as its imperative counterpart. As I have admitted before, the code is marginally longer in Erlang.
The point I was trying to make is that, code doesn't necessarily become smaller, in Erlang (and as such in functional programming languages), as some people claim.

I think it is easy to convert any for loop into its recursion counterpart, by following this print example.

But thinking in recursion is what take time, because I still think in imperative terms and then convert my code to functional.

The notion of recursion and syntax of Erlang is very overwhelming for new developers in general and my colleagues in particular. Its difficult for me to sell Erlang as a better programming languages to my peers. The only selling point that makes sense is the built in concurrency and distributed nature of Erlang, and the hence build massively scalable server.

Erlang doesn't seem suitable for general purpose programming, at least on its face. I would like to hear some comments on this. Specifically, for what other types of application is Erlang more suitable, besides distributed servers.

Also Lastly I would like to point a ruby example:

Code:

def count
  count.times(){|x| puts x}
end


Its intuitive, readable, concise and beautiful all at the same time Smile
View user's profile Send private message
Mazen
Posted: Thu Nov 01, 2007 5:12 pm Reply with quote
User Joined: 20 Jul 2006 Posts: 164 Location: London
Jigar Gosar wrote:

The point I was trying to make is that, code doesn't necessarily become smaller, in Erlang (and as such in functional programming languages), as some people claim.


IMHO The difference in such a small example is marginal and doesn't really show anything sensible.

If you would compare bigger commercial applications I think the difference would be more obvious (for or against).

Further more; syntetic sugar is not needed except for when you use the function as an API towards other applications. In all other cases you don't really create 2 functions with different number arities just for looks even if it would make sense in some situations where you want to provide a nicer environment for real time tracing.

/M
View user's profile Send private message
zambal
Posted: Thu Nov 01, 2007 8:29 pm Reply with quote
User Joined: 03 Jul 2007 Posts: 11
Hi,

Hereby another solution, by using the lists library:

Code:

print6(N) ->
    lists:foreach(
      fun(X)-> io:fwrite("~p~n",[X]) end,
      lists:seq(1, N)).


It's still recursive, but hided by the library functions. If you'd import the used functions in your module, it could be as short as:

Code:

print6(N) ->
    foreach(
      fun(X)-> fwrite("~p~n",[X]) end,
      seq(1, N)).


I'm not sure what solution is more idiomatic, but I think this one's pretty readable.


-zambal
View user's profile Send private message
gbulmer
Posted: Thu Nov 01, 2007 11:37 pm Reply with quote
Joined: 01 Nov 2007 Posts: 1
Jigar Gosar wrote:
I agree its just 4 lines, but the syntactic sugar of print4/1 is necessary to make it as convenient to use as its imperative counterpart. As I have admitted before, the code is marginally longer in Erlang.
The point I was trying to make is that, code doesn't necessarily become smaller, in Erlang (and as such in functional programming languages), as some people claim.

I really believe there is much more to comparing programming languages than counting lines of code, but if that is your dominant criteria, how about something like:
Code:
count(N) -> [io:format("~w~n",[X]) || X <- lists:seq(1,N)], ok.


Quote:
But thinking in recursion is what take time, because I still think in imperative terms and then convert my code to functional.

The notion of recursion and syntax of Erlang is very overwhelming for new developers in general and my colleagues in particular.

I have learned and used more than a dozen programming languages commercially (and many more for fun); the syntax stops being a problem after a day or two (except for Perl Very Happy).

IMHO, You will need to unlearn habits that have been successful for you in an imperative, iterative language, to 'get' Functional Programming Languages, rather than try to translate. Did you learn about proof by induction in math at school? You may be able to use thinking about those proofs as a path.
Quote:
Its difficult for me to sell Erlang as a better programming languages to my peers. The only selling point that makes sense is the built in concurrency and distributed nature of Erlang, and the hence build massively scalable server.

I strongly believe you should not try to sell Erlang to developers unless it is clearly superior to their current technology. There is a significant cost and risk associated with learning and deploying a new technology. It is much better to wait until you have a project where those costs and risks are dwarfed by Erlangs benefits instead of trying to sell Erlang into unsuitable contexts. You do Erlang, your colleagues and yourself no favours otherwise.

Sorry for the harsh position, but the industry statistics are still that more than 75% of money spent on software never yields any results, and I believe inappropriate use of technology is a significant factor in that level of failure.
Quote:

Erlang doesn't seem suitable for general purpose programming, at least on its face. I would like to hear some comments on this. Specifically, for what other types of application is Erlang more suitable, besides distributed servers.

Maybe you could outline the sort of systems you and your colleagues build, and maybe someone can help you see where Erlang may be relevant.
Quote:

Also Lastly I would like to point a ruby example:

Code:

def count
  count.times(){|x| puts x}
end


Its intuitive, readable, concise and beautiful all at the same time Smile

It may have those properties, but I doubt it because it is incorrect. Maybe you were aiming for:
Code:

def count(n)
  n.times(){|x| puts x+1}
end

Which prints a sequence of integers, one per line, starting at 1.

I accept the Ruby is shorter than the Erlang, but maybe we can agree that printing a finite sequence of integers isn't a very good fit with Erlang, and leave it at that.
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

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