Erlang Mailing Lists

Author Message

<  Erlang questions mailing list  ~  Small poll

erlang at manderp.freeser
Posted: Fri Dec 19, 2003 7:54 am Reply with quote
Guest
On the "let it crash" vein of the topic, I'm writing a SIP message parser. I ended up writing functions and code that only match positively with lexemes, letting the parser "crash" on mismatches, and catching to retry with alternative lexemes where multiple matches may occur. It makes the lexer *much* easier to read and debug!

In the end the parser exclusively uses only pattern matching and function clauses. No "if" or "case" or any other syntactic sugar. And it reads very clearly! (well, for me at least!)

Adding clauses containing exit, throw or returning {error,ErrCode} just adds clutter with no advantage whatsoever.

Pete.

On Thu, 18 Dec 2003 12:03:58 -0800
Chris Pressey <cpressey_at_catseye.mine.nu> wrote:

> On Thu, 18 Dec 2003 10:29:06 +0100
> Bengt Kleberg <Bengt.Kleberg_at_ericsson.com> wrote:
>
> > Chris Pressey wrote:
> > > But even if you don't use it, you have to recognize that many
> > > programmers do, and for the "let it crash" style to work, code has
> > > to be allowed to crash at runtime, even when it "can't be right".
> >
> > yes, i am all for letting code crash. i just do not think it is
> > usefull to let the compiler produce code for a module that will always
> > crash because potentially correct code is written in such a way as to
> > produce a runtime error.
> >
> > use
> > erlang:throw/1
> > or
> > erlang:exit/1
> > if an runtime error is what you want.
>
> You're of course entitled to hold any opinion you wish, but I really
> have to say that I disagree, and that I can't quite see your reasoning.
>
> In Erlang as we know it, a + 42 generates an exception. An exception is
> by definition not a show-stopper; it can be caught and acted upon. But
> by changing it into a compile-time error, you're not even giving the
> program an *opportunity* to crash. This runs against the "let it crash"
> philosophy in my book.
>
> Also, by forcing the programmer to write throw(blah) to cause an
> exception, you're making them *make* it crash, which also runs counter
> to "let it crash" - the programmer needn't exert such explicit effort.
>
> To once again attempt to illustrate the difference:
>
> foo() = (catch bar()).
> bar() ->
> true = some_assertion_which_may_or_may_not_be_constant(),
> stuff().
>
> ...versus...
>
> foo() = (catch bar()).
> bar() ->
> case some_assertion_which_may_or_may_not_be_constant() of
> true -> stuff();
> false -> throw(badarg)
> end.
>
> I'd much rather write (and read) the first version than the second.
> Maybe it's just me, but I think it's more concise, more direct, and just
> generally clearer. I also don't think it makes sense for the
> compilation itself to succeed or fail based solely on whether
> some_assertion_which_may_or_may_not_be_constant() is (detectably)
> constant or not. That's why I'd much rather it be merely a compile-time
> warning.
>
> I'm all for getting as much information about possible errors as early
> as possible - but I'm not in favour of dramatic shifts in how this
> information would affect what is and what is not "legal Erlang".
>
> -Chris
>
>


--
"The Tao of Programming
flows far away
and returns
on the wind of morning."



