mats
The important thing is that Erlang gets the hard fundamental stuff
right. The rest can be improved with time.
> mats<mats_cronqvist.vcf>______________________________________________
> _
> erlang-questions mailing list
> erlang-q...@erlang.org
> http://www.erlang.org/mailman/listinfo/erlang-questions
Just speaking from my own impression as a newcommer, I really agree with the original author about the separator-vs.-terminator issue. The separators are a hassle for me.
Perhaps in order to make it work nicely, Erlang would need a major shake-up of its tokens and syntax, and thus the change wouldn't be worthwhile. I'm just saying that if I could design Erlang's syntax from scratch it would largely reflect the author's concerns.
This is very true -- however, it also means that the community now needs
to go through the EEP's, massive discussion of somekind, strong arm
someone with commit access, or enter into some kind of bureaucratic
ordealto do something like improve support for UTF-8 or strings, instead
of just /fixing it/.
Shouldn't the "hard fundamental stuff" be that which deserves
discussion, and the simple, pretty stuff already be in place? With
people we are aware of both, can't we get the pretty stuff in
place /now/, and improve it's performance /later/?
This is clearly going to be a recurring theme in Erlang-world as more
and more people see the power in Erlang, and are turned to stone viewing
the visage of it's warts.
--
Armando Di Cianno
http://dicianno.org/blog
arm...@dicianno.org
arm...@goodship.net
Not sure if this is visible enough in the documentation, but
"comma" reads as "and",
"semicolon" reads as "or",
and the full stop should be self explanatory.
Pretty straightforward.
(Yes, this comes from the Prolog heritage.)
I think people get hung up about this, because it is easy to have an
opinion on. Kinda like indentation, or _ vs CamelCaps.
Robby
PS I actually think the syntax differences are great, cause it means I
don't get suckered into writing Java code in Erlang!
[snip]
> I think people get hung up about this, because it is easy to have an
> opinion on. Kinda like indentation, or _ vs CamelCaps.
I don't think so. This is more like a practical thing: it is indeed a
little bit cumbersome to reorganize the branches because you have to
change the line endings.
Not a big issue, anyway.
Regards,
Alpar
> Robby
>
> PS I actually think the syntax differences are great, cause it means I
> don't get suckered into writing Java code in Erlang!
>
> _______________________________________________
--
Mazen Harake <ma...@erlang-consulting.com>
Erlang Software Developer and Consultant,
Erlang Training & Consulting, Ltd
Mobile Phone: +44 (0)795 13 26 317
Office Phone: +44 (0)207 45 61 020
Office Address:
401 London Fruit & Wool Exchange
Brushfield St, London, E1 6EL
United Kingdom
This email and its attachments may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of "Erlang Training & Consulting, Ltd".
If you are not the intended recipient of this email and its attachments, you must take no action based upon them, nor must you copy or show them to anyone. Please contact the sender if you believe you have received this email in error.
In the end, LFE might be the way to go. I have not had time to take a look
however. Anyone have anything bad to say about it?
DBM
I complained about this issue 7 months ago:
http://www.erlang.org/pipermail/erlang-questions/2007-August/028516.html
In the end, LFE might be the way to go. I have not had time to take a look
however. Anyone have anything bad to say about it?
> Damien Katz ( of couchDB fame) has written a blog post about the
> warts of erlang.
> (http://damienkatz.net/2008/03/what_sucks_abou.html)
Some of what Damien Katz says puzzles me greatly.
He claims, for example, that Erlang is exceptionally hard to edit.
I can only say that I have not found it so, and I don't even use
an Erlang-aware editor.
When he writes
Erlang string operations are just not as simple or easy as
most languages with integrated string types
the obvious retort is "No, they are simpler and easier".
However, sometimes giving a whining child a lollipop is a rational
thing to do. Maybe it is time for a string type that holds sequences
of Unicode characters in some unspecified compact format; binaries with
a different tag.
(1) I'm used to the Prolog approach, where every clause ends with a
full stop.
I'm also used to SML and Haskell and Clean, where again every
clause ends
the same way (with nothing). If Prolog and Haskell can figure
out that
adjacent clauses defining the same thing belong to the same
definition, it
isn't clear to me why Erlang can't. I once wrote a functional
preprocessor
for Prolog where I could write
append([], Ys) = Ys.
append([X|Xs], Ys) = [X | append(Xs, Ys)].
and the use of a dot at the end of every function clause was no
trouble at
all. Nor is it any trouble in Mercury.
I generally don't accept arguments about re-ordering definition
clauses,
because if you know what you are doing it is pretty rare. But I
*do*
accept arguments about *adding* clauses when you revise a data
type, so
I wish that Erlang would allow all function clauses to end with a
full
stop.
(2) Again, I generally don't accept arguments about re-ordering function
calls in a body. I don't find that to be a common mistake. Oh,
I do
make mistakes in Erlang. I make mistakes all the time in all
sorts of
languages. One mistake I do make in Erlang and in C is to get
the order
of arguments wrong. So why isn't Mr "Erlang sucks" complaining
bitterly
about how C and Java use different terminators after the last
argument ")"
and all the others ",", making it hard to swap arguments?
Presumably he
isn't complaining about that BECAUSE C and Java do the same
thing, so he
hasn't noticed it.
(3) For what it's worth, my text editor, modelled on Emacs, but
originally
small enough to fit comfortably on a PDP-11, has a "swap terms"
command
that interchanges the closed terms on either side of the cursor.
Given
foo(X) ->
bar(X),^
ugh(X).
with the cursor where the ^ is, Ctrl-X t will convert this to
foo(X) ->
ugh(X),^
bar(X).
with no trouble at all. More generally, the DEdit editor in
Interlisp-D
had a nice facility: you could build up a stack of selections
and then
choose an operation, so you could
select thing one (except for its terminator)
select thing two (except for its terminator)
swap top selections
Gosh, I miss the ability to have multiple selections.
So this is arguably an EDITOR problem, not a LANGUAGE problem,
and it
can be addressed by more/better editor support. (Is there an XCode
plugin for Erlang?)
However, sometimes giving a whining child a lollipop is a rational thing to do.
-- Michael T. Richter <ttmri...@gmail.com> (GoogleTalk: ttmri...@gmail.com) All really first class designers are both artists, engineers, and men of a powerful and intolerant temper, quick to resist the least modification of the plans, energetic in fighting the least infringement upon what they regard as their own sphere of action. (Nevil Shute) |
On Tue, 2008-03-11 at 13:40 +1300, Richard A. O'Keefe wrote:However, sometimes giving a whining child a lollipop is a rational
thing to do.
Way to dismiss valid complaints with an insulting backhand.
And then people wonder why it is technical types have a reputation for having no social skills.
There are several threads in the article (and comments) perhaps worthy
of discussion here at EQ.
My general impression of the article is that while I agree that the
complaints are valid, the reader comes away from it with the distinct
impression that Damien Katz would be content if he never had to
touch Erlang again, despite the contention that he could fill a book
with the things he likes about it - much like everyone now "knows"
that Erlang sucks at file I/O, since it did in the original Wayfinder
experiments, and it was noted in a blog article.
So, I'm inclined to agree with Tobbe. Someone reading the article, who
might have been interested in checking out Erlang, might well be
persuaded not to do so. I don't think that was the author's intention.
Still, the blogosphere is free, thankfully, so - on to the complaints.
- I'd like to try (= see someone else implement) an indentation-sensitive
front-end to the compiler, but perhaps ROK's suggestion that a full stop
can be used in place of a semicolon would cause less uproar.
- With the bit syntax improvements in R12B, and EEP9, I think we're starting
to come close to the foundations of an alternative string handling library.
When we get there, we'll surely be able to see further.
- I don't agree that Erlang is bad for writing test suites. On the contrary,
I think Erlang is, on the whole, just about the best test automation
environment in existence, especially if you include QuickCheck.
The problem with numbering variables is real, but can be addressed
with a change of programming style (which is both a good thing and
a very bad thing, depending on your POV). The advantage of immutable
variables far outweighs this inconvenience, anyway, even though I
guess that this particular issue is much less of a problem in currying
languages.
- The gripe about records, well, is well-founded, but also ground well covered.
Perhaps we should finally do something about it?
- I agree with Klacke on the out-of-memory issue. I once complained about it,
but have long-since decided that exit(1) is most likely the best option in
general. It is possible that one could allow for a callback, or specification,
that could guide the VM in releasing memory, in the cases where this
would be a reasonable thing to do. Perhaps before killing processes, one
could have a go at removing memory fragmentation, which would appear
as a very expensive GC. But Erlang does already have options for plugging
in a more aggressive memory allocator, which works harder to avoid
fragmentation in the first place. It also has quite a battery of features for
implementing sophisticated load control, e.g. barring new jobs if there
doesn't seem to be enough memory left.
- Regarding the uneven documentation, I'd like to point out that docbuilder
allows people to write alternative documentation that has the same look
and feel as the Erlang/OTP documentation. This is new as of OTP R12B.
- One comment dismissed Erlang as a specialized language. I think this
reflects the idea that concurrency is something that you only use when
it's really needed, and something to avoid otherwise. I'd like to turn the
tables and suggest that languages that are very good at sequential
processing, but suck at concurrency, are the specialized ones. So many
interesting applications require strong concurrency support, and as it
turns out, message-passing lightweight concurrency is a modeling
paradigm in its own right at least as powerful as OO. Perhaps we can
improve at getting this message across?
BR,
Ulf W
katz starts out like this; "...it's time to whine about my favorite
language I use quite extensively." seems pretty clear that the problem
is not that he is a troll, but rather that the erlang community (or at
least certain members of it) is immature. CouchDB is a major erlang
application, and katz should not have to take any crap from people that
has never written a significant piece of erlang (I'm not talking about
you, ulf!)
more so because most of his complaints are essentially valid.
* the syntax does suck. for beginners, because it looks weird (i.e.
not like ALGOL), thus being a major obstacle to adoption. for pros,
because the silly separators, and the needless verbosity (lambdas, using
'receive' instead of '?', etc)
* 'if' is completely worthless, and should ideally be obsoleted.
* strings as lists of integers is often annoying.
* the X1=x1(X),X2=x2(X1),,, pattern is tedious and error prone.
* records are "limited and verbose" (for a reason, but still)
* some of the libs/docs are of poor quality.
clearly, none of this is particularly bothersome once you've built up
some experience. but that doesn't mean they shouldn't be taken
seriously, especially if Erlang is to attract coders of katz' quality.
(http://damienkatz.net/2005/01/formula-engine-rewrite.html)
so what to do? some suggestions;
* documenting bad design patterns such as; using 'if', the "numbering
variables" pattern etc.
* writing a string handling lib on top of binaries
* introducing syntax for currying and monads
* introducing an alternative to records
(http://www.erlang.org/faq/faq.html#AEN1268).
* gen_servers with less boilerplate.
not very ground-breaking (quite the opposite). A "Worst Practice"
document prominently placed on the OTP home page would probably go a
long way.
> - I'd like to try (= see someone else implement) an indentation-sensitive
> front-end to the compiler, but perhaps ROK's suggestion that a full stop
> can be used in place of a semicolon would cause less uproar.
>
this would be truly cool. see
http://okasaki.blogspot.com/2008/02/in-praise-of-mandatory-indentation-for.html
mats
p.s. just to be clear; i think the conservative approach of the OTP team
is one of the great things about erlang. in my 10 years at ericsson,
where I took part in deploying 1000's of erlang systems, i can not
remember a single emulator crash (in a live system).
p.p.s. exit(1) when malloc() fails is, i think, The Right Thing(tm).
I think that something that gets lost in the noise of this discussion is
the difference between /better string support/ and /first class support
of UTF-8/.
I can deal w/o the better string support ad infinitum. I can also deal
w/o first class UTF-8 support as long as I'm writing apps that go DB <->
Web. However, if I can't write in Hindi/Sanskrit -- for e.g. -- for a
GUI app running on a system, without jumping through hoops, I'm not
terribly interested to write more-native-type programs in that language.
>
> On Tue, 2008-03-11 at 09:11 +0100, Ulf Wiger wrote:
>> IOW many complain about various quirks in Erlang, as well as the
>> apparent lack of efficient (at the very least familiar) string
>> handling support. We can choose to dismiss the complaints as
>> secondary
>> (which may or may not be true, depending on context), or address the
>> specific issues. I am quite sure I read ROK's post as suggesting the
>> latter, as he suggests fixing the deliminator issue, and puts in a
>> vote for a unicode-capable string type.
>
> I think that something that gets lost in the noise of this
> discussion is
> the difference between /better string support/ and /first class
> support
> of UTF-8/.
Honestly, in this day and age, I'm not convinced there's a strong
difference here. Or, rather, the second is a subset of the first.
Doing strings well in the modern world necessarily means confronting
the issues of Unicode support. (Which I assume is what you really
meant. UTF-8 vs. any other character encoding is an implementation
detail.)
There's one more thing that sometimes drive me nuts - due to the lack of
decent 'if' statement, new functions are written instead of branches of
a conditional statement. So I see a lot of code like this:
do_something(X, Y) ->
really_do_something(X, Y).
really_do_something(a, Y) ->
really_really_do_something(a, Y);
...
really_really_do_something(a, b) ->
... % could be a one liner
The problem is that the really_really_do_something is way to long to
type for people whose editor can't complete function names, so they'll
write rrds instead - which is very non-intuitive. I've just checked and
our code contains more than 150 functions with 3 character name, more
than 50 functions with 2 character name and more than 150 functions with
4 character name. Some of these names actually make sense (e.g. get,
set), but most of them do not - and I don't like function names that do
not make sense. I haven't seen this practice in C++ or Java projects.
Bye,NAR
--
"Beware of bugs in the above code; I have only proved it correct, not
tried it."
Commenting out first or last clauses or first or last statements are not
that rare during debugging - and the compiler error is really annoying
at that time.
> (2) Again, I generally don't accept arguments about re-ordering function
> calls in a body. I don't find that to be a common mistake. Oh,
> I do
> make mistakes in Erlang. I make mistakes all the time in all
> sorts of
> languages. One mistake I do make in Erlang and in C is to get
> the order
> of arguments wrong. So why isn't Mr "Erlang sucks" complaining
> bitterly
> about how C and Java use different terminators after the last
> argument ")"
> and all the others ",", making it hard to swap arguments?
> Presumably he
> isn't complaining about that BECAUSE C and Java do the same
> thing, so he
> hasn't noticed it.
Actually that's annoying in C or Java too. However, reordering arguments
is rare during debugging, commenting out arguments is not that rare. And
we've got the /* */ style comment in those languages that makes it
easy.
>
> * 'if' is completely worthless, and should ideally be obsoleted.
No, no no! I like 'if' It allows some neat constructs that are
horrible with case.
Counting 'if' and 'case' for one of the apps in our codebase gives
this result:
alex:src sean$ grep -v '^[[:space:]]*\($\|%\)' $(find . -name "*rl") |
grep " if " | wc -l
345
alex:src sean$ grep -v '^[[:space:]]*\($\|%\)' $(find . -name "*rl") |
grep " case " | wc -l
1052
~ one quarter of branching constructs are 'if'. Not at all
insignificant.
Sean
i was afraid no one was going to bite... still, I'd like an example or 2.
mats
I'm thinking of things like:
case X of
_ when X == abc; X == xyz ->
do_abc_or_xyz();
_ when X == '123', X == '456' ->
do_123456()
'123' ->
do_123_only();
fred ->
do_fred()
end
vs
if
X == abc;
X == xyz ->
do_abc_or_xyz();
X == '123',
X == '456' ->
do_123456();
X == '123' ->
do_123_only();
X == fred ->
do_fred()
end
I don't much like the _ when business.
'if' is also useful when you want to branch on a bunch of unrelated
boolean variables in various combinations:
case {X,Y,Z} of
{true, false, _} ->
do_a();
{false, _, true} ->
do_b();
_ ->
do_c()
end
vs
if
X and not Y ->
do_a;
not X and Z ->
do_b;
true ->
do_c
end.
I find the second more clearly states the intent. You also don't have
to remember the positions in the tuple to parse the code (though you
do need to know that 'not' is stickier* than 'and')
Sean
* IANACS
One very good reason for doing this(*) is that Erlang has excellent
trace facilities for function calls, but no ability to trace on
branching. I tend to agree that it often leads to less readable
code, but I don't agree that it's because of 'if' - at least not
in the cases where I've observed it in our code.
(*) this = using many small functions - not using illegible function
names, which is just silly.
BR,
Ulf W
For what it's worth, it was an indirect reference to
Alan Perlis's epigram number 93:
When someone says "I want a programming language in which I need
only say what I wish done," give him a lollipop.
(See SIGPLAN Notices Vol. 17, No. 9, September 1982, pages 7-13.)
Epigram 73 is also relevant:
It is not a language's weaknesses but its strengths that control
the gradient of its change: Alas, a language never escapes its
embryonic sac.
Epigram 93 got cross-linked with the fact that I *have* children who
*do*
whine sometimes (well, one of them has experienced pretty much
constant pain
for over a year and the hospital are having no luck diagnosing it; she
can
bear it but it's no fun) and I *have* found it rational to offer a
lollipop
from time to time (distraction is an approved method of coping with
pain).
Some times there are other things you have to do, and there isn't any
point
in arguing any more.
Take strings. 3 decades of computing have convinced me that in any
and every
language STRINGS ARE WRONG. Perl is the perfect example of how easy a
language can make it to write the wrong program (a program that does the
wrong thing, and does it badly). I keep a book on my shelves to show
to Perl
fans: it's a book explaining in all earnest how to do some useful
things in
Perl, and every single program in it has at least one fundamental flaw
that
means it will mostly work most of the time, but break when you need it
most.
One of the reasons I found C to be a vastly better language for text
processing
than PL/I (yes, I'm old enough to have been a PL/I programmer) was
that C did
NOT have a built in string data type. One of the reasons that my C
code can
still make student C++ code look like a sick snail is that C does not
have a
built in string data type, and C++ these days does. As for Java,
let's not go
there.
I suspect that there are two things that influence my views which many
others
do not share. First, a taste for minimalism. In many respects Erlang
is a
minimalist language, in contrast to C++, which is a maximalist
language (except
where it might be useful; the arguments against nested functions that
made
sense for classic C are absurd in the context of C++). Second,
experience with
several declarative languages and familiarity with the "trees are
trivial" way
of thinking that goes with that. I have been shocked at how hard our
Java-trained students find trees to be; it's a safe bet that someone
with a
C++ or Java or Perl or Python or Ruby background not only isn't going
to think
of an alternative to strings for representing text, they aren't going
to find it
imaginable that there might _be_ an alternative or that it might be
desirable.
One particular experience sticks with me. Before learning Prolog, I
learned
Interlisp. I was impressed by the Interlisp pattern-match compiler.
Boy,
that was cool. I thought. When I met Prolog, I said to myself: "I
would like
to have something like the Interlisp pattern-match compiler for
Prolog. What
I'll do is work through the Lisp pattern constructs and see how they
can be
translated to Prolog, and then I'll write a compiler, using
term_expansion/2."
But by the time I had finished seeing how to convert an Interlisp
pattern to
Prolog, I didn't want Interlisp patterns any more. That was for two
reasons.
The first was that I could now write whatever Interlisp pattern I wanted
*directly* in Prolog, and it looked rather better. The second was
that I
realised that I should usually be using trees, not lists, so that I
didn't
*have* to do complicated pattern matching.
So when people go on and on about wanting strings in Erlang, I find
myself
wanting to shout THINK! MEASURE! IMAGINE! Or "if you want Perl, you
know
where to find it". But there comes a point where you realise that
that is
no longer rational.
The fact that we now have to deal with Unicode, which is much more
complicated than most programmers realise, means that a string data type
would *now* do more than soothe people crying for the old familiar ways
of doing things. It really could make it easier for people to write
correct Erlang programs, by packaging up all the things that Unicode
makes
tricky. It *is* in the spirit of Erlang/OTP to provide support for
something tricky useful in communication, and binaries (which are
logically
redundant, given tuples and integers) show that it's in the spirit of
Erlang
to provide such support even at the expense of minimalism.
Example of perfectly legal but in my opinion ugly code (where 'if' or
using guards in a function-head of a help function is the correct
solution):
case X of
X when X>10 ->
:-)
Lennart
---------------------------------------------------------------------------
Lennart Öhman phone : +46-8-587 623 27
Sjöland & Thyselius Telecom AB cellular: +46-70-552 6735
Hälsingegatan 43, 10th floor fax : +46-8-667 8230
SE-113 31 STOCKHOLM, SWEDEN email : lennar...@st.se
-----Original Message-----
From: erlang-quest...@erlang.org [mailto:erlang-quest...@erlang.org] On Behalf Of Sean Hinde
Sent: den 11 mars 2008 20:18
To: Mats Cronqvist
Cc: Erlang mailing list
Subject: Re: [erlang-questions] erlang sucks
Sean
_______________________________________________
of course, a less (more?) contrived example would be this;
case is_imaginary(Friend) of
true -> sad(self());
false-> sound(self())
end.
vs.
FriendIsImaginary = is_imaginary(Friend),
if
not FriendIsImaginary -> sad(self());
true -> sound(self())
end.
where the second one makes my head spin. the point is that you can't
ignore the fact that you have to bind X, Y and Z in the 'if' example.
> 'if' is also useful when you want to branch on a bunch of unrelated
> boolean variables in various combinations:
>
> case {X,Y,Z} of
> {true, false, _} ->
> do_a();
> {false, _, true} ->
> do_b();
> _ ->
> do_c()
> end
>
> vs
>
> if
> X and not Y ->
> do_a;
> not X and Z ->
> do_b;
> true ->
> do_c
> end.
same here; when you take into account that you have to bind X, Y and Z
in the second example, but not in the first, the 'case' version comes
out ahead. objectively :>
i remain convinced that 'if' is worthless and does nothing but add to
the bloat.
mats
> Sean Hinde wrote:
>>
>>
>> I don't much like the _ when business.
>
> of course, a less (more?) contrived example would be this;
>
> case is_imaginary(Friend) of
> true -> sad(self());
> false-> sound(self())
> end.
>
> vs.
>
> FriendIsImaginary = is_imaginary(Friend),
> if
> not FriendIsImaginary -> sad(self());
> true -> sound(self())
> end.
>
> where the second one makes my head spin. the point is that you can't
> ignore the fact that you have to bind X, Y and Z in the 'if' example.
I agree your second version is ugly. That is why I idid not write my
usage of 'if' in that way ;-)
OTOH in our shop we do have one or two horrible sections of code
following your convention. In one place we have around 10 variables
made boolean then scattered throughout a huge if with many clauses of
complex boolean logic - head spinning indeed! Although it's not that
obvious how to deal with it in a much better way. We could carefully
pick it all apart, looking for state space reductions and building
complex hiearchies of smaller functions, but that is a lot of work for
perhaps little real gain...
>
>
>> 'if' is also useful when you want to branch on a bunch of unrelated
>> boolean variables in various combinations:
>>
>> case {X,Y,Z} of
>> {true, false, _} ->
>> do_a();
>> {false, _, true} ->
>> do_b();
>> _ ->
>> do_c()
>> end
>>
>> vs
>>
>> if
>> X and not Y ->
>> do_a;
>> not X and Z ->
>> do_b;
>> true ->
>> do_c
>> end.
> same here; when you take into account that you have to bind X, Y and
> Z in the second example, but not in the first, the 'case' version
> comes out ahead. objectively :>
Why, as the reader of the code, should I care that Z does not have to
be bound. As the reader of the code I can divine the intention much
more clearly with the second one, therefore it is better.
> i remain convinced that 'if' is worthless and does nothing but add
> to the bloat.
1/4 of our code says you are wrong!
Sean
> attila.ra...@ericsson.com skrev:
>>
>> There's one more thing that sometimes drive me nuts - due to the lack of
>> decent 'if' statement, new functions are written instead of branches of
>> a conditional statement. So I see a lot of code like this:
>> do_something(X, Y) ->
>> really_do_something(X, Y).
>>
>> really_do_something(a, Y) ->
>> really_really_do_something(a, Y);
>> ...
>>
>> really_really_do_something(a, b) ->
>> ... % could be a one liner
>>
>> The problem is that the really_really_do_something is way to long to
>> type for people whose editor can't complete function names, so they'll
>> write rrds instead - which is very non-intuitive. I've just checked and
>> our code contains more than 150 functions with 3 character name, more
>> than 50 functions with 2 character name and more than 150 functions with
>> 4 character name. Some of these names actually make sense (e.g. get,
>> set), but most of them do not - and I don't like function names that do
>> not make sense. I haven't seen this practice in C++ or Java projects.
>
> One very good reason for doing this(*) is that Erlang has excellent
> trace facilities for function calls, but no ability to trace on
> branching.
Yes, erlang has excellent trace facilities, it shows me that the 'rfmm'
function was called - unfortunately it doesn't show that which of the 10
rfmm functions was called. OK, I could figure out from the argument list
(also in the trace), but when the argument list is 100 lines long (you
have to pass the whole damn state as a parameter!), I just don't find it
that useful. Actually it's faster to insert some io:format calls into
the code and check the output.
> I tend to agree that it often leads to less readable
> code, but I don't agree that it's because of 'if' - at least not
> in the cases where I've observed it in our code.
>
> (*) this = using many small functions - not using illegible function
> names, which is just silly.
I agree that using small functions is a good practice. However, many one
liner function just makes following the code flow harder, because in the
end the code is longer. One pattern I often see is:
some_function(X, Y, Z) ->
rc(handle_some_function(X, Y, Z)).
rc(ok) ->
ok;
rc(error1) ->
handle_error1();
rc(error2) ->
handle_error2().
I think this is just bloat, it's a lot more elegant even in pesudo-C:
some_function(X, Y, Z) {
rc=handle_some_function(X, Y, Z);
if (error1==rc) {
handle_error1();
}
else if (error2==rc) {
handle_error2();
}
}
It's shorter by only 2 lines, still, my eyes don't have to jump around
that much when I follow the code. I guess this could be done in erlang
with if's, but the crusaders against if's have reached our design rule
document :-)
Bye,NAR
--
NOHL Attila Rajmund, Research Fellow
Ericsson R&D, Hungary, IP Services Phone: +36-1-437-7471
H-1037 Budapest, Laborc u. 1. Fax: +36-1-437-7792
Email: Attila.Ra...@ericsson.com
> On Tue, 11 Mar 2008, Ulf Wiger (TN/EAB) wrote:
>
>> attila.ra...@ericsson.com skrev:
>>>
>>>
>
> I agree that using small functions is a good practice. However, many
> one
> liner function just makes following the code flow harder, because in
> the
> end the code is longer. One pattern I often see is:
>
> some_function(X, Y, Z) ->
> rc(handle_some_function(X, Y, Z)).
>
> rc(ok) ->
> ok;
>
> rc(error1) ->
> handle_error1();
>
> rc(error2) ->
> handle_error2().
>
> I think this is just bloat, it's a lot more elegant even in pesudo-C:
>
> some_function(X, Y, Z) {
> rc=handle_some_function(X, Y, Z);
> if (error1==rc) {
> handle_error1();
> }
> else if (error2==rc) {
> handle_error2();
> }
> }
>
> It's shorter by only 2 lines, still, my eyes don't have to jump around
> that much when I follow the code. I guess this could be done in erlang
> with if's, but the crusaders against if's have reached our design rule
> document :-)
If rc is a common error handling function for many functions
throughout the module then I'd say this was OK and serves it's purpose
well.
The more normal Erlang way to write the equivalent of the C version
would be simply:
some_function(X,Y,Z) ->
case handle_some_function(X,Y,Z) of
ok -> ok;
error1 -> handle_error1();
error2 -> handle_error2()
end.
I'd argue that it is even more readable than the C version. And not an
'if' in sight :-)
Sean
i remain convinced that 'if' is worthless and does nothing but add to
the bloat.
mats
You might not think that when the code is at a customer site and
applying patches isn't something the customer (or the layers of
management between you and the customer) will let you do.
> > I tend to agree that it often leads to less readable
> > code, but I don't agree that it's because of 'if' - at least not
> > in the cases where I've observed it in our code.
> >
> > (*) this = using many small functions - not using illegible function
> > names, which is just silly.
>
> I agree that using small functions is a good practice. However, many one
> liner function just makes following the code flow harder, because in the
> end the code is longer. One pattern I often see is:
This is just your opinion of course but consider your example below
and replace handle_error1/handle_error2 with calls to some popular OTP
function say. The advantage of the one-liners is that you can see what
code you've executed by tracing on rc/1 alone. Rewrite it as a case
and you might still be able to if the different branches of your case
return distinct values but if not then you have to trace on these
popular OTP functions as well, which may give you a lot more trace
than you bargained for for starters. Things can get a lot worse in
real code in which constructing appropriate trace to determine what's
going on can be a real chore.
If I had my way I'd remove the case statement along with the if
statement since their overuse can effectively negate the advantage
that the trace facilities provide.
Anders
>
> some_function(X, Y, Z) ->
> rc(handle_some_function(X, Y, Z)).
>
> rc(ok) ->
> ok;
>
> rc(error1) ->
> handle_error1();
>
> rc(error2) ->
> handle_error2().
>
> I think this is just bloat, it's a lot more elegant even in pesudo-C:
>
> some_function(X, Y, Z) {
> rc=handle_some_function(X, Y, Z);
> if (error1==rc) {
> handle_error1();
> }
> else if (error2==rc) {
> handle_error2();
> }
> }
>
> It's shorter by only 2 lines, still, my eyes don't have to jump around
> that much when I follow the code. I guess this could be done in erlang
> with if's, but the crusaders against if's have reached our design rule
> document :-)
If there's such a dire need for an if-like construct with
slightly different semantics than the existing 'if', let's
not break existing code by changing 'if', but rather adding
(bloat) another construct. Perhaps we should call it 'switch',
and make it almost like a C switch, but subtly different in
creative ways? (:
The 'if' statement is not high on my list of things that need
improving. It's actually quite ok, except it could perhaps have
been named differently, in order not to give people false
expectations.
BR,
Ulf W
just to be clear; i don't think 'if ' should be improved.
and i realize it cannot be removed either :<
what i proposed was that it'd be obsoleted. in practice that would
mean that there'd
be a prominent document named "Obsolete features" or somesuch. That
document would list
old cruft; such as
* 'if'
* the three different 'and' (*)
* split_binary()
* the old type guards (integer() vs. is_integer())
* tuple funs
etc...
mats
(*)
(case x of x when true,false ->ok; _-> nok end.
nok
case x of x when true and false ->ok; _-> nok end.
nok
case x of x when true andalso false ->ok; _-> nok end.
nok
> On 11/03/2008, Mats Cronqvist
> <mats.cr...@kreditor.se> wrote:
> >
> >
> >
> > i remain convinced that 'if' is worthless and
> does nothing but add to
> > the bloat.
>
>
> It would actually be possible to extend 'if' to
> allow non-guard tests and
> user defined boolean functions in the test. Like in
> lisp.
We even have a keyword waiting for this: cond. On
consideration, I think I'd prefer instead generalizing
guards into deep guards (ie, at the very least,
user-defined calls available) everywhere.
An arbitrary call exiting in a guard would have to
convert to failure, just as guards work today. I'd
also suggest turning off side-effects while inside a
guard (even deep down in function calls), converting
attempted side-effects into exits.
(I guess the modest proposal above ought to be an EEP
too.)
Best,
Thomas
____________________________________________________________________________________
Be a better friend, newshound, and
know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
or are you saying there is a need for several 'and'? in that case i
disagree.
mats
Breaking a small subject off the main thread. I haven't written much
Erlang yet so maybe I'm just missing something, but I get the impression
Erlang won't tell me the line number when something goes wrong. I feel
it would be useful to know this and very in keeping with the Erlang
approach of making bugs nice and visible. So my vote while we're all
requesting changes to Erlang :) is for more line number visibility.
On a related subject I've played around with the LINE macro to tag
my own logging/error messages with line numbers and the best I could
produce was something like this :
-define(log(Line, Message, Var), log_message(?MODULE, Line, Message,
??Var, Var)). % LINE macro always gives '1' if I put it here.
log_message(Module, Line, Message, VarName, Var) ->
io:format("log: {~p, ~p} ~s ~s = ~p~n", [Module, Line, Message,
VarName, Var]).
and then in my code I can do things like
?log(?LINE, "Unexpected post", Other),
This works fine, but it would be nice to just write
?log("Unexpected post", Other),
and get the line number somehow. Can this be done?
Richard.
mats
-define(d(Format, Args),
io:format("~s" ++ Format,
[string:left(lists:flatten(io_lib:format("~p~p(~p):", [self(),?
MODULE, ?LINE])), 35, $ ) | Args])).
> _______________________________________________
> erlang-questions mailing list
> erlang-q...@erlang.org
> http://www.erlang.org/mailman/listinfo/erlang-questions
Thankfully I haven't been in this situation. But I stand by my claim -
if it's possible, it's often faster to insert io:format calls into the
call than to try to make sense of hundreds of lines of trace generated by
two simple function calls. Actually it would be nice if we'd have a tool
that could parse such trace and the source code and could show me that
which function was called...
But you have to write nonsense like:
ok -> ok;
when X == '123', X == '456'
Please advise. Thank-you.
DBM
-----Original Message-----
From: erlang-quest...@erlang.org
[mailto:erlang-quest...@erlang.org] On Behalf Of Sean Hinde
Sent: Tuesday, March 11, 2008 15:06
To: Mats Cronqvist
Cc: Erlang mailing list
Subject: Re: [erlang-questions] erlang sucks
vs
vs
Sean
* IANACS
_______________________________________________
> On Tue, 11 Mar 2008, Sean Hinde wrote:
> [...]
>> The more normal Erlang way to write the equivalent of the C version
>> would be
>> simply:
>>
>> some_function(X,Y,Z) ->
>> case handle_some_function(X,Y,Z) of
>> ok -> ok;
>> error1 -> handle_error1();
>> error2 -> handle_error2()
>> end.
>>
>> I'd argue that it is even more readable than the C version. And not
>> an 'if'
>> in sight :-)
>
> But you have to write nonsense like:
> ok -> ok;
You seem to be mostly complaining about the fact that case .. end and
if .. end do not have an implicit pass through when no clauses match.
Well, Erlang is not C.
Idiomatic Elang does not mean writing everything in single function
with a few hundred lines of ifs and gotos. I've read many C programs
in that style, and also seen Erlang code attempting to follow the
same style. It makes for ugly and hard to debug Erlang code. I've no
idea if it is good C coding style.
In Erlang you have the choice to throw a runtime exception if no
clause matches, or to provide an explicit wildcard case. The Erlang
"crash early" philosophy means that in most cases wildcard is the
wrong solution.
Sean
>
> Bye,NAR
> --
> "Beware of bugs in the above code; I have only proved it correct, not
> tried it."
Sean
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
What happens if those user defined functions exchange messages with the
rest of the world is not something I want to think about...
Out of interest:
Does anybody know of _anything_ that has been removed, ever?
bengt
> _______________________________________________
> erlang-questions mailing list
> erlang-q...@erlang.org
> http://www.erlang.org/mailman/listinfo/erlang-questions
the need for a better tool than dbg to interface with the trace BIF is
a different issue.
mats
*Erik.
mats
> Greetings,
>
> Out of interest:
> Does anybody know of _anything_ that has been removed, ever?
A number of deprecated BIFs and functions were removed in R12B.
Minor features (such as zombie processes) have been removed in past.
/Bjorn
--
Björn Gustavsson, Erlang/OTP, Ericsson AB
> katz starts out like this; "...it's time to whine about my favorite
> language I use quite extensively." seems pretty clear that the problem
> is not that he is a troll, but rather that the erlang community (or at
> least certain members of it) is immature. CouchDB is a major erlang
> application, and katz should not have to take any crap from people that
> has never written a significant piece of erlang (I'm not talking about
> you, ulf!)
>
> more so because most of his complaints are essentially valid.
> * the syntax does suck. for beginners, because it looks weird (i.e. not
> like ALGOL), thus being a major obstacle to adoption. for pros, because
> the silly separators, and the needless verbosity (lambdas, using
> 'receive' instead of '?', etc)
> * 'if' is completely worthless, and should ideally be obsoleted.
> * strings as lists of integers is often annoying.
> * the X1=x1(X),X2=x2(X1),,, pattern is tedious and error prone.
> * records are "limited and verbose" (for a reason, but still)
> * some of the libs/docs are of poor quality.
>
I mostly agree with all those complaints about Erlang. Syntax is not
usually a problem for programmers that know and use more than one
language at a time, but it is still an obstacle for newcomers.
My (little) experience about teaching Erlang at university gave me the
impression that students are attracted by many of the *cool* features
of the language (concurrency, message passing, reliability, gen_*) but
are mostly disappointed by syntax and libraries.
Maybe it is due to the fact that most of them know C/C++/Java/Python.
Maybe Erlang syntax is not so intuitive and easy as one could expect
from a modern and powerful languages.
Maybe because the standard library is not so rich and not so
consistent as expected from a mature language.
I think that the blogpost written by kats summerizes the most relevant
issues that should be solved in order to make Erlang a main-stream
language. Given that this community and people at Ericsson really want
this to happen......:-)
HND
Enzo
--
[ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
[ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
[ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
[ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
> On Tue, Mar 11, 2008 at 01:47:27PM +0100, Mats Cronqvist wrote:
>
>
> Maybe it is due to the fact that most of them know C/C++/Java/Python.
> Maybe Erlang syntax is not so intuitive and easy as one could expect
> from a modern and powerful languages.
> Maybe because the standard library is not so rich and not so
> consistent as expected from a mature language.
As someone who learned Erlang before C or Java my observation was
quite the opposite. I found the Erlang syntax to be extremely simple
and elegant, and that it was very easy to express the meaning of the
code. I find C/Java Syntax ugly and unnatural.
Erlang syntax didn't spring from nowhere. I bet Prolog programmers
find it quite comfortable :-)
Sean
Also, as having been a student and among students I know that students
are way too stupid to have worthy opinions.
I mostly avoided EE class so couldn't comment.
Maybe I should have blogged about how C syntax should change to be
more like Erlang. Darn! Blogs weren't invented then ;-)
Sean
Speaking as one who knew Prolog before learning Erlang, I found the
syntax faimilar, but that wasn't a help. Once you started write code you
soon realized that this just fooled you into believing Erlang did all
those nice thing Prolog does, but it doesn't. (Not surprising really,
since Erlang is functional, not logic based.)
Also, there are some subtle differences in the syntax, and those are
usually around the things people have been complaining about here, such
as the different separators. In Prolog much of these things don't happen
since the order of definitions and statements are pretty unimportant in
Prolog (you should get the same results no matter how you define things,
just the order of the results will differ. Prolog will give all
solutions, and not just the first that matches.)
(Prolog is much nicer... ;-) )
Johnny
Coming from Haskell I do find that the Erlang lists library has some
surprising omissions. An easy concrete step would be just to borrow the
missing functions on lists from Haskell.
John
I cannot agree with it. I grew up in the C/C++ world and also had known
Python before I met Erlang, still I find it very intuitive. I'm also
_very_ impressed by the simplicity and the expressive power. (I'm not a
student though...)
I think, the major obstacle for newcomers is not the syntax, but the
immutable data structures, the impossibility of variable rebinding, and
the miss of loop constructs like 'for' and 'while'. For someone familiar
(only) with procedural languages, it is hard to believe that a language
can be efficient without these features.
Regards,
Alpar
I cannot agree with it. I grew up in the C/C++ world and also had known
Claimed need? Predicate functions are absolutely necessary in handling dispatch decisions for any sort of system whose message vocabulary is upgraded over time, in my experience. Having to put the explicit matching specification any place where a message or data structure is handled (even for simple dispatch pass-through which doesn't do anything with the contents) instead of deferring to a predicate is a horrible violation of DRY, and requires error-prone code hunting if it ever changes shape. Also, the ability to handle an entire category of messages via predicate, as opposed to matching each individual shape in its own clause, is substantial.
Of course, one work-around to the lack of functions in guards is to prepend all functions you'd use before the case/receive and bind their results in variables. That works, but again trashes your code organization, especially when your main receive or case dispatch gets to be fairly large; is again a violation of DRY putting all the gory message details into something that doesn't use them; and is horribly sub-optimal since everything is called all the time instead of only enough to get the result that's needed.
> What happens if those user defined functions exchange messages with the
> rest of the world is not something I want to think about...
If you're so worried about being coddled by the language, then we really need a notion similar to C++ "constness". Track and propagate which functions are pure functional, and toss compile-time, module-load time, or runtime errors if you choose to do so. I'd much rather have user-defined guard functions and have it upon myself to use them properly, than to throw out the baby with the bathwater just because it could possibly be misused.
Yeah, I'm a little irate about the guard issue, simply because it seems it's clung to purely because of stick-in-the-mud attitude. Yes, I know that guard BIFs compile into BEAM directly and have their own optimization strategy, but function calls are still BEAM code you can generate. I don't care if it's a bit slower. We use code generation from spec DSLs for all event types and now full protocol specifications, so the ability to defer "is this a Hello message?" decisions to external generated functions is a basic requirement. Right now, we have to try to hack it into ?IS_HELLO style macros which expand to only guard BIFs where it can fit and mess with .hrl files. If you say that that's a decent solution, I might have more irate words to dispense. ;)
_________________________________________________________________
Shed those extra pounds with MSN and The Biggest Loser!
http://biggestloser.msn.com/
From odbc-2.0 releasnotes: (this was a long time ago)
- The old interface that became deprecated in odbc 1.0 has now been removed.
From Inets-5.0 release notes: (R12)
-Deprecated base64 decode/encode functions have been removed. Inets uses
base64 in STDLIB instead.
- The Inets application now has to be explicitly started and stopped
i.e. it will not automatically be started as a temporary application as
it did before. Although a practical feature when testing things in the
shell it is not desirable that people take advantage of this and not
start the Inets application in a correct way in their products. Added
functions to the Inets API that call application:start/stop.
From ssl-2.1 release notes: (this was a long time ago)
- The confounded notions of verify mode and verify depth has been
corrected. The option verifydepth has been removed, and the two separate
options verify and depth has been added.
The list can be made much longer but I have better thing to do ;)
Regards Ingela
Richard.
> --
> --Hynek (Pichi) Vychodil
I didn't try to compare Erlang to any other functional language. You
said that it is seems hard-to-learn for students and concluded that it
must be because of its bad syntax. What I answered is that basically
nothing is wrong with the syntax of Erlang (it is simple, intuitive and
easy-to-learn). It might be better, but the real difficulty of its
learning for a student that it is functional.
> Those features are not erlang-centric: also Ocaml and haskell would
> require a little of an effort for a C programmer.
I didn't want to say the opposite.
> In a couple of words, we don't have just to choose among Erlang OR
> imperative programming (C/Java/Python & Co.): we've a lot of choices
> in the field of funtional languages, and a couple of them have some
> nicer syntax and features compared to Erlang.
What is your experience, do your students tend to really prefer Haskell
to Erlang?
Best regards,
Alpar
If we should talk about expressiveness, I think that haskell mostly wins
among functional languages. But haskell syntax (just to keep this example)
is far more intuitive and clear (and orthogonal) than Erlang's.
>
> I think, the major obstacle for newcomers is not the syntax, but the
> immutable data structures, the impossibility of variable rebinding, and
> the miss of loop constructs like 'for' and 'while'. For someone familiar
> (only) with procedural languages, it is hard to believe that a language
> can be efficient without these features.
>
Those features are not erlang-centric: also Ocaml and haskell would
require a little of an effort for a C programmer. BTW, the little
experience I have in writing Erlang code says that if I had written
it in haskell it would have benn far more readable and nice.
In a couple of words, we don't have just to choose among Erlang OR
imperative programming (C/Java/Python & Co.): we've a lot of choices
in the field of funtional languages, and a couple of them have some
nicer syntax and features compared to Erlang.
HND
KatolaZ
These "features" make it much easier to write buggy code (and much harder to
find such buggy code). The developers you speak of need to take off their
blinders if they ever hope to see the light.
> the miss of loop constructs like 'for' and 'while'.
Erlang has plenty of loop constructs--how else could you write a server
loop? And with the use of tail-recursion this need not be inefficient.
There's also lists:foldl/3, lists:foreach/2, list comprehensions, etc. I
much, much prefer the look of these constructs over the equivalent
for or while loops--regardless, the same can be accomplished with both.
> For someone familiar
> (only) with procedural languages, it is hard to believe that a language
> can be efficient without these features.
For someone more familiar with functional languages, it is hard to believe
applications can be written correctly (let alone efficiently) _with_ those
features.
-Rick
I agree that Haskell's syntax is very nice, once you've gotten
used to it. The main problem for a beginner, is that it has
so little of the usual cruft, that it's difficult to tell
what's going on. (:
I think it's a bit unfortunate that there isn't more sharing
between Haskell, ML/OCaml and Erlang. Every once in a while,
there has been some talk about developing interop libraries
for going back and forth between the different languages.
Personally, I think it's a cop-out to say that all three
support interfacing to C. It still leaves a lot of work for
the programmer wanting to make use of some good library
written in one of the other languages.
There is the ErlOCaml Google group, which actually has some
code in it:
http://code.google.com/p/erlocaml/
Then there are the various pet projects offering alternative
syntax on top of the Erlang VM.
These are the various projects I know of:
- lersp which interprets "an approximation of scheme"
(http://jungerl.cvs.sourceforge.net/jungerl/jungerl/lib/lersp/),
- Erlang/Gambit interface (interfacing Erlang from Scheme)
http://theschemeway.blogspot.com/2007/07/schemeerlang-interoperability-sequel.html
(especially aiming at accessing Mnesia from Scheme, it seems)
- LFE - Lisp for Erlang, obviously
- HaskErl - Haskell to Erlang Core Compiler
http://blog.tornkvist.org/blog.yaws?id=1190846785574003
(There is also a Perl extension to Haskell, called Haskerl,
predating the above by about 15 years...)
- ETOS - Erlang to Scheme compiler
http://www.iro.umontreal.ca/~larosem/papers/etos.ps.gz
- Stoe - Scheme to Erlang compiler
https://webmail.iro.umontreal.ca/pipermail/gambit-list/2007-June/001466.html
- My own hack to allow different syntaxes in the Erlang shell:
http://ulf.wiger.net/weblog/2007/11/21/extending-the-erlang-shell-part-2/
(it would be better if there existed a Core Erlang evaluator)
Judging by past attempts, I'd say that interop solutions have a far
better chance of gathering an audience than an X-to-Y compiler.
But whatever stimulates sharing of ideas across communities is
most likely a Good Thing.
BR,
Ulf W
Is my English so bad?
Regars,
Alpar
>
>
>> In a couple of words, we don't have just to choose among Erlang OR
>> imperative programming (C/Java/Python & Co.): we've a lot of choices
>> in the field of funtional languages, and a couple of them have some
>> nicer syntax and features compared to Erlang.
>
> What is your experience, do your students tend to really prefer
> Haskell
> to Erlang?
Personally, I feel like for the type of tasks that most students /
academics do, Haskell is nicer. For the sort of thing that most
professional programmers do, Erlang is nicer. I can live with some
modest extra verbosity in exchange for solving some really hard
practical problems.
-kevin
-Vance
To be honest, I don't think that the matter is "the type of tasks that
most students / academics do" :-) I think that Erlang has some nice
stuff that haskell still misses (like native support for reliability
management, for instance); but anybody who knows a bit of haskell
cannot deny that its syntax is much more clear and expressive, and
this does not have anything to do with the fact that you are an
experienced firm programmer or an undergraduate student: it is just a
matter of fact :-)
I usually hear Erlang programmers complaining about Lisp parentheses,
but if you look into an Erlang module which does something meaningful,
you would find tons of parentheses, and of 4 different types: "()",
"[]", "{}", "<<>>".
What I mean is that we need to use a little of criticism also when we
talk about our favourite language, and in this sense I really
appreciated that blogpost which started this kind of flame: if we read
it from a "neutral" point of view, we'll find that most of what ketz
have written is TRUE, expecially if we use another FPL like haskell
for the comparison.
Finally, I agree with Ulf when he says that Erlang, Haskell,
lisp/scheme and ML/OCaml communities should work together much more
than how they are actually doing: all of them could benefit from such
kind of collaboration. Maybe Erlang would have been a better language
today from many perspectives, if our community had got ideas and
solutions from haskell/OCaml/scheme experiences.
My2Cents
Enzo
http://www.macs.hw.ac.uk/~dsg/gdh/papers/FaultToleranceProposal_sfp00_draft.ps
is a little bit in that direction, i guess. presumably not exactly
industrially proven yet, vs. Erlang's hallowed history :)
Not at all, and I apologize if I offended you.
The bottom line, though, is erlang is not a procedural language. Therefore,
people that can't switch to a functional/concurrent programming paradigm are
naturally going to have a hard time, and maybe even dislike the language.
Tossing something that looks like a for or while loop at them to help them
learn the language doesn't make sense--it doesn't help them switch to the
new paradigm. Where iteration used to be a "good fit", now recursion is
employed, etc.
Likewise, variables are single assignment. Dict and other modules can be
used to try and cheat and get multiple assignment (or worse, global variables),
but that's terrible style and so it also won't help them out in the long run
(probably won't help in the short run, either).
I used to be one of these poor souls, but I switched over to erlang so long
ago and haven't look back since--I'm not sure I recall exactly how I got
here :-)
I do think there's hope for newcomers, though, considering I did get here and
without a lot of resources now available to newcomers:
1) Joe's new book
2) better docs
3) sites like erlware, trap exit, etc which give great examples, include
tutorials geared towards the beginner, etc
4) this mailing list (which was around way back when I was learning, but
with so many more subscribers today than 5+ years ago it's that much
quicker/easier to get answers--and there's years of archives to dig
through as well)
-Rick
t
On Thu, Mar 13, 2008 at 4:12 PM, Rick Pettit <rpe...@vailsys.com> wrote:
[snip]
>
> 1) Joe's new book
>
> 2) better docs
>
> 3) sites like erlware, trap exit, etc which give great examples, include
> tutorials geared towards the beginner, etc
>
> 4) this mailing list (which was around way back when I was learning, but
> with so many more subscribers today than 5+ years ago it's that much
> quicker/easier to get answers--and there's years of archives to dig
> through as well)
>
>
>
> -Rick
On Thu, Mar 13, 2008 at 09:59:27AM -0700, Kevin Scaldeferri wrote:To be honest, I don't think that the matter is "the type of tasks that
>
> Personally, I feel like for the type of tasks that most students /
> academics do, Haskell is nicer. For the sort of thing that most
> professional programmers do, Erlang is nicer. I can live with some
> modest extra verbosity in exchange for solving some really hard
> practical problems.
>
most students / academics do" :-) I think that Erlang has some nice
stuff that haskell still misses (like native support for reliability
What I mean is that we need to use a little of criticism also when we
talk about our favourite language, and in this sense I really
appreciated that blogpost which started this kind of flame: if we read
it from a "neutral" point of view, we'll find that most of what ketz
have written is TRUE, expecially if we use another FPL like haskell
for the comparison.
Finally, I agree with Ulf when he says that Erlang, Haskell,
lisp/scheme and ML/OCaml communities should work together much more
than how they are actually doing: all of them could benefit from such
kind of collaboration. Maybe Erlang would have been a better language
today from many perspectives, if our community had got ideas and
solutions from haskell/OCaml/scheme experiences.
My2Cents
Enzo
--
[ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
[ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
[ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
[ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
_______________________________________________
Yeah, I'm a little irate about the guard issue, simply because it seems it's clung to purely because of stick-in-the-mud attitude. Yes, I know that guard BIFs compile into BEAM directly and have their own optimization strategy, but function calls are still BEAM code you can generate. I don't care if it's a bit slower. We use code generation from spec DSLs for all event types and now full protocol specifications, so the ability to defer "is this a Hello message?" decisions to external generated functions is a basic requirement. Right now, we have to try to hack it into ?IS_HELLO style macros which expand to only guard BIFs where it can fit and mess with .hrl files. If you say that that's a decent solution, I might have more irate words to dispense. ;)
this has nothing to do with the reality of Erlang :-) but presumably
in a sufficiently powerful type system you could constrain the guards
to be safe?
Yes. CLAIMED need.
Remember, while guards resemble Erlang expressions, they are
fundamentally
different. Indeed, it is a real shame that new BIFs have been
introduced
that can be used in both guards and expressions; it would have been
better
to make the two sets of BIFs disjoint. It is also a real shame that
there
are alternatives to "," and ";" in guards borrowed from the expression
world. Again, the two should have been kept clearly distinct.
The differences really boil down to this:
guards are for INDEXING.
Just as a compiler is free to do unification in any order and to share
submatches across any number of clauses, so a compiler is free to do
guard
code in any order, to share guard tests across any number of
alternatives,
and to arbitrarily interleave matching and guard testing. For example,
I would hope a compiler to translate
p(X, "big hairy pattern") when integer(X), X > 0 -> ...
by testing the type and value of X before matching "big hairy pattern".
In order to freely reorder and share guard computations, the code must
be
known to be free of side effects, including input/output and message
passing.
To handle "exception = guard failure", it really pays to have
operations that
could raise exceptions where the index compiler can see them, not
hidden in
functions that do who knows what.
Haskell has it easier here, of course, because any side effects of a
function
must be revealed in its type.
Suppose we ha
cond E1 -> S1
; E2 -> S2
; En -> Sn
end
This can be handled pretty closely by
case E1 of true -> S1;
case E2 of true -> S2;
...
case En of true -> Sn
end ... end end
All that's really needed here is an equivalent of Algol 68's "ouse",
which was to 'case' as 'elif' was to 'if'. So add it!
case E1 of true -> S1
ouse E2 of true -> S2
...
ouse En of true -> Sn
end
"ouse" is pretty horrible (almost the only Algol 68 keyword I disliked;
what have cases got to do with the river Ouse?). Doubtless some better
keyword could be found. 'orca', perhaps? (Joke.)
> Predicate functions are absolutely necessary in handling dispatch
> decisions for any sort of system whose message vocabulary is
> upgraded over time, in my experience.
Just today I found that something I thought for *sure* was a Boolean
function actually needed to distinguish three cases. I have to agree
that *classification* functions are necessary; it is far from obvious
that they have to be Boolean. Again, in Haskell I often find that
something I originally thought of as returning a Boolean should return
a Maybe or Either instead.
Above I explained why changing 'if' to be 'cond' would be a bad idea.
We really do have good uses for something that acts the way 'if' does
now.
I have also mentioned the 'cond' proposal.
But I have now explained why 'cond' should normally be avoided even if
we
had it: it forces you to use Boolean results, which may seriously limit
your imagination.
Any time you have
cond p1(X) -> f(X, g1(X))
; p2(X) -> h(X, g2(X))
...
you should probably be using
case classify(X)
of {p1,G1} -> f(X, G1)
; {p2,G2) -> h(X, G2)
...
just as it is better to do
case X
of [H|T] ->
...
than
if is_cons(X) -> ... head(X) .. tail(X) ...
> Having to put the explicit matching specification any place where a
> message or data structure is handled (even for simple dispatch pass-
> through which doesn't do anything with the contents) instead of
> deferring to a predicate is a horrible violation of DRY,
I don't know what the acronym "DRY" stands for.
To the extent that I follow what you are saying here, I agree that you
shouldn't do that, but I deny that the absence of xif/cond makes you
do it.
The suggestion about something similar to C++ "constness" (really,
something
similar to what other declaration languages call "purity") is
something I
thought about back in 1988, and was actually writing up a proposal for
when
funs were introduced into the language and made it much more difficult.
C++ does it in the type system, and Erlang doesn't normally use a type
system,
because of the difficulties combining that with hot loading.
If you are generating Erlang code from a DSL, then why not just fix your
code generator?
As a matter of fact, the 'abstract patterns' proposal I put forward oh
so many
years ago would presumably solve your problem pretty much the way you
want to
solve it, because abstract patterns are sufficiently constrained that
they
CAN be safely used in guards.
f(Msg = #hello{}) -> ...
is necessarily safe, whereas
f(Msg) when strange_module:is_hello(Msg) ->
would not be.
I'm not sure whether to be gratified at how abstract patterns keep
solving
problems, or saddened...
Given the state of type checking in Erlang nowadays, this might indeed
be ripe for some research and prototyping.
BR,
Ulf W
> Raoul Duke skrev:
>
> > this has nothing to do with the reality of Erlang
> :-) but presumably
> > in a sufficiently powerful type system you could
> constrain the guards
> > to be safe?
>
> Given the state of type checking in Erlang nowadays,
> this might indeed
> be ripe for some research and prototyping.
Marking functions as safe/pure is straightforward when
you have the whole program -- just mark the uncertain
cases as impure -- so you could easily verify that a
certain software release only uses safe guards.
As far as I can see, the main problem would be
piecemeal use of code, such as in ad hoc hot code
loading. But even here, it seems you could reject the
module at load time by (a) enclosing suitable
annotations with the beam file and (b) a quick bit of
load-time analysis.
Best,
Thomas
____________________________________________________________________________________
Be a better friend, newshound, and
know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
...or mark calls to external functions as impure/unsafe.
I think this is a reasonable restriction.
BR,
Ulf W
I was following this topic and was waiting for the right time to throw
in my ideas :-)
> case X of
> _ when X == abc; X == xyz ->
> do_abc_or_xyz();
> I don't much like the _ when business.
Yes, I agree, but while you suggest using 'if' in similar cases, I
suggest a different solution.
The point here is that you want do have the same result in several
cases, but you can't do it with the 'case' construct. You use guards
instead of pattern matching, because the logic "OR" operator (;) can be
used with guards, while it cannot be used with patterns.
Pattern matching basically tests whether a term is a member of a subset
of terms. So a pattern describes a subset of terms. Patterns and guards
together do the same, they describe a subset of terms by deselecting
values that don't satisfy the guards.
The ; operator means union. The pattern
Pattern when Guard1; Guard2
describes the subset of terms:
(Pattern when Guard1) UNION (Pattern when Guard2)
Why don't we extend the notion of patterns to somehow describe the union
set operation?
We already can describe the intersection of patterns:
Pattern1=Pattern2
describes the subset
Pattern1 INTERSECTION Pattern2
I think there is no '\/' operator in Erlang, so
Pattern1 \/ Pattern2 could mean Pattern1 UNION Pattern2
Let's see some example uses:
{a,_,_} \/ {b,_,_}
[ a \/ b | Tail ]
{a,X,_} when is_integer(X) \/ {X,b,_} when X>3
The union of patterns matches if (at least) one of the patterns matches.
The union pattern binds only the names that are present in each pattern.
Other names are considered unsafe.
There is one more basic set operation: subtraction. With the use of
guards, you can subtract a subsets from a set described by a pattern:
A positive guard subtracts the terms that don't satisfy the guard,
negated guards subtract the terms that do.
But you cannot subtract a subset of terms described by a pattern.
I've already suggested a pattern-match-test operator. It does have other
uses as well, but it is also useful for subtracting subsets:
Let "Pattern ~= Expression" semantically mean
case Expression of Pattern -> true; _ -> false end
You'll want to use this in guards:
Pattern1 when not (Pattern2 ~= Pattern1)
means
Pattern1 MINUS Pattern2
Of course the syntax might seem terrible, there are probably better
symbols for set operations.
The addition of these two constructs would:
- amend patterns to be a complete syntax for describing a subset of
terms
- allow programmers to avoid duplicated code
- only _extend_ Erlang, not changing the behaviour of existing programs
- almost entirely obsolate the 'if' construct
However, in order to fully obsolate 'if', we'd need some case-like
construct that can check multiple expressions.
This is what Richard A. O'Keefe suggested:
> This can be handled pretty closely by
> case E1 of true -> S1;
> case E2 of true -> S2;
> ...
> case En of true -> Sn
> end ... end end
> All that's really needed here is an equivalent of Algol 68's "ouse",
> which was to 'case' as 'elif' was to 'if'. So add it!
>
> case E1 of true -> S1
> ouse E2 of true -> S2
> ...
> ouse En of true -> Sn
> end
I don't have a better syntax proposal, but I completely agree.
Besides:
> The differences really boil down to this:
> guards are for INDEXING.
Yes, patterns and guards not only have to be expressive, they also have
to be very efficient.
You might think that the above idea of extending pattern matching with
the union operator ruins the clever indexing of patterns. It does not,
because the decision diagram does not have to be a tree, i.e. union'd
patterns might have independent paths in the decision diagram, but end
in the same leaf (function or case clause).
Georgy
On Fri, Mar 14, 2008 at 12:57 PM, Andras Georgy Bekes <bek...@sch.bme.hu> wrote:
> Why don't we extend the notion of patterns to somehow describe the union
> set operation?
That's a very good idea, I think. I mean not only the union operation,
but the whole proposal. Maybe you should prepare an EEP -- pattern
matching is one of the main strengths of Erlang as a language and
improving it would affect positively all the code base. [and it's a
backward-compatible change]
I see a couple of additional (future) steps:
** Since something new is added to the language, we could look at
removing something: the guards, by allowing inlined guard expressions
in the pattern itself, like for example
{integer(X), _, X>3, atom(Y), Z!=[X,Y]}
or
{integer(X>3), _, X, atom(Y), Z!={X,Y]}
would be equivalent to
{X, _, X, Y} when is_integer(X), X>3, is_atom(Y), not(Z ~=[X, Y]).
** And from here I think only the '?' and '*' operators (i.e. the
optional marker and the Kleene closure) are missing in order to get a
pattern language with full regular expression power. But that can wait
for a little while, maybe :-)
best regards,
Vlad
--
Some people see things that are and ask, Why?
Some people dream of things that never were and ask, Why not?
Some people have to go to work and don't have time for all that.
--- George Carlin
I'm still a bit fuzzy on the difference between DRY and SPOT (single point of
truth).
I've got the book around here someplace--maybe I need a review :-)
-Rick
P.S. Naturally if DRY == SPOT then DRY wins (less typing, and we all know that
laziness is a virtue).
Hi,
just changing the subject on this thread, so I don't have to
repeatedly be told in my inbox that erlang sucks.
of course, it probably won't work because people will keep replying
to the old thread, and then every few minutes my mail will inform me
that erlang sucks.
*grin*
--fess
"erlang high school football rules!"
I'm sure Erlang will survive the accusation :-)
Sean
Don't forget the (tongue in cheek) converse "WET" principal... "Write
Everything Twice". =)
What is the state of the art right now?
Thanks.
Cheers,
David
-----Original Message-----
From: erlang-quest...@erlang.org
[mailto:erlang-quest...@erlang.org] On Behalf Of Erik Reitsma
Sent: Thursday, March 13, 2008 03:06
To: Bengt Kleberg
Cc: Erlang mailing list
Subject: Re: [erlang-questions] erlang sucks
If you count libraries: after rewriting a GUI from iv to tcl I gave up
when tcl was removed. I guess gs has been around long enough to consider
it, but then again there are still GUI alternatives floating around, and
I am afraid they will become better than gs and gs will be replaced.
*Erik.
> Out of interest:
> Does anybody know of _anything_ that has been removed, ever?
>
>
> bengt
>
> On Wed, 2008-03-12 at 16:53 +0100, Mats Cronqvist wrote:
> > Hynek Vychodil wrote:
> > >
> > >
> > > On Wed, Mar 12, 2008 at 3:02 PM, Mats Cronqvist
> > > <mats.cr...@kreditor.se
> <mailto:mats.cr...@kreditor.se>> wrote:
> > >
> > > or are you saying there is a need for several
> 'and'? in that case i
> > > disagree.
> > >
> > > ...
> > > I think there is no way to change it, because if you
> remove 'andalso'
> > > and use 'and' in programmers manner lazy behaviour, you
> will break
> > > some legacy code a vice versa. This change is impossible.
> You can be
> > > not agree with it. You can argue against it, but it is
> all what you
> > > can do with it.
> > if you go back a few posts, you'll see that i try to make it very
> > clear that nothing will be removed (at least not for the
> next few years).
> >
> > mats
I've tried three approaches, all of which work well depending on what
you want to do. There are of course other approaches.
wxErlang is an interface to the wxWidgets library and although it's
coverage is not 100% yet I've found it stable and good enough to write
reasonably complex GUI's. This is good if you want to stay entirely in
the Erlang world.
Java and Swing using the jInterface library. This also works very well
if you don't mind straying away from Erlang and don't mind some code
bloat in the interfacing.
Yaws and Erlyweb make a good pair but it depends on your interface
complexity and usability. You might actually end up with a good bit of
your ui code in java script using perhaps one of the Ajax libraries like
DoJo.
Just my pennyworth.
- Bob
Hi, im new here, I started learning erlang by reading the book of joe
armostrong.
I think a good approach will be to write some kind of wrapper or
utility library around XUL[1] to output a feature rich GUI over a web
server, then you have the best of both worlds. A great and unified
GUI and all written on erlang (some javascript will be needed but
that's not a problem I guess).
Here are some nice examples (requires a gecko based browser);
* http://www.faser.net/mab/chrome/content/mab.xul
* http://xulplanet.com/testcases/example-viewer.xul
* firefox/seamonkey/thunderbird/songbird
* http://songbirdnest.com/
you can use XulRunner[2] or Prism[3] to run "desktop applications" or
just give the user an URL.
by using this as the GUI library you have a lot of advantages, you
have a desktop look and feel, transition to a web applications is
realy easy, you dont have bindings, the GUI is described on separated
files, platform independence etc.
Hope that helps :P
[1] http://www.xulplanet.com/
[2] http://developer.mozilla.org/es/docs/XULRunner
[3] http://wiki.mozilla.org/Prism
Is there any Erlang XPCOM interface ?
XUL is XML, which requires tools for efficient editing, does such a
tool exist and does it fit into your workflow ?
regards
Roberto
> _______________________________________________
> erlang-questions mailing list
> erlang-q...@erlang.org
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
--
Roberto Saccon
http://rsaccon.com
I was thinking on XUL as a replacement for the HTML over yaws
solution not as a replacement for wxWindows, if you use some kind of
template engine, and open Prism pointing to for example
http://127.0.0.1:1337 and using async calls to some kind of REST
service or erlang replacement of that (JSON could work nice here :)),
you have a web application running locally that looks like a destop
application, just replacing the URL you have a website :).
you will have some javascript there, but well, if you do the HTML
solution you will have it to, and using wxWindows means to have a
binding to another library that is not fully implemented and may have
problems with concurrent calls (I dont know if that will happen, but
for example GTK doesn't support threads very well)
also, with this solution you have the best of both worlds I guess.. a
web app with native look and feel.
I don't know if that answer your question.
Consider
f(a\/b, a\/b, ..., a\/b) -> ...
If f has n arguments, this expresses 2**n matches.
At first sight, this is great. Expressiveness is always nice.
But there is a question about how costly it is.
At second glance, what's the problem? We match one argument,
then move on. But now consider
f({X,_}\/{_,X},
{Y,X}\/{X,Y},
...
{Z,W}\/{W,Z}
)
I don't have a proof, but my gut feeling is that the combination
of compiling and executing clauses with "or" patterns has to be NP.
So this most definitely does "ruin efficiency".
You could hack around this by requiring that if a head variable is
bound in a disjunctive pattern it is not matched by any other head
pattern. But there are limits to the artificial restrictions that
are tolerable. If you want each pattern to commit as soon as it has
matched, then I believe you have to define the order in which the
patterns are matched, which is not something Erlang has hitherto needed.
I note that my abstract pattern proposal *already* gives you disjunctive
patterns, BUT in such a way that the disjunctions can't interact like
this.
The "or" and "+" operators have no valid semantics in patterns. I
think either of those would be much more aesthetically pleasing than
"\/" for this hypothetical pattern-union operator. E.g.,
case X of
a or b -> f();
c or d -> g()
end.
Speaking of which, what are the best ways of creating GUIs to interact with
Erlang? Gs? Run Yaws or Erlyweb or something and use the web browser? I
heard Joe once mention using Flash as the UI front end?
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions