Noob - Getting Started Infinte Loop?

classic Classic list List threaded Threaded
41 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Noob - Getting Started Infinte Loop?

kurtosis
Hi all, I'm an Erlang noob working through the getting started material at erlang.org, and I have a question about a problem that's occuring with my code.  If this isn't the appropriate place for this question, my apologies for wasting the bandwidth, please point me in the right direction.  Otherwise, running the function listlen([1,2,...n]) crashes the Erlang emulator in WinXP.  However, I can't see the difference b/t my code and the example code:

Example code:
The following example shows how we find the length of a list:

-module(tut4).
-export([list_length/1]).

list_length([]) ->
    0;    
list_length([First | Rest]) ->
    1 + list_length(Rest).

Compile (file tut4.erl) and test:
29> c(tut4).
{ok,tut4}
30> tut4:list_length([1,2,3,4,5,6,7]).
7
My code:
-module(tut).
-export([double/1,fac/1,mult/2,convert/1,conv/2,listlen/1]).

double(X) -> 2 * X.
fac(0) -> 1;
fac(N) -> N * fac(N-1).
mult(X,Y) -> X*Y.
conv(M,toInch) -> M/2.54;
conv(N,toCentimeter) -> N*2.54.
convert({M,centimeters}) -> {M/2.54,inches};
convert({M,inches}) -> {M*2.54,centimeters}.
listlen([]) -> 0;
listlen([First|TheRest]) -> 1 + listlen([TheRest]).
And the result of running my code:
Erlang (BEAM) emulator version 5.5 [async-threads:0]

Eshell V5.5  (abort with ^G)
1> c(tut).
./tut.erl:13: Warning: variable 'First' is unused
{ok,tut}
2> tut:listlen([]).
0
3> tut:listlen([1,2]).

Crash dump was written to: erl_crash.dump
eheap_alloc: Cannot allocate 583848200 bytes of memory (of type "heap").

Abnormal termination
Windows Task Manager confirms the process werl is trying to use 581MB of RAM.  Before I tried to run this, Task Manager showed 821MB RAM in use, out of 1GB.  Is this a problem with my code, or with my memory useage?  Any suggestions about what I'm doing wrong?  Thanks,

Byron
Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

Per Gustafsson
fbg111 wrote:

> Hi all, I'm an Erlang noob working through the getting started material at
> erlang.org, and I have a question about a problem that's occuring with my
> code.  If this isn't the appropriate place for this question, my apologies
> for wasting the bandwidth, please point me in the right direction.
> Otherwise, running the function listlen([1,2,...n]) crashes the Erlang
> emulator in WinXP.  However, I can't see the difference b/t my code and the
> example code:
>
> http://erlang.org/doc/doc-5.5/doc/getting_started/seq_prog.html#2.5 Example
> code:
>
>
>
>>The following example shows how we find the length of a list:
>>
>>-module(tut4).
>>-export([list_length/1]).
>>
>>list_length([]) ->
>>    0;    
>>list_length([First | Rest]) ->
>>    1 + list_length(Rest).
>>
>>Compile (file tut4.erl) and test:
>>29> c(tut4).
>>{ok,tut4}
>>30> tut4:list_length([1,2,3,4,5,6,7]).
>>7
>>
>
>
> My code:
>
>
>
>>-module(tut).
>>-export([double/1,fac/1,mult/2,convert/1,conv/2,listlen/1]).
>>
>>double(X) -> 2 * X.
>>fac(0) -> 1;
>>fac(N) -> N * fac(N-1).
>>mult(X,Y) -> X*Y.
>>conv(M,toInch) -> M/2.54;
>>conv(N,toCentimeter) -> N*2.54.
>>convert({M,centimeters}) -> {M/2.54,inches};
>>convert({M,inches}) -> {M*2.54,centimeters}.
>>listlen([]) -> 0;
>>listlen([First|TheRest]) -> 1 + listlen([TheRest]).
>>

listlen should be defined as:

listlen([]) -> 0;
listlen([First|TheRest]) -> 1 + listlen(TheRest).

because in your definition the recursive call is always made with a list
consisting of one element ([TheRest]) because of this your function does
not terminate and it runs out of memory.

Per

Reply | Threaded
Open this post in threaded view
|

SV: Noob - Getting Started Infinte Loop?

Lennart Öhman-2
In reply to this post by kurtosis
Noob - Getting Started Infinte Loop?
Hi, you have encapsulated TheRest in a list. Meaning that
you will recursively call listlen/1 with a list of one element
(the list of all remaining elements except the first one from the
first call to listlen/1). Then that call will end up at the second
clause, where the recursive call will be made on: listlen([[]])
which in its turn will end up on the second clause causing a
recursive call to listlen([[]]), and so on, until you run out
of stack.
 
Best Regards,
Lennart
 
 
> listlen([]) -> 0;
> listlen([First|TheRest]) -> 1 + listlen([TheRest]).
                                          ^^^^^^^^^
-------------------------------------------------------------
Lennart Ohman                   phone   : +46-8-587 623 27
Sjöland & Thyselius Telecom AB  cellular: +46-70-552 6735
Sehlstedtsgatan 6               fax     : +46-8-667 8230
SE-115 28 STOCKHOLM, SWEDEN     email   : [hidden email]


Från: [hidden email] genom fbg111
Skickat: on 2006-08-30 13:06
Till: [hidden email]
Ämne: Noob - Getting Started Infinte Loop?


Hi all, I'm an Erlang noob working through the getting started material at
erlang.org, and I have a question about a problem that's occuring with my
code.  If this isn't the appropriate place for this question, my apologies
for wasting the bandwidth, please point me in the right direction.
Otherwise, running the function listlen([1,2,...n]) crashes the Erlang
emulator in WinXP.  However, I can't see the difference b/t my code and the
example code:

http://erlang.org/doc/doc-5.5/doc/getting_started/seq_prog.html#2.5 Example
code:


> The following example shows how we find the length of a list:
>
> -module(tut4).
> -export([list_length/1]).
>
> list_length([]) ->
>     0;   
> list_length([First | Rest]) ->
>     1 + list_length(Rest).
>
> Compile (file tut4.erl) and test:
> 29> c(tut4).
> {ok,tut4}
> 30> tut4:list_length([1,2,3,4,5,6,7]).
> 7
>

My code:


> -module(tut).
> -export([double/1,fac/1,mult/2,convert/1,conv/2,listlen/1]).
>
> double(X) -> 2 * X.
> fac(0) -> 1;
> fac(N) -> N * fac(N-1).
> mult(X,Y) -> X*Y.
> conv(M,toInch) -> M/2.54;
> conv(N,toCentimeter) -> N*2.54.
> convert({M,centimeters}) -> {M/2.54,inches};
> convert({M,inches}) -> {M*2.54,centimeters}.
> listlen([]) -> 0;
> listlen([First|TheRest]) -> 1 + listlen([TheRest]).
>

And the result of running my code:


> Erlang (BEAM) emulator version 5.5 [async-threads:0]
>
> Eshell V5.5  (abort with ^G)
> 1> c(tut).
> ./tut.erl:13: Warning: variable 'First' is unused
> {ok,tut}
> 2> tut:listlen([]).
> 0
> 3> tut:listlen([1,2]).
>
> Crash dump was written to: erl_crash.dump
> eheap_alloc: Cannot allocate 583848200 bytes of memory (of type "heap").
>
> Abnormal termination
>

Windows Task Manager confirms the process werl is trying to use 581MB of
RAM.  Before I tried to run this, Task Manager showed 821MB RAM in use, out
of 1GB.  Is this a problem with my code, or with my memory useage?  Any
suggestions about what I'm doing wrong?  Thanks,

Byron
--
View this message in context: http://www.nabble.com/Noob---Getting-Started-Infinte-Loop--tf2189189.html#a6056733
Sent from the Erlang Questions forum at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

Nick Linker
In reply to this post by kurtosis
fbg111 wrote:

Should be

        listlen([First|TheRest]) -> 1 + listlen(TheRest).

Previous variant builds infinitely nested list.

Best regards,
Nick.

Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

Romain Lenglet
In reply to this post by kurtosis
fbg111 wrote:
> > listlen([First|TheRest]) -> 1 + listlen([TheRest]).

You are creating a (non-empty) list at every step. Therefore your
code recurses infinitely. This code should be:
listlen([First|TheRest]) -> 1 + listlen(TheRest).

TheRest (the tail of the list) is already a list.

--
Romain LENGLET
Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

Vlad Dumitrescu-2
In reply to this post by kurtosis
Hi and welcome!

On 8/30/06, fbg111 <[hidden email]> wrote:
> However, I can't see the difference b/t my code and the
> example code:

> > list_length([]) ->  0;
> > list_length([First | Rest]) -> 1 + list_length(Rest).

> > listlen([]) -> 0;
> > listlen([First|TheRest]) -> 1 + listlen([TheRest]).

The difference is that the last line in your code should read

  listlen([First|TheRest]) -> 1 + listlen(TheRest).

i.e. TheRest and not [TheRest] as argument.

What happens is that listlen gets called with following arguments:
[1, 2, 3]
[[2,3]]
[[]]
[[]]
[[]]
[[]]
.....   so it's an endless recusrion that finally kills the VM

best regards,
Vlad
Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

ke han
In reply to this post by kurtosis
Byron,

A few notes in regards to this line of code:

>> listlen([First|TheRest]) -> 1 + listlen([TheRest]).

1 - your error appears to be that you are laking the tail of the  
list, bound as TheRest, and putting it back inside another list by  
your call to listlen([TheRest]).  This is a common type of bug, no  
shame here, I'm sure I've done it before.  TheRest is already a list,  
your tail recursive call is wrapping it inside another list with each  
call.  So, yes you will run out of memory ;-)

2 - I would always put a space between my variable names and the |  
symbol.  Your code:  [First|TheRest] needs to be more readable.   I  
always write code that has good spacing / formatting both for  
readability and to ensure I never hit any potential edge/corner cases  
of the compile toolchain.   This is a general programming rule.  I  
know of no reasons why erlang would read your code incorrectly.

3 - Also, for efficiency sake, you should name the variable "First"  
as "_First" to indicate you do not want the value bound.

have fun, ke han


On Aug 30, 2006, at 7:06 PM, fbg111 wrote:

>
> Hi all, I'm an Erlang noob working through the getting started  
> material at
> erlang.org, and I have a question about a problem that's occuring  
> with my
> code.  If this isn't the appropriate place for this question, my  
> apologies
> for wasting the bandwidth, please point me in the right direction.
> Otherwise, running the function listlen([1,2,...n]) crashes the Erlang
> emulator in WinXP.  However, I can't see the difference b/t my code  
> and the
> example code:
>
> http://erlang.org/doc/doc-5.5/doc/getting_started/seq_prog.html#2.5 
> Example
> code:
>
>
>> The following example shows how we find the length of a list:
>>
>> -module(tut4).
>> -export([list_length/1]).
>>
>> list_length([]) ->
>>     0;
>> list_length([First | Rest]) ->
>>     1 + list_length(Rest).
>>
>> Compile (file tut4.erl) and test:
>> 29> c(tut4).
>> {ok,tut4}
>> 30> tut4:list_length([1,2,3,4,5,6,7]).
>> 7
>>
>
> My code:
>
>
>> -module(tut).
>> -export([double/1,fac/1,mult/2,convert/1,conv/2,listlen/1]).
>>
>> double(X) -> 2 * X.
>> fac(0) -> 1;
>> fac(N) -> N * fac(N-1).
>> mult(X,Y) -> X*Y.
>> conv(M,toInch) -> M/2.54;
>> conv(N,toCentimeter) -> N*2.54.
>> convert({M,centimeters}) -> {M/2.54,inches};
>> convert({M,inches}) -> {M*2.54,centimeters}.
>> listlen([]) -> 0;
>> listlen([First|TheRest]) -> 1 + listlen([TheRest]).
>>
>
> And the result of running my code:
>
>
>> Erlang (BEAM) emulator version 5.5 [async-threads:0]
>>
>> Eshell V5.5  (abort with ^G)
>> 1> c(tut).
>> ./tut.erl:13: Warning: variable 'First' is unused
>> {ok,tut}
>> 2> tut:listlen([]).
>> 0
>> 3> tut:listlen([1,2]).
>>
>> Crash dump was written to: erl_crash.dump
>> eheap_alloc: Cannot allocate 583848200 bytes of memory (of type  
>> "heap").
>>
>> Abnormal termination
>>
>
> Windows Task Manager confirms the process werl is trying to use  
> 581MB of
> RAM.  Before I tried to run this, Task Manager showed 821MB RAM in  
> use, out
> of 1GB.  Is this a problem with my code, or with my memory useage?  
> Any
> suggestions about what I'm doing wrong?  Thanks,
>
> Byron
> --
> View this message in context: http://www.nabble.com/Noob---Getting- 
> Started-Infinte-Loop--tf2189189.html#a6056733
> Sent from the Erlang Questions forum at Nabble.com.
>

Reply | Threaded
Open this post in threaded view
|

Noob - Getting Started Infinte Loop?

fbg111


ke han wrote:
>
> I always write code that has good spacing / formatting both for  
> readability and to ensure I never hit any potential edge/corner cases  
> of the compile toolchain.
>

Thanks, I'll use your suggestions, especially if this is what other Erlang
coders expect.  What are edge/corner cases, though?  Situtations where
spacing causes the compiler to interpret code differently?
--
View this message in context: http://www.nabble.com/Noob---Getting-Started-Infinte-Loop--tf2189189.html#a6069923
Sent from the Erlang Questions forum at Nabble.com.



Reply | Threaded
Open this post in threaded view
|

Noob - Getting Started Infinte Loop?

fbg111
In reply to this post by ke han


ke han wrote:
>
> 3 - Also, for efficiency sake, you should name the variable "First"  
> as "_First" to indicate you do not want the value bound.
>

I was under the impression so far that all variables in Erlang are bound,
unless 'bound' means something other than you can't change the value of a
variable after assignment?  Thanks!
--
View this message in context: http://www.nabble.com/Noob---Getting-Started-Infinte-Loop--tf2189189.html#a6069968
Sent from the Erlang Questions forum at Nabble.com.



Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

kurtosis
In reply to this post by ke han
ke han wrote
I always write code that has good spacing / formatting both for  
readability and to ensure I never hit any potential edge/corner cases  
of the compile toolchain.
Thanks, I'll use your suggestions, especially if this is what other Erlang coders expect.  What are edge/corner cases, though?  Situtations where spacing causes the compiler to interpret code differently?
Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

kurtosis
In reply to this post by ke han
ke han wrote
3 - Also, for efficiency sake, you should name the variable "First"  
as "_First" to indicate you do not want the value bound.
I was under the impression so far that all variables in Erlang are bound, unless 'bound' means something other than you can't change the value of a variable after assignment?  Thanks!
Reply | Threaded
Open this post in threaded view
|

Thanks all! Obvious in hindsight, appreciate the pointers! (nt)

kurtosis
In reply to this post by kurtosis
Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

Håkan Stenholm
In reply to this post by kurtosis
fbg111 wrote:

>
>ke han wrote:
>
>>3 - Also, for efficiency sake, you should name the variable "First"  
>>as "_First" to indicate you do not want the value bound.
>>
>>
>
>I was under the impression so far that all variables in Erlang are bound,
>unless 'bound' means something other than you can't change the value of a
>variable after assignment?  Thanks!
>
There are actualy two uses of of the _ (underscore).


* case 1; as a way to tell pattern matching to match anything (and don't
bind anything to the _) e.g. in a function clause:

foo(_, V2) -> V2;  % ignore the first argument, as it's unused in this
function clause
foo(...) -> ...



* case 2; as a way to tell the compiler that it is ok that the variable
name V is unused (you'll otherwise get a "variable V unused in ..."
error when using erlc) e.g.:

foo(_V) -> ok;  % variable V is unused, renamed to _V to inidicate that
it's not used in this clause
foo(V) -> ....

Note that _V is still a valid variablename, so the code below is valid:

    foo(_V) ->
        _V * 2.

    a call to foo(42) would yield 84 in this case.


But you should never use _ in variable names in this way (instead remove
the _ if the V is to be used).

The _ is usually applied to variable names after the compiler complains
about unused variable names and we have ensured that the lack of usuage
isn't due to some kind of bug - e.g. we forgot to use the variable or
accidently instead used another variable in the wrong place.
Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

Richard A. O'Keefe-2
In reply to this post by kurtosis
ke han wrote:
        > 3 - Also, for efficiency sake, you should name the variable "First"  
        > as "_First" to indicate you do not want the value bound.

In "Murder in the Cathedral" T.S.Eliot had Thomas a Becket say (from
memory): "The last temptation is the greatest treason,
          to do the right thing for the wrong reason."

Because anonymous variables are spelled "_", and everyone (compiler and
human reader alike) knows that you don't care what value is bound to an
anonymous variable, Prolog and Erlang have adopted a convention that
if there is a variable which you have written down because you have to
have *some* variable there, but you intend it to occur only once (you
don't care what value gets bound to it), then you spell that variable
with a leading underscore too.

This is a hint to HUMAN BEINGS.  The Erlang compiler does not need it.
It is NOT an efficiency issue.  The compiler can work out quite easily
for itself that the variable is never used again.  It's all about making
it clear to HUMAN readers that you are doing this ON PURPOSE.

I would expect

    listlen([First|Rest]) -> 1 + listlen(Rest) % 1

and

    listlen(_First|Rest]) -> 1 + listlen(Rest) % 2

and

    listlen([_|Rest]) -> 1 + listlen(Rest) % 3