Post generated using Mail2Forum (http://m2f.sourceforge.net)
ok at cs.otago.ac.nz
Posted: Mon Dec 22, 2003 11:22 am Reply with quote
Guest
Kostis Sagonas <kostis_at_user.it.uu.se> wrote:
Sorry to suddently turn this thread into a political one, but the
above argument seems to me an argument of the form:

"Why try to eliminate some social injustices, since we are never
going to eliminate them all (especially the most subtle ones)."

Just think about it...

Well yes, I have thought about it, and the analogy is invalid.
A much more interesting and possibly more fruitful analogy is to
the "human factors and safety of interfaces" stuff one often sees
popping up in comp.risks. If you automate too much, people get to
rely on the machine, and then the automation has to be _really_ good.
If you have alarms that keep going off, people start ignoring them,
and then really bad things happen, because some of the alarms aren't
false. It seems that there's an optimal level of human involvement
in checking; too much and people can't do it, too little and people
do even less than they should. It is important for people to have
a clear understanding of what the machine will check (so they don't
have to) and what it won't (so they DO have to).

A question I asked a couple of times in this year's functional programming
exam paper had the general form
- description of data structure
- set up the type declarations in Haskell!
- how much of the data structure invariants were you able
to tell the Haskell compiler about, and why?
- finish the job!

Whatever you end up doing, it is a human factors disaster if the
BEAM compiler and the HiPE compiler disagree, because then people will
not be able to form a coherent mental model of what will be checked
by machine and what they must check in their inspections.





Post generated using Mail2Forum (http://m2f.sourceforge.net)
Bengt.Kleberg at ericsson
Posted: Mon Dec 22, 2003 11:34 am Reply with quote
Guest
Chris Pressey wrote:
...deleted
> In Erlang as we know it, a + 42 generates an exception. An exception is
> by definition not a show-stopper; it can be caught and acted upon. But
> by changing it into a compile-time error, you're not even giving the
> program an *opportunity* to crash. This runs against the "let it crash"
> philosophy in my book.

as i see it (ie, really subjective thinking will follow here):
i think ''let it crash'' is a good idea. i think it is such a good idea
that i want it to happen as soon as possible. in this case*, as soon as
possible is during compilation.

*quick reminder:
all exported functions in the module will crash, there are no
alternative ways for them to maybe succeed.


> Also, by forcing the programmer to write throw(blah) to cause an
> exception, you're making them *make* it crash, which also runs counter
> to "let it crash" - the programmer needn't exert such explicit effort.

i am advocating erlang:throw() as a better solution than ''a+42'' to
force a crash. i am not advocating erlang:throw() as a replacement for
mistyping ''A+42'' :-)


bengt



Post generated using Mail2Forum (http://m2f.sourceforge.net)
joachim.durchholz at web.
Posted: Mon Dec 22, 2003 12:17 pm Reply with quote
Guest
Chris Pressey wrote:

> Bengt Kleberg <Bengt.Kleberg_at_ericsson.com> wrote:
>
>> Chris Pressey wrote:
>>
>> yes, i am all for letting code crash. i just do not think it is
>> usefull to let the compiler produce code for a module that will
>> always crash because potentially correct code is written in such a
>> way as to produce a runtime error.
>>
>> use erlang:throw/1 or erlang:exit/1 if an runtime error is what you
>> want.
>
> You're of course entitled to hold any opinion you wish, but I really
> have to say that I disagree, and that I can't quite see your
> reasoning.
>
> In Erlang as we know it, a + 42 generates an exception. An exception
> is by definition not a show-stopper; it can be caught and acted upon.
> But by changing it into a compile-time error, you're not even giving
> the program an *opportunity* to crash. This runs against the "let it
> crash" philosophy in my book.

I think you're misunderstanding Chris. I don't remember him advocating
adding a
_ = throw ("No pattern matched for function foo")
clause to every function. He's advocating replacing
a + 42
with
throw ("Not Implemented Yet")
and I'd like to join in: `throw' tells the reader that the error was
intentional, and its argument provides information why the crash was
programmed and whether that's a temporary or permanent decision. That's
*far* better than `a + 42'.
`a + 42' is a cute trick - and cute tricks should be avoided since they
make software less maintainable, at least in my experience; software
should explicitly state what it does, and not rely on implicit behaviour
- I know that both constructing and deciphering cute tricks can give
enormous mental satisfaction, but the downside is that the code will be
readable for a slightly smaller fraction of programmers, and that's an
unacceptable side effect. IMHO.

Regards,
Jo



Post generated using Mail2Forum (http://m2f.sourceforge.net)
ulf.wiger at telia.com
Posted: Wed Dec 24, 2003 8:43 pm Reply with quote
Guest
On 17 Dec 2003 21:31:39 +0100, Luke Gorrie <luke_at_bluetail.com> wrote:


> I really want it as a way to write a who_calls(M,F,A)->[{M,F,A}]
> function that could be used by Emacs for a "reverse tags lookup".
> who_calls would expect all relevant modules to be loaded and do a fold
> over them to find all callers. Then I can present the results in a
> "hyperlinked" buffer and save myself a lot of grep'ery.

CCviewer does this, and also who_uses_record(R) and who_uses_macro(M).
It keeps a RAM database which is incrementally updated as it discovers
that source modules have changed. There are some built-in analyses
that can be used through the web interface, like finding cyclical
dependencies between modules (or functions), and listing all users
of a particular application.

I've been meaning to provide an API other than the web interface to
facilitate static analysis on the fly, perhaps from Distel. What's
been stopping me is that my maintenance effort for CCviewer is ~0
right now, and that suits me just fine. So unless someone really
wants to start using it and doing weird and wonderful stuff with it,
it stays the way it is.

/Uffe
--
Ulf Wiger



Post generated using Mail2Forum (http://m2f.sourceforge.net)
robert.virding at telia.c
Posted: Tue Dec 30, 2003 11:37 pm Reply with quote
Guest
This discussion just goes on :-)

I still have not seen any good reasons to change my viewpoint, in fact I have got a few to become even more restrictive:

1. a+42, 1=2, etc are all legal expressions even if they generate errors when evaluated. As errors have meaning in Erlang then you can't just forbid them.

2. Many of the warnings generated by the compiler have been chosen in an extremely ad hoc fashion, they were deemed useful by someone and easy to implement. There is really no clear policy for what is checked and what is not. I mean why check the arguments to io:format and not a host of other common library functions. Especially considering that io:format is easy to guard against. Richard O'Keefe wrote some good stuff about the problems of getting the right level of checking.

3. With this in mind then Bjorn's new checks are probably a bad idea, the warnings become even more ad hoc and difficult to understand. I wonder if maybe some of the existing warnings should be removed. I still say that many of the warnings give very little and some are a right pain.***

4. You cannot have the option of forbidding legal code, no matter how stupid it may seem. The compiler must handle all legal code. Trying to guess and saying that 90% of the time the user wrote this then they made an error is not good enough. This is similat to the syntax change suggestion concerning =<< made earlier.

5. I wonder if it is good for the compiler to try and use warnings to enforce a certain programming style?

*** Two warnings that really anoy me are unused vars and unused functions.

I seldom use '_', the anonymous variable, but prefer to give all variables names so I know what they are, even if I don't use them later. I DON'T LIKE the _Varname convention so why should the compiler try and enforce. Of course the alternative would be to ALWAYS use it. That would teach the compiler to mind its own business. :-)

When I define a data structure and its access functions I always define full range of access functions, even those which are not used. I think the structure and how it is intended to be used becomes clearer then. Having the compiler burn me with warnings is irritating to say the least. Yes I can wrap the unused ones in comments but then I don't get any checking. This has been done to me in the compiler code. Anyway what is wrong with defining unused functions? They don't hurt anyone and the compiler removes them from the code anyway.


Robert



Post generated using Mail2Forum (http://m2f.sourceforge.net)
james at dadgum.com
Posted: Wed Dec 31, 2003 6:36 pm Reply with quote
Guest
Robert Virding wrote:
>2. Many of the warnings generated by the
>compiler have been chosen in an extremely
>ad hoc fashion, they were deemed useful by
>someone and easy to implement. There is
>really no clear policy for what is checked
>and what is not. I mean why check the
>arguments to io:format and not a host of
>other common library functions.

I tried to make this point in an earlier message, though I may not
have succeeded. I don't really want to see the compiler cluttered up
with a lot of checks for things that may or may not be errors,
especially when:

1. There are many more things that are not checked (for example, any
place where a newbie types "x" instead of "X"). Trying to catch them
all seems like a long and unproductive road to go down. (Okay, I
once complained about list comprehensions without generators being
quietly compiled, but I'd argue that's invalid Erlang.)

2. Simple, interactive testing catches all of these errors anyway,
even the ones that aren't warned about.

Additionally, I think Erlang--both the language and implementation--
are on the verge of becoming too complicated. I think both could use
some streamlining. Adding ad hoc warnings is a step in the other
direction.



Post generated using Mail2Forum (http://m2f.sourceforge.net)
joachim.durchholz at web.
Posted: Wed Dec 31, 2003 7:51 pm Reply with quote
Guest
James Hague wrote:
> 2. Simple, interactive testing catches all of these errors anyway,
> even the ones that aren't warned about.

Experiences users will find them.
Warnings are useful for those things that newbies often fall trap to:
these should be warnings. Or at least warnings that can be switched on
using a compiler option.

Just my 2c.

Regards,
Jo



Post generated using Mail2Forum (http://m2f.sourceforge.net)
james at dadgum.com
Posted: Wed Dec 31, 2003 11:58 pm Reply with quote
Guest
Joachim Durchholz wrote:
>Warnings are useful for those things that
>newbies often fall trap to: these should be
>warnings. Or at least warnings that can be
>switched on using a compiler option.

I agree in principle, but then you see newbies making errors that you
can't check for:

second([x,y|t]) -> y.

Where x, y, and t were intended to be variables, not atoms. Or using
"/" instead of "div". Or the more common case of calling an external
function with the wrong number of parameters, or simply a non-
existant external function (which, I admit, would be nice to check
for, though not so simple). It's a slippery slope to try to fix all
of these at compile time, and it isn't clear that an overly pedantic
compiler is a worthy goal. There should at least be consistent
principles for what is warned about and what isn't.

That said, I still like the new warning for "This statement will
never match," maybe just because I've seen similar warnings in ML-
like languages.



Post generated using Mail2Forum (http://m2f.sourceforge.net)
joachim.durchholz at web.
Posted: Thu Jan 01, 2004 1:05 pm Reply with quote
Guest
James Hague wrote:
> Joachim Durchholz wrote:
>
>>Warnings are useful for those things that
>>newbies often fall trap to: these should be
>>warnings. Or at least warnings that can be
>>switched on using a compiler option.
>
> I agree in principle, but then you see newbies making errors that you
> can't check for:

Right.
It's impossible to flag all newbie errors anyway. But every error that
gets flagged will make the learning curve less steep, which is generally
a Good Thing IMHO.
Once people get used to the issues (iow as soon as the warnings become
more annoying than helpful), they'll turn warnings off.

Just my 2c, back to lurk mode Smile
Regards,
Jo



Post generated using Mail2Forum (http://m2f.sourceforge.net)
bjorn at erix.ericsson.se
Posted: Wed Jan 07, 2004 12:39 pm Reply with quote
Guest
"Robert Virding" <robert.virding_at_telia.com> writes:

> This discussion just goes on Smile
>
> I still have not seen any good reasons to change my viewpoint, in fact I have got a few to become even more restrictive:
>
> 1. a+42, 1=2, etc are all legal expressions even if they generate errors when evaluated. As errors have meaning in Erlang then you can't just forbid them.

I agree.

> 2. Many of the warnings generated by the compiler have been chosen in an extremely ad hoc fashion, they were deemed useful by someone and easy to implement. There is really no clear policy for what is checked and what is not. I mean why check the arguments to io:format and not a host of other common library functions. Especially considering that io:format is easy to guard against. Richard O'Keefe wrote some good stuff about the problems of getting the right level of checking.

I disagree.

The warnings for io:format were implemented because many users often DID
make mistakes. Furthermore, io:formats in error handling might not have been
properly tested, so the first time the error handling code was actually executed
it crashed.

Also, it was not particularily easy to add the io:format code. We have had
quite a bit work keeping the checks correct.

So that is bad example of something we added because it was easy.

>
> 3. With this in mind then Bjorn's new checks are probably a bad idea, the warnings become even more ad hoc and difficult to understand. I wonder if maybe some of the existing warnings should be removed. I still say that many of the warnings give very little and some are a right pain.***

In old versions of OTP, there were warnings for imports that you didn't use
and for exporting variables out of case statements. We have turned off those
warnings by default.

>
> 4. You cannot have the option of forbidding legal code, no matter how stupid it may seem. The compiler must handle all legal code. Trying to guess and saying that 90% of the time the user wrote this then they made an error is not good enough. This is similat to the syntax change suggestion concerning =<< made earlier.
>

I agree. We don't forbid legal code, we just warn about it.

> 5. I wonder if it is good for the compiler to try and use warnings to enforce a certain programming style?
>
> *** Two warnings that really anoy me are unused vars and unused functions.
>
> I seldom use '_', the anonymous variable, but prefer to give all variables names so I know what they are, even if I don't use them later. I DON'T LIKE the _Varname convention so why should the compiler try and enforce.

Even if YOU don't like the _Varname convention, other people love it.

Since we started to use the warn_unused_vars option, we have found many
minor bugs in the OTP code. I have also found several bugs in Wings.

That was in WORKING code; in the OTP code we also have extensive test suites.

When I write new code, the warnings immediately inform me about a bug that
otherwise could have taken me some time to find by testing.

> Of course the alternative would be to ALWAYS use it. That would teach the compiler to mind its own business. Smile
>

You can also use the nowarn_unused_vars option.

> When I define a data structure and its access functions I always define full range of access functions, even those which are not used. I think the structure and how it is intended to be used becomes clearer then. Having the compiler burn me with warnings is irritating to say the least. Yes I can wrap the unused ones in comments but then I don't get any checking.

There should really be a way to turn off the warnings for unused functions.
We might add a mechanism in R10 for doing that.

> This has been done to me in the compiler code.

As we don't want to see the warning in our daily builds, we had to comment
out the functions.

> Anyway what is wrong with defining unused functions? They don't hurt anyone and the compiler removes them from the code anyway.

When maintaining other people's code (I am NOT talking about the compiler
here), you often find stray functions that are left from a previous version
of the module, but is no longer used.


To summarize: IMO, every warning that helps you to find more bugs are
useful.

/Bjorn

--
Bj
bjorn at erix.ericsson.se
Posted: Wed Jan 07, 2004 1:01 pm Reply with quote
Guest
"James Hague" <james_at_dadgum.com> writes:

> Robert Virding wrote:
> >2. Many of the warnings generated by the
> >compiler have been chosen in an extremely
> >ad hoc fashion, they were deemed useful by
> >someone and easy to implement. There is
> >really no clear policy for what is checked
> >and what is not. I mean why check the
> >arguments to io:format and not a host of
> >other common library functions.
>
> I tried to make this point in an earlier message, though I may not
> have succeeded. I don't really want to see the compiler cluttered up
> with a lot of checks for things that may or may not be errors,
> especially when:
>
> 1. There are many more things that are not checked (for example, any
> place where a newbie types "x" instead of "X"). Trying to catch them
> all seems like a long and unproductive road to go down. (Okay, I
> once complained about list comprehensions without generators being
> quietly compiled, but I'd argue that's invalid Erlang.)

Our intention is not to try to catch all possible errors.

The new warnings I've added are emitted by the optimization passes.
Instead of silently removing a clause that cannot possible match,
a warning is produced. Thus, there is not a lot of extra code in the
compiler.

There were many warnings in the OTP code for clauses that could not match.
Most of them harmless, of course, since the code is working, but the
redundant clauses are confusing for anyone reading the code.

I found a few redundant clauses in the compiler itself.

>
> 2. Simple, interactive testing catches all of these errors anyway,
> even the ones that aren't warned about.
>

IMO, everything that help you find more bug is useful. When working
against a tight dead-line, most people forget to do the simple test,
to "save time".

> Additionally, I think Erlang--both the language and implementation--
> are on the verge of becoming too complicated. I think both could use
> some streamlining. Adding ad hoc warnings is a step in the other
> direction.

I see your point, but I consider the new warnings to be useful,
and they did not add much complexity to the compiler. Maybe reduced
the complexity, as I could clean up part of the code at the same time.

/Bjorn
--
Bj
robert.virding at telia.c
Posted: Wed Jan 14, 2004 8:06 am Reply with quote
Guest
Bjorn Gustavsson wrote:
> "Robert Virding" <robert.virding_at_telia.com> writes:
>
>
>>This discussion just goes on Smile
>>3. With this in mind then Bjorn's new checks are probably a bad idea, the warnings become even more ad hoc and difficult to understand. I wonder if maybe some of the existing warnings should be removed. I still say that many of the warnings give very little and some are a right pain.***
>
>
> In old versions of OTP, there were warnings for imports that you didn't use
> and for exporting variables out of case statements. We have turned off those
> warnings by default.

Warning about exporting variables out of if/case/receive statements is
one one I would have left in as it is clearly dangerous. :-)

> Even if YOU don't like the _Varname convention, other people love it.

Fine, but why force it on me by default? Leave the warning in there but
let people who want it turn it on explicitly. Having it as default means
you are trying to enforce a certain style.

> There should really be a way to turn off the warnings for unused functions.
> We might add a mechanism in R10 for doing that.

Defintely add an option to turn warning about unused functions on and
off, but have the default value OFF.

Robert



Post generated using Mail2Forum (http://m2f.sourceforge.net)
luke at bluetail.com
Posted: Wed Jan 14, 2004 8:11 am Reply with quote
Guest
Robert Virding <robert.virding_at_telia.com> writes:

> Warning about exporting variables out of if/case/receive statements is
> one one I would have left in as it is clearly dangerous. :-)

But today it's an _error_ to unsafely export from if/case/receive,
right?

Fanning the flames Smile,
Luke



Post generated using Mail2Forum (http://m2f.sourceforge.net)
bjorn at erix.ericsson.se
Posted: Wed Jan 14, 2004 10:47 am Reply with quote
Guest
Robert Virding <robert.virding_at_telia.com> writes:

> Warning about exporting variables out of if/case/receive statements is
> one one I would have left in as it is clearly dangerous. :-)

There is still a warning if you use the exported variable in
a matching operation, because THAT is usually dangerous.

If you use the exported variable in an expression, you get no
warning.

>
> > Even if YOU don't like the _Varname convention, other people love it.
>
>Having it as default means you are trying to enforce a certain style.
>

Yes, we are. :)

/Bjorn

--
Bj

Display posts from previous:  

All times are GMT
Page 5 of 6
Goto page Previous  1, 2, 3, 4, 5, 6  Next
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