erlang sucks

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 - 3 - 4 - 5 - 6 - 7 | Next >

Re: erlang sucks

by Christian S-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

>  HR1=f(HugeRecord),
>  HR2=f2(HR1),
>  ...
>  g(HR1).

But HR2 going unused will emit a compiler warning?  If your ellipsis
of code uses HR2 then some simple unit tests should detect your
mistake before the code is committed.


I appreciate that the resulting code is easier to reason about when
you have immutable values and single assignment variables.

The mental exercise of executing the code in your head becomes simpler
when there is only one value throughout the variable's scope.
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang sucks

by Jani Hakala :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

attila.rajmund.nohl@... writes:

> I don't think that immutable variables make it easier to write less
> buggier code. On the contrary, I often see code like this:
>
> HR1=f(HugeRecord),
> ...
> g(HR1).
>
> Then someone adds a line to modify the HugeRecord and forgets to update
> the call to 'g':
>
> HR1=f(HugeRecord),
> HR2=f2(HR1),
> ...
> g(HR1).
>
> Now we have a stupid bug.
>
The compiler would warn about that
    Warning: variable 'HR2' is unused

Jani Hakala
--
University of Jyväskylä, Department of Physics
email:  jahakala@...
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang sucks

by attila.rajmund.nohl :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, 13 Mar 2008, Mats Cronqvist wrote:

> attila.rajmund.nohl@... wrote:
>> On Wed, 12 Mar 2008, Anders G S Svensson wrote:
>> [...]
>>
>>> 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.
>>>
>>
>> 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...
>>
> i claim that in a real system, it is *always* faster to use the trace BIF
> than io:format, if you are equally skilled with both.
> for example, the "hundreds of lines of trace" you're talking about would
> presumably be the arguments to functions calls?
> from the erlang:trace/3 man page; "arity - Used in conjunction with the call
> trace flag. {M, F, Arity} will be specified instead of {M, F, Args} in call
> trace messages."

Actually I do need some of the arguments (how would I know which one of
the 10 similarly named functions is called?), I just don't need the
whole process state.
  Bye,NAR
--
"Beware of bugs in the above code; I have only proved it correct, not
  tried it."
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang sucks

by Mats Cronqvist-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

attila.rajmund.nohl@... wrote:

> On Thu, 13 Mar 2008, Mats Cronqvist wrote:
>
>> i claim that in a real system, it is *always* faster to use the trace
>> BIF than io:format, if you are equally skilled with both.
>> for example, the "hundreds of lines of trace" you're talking about
>> would presumably be the arguments to functions calls?
>> from the erlang:trace/3 man page; "arity - Used in conjunction with
>> the call trace flag. {M, F, Arity} will be specified instead of {M,
>> F, Args} in call trace messages."
>
> Actually I do need some of the arguments (how would I know which one of
> the 10 similarly named functions is called?), I just don't need the
> whole process state.
http://erlang.org/doc/apps/erts/match_spec.html#1.6


[mats_cronqvist.vcf]

begin:vcard
fn:Mats Cronqvist
n:Cronqvist;Mats
org:Kreditor Europe AB
email;internet:mats.cronqvist@...
title:Senior Developer
x-mozilla-html:FALSE
version:2.1
end:vcard



_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang *****

by Bugzilla from bekesa@sch.bme.hu :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> But now consider
>
> f({X,_}\/{_,X},
>  {Y,X}\/{X,Y},
>  ...
>  {Z,W}\/{W,Z}
> )
So matching this pattern must involve backtracking. Awww.

> 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.
The problem does exist in a single pattern:
         {{X,_}\/{_,X},
   {Y,X}\/{X,Y},
   ...
   {Z,W}\/{W,Z}}

We could of course generalise the above restriction, but it doesn't make
it tolerable.

But what are the real problems with the search for the right match with
backtracking? If the programmer has written that silly pattern, he/she
should be aware that it might not be very fast. Are there consequences
other than the match being slow?

> 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.
Could you give some reference?
I've searched for "abstract pattern" in the archives and found a few
mail, but not your paper.

        Georgy
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang *****

by Robert Virding :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

One thing that has to be considered in this discussions are guards. Guards are, irrespective of how some people would like to view them, part of pattern matching but those bits which can be difficult to express in a pattern*. As the guard varies with the pattern then they have to be kept together, something like:

foo(Pat11, ...) when Guard1 ;
foo(Pat12, ...) when Guard2 ;
foo(Pat13, ...) when Guard3 ->
    ...;
etc.

Having no "-> Body" after the pattern/guard means that you share the same body as the following clauses down to a clause with a body. In case/receive it would look something like:

case ... of
    Pat1 when Guard1 ;
    Pat2 when Guard2 -> ...;
    ...
end

This is just a suggestion to both include patterns, which you must, and not introduce any new syntax. It also looks a bit more Erlangy. I haven't tried modifying the parser but it will probably need modification of the AST. I don't think there would be any problems in compiling this, or an equivalent.

I remember that Richard's abstract patterns would also do this but here it would just be more explicit and dynamic.

Robert

* I have seen attempts to bake in guard tests into patterns but I think they become largely unreadable and manage to effectively hide the actual pattern.


On 17/03/2008, Andras Georgy Bekes <bekesa@...> wrote:
> But now consider
>
>       f({X,_}\/{_,X},
>         {Y,X}\/{X,Y},
>         ...
>         {Z,W}\/{W,Z}
>       )

So matching this pattern must involve backtracking. Awww.


> 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.

The problem does exist in a single pattern:

         {{X,_}\/{_,X},
          {Y,X}\/{X,Y},
          ...
          {Z,W}\/{W,Z}}


We could of course generalise the above restriction, but it doesn't make
it tolerable.

But what are the real problems with the search for the right match with
backtracking? If the programmer has written that silly pattern, he/she
should be aware that it might not be very fast. Are there consequences
other than the match being slow?


> 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.

Could you give some reference?
I've searched for "abstract pattern" in the archives and found a few
mail, but not your paper.


        Georgy

_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang sucks

by Kevin Scaldeferri :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Mar 17, 2008, at 6:31 AM, Jani Hakala wrote:

> attila.rajmund.nohl@... writes:
>
>> I don't think that immutable variables make it easier to write less
>> buggier code. On the contrary, I often see code like this:
>>
>> HR1=f(HugeRecord),
>> ...
>> g(HR1).
>>
>> Then someone adds a line to modify the HugeRecord and forgets to  
>> update
>> the call to 'g':
>>
>> HR1=f(HugeRecord),
>> HR2=f2(HR1),
>> ...
>> g(HR1).
>>
>> Now we have a stupid bug.
>>
> The compiler would warn about that
>    Warning: variable 'HR2' is unused


These examples always feel like people are insisting on writing  
imperative code in a functional language.  Why not:

HR1 = f2(f(HugeRecord)),
...
g(HR1)


There you go: no bug.


-kevin
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang sucks

by Michael Campbell-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Jani Hakala wrote:

> attila.rajmund.nohl@... writes:
>
>> I don't think that immutable variables make it easier to write less
>> buggier code. On the contrary, I often see code like this:
>>
>> HR1=f(HugeRecord),
>> ...
>> g(HR1).
>>
>> Then someone adds a line to modify the HugeRecord and forgets to update
>> the call to 'g':
>>
>> HR1=f(HugeRecord),
>> HR2=f2(HR1),
>> ...
>> g(HR1).
>>
>> Now we have a stupid bug.
>>
> The compiler would warn about that
>     Warning: variable 'HR2' is unused

Unless, in fact, it weren't unused...  Something in the "..." could have used
it, no?
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang *****

by Robert Virding :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.
When I was checking through trapexit.org after I had posted my reply I found that in trapexit mr mail had been truncated after the 3rd clause of foo. Did this happen to everyone else as well, a possible gmail bug, or was this only at trapexit, a trapexit bug? We'll see if it gets through uncut into trapexit as quoted text.

Robert

On 17/03/2008, Robert Virding <rvirding@...> wrote:
One thing that has to be considered in this discussions are guards. Guards are, irrespective of how some people would like to view them, part of pattern matching but those bits which can be difficult to express in a pattern*. As the guard varies with the pattern then they have to be kept together, something like:

foo(Pat11, ...) when Guard1 ;
foo(Pat12, ...) when Guard2 ;
foo(Pat13, ...) when Guard3 ->
    ...;
etc.

Having no "-> Body" after the pattern/guard means that you share the same body as the following clauses down to a clause with a body. In case/receive it would look something like:

case ... of
    Pat1 when Guard1 ;
    Pat2 when Guard2 -> ...;
    ...
end

This is just a suggestion to both include patterns, which you must, and not introduce any new syntax. It also looks a bit more Erlangy. I haven't tried modifying the parser but it will probably need modification of the AST. I don't think there would be any problems in compiling this, or an equivalent.

I remember that Richard's abstract patterns would also do this but here it would just be more explicit and dynamic.

Robert

* I have seen attempts to bake in guard tests into patterns but I think they become largely unreadable and manage to effectively hide the actual pattern.



On 17/03/2008, Andras Georgy Bekes <bekesa@...> wrote:
> But now consider
>
>       f({X,_}\/{_,X},
>         {Y,X}\/{X,Y},
>         ...
>         {Z,W}\/{W,Z}
>       )

So matching this pattern must involve backtracking. Awww.


> 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.

The problem does exist in a single pattern:

         {{X,_}\/{_,X},
          {Y,X}\/{X,Y},
          ...
          {Z,W}\/{W,Z}}


We could of course generalise the above restriction, but it doesn't make
it tolerable.

But what are the real problems with the search for the right match with
backtracking? If the programmer has written that silly pattern, he/she
should be aware that it might not be very fast. Are there consequences
other than the match being slow?


> 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.

Could you give some reference?
I've searched for "abstract pattern" in the archives and found a few
mail, but not your paper.


        Georgy

_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang *****

by Richard O'Keefe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I pointed out that allowing even one outermost level of disjunction of
patterns within a function head makes it possible to express clause  
choice
rules that appear to require exponential time to check.  Let me now  
point
out that my proposed fix, "a variable bound inside a disjunction must  
not
be tested in any other pattern" is not enough.
Instead of
        f({X,_}\/{_,X},
          {Y,X}\/{X,Y},
          ...
          {Z,W}\/{W,Z}
        ) ->
take
        f({X,_} \/{_,X},
          {Y,X1}\/{X1,Y},
          ...
          {Z,W1}\/{W1,Z}
        ) when X == X1, ..., W = W1 ->

On 18 Mar 2008, at 4:02 am, Andras Georgy Bekes wrote:
> So matching this pattern must involve backtracking. Awww.


I am somewhat at a loss to interpret "Awww".  I would like to think
it's "oh dear, now I understand why this is a really bad idea", but
I suspect it's "silly little you for caring about such things."

OK, let's try this.  As noted by the original proposer, '=' in
patterns is conjunction.  So we can write
        ({A,_,_,_,_,_,_,_,_} \/
         {_,A,_,_,_,_,_,_,_} \/
         {_,_,A,_,_,_,_,_,_} \/
         ...
         {_,_,_,_,_,_,_,_,A}
        )
to express "A is an element of this 9-element tuple".
By using
        ?E(A)=?E(B)=...=?E(I)
...
        when A /= B, A/= C, ..., A /= I, ..., H /= I
we can express "{A,...,I} is a permutation of this 9-element tuple".
If you're still with me, you now see how to express any 9x9 Sudoku  
problem
as a single clause match in Erlang extended with pattern disjunction.

I respectfully suggest that the Erlang developers have better things  
to do
with their time.
>

> The problem does exist in a single pattern:
>         {{X,_}\/{_,X},
>  {Y,X}\/{X,Y},
>  ...
>  {Z,W}\/{W,Z}}

It was not clear that the original proposal was calling for embedded
disjunctions.
>

> But what are the real problems with the search for the right match  
> with
> backtracking?

First, the current Erlang pattern matching compiler does not have to  
deal
with backtracking of any kind.  So we are not talking about just a tiny
syntactic extension, along the lines of allowing
        A andalso B
as equivalent to
        case A of true -> case B of true -> true ; false -> false end
                ; false -> false end
On the contrary, we are talking about a tiny syntactic extension with  
major
semantic effect, requiring a major rewrite of a core chunk of any  
compiler.

Second, the current Erlang pattern matching feature currently has  
predictable
costs.  If you have no repeated variables (the "linearity" condition,  
enforced
in Haskell and SML) the cost of pattern matching is linear in the size  
of the
pattern; with repeated variables it may be linear in the size of the  
input.
This lets us think of pattern matching as a glorified 'case'  
statement, and use
it freely.

> If the programmer has written that silly pattern, he/she
> should be aware that it might not be very fast.

This is what's called a "counsel of perfection", not in the historic
or literal sense (http://en.wikipedia.org/wiki/Evangelical_counsels)
but in the vernacular sense (excellent advice which can only be taken
by people who are already perfect), see for example
(http://forum.wordreference.com/showthread.php?t=5096).

I worked at Quintus for quite a while.  There were an amazing number of
customers who simply could not be made to understand that NO programming
language could solve an EXPTIME problem in linear time.  If an algorithm
could be written in a small number of times, then as far as they were
concerned it HAD to run in a short amount of time, and if it didn't,
then our Prolog compiler was no d--- good.

Now some constraint satisfaction problems of the kind that can be  
expressed
using conjunctions and disjunctions of patterns can be solved  
efficiently,
and some can't.  It's really asking too much for the Erlang compiler  
to tell
which are which and use special strategies for the efficiently  
solvable ones.
It is also asking too much to expect J. A. Luser, a typical Erlang  
programmer,
to figure out which ones are going to run fast and which are not,  
because
the speed will NOT depend just on what the conjoined and disjoint  
patterns
are, but on what the Erlang compiler does with them, and poor old Luser
doesn't know that (and cannot know what the next release of the compiler
will do).

This doesn't apply to the present system, where a fairly naive "what  
you see
is what it does" understanding won't mislead you too badly.

> Are there consequences
> other than the match being slow?

Not slow:  *unbelievably* slow.
>
>
>> 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.
> Could you give some reference?
> I've searched for "abstract pattern" in the archives and found a few
> mail, but not your paper.

A Google search for "abstract patterns Erlang" quickly located
http://www.erlang.org/ml-archive/erlang-questions/200309/msg00309.html

_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang sucks

by David Holz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


From: ok@...
> The differences really boil down to this:
> guards are for INDEXING.
> ... optimization ... reordering ... lack of side effects ...

In that, I agree with you.  I don't want this for anything other than indexing.  I want to _externalize_ the _purely functional_ indexing analysis of whatever is being checked, instead of being forced to always write it in-line wherever any match takes place.

I am of the opinion that if I call anything including side effects inside guards, I am doing bad things and things will break.  As I said, have it detect what functions are pure functional and only allow those if you want.  Everything will then work with user-defined guards, and everybody's happy.  I do not understand the resistance to this.

There are at least 3 ways to detect pure functional guard use, as has been discussed by myself and others on this list:

1) Have some internal state flag for "inside a guard?", and check that on side-effectful BIFs, tossing an error if it is inside one.  Since side effects are generally slower than functional BIFs, adding the overhead there should be less of a hit than the internal reduction counter for process switching.

2) Do compile- and module-load-time deep checking, marking what is known as pure functional, tossing errors earlier than the above.  This is weaker in that it can't detect variable-based M:F or fun calls until they're actually invoked; it could simply consider all such calls as dirty.

3) Only allow user-defined pure functional guards from the local module, to avoid any runtime issues.

Also, there's the option to make Dialyzer detect these sorts of things.

There is no good reason to keep user functions out of guards completely.  The whole "oh no, some idiot might put side effects in guards!" is nothing but a strawman, and as I listed above, it can be a sensibly detectable error condition with no difficulty in hot code loading.

But honestly I don't see any problem whatsoever in simply allowing anything in guards, side effects or not.  It would be nice to be able to send logging info regardless of guard context if you're debugging.  The caveats of calling side-effectful code from guards would not be new.  Threaded GUI systems are notorious for this yet still work fine; you simply know if you do things a certain way, some function gets called>=0 times.  What's the big deal?  Pure functional user defined functions in guards would be the norm, as is the case that I want.  Calling receive from within another receive guard should throw an error.

> If you are generating Erlang code from a DSL, then why not just fix your
> code generator?

The problem is user-written code that uses the generated stuff.  As it is, the human cannot easily defer to the generated stuff for guard decisions without resorting to weird tricks.