and

    listlen([Betty_Crocker|Sony_RCA_Magnavox_TEAC]) -> % 4
        1 + listlen(Sony_RCA_Magnavox_TEAC)

to all result in exactly the same code.  The only difference between them
is that % 2 is more helpful to human beings:  _First says "this variable
will hold the first element of a list, but it's never used again, and I
know and intend that it should never be used again".

fbg111 <[hidden email]> asked:
        I was under the impression so far that all variables in Erlang
        are bound, unless 'bound' means something other than you can't
        change the value of a variable after assignment?

Actually, that ISN'T what "bound means".  Bound means "has a value".
And putting an underscore in front of a variable does NOT mean that
it will not get a value bound to it.  As far as the meaning of the
language goes, any time you successfully match a pattern against a term,
new variables in the pattern end up bound.

What's at issue is not whether the variable becomes bound or not,
but whether the binding is *live* (might be of use in the future).
If a variable has only a single occurrence, then the pattern matching
code the compiler need not include anything to save the corresponding
value anywhere.  But it's just a fully automatic optimisation that you
should not be concerned with.

If you want to worry about efficiency, go on to the next lesson in
the tutorial, where it should tell you to do

    list_length(List) ->
        list_length_loop(List, 0).

    list_length_loop([_|Rest], N) ->
        list_length_loop(Rest, N+1);
    list_length_loop([], N) ->
        N.

which is just a "while" loop in disguise.

Reply | Threaded
Open this post in threaded view
|

RE: Noob - Getting Started Infinte Loop?

Lennart Öhman-2
In reply to this post by kurtosis
Hi,
the _ (only an underscore) is never bound from efficiency
reasons. For instance:

f(foo,bar) -> ...;
f(frotz,X) -> ...;
f(_,X) -> ....

could be used to indicate in the third clause that Erlang
should not spend time on binding the first argument to a
variable since it will not be used. Actually, if you replace
the third head with f(DontCare,X) -> you will get a compiler
warning. The compiler suspects that you misspelled that variable
name, and it should be one you actually use in the body.

Then you have the possibility of placing an _ in front of
a variable name. Like _dontCare. That will actually make the
variable bound and possible to use (however good Erlang practise
says you shouldn't). The underscore removes the compiler
warnings in this case.

Best Regards
Lennart

-------------------------------------------------------------
Lennart Ohman                   office  : +46-8-587 623 27
Sjoland & Thyselius Telecom AB  cellular: +46-70-552 67 35
Sehlstedtsgatan 6               fax     : +46-8-667 82 30
SE-115 28, STOCKHOLM, SWEDEN    email   : [hidden email]

> -----Original Message-----
> From: [hidden email] [mailto:owner-erlang-
> [hidden email]] On Behalf Of fbg111
> Sent: Thursday, August 31, 2006 12:58 AM
> To: [hidden email]
> Subject: Re: Noob - Getting Started Infinte Loop?
>
>
>
> ke han wrote:
> >
> > 3 - Also, for efficiency sake, you should name the variable "First"
> > as "_First" to indicate you do not want the value bound.
> >
>
> I was under the impression so far that all variables in Erlang are bound,
> unless 'bound' means something other than you can't change the value of a
> variable after assignment?  Thanks!
> --
> View this message in context: http://www.nabble.com/Noob---Getting-
> Started-Infinte-Loop--tf2189189.html#a6069968
> Sent from the Erlang Questions forum at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

ke han
In reply to this post by kurtosis

On Aug 31, 2006, at 6:54 AM, fbg111 wrote:

>
>
> ke han wrote:
>>
>> I always write code that has good spacing / formatting both for
>> readability and to ensure I never hit any potential edge/corner cases
>> of the compile toolchain.
>>
>
> Thanks, I'll use your suggestions, especially if this is what other  
> Erlang
> coders expect.  What are edge/corner cases, though?  Situtations where
> spacing causes the compiler to interpret code differently?

I don't know what cases might be interpreted different than the  
programmer intended.  I have a long standing practice in all  
programming languages to write highly readable code..I therefore  
never hit on errors related to code style.  My guess is that erlang's  
parse tools are much more refined than many other implementations in  
other languages.  So don't let me scare you by thinking there are  
some issues to worry about.  But not putting spaces on either side of  
a | or a ! is very hard for a guy like me to read regardless of what  
erlang thinks ;-).

ke han


> --
> View this message in context: http://www.nabble.com/Noob---Getting- 
> Started-Infinte-Loop--tf2189189.html#a6069923
> Sent from the Erlang Questions forum at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

underscore prefixed variables (was: Re: Noob - Getting Started Infinte Loop?)

Fredrik Thulin
In reply to this post by Håkan Stenholm
On Thursday 31 August 2006 03:03, Håkan Stenholm wrote:
...
> Note that _V is still a valid variablename, so the code below is
> valid:
>
>     foo(_V) ->
>         _V * 2.
>
>     a call to foo(42) would yield 84 in this case.

As Håkan points out, _V * 2 is valid. I think this is bad. In
combination with assign-once, it introduces bugs like in this example :

 case lists:keysearch(primary, 1, MyList) of
    {value, {primary, _Socket}} ->
        %% do something because our "primary" socket exists, although we
        %% don't really care about the socket iself
        ...
    false ->
        case lists:keysearch(secondary, 1, MyList) of
            {value, {secondary, _Socket}} ->
                 %% do something because our "secondary" socket exists,
                 %% although we don't really care about the socket itself

I think that

  a) variables prefixed with "_" should really not be variables that get
     set - like the special case _.
  b) the compiler should issue a warning that you are actually using a
     variable prefixed with "_".

Would others care to share their view on this?

/Fredrik
Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

Mats Cronqvist
In reply to this post by ke han
ke han wrote:

>
> On Aug 31, 2006, at 6:54 AM, fbg111 wrote:
>
>>
>>
>> ke han wrote:
>>>
>>> I always write code that has good spacing / formatting both for
>>> readability and to ensure I never hit any potential edge/corner cases
>>> of the compile toolchain.
>>>
>>
>> Thanks, I'll use your suggestions, especially if this is what other
>> Erlang
>> coders expect.  What are edge/corner cases, though?  Situtations where
>> spacing causes the compiler to interpret code differently?

   here's an example.

24> A=<<"a">>.
** 1: syntax error before: '<' **
24> A = <<"a">>.
<<97>>
25> A=<<<"a">>.
true

   mats
Reply | Threaded
Open this post in threaded view
|

Re: underscore prefixed variables (was: Re: Noob - Getting Started Infinte Loop?)

Bjorn Gustavsson
In reply to this post by Fredrik Thulin
It is sometimes useful to refer to variables with underscores
in debug code. In the example below, the io:format/2 call can
be simply uncommented when needed:

foo(V) ->
        ....
foo(_V) ->
   %% io:format("~p\n", [_V]),
   error.

/Bjorn

Fredrik Thulin <[hidden email]> writes:

> On Thursday 31 August 2006 03:03, Håkan Stenholm wrote:
> ...
> > Note that _V is still a valid variablename, so the code below is
> > valid:
> >
> >     foo(_V) ->
> >         _V * 2.
> >
> >     a call to foo(42) would yield 84 in this case.
>
> As Håkan points out, _V * 2 is valid. I think this is bad. In
> combination with assign-once, it introduces bugs like in this example :
>
>  case lists:keysearch(primary, 1, MyList) of
>     {value, {primary, _Socket}} ->
>         %% do something because our "primary" socket exists, although we
>         %% don't really care about the socket iself
>         ...
>     false ->
>         case lists:keysearch(secondary, 1, MyList) of
>    {value, {secondary, _Socket}} ->
>         %% do something because our "secondary" socket exists,
>         %% although we don't really care about the socket itself
>
> I think that
>
>   a) variables prefixed with "_" should really not be variables that get
>      set - like the special case _.
>   b) the compiler should issue a warning that you are actually using a
>      variable prefixed with "_".
>
> Would others care to share their view on this?
>
> /Fredrik
>

--
Björn Gustavsson, Erlang/OTP, Ericsson AB
Reply | Threaded
Open this post in threaded view
|

Re: Noob - Getting Started Infinte Loop?

Bengt Kleberg
In reply to this post by ke han
On 2006-08-31 10:50, ke han wrote:
...deleted
> about.  But not putting spaces on either side of a | or a ! is very hard
> for a guy like me to read regardless of what erlang thinks ;-).

if you want to avoid ''hard to read'' you should avoid
NamesThatLookLikeThis. Names_that_look_like_this are easier to read(*)


bengt

(*) yes, it is possible to learn how to read the former. one can become
almost as good on this as the latter. but why use something that
requires both time and effort and still only manages to achive almost as
good?
--
    EPO guidelines 1978: "If the contribution to the known art resides
    solely in a computer program then the subject matter is not
    patentable in whatever manner it may be presented in the claims."
123