> f(Msg = #hello{}) -> ...
>
> is necessarily safe, whereas

It may be "safe", but it doesn't abstract what "Hello" is.  It still relies on there being a record called "hello" and if the codegen decides to represent it in any other way, this assumption breaks.  Hence the need to be able to defer guards to external code.

_________________________________________________________________
Climb to the top of the charts! Play the word scramble challenge with star power.
http://club.live.com/star_shuffle.aspx?icid=starshuffle_wlmailtextlink_jan
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang sucks

by Richard O'Keefe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 18 Mar 2008, at 1:35 pm, David Holz misunderstood:
>> f(Msg = #hello{}) -> ...
>>
>> is necessarily safe, whereas
>
> It may be "safe", but it doesn't abstract what "Hello" is.

This was presented as an example of using ABSTRACT PATTERNS, not  
RECORDS.
As such, it most definitely DOES abstract what "Hello" is

> It still relies on there being a record called "hello"

and DOESN'T rely on there being any record called "hello"

> and if the codegen decides to represent it in any other way, this  
> assumption breaks.  Hence the need to be able to defer guards to  
> external code.

and DOES allow the definition to be external.

You can very nearly think of abstract patterns as being the functions
you want, but constrained at the point of definition (and by the syntax)
so that they are safe to call, WITHOUT any runtime test, and pretty much
without any downside that I can see.

A note on implementation:
        #abspat(args)
in a clause head would be compiled as
        load current item into argument register
        normal function call
        failure address
        -- at this point function has left some stuff on the stack
        code to match those arguments
        ...
failure address:
        look for next matching clause.

The function would exit in one of two ways:
        failure-return
                Return no results,
                Instead of returning to X, return to *X
        success-return N
                move the N arguments to a standard place (perhaps the argument
                registers)
                Instead of returing to X, return to X + failure address size

Note: it would be absurd, as in "what a dreadful waste of effort" for  
the
user-defined things allowed in patterns to merely return true or false.
They need to SUCCEED returning a bunch of parts or FAIL.
This is not just more efficient than returning 'true' or 'false' and  
then
going a bit Alzheimic and checking to see which it was, it is  
considerably
more expressive.

Here is an example.  Suppose we have a bunch of messages including
        {hello,From,_,_,_}
        {teenaa_koe,_,From,_}
        {nihao,_,_,From,_,_}
and we would like (a) to classify all these as 'hello' messages and (b)
recover the From field from them.
        #hello(From) -> {hello,From,_,_,_};
        #hello(From) -> {teenaa_koe,_,From,_};
        #hello(From) -> {nihao,_,_,From,_,_}.

        #hello() -> #hello(_).

Now we can not only write

        f(Msg = #hello()) -> ... From = hello_from(Msg) ...

but we can also write

        f(Msg = #hello(From)) -> ...

Abstract patterns not only do not rely on -record,
they were intended to replace it!


_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang *****

by Matthew Dempsky-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 3/17/08, Richard A. O'Keefe <ok@...> wrote:
> I am somewhat at a loss to interpret "Awww".  I would like to think
>  it's "oh dear, now I understand why this is a really bad idea", but
>  I suspect it's "silly little you for caring about such things."

I think it's "So what? There are lots of programming constructs that
when misused can lead to inefficiency."

You'd laugh at someone who was concerned about adding recursive
functions to a language because a naive user might write "fibb(N) =
fibb(N - 1) + fibb(N - 2)" or that adding general looping constructs
means we can't ensure arbitrary programs will halt on a given input.
I see no reason to worry about similar arguments for disjunctive
patterns.
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang sucks

by Mats Cronqvist-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Kevin Scaldeferri wrote:

> On Mar 17, 2008, at 6:31 AM, Jani Hakala wrote:
>
>  
>> attila.rajmund.nohl@... writes:
>>
>>    
>>> I don't think that immutable variables make it easier to write less
>>> buggier code. On the contrary, I often see code like this:
>>>
>>> HR1=f(HugeRecord),
>>> ...
>>> g(HR1).
>>>
>>> Then someone adds a line to modify the HugeRecord and forgets to  
>>> update
>>> the call to 'g':
>>>
>>> HR1=f(HugeRecord),
>>> HR2=f2(HR1),
>>> ...
>>> g(HR1).
>>>
>>> Now we have a stupid bug.
>>>
>>>      
>> The compiler would warn about that
>>    Warning: variable 'HR2' is unused
>>    
>
>
> These examples always feel like people are insisting on writing  
> imperative code in a functional language.  Why not:
>
> HR1 = f2(f(HugeRecord)),
> ...
> g(HR1)
  word. i too tried to get erlc to compile thinly disguised C code when
i first learned erlang.

  mats


[mats_cronqvist.vcf]

begin:vcard
fn:Mats Cronqvist
n:Cronqvist;Mats
org:Kreditor Europe AB
email;internet:mats.cronqvist@...
title:Senior Developer
x-mozilla-html:FALSE
version:2.1
end:vcard



_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang *****

by Ulf Wiger :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2008/3/18, Matthew Dempsky <matthew@...>:
>
>  You'd laugh at someone who was concerned about adding recursive
>  functions to a language because a naive user might write "fibb(N) =
>  fibb(N - 1) + fibb(N - 2)" or that adding general looping constructs
>  means we can't ensure arbitrary programs will halt on a given input.
>  I see no reason to worry about similar arguments for disjunctive
>  patterns.

I think there is always reason to worry about such arguments.
I think that one of Erlang's strengths, both compared to more
"sophisticated" functional languages like Haskell, and to more
mainstream languages like C++, is that fairly average
programmers can quickly learn to write pretty solid production
code (perhaps not great, elegant or terribly efficient, but good
enough for industrial use, even with very high quality standards).

Great programmers can write elegant and efficient programs in
practically any language, and one of my main gripes about C++
is that great programmers are often able to use this to sway
policy decisions towards C++, not understanding (or caring?) that
such power tools can be disastrous in the hands of the "average
programmer" - after all, why should we base important design
decisions on expectations of how badly our design can be abused
by stupid people?

The main question is really: how easy is it to tell the efficient uses
from the horribly inefficient ones?

In the fibb example above, it is perfectly reasonable to teach
beginners (as we have done in Erlang for years) e.g. that a
recursive function will grow the stack if it has outstanding
computations when making the recursive call. This appears
to be easy to grasp for most programmers, and is immediately
obvious in the fibb() example. It is also immediately obvious
that it's exponential.

This is very different from allowing a subtle change in a complex
pattern match to shift evaluation from constant-time or linear
to NP - especially when programmers have learned to expect
and appreciate that pattern-matching is predictable in cost.

I am very much in favour of keeping Erlang's pattern-matching
both pure and predictable in cost. I don't mind having list
comprehensions, query comprehensions etc that are not.

BR,
Ulf W
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang *****

by Alpár Jüttner-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> 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.

The current pattern matching is also NP, so it wouldn't be a problem.
(Contrary to a common misconception, the meaning of NP is _not_
non-polynomial!)
You probably wanted to guess that it is NP-hard (which still doesn't
mean non-polynomial, but something quite close to it.)

If you want to do the pattern matching of all parameters in on step,
then it indeed NP-hard (I even have a proof for it).

However, if pattern matchings are done one-by-one and left-to-right,
then there is no performance problem. The union operator becomes less
flexible in this case, but it is still quite useful.

Actually, if we want the pattern matching to be deterministic, we _must_
do such a restriction. For example using the patter {X,_} V {_X}, the
value of X could be either element of the tuple. Using the left-to-right
rule, X will always be the first element.

Regards,
Alpar


_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang sucks

by attila.rajmund.nohl :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, 17 Mar 2008, Kevin Scaldeferri wrote:

> On Mar 17, 2008, at 6:31 AM, Jani Hakala wrote:
>
>> attila.rajmund.nohl@... writes:
>>
>>> I don't think that immutable variables make it easier to write less
>>> buggier code. On the contrary, I often see code like this:
>>>
>>> HR1=f(HugeRecord),
>>> ...
>>> g(HR1).
>>>
>>> Then someone adds a line to modify the HugeRecord and forgets to
>>> update
>>> the call to 'g':
>>>
>>> HR1=f(HugeRecord),
>>> HR2=f2(HR1),
>>> ...
>>> g(HR1).
>>>
>>> Now we have a stupid bug.
>>>
>> The compiler would warn about that
>>    Warning: variable 'HR2' is unused
>
> These examples always feel like people are insisting on writing
> imperative code in a functional language.  Why not:
>
> HR1 = f2(f(HugeRecord)),
> ...
> g(HR1)

Because this is a mock-example, the real code looks more like

HR1=HugeRecord#hugeRecordType{someField=SomeValue}
... code uses HR1
HR2=HR1#hugeRecordType{someOtherField=SomeOtherValue}
...
g(HR1), % forgot to update variable name
h(HR2). % didn't forget to update variable name

In this case the compiler won't save my a**. I see this kind of code
change all the time. Every week I see a checkin which only fixes a
variable name that wasn't updated, so this is not exactly a rare bug.

  Bye,NAR
--
"Beware of bugs in the above code; I have only proved it correct, not
  tried it."
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang *****

by Bugzilla from bekesa@sch.bme.hu :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> 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]).

I looks nice for the type-testing guard BIFs ( is_* ), but I don't know
how do you want to write the rest of them:
  abs(Number)
  element(N, Tuple)
  float(Term)
  hd(List)
  length(List)
  node()
  node(Pid|Ref|Port)
  round(Number)
  self()
  size(Tuple|Binary)
  tl(List)
  trunc(Number)
?

        Georgy
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang *****

by Bugzilla from bekesa@sch.bme.hu :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> > So matching this pattern must involve backtracking. Awww.
> I am somewhat at a loss to interpret "Awww".  I would like to think
> it's "oh dear, now I understand why this is a really bad idea", but
> I suspect it's "silly little you for caring about such things."
I meant: "Oh, sh** there is some real problem with this idea I failed to
think about. It probably needs radical changes in the compiler/vm with
consequences I surely can't foresee."

> If you're still with me, you now see how to express any 9x9 Sudoku
> problem as a single clause match in Erlang extended with pattern
> disjunction.
Wow, THAT would be a great advertisement for Erlang ;-)

> It's really asking too much for the Erlang compiler
> to tell which are which and use special strategies for the
> efficiently solvable ones. It is also asking too much to expect J. A.
> Luser, a typical Erlang programmer, to figure out which ones are
> going to run fast and which are not

Back to the real world: I worked with Prolog much, and wouldn't expect
anything better than a depth-first search for the first match. I think
I'd use it quite happily without having too much trouble with
unexpected match times.

I think the simple backtracking wouldn't be hard to implement, however,
it certainly needs radical changes in the compiler/vm, and has
unforeseen consequences.

> Second, the current Erlang pattern matching feature currently has  
> predictable costs.
Consequences like this: I might be wrong, but I think a pattern match is
an atomic operation in the VM, I mean, the scheduler won't switch to
another process in the middle of a pattern match. If this is true, a
long pattern match halts the whole Erlang VM. With careful work, you
can forge a long-running pattern match in Erlang (as you said: "it may
be linear in the size of the input") but with the
backtracking-pattern-union match it is just so much easier. I think I
am convinced, it is a really-really bad idea.

However, if a pattern match is not atomic in the above sense, it can't
cause such big trouble. I mean, at least the above problem does not
exist. There might be other serious issues I failed to think about.

> It was not clear that the original proposal was calling for embedded
> disjunctions.
It was. Basically I suggested '\/' as a
pattern*pattern -> pattern "function", which can be used anywhere.

However, what Robert suggests is a nice compromise:
> foo(Pat11, ...) when Guard1 ;
> foo(Pat12, ...) when Guard2 ;
> foo(Pat13, ...) when Guard3 ->
>     ...;
and
> case ... of
>     Pat1 when Guard1 ;
>     Pat2 when Guard2 -> ...;
>     ...
> end

This doesn't need any radical change in the compiler/vm. You simply act
as if the only clause body was used for all the patterns.

I'd be happy with this solution: it would solve >90% of the cases I'd
use pattern union for. But only together with the pattern-match-test
guard BIF. I'd still need it :-)

However, I don't think the above syntax is a good enough: after the ';'
token either a guard can follow (guard expressions separated by ','s)
or a new pattern. There should be a new keyword I think.

        Georgy
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: erlang *****

by Alpár Jüttner-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> This is very different from allowing a subtle change in a complex
> pattern match to shift evaluation from constant-time or linear
> to NP - especially when programmers have learned to expect
> and appreciate that pattern-matching is predictable in cost.

Once again, please: NP does _not_ mean non-polynomial, but something
very-very different. If you want to say "worse than polynomial" you can
say "superpolynomial" or "exponential" (if the running time is indeed
something like O(2^n)).

> I am very much in favour of keeping Erlang's pattern-matching
> both pure and predictable in cost.

But, if the left-to-right rule was used for evaluating the disjunctive
pattern matching, it would meet your requirements, wouldn't it?

Best regards,
Alpar

_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions
< Prev | 1 - 2 - 3 - 4 - 5 - 6 - 7 | Next >