Erlang/OTP Forums

Author Message

<  Erlang questions mailing list  ~  Guards and side effects

thomas.xa.johnsson at eri
Posted: Fri Mar 11, 2005 10:09 am Reply with quote
Guest
(Subduing the hardcore functional programmer in me for a bit ... :-)

I see really no compelling reason to prohibit side effects in guards,
in fact there may well be sensible uses, for instance, communicating
with another process to find out the value of the guard, consult ets tables
or other data bases, call a memo function ....

The only tricky place, as far as I can see, is guard evaluation
in a receive: to evaluate guards to select a message in the own process in-queue,
it makes sense *not* to allow another 'recursive' receive to find the value of the guard,
but to issue a run time error instead.
( An aside: this is akin to black hole:ing in implementing a lazy functional language, where in
the process of evaluating a 'thunk' you need the value of the same thunk)

There are many opportunities for the programmer to shoot him/herself in the foot,
but to hold the programmer in strict harness in this particular corner of the
language, and nowhere else, I find that misguided.

-- Thomas


Post generated using Mail2Forum (http://m2f.sourceforge.net)
ulf.wiger at ericsson.com
Posted: Fri Mar 11, 2005 10:37 am Reply with quote
Guest
> -----Original Message-----
> From: Thomas Johnsson XA (LN/EAB)
> Sent: den 11 mars 2005 10:35
> To: erlang-questions@erlang.org
> Subject: Guards and side effects
>
>
> (Subduing the hardcore functional programmer in me for a bit ... Smile
>
> I see really no compelling reason to prohibit side effects in guards,
> in fact there may well be sensible uses, for instance, communicating
> with another process to find out the value of the guard,
> consult ets tables or other data bases, call a memo function ....

I completely disagree. (-:

I would like to see a way to declare new guard expressions,
but think those guard expressions should be declarative and
fall strictly within the realm of pattern matching.

I think it is perfectly reasonable and sound to clearly
differentiate between functions that modify data (and perhaps
produce side-effects) and expressions that test the validity
of data in a side-effect free manner.

The purpose of user-defined guards should be to allow for
more expressive (and/or more intuitive) match expressions,
not to introduce new semantics.

/Uffe


Post generated using Mail2Forum (http://m2f.sourceforge.net)
mickael.remond at erlang-
Posted: Fri Mar 11, 2005 10:48 am Reply with quote
Guest
Thomas Johnsson XA (LN/EAB) wrote:
> (Subduing the hardcore functional programmer in me for a bit ... Smile
>
> I see really no compelling reason to prohibit side effects in guards,
> in fact there may well be sensible uses, for instance, communicating
> with another process to find out the value of the guard, consult ets tables
> or other data bases, call a memo function ....

Getting information from a process has no side effect.
I think there is a conceptual problem with side effect in guards.
Functions clause are selected by guards, but what happens if the guard
do real side-effect processing and the clause if finally not selected ?
It will result in side effect generated bu clause that are different
from the executed clause. In my opinion, this seems at least at first
sight conter intuitive and can lead to program very hard to debug.

--
Micka
vladdu
Posted: Fri Mar 11, 2005 10:56 am Reply with quote
User Joined: 28 Feb 2005 Posts: 397 Location: Gothenburg, Sweden
Hi,

From: "Thomas Johnsson XA (LN/EAB)" <thomas.xa.johnsson@ericsson.com>
> There are many opportunities for the programmer to shoot him/herself in the
foot,
> but to hold the programmer in strict harness in this particular corner of the
> language, and nowhere else, I find that misguided.

Good point, I think. The language proper should not be restricted by what are
mostly implementation/optimization issues. And extra power might open
possibilities that now are closed.

However, Erlang has a very pragmatic background. If the extra power means a
noticeable slowdown in applications that don't use that power, it's not going to
be easy to convince users it's good idea.

Also, a more powerful language also needs more top-of-the-range developers. Not
that the existing ones aren't good enough, but the new generation might be even
more tempted choose Java, because all it's safeguards don't let them shoot
themselves in the foot as easily [*]

So IMHO it is a very difficult balance to keep.

best regards,
Vlad

[*] More precisely, in Java it looks like it's more safe. One can do silly stuff
there too :-)



Post generated using Mail2Forum (http://m2f.sourceforge.net)
View user's profile Send private message
osxroolz at mymacmail.com
Posted: Fri Mar 11, 2005 11:18 am Reply with quote
Guest
I see no compelling reason to prohibit pointer manipulation in Erlang.
Just imagine how many really useful things you could do if
you could manipulate pointers. Communicate with other processes,
re-examine
garbage-collected data and cause behaviour in your program which you
never
imagined possible!!! This would be a real performance boaster.

There are many opportunities for the programmer to shoot him/herself
in the foot, but to hold the programmer in strict harness in this
particular corner of the language, and nowhere else, I find that
misguided.

iMan

---------

"Thomas Johnsson XA (LN/EAB)" wrote

(Subduing the hardcore functional programmer in me for a bit ... :-)

I see really no compelling reason to prohibit side effects in guards,
in fact there may well be sensible uses, for instance, communicating
with another process
***
There are many opportunities for the programmer to shoot him/herself in
the foot,
but to hold the programmer in strict harness in this particular corner
of the
language, and nowhere else, I find that misguided.

-- Thomas
--

osxroolz@mymacmail.com


Post generated using Mail2Forum (http://m2f.sourceforge.net)
tobbe at nortel.com
Posted: Fri Mar 11, 2005 11:52 am Reply with quote
Guest
Thomas Johnsson XA (LN/EAB) wrote:

>(Subduing the hardcore functional programmer in me for a bit ... Smile
>
>I see really no compelling reason to prohibit side effects in guards,
>in fact there may well be sensible uses, for instance, communicating
>with another process to find out the value of the guard, consult ets tables
>or other data bases, call a memo function ....
>
>
I must say that I totally disagree here!
Side-effects must be kept as few as possible!

The hardest problem I find, when debugging
code, are those that involves side-effects, i.e
ets, process dict., message sending, etc
To open up guards to be allowed to do this
would be a nightmare.

User defined guards which is guaranteed to
be side-effect free may be ok, but then we
have the termination problem of course.

Cheers, Tobbe


Post generated using Mail2Forum (http://m2f.sourceforge.net)
mccratch at gmx.net
Posted: Fri Mar 11, 2005 11:54 am Reply with quote
Guest
On 2005-03-11 at 11:28:05 (+0100), Vlad Dumitrescu wrote:
> Hi,
>
> From: "Thomas Johnsson XA (LN/EAB)" <thomas.xa.johnsson@ericsson.com>
> > There are many opportunities for the programmer to shoot him/herself in the
> foot,
> > but to hold the programmer in strict harness in this particular corner of the
> > language, and nowhere else, I find that misguided.
>
> Good point, I think. The language proper should not be restricted by what are
> mostly implementation/optimization issues. And extra power might open
> possibilities that now are closed.
>
> However, Erlang has a very pragmatic background. If the extra power means a
> noticeable slowdown in applications that don't use that power, it's not going to
> be easy to convince users it's good idea.

Well the extra power is just "syntactic sugar" for something that is
already possible in Erlang. Not being able to express some condition
in guards just forces one to use another approach which might look
ugly.

In fact I think it would be really possible to introduce the extension
(using arbitrary boolean expressions in guards) using
the parse_transform mechanism for at least functions and if
expressions (preserving the semantics of a receive statement I think is
very difficult). It is just some work and might reduce the performance
compared to an implementation in the compiler (of the generated code).

Performance loss for old code should not occur, because a guard
expression using only expressions allowed today in guards can be
compiled as it is now.

--
Cheers
Matthias Kretschmer


Post generated using Mail2Forum (http://m2f.sourceforge.net)
luke at synap.se
Posted: Fri Mar 11, 2005 12:16 pm Reply with quote
Guest
"Ulf Wiger \(AL/EAB\)" <ulf.wiger@ericsson.com> writes:

> I think it is perfectly reasonable and sound to clearly
> differentiate between functions that modify data (and perhaps
> produce side-effects) and expressions that test the validity
> of data in a side-effect free manner.

I'm with you, I like guards the way they are.

I think the main issue is that guards look so nice:

foo(X) when guard1(X) -> code1;
foo(X) when guard2(X) -> code2;
...

but if you need a non-guard test then it's way more verbose:

foo(X) ->
case test1(X) of
true ->
code1;
false ->
case test2(X) of
true ->
code2;
false ->
...
end
end

Seems a bit unnecessary.

The related and bigger problem for me is code like:

case foo() of
{ok, F} ->
case bar() of
{ok, B} ->
... ;
Err = {error, Reason} ->
Err
end;
Err = {error, Reason} ->
Err
end

I'm looking forward to trying out the new try-catch on this code once
we manage to upgrade to R10.

Cheers,
Luke



Post generated using Mail2Forum (http://m2f.sourceforge.net)
thomas.xa.johnsson at eri
Posted: Fri Mar 11, 2005 12:40 pm Reply with quote
Guest
The torch I threw in seems to have caught fire -- good! (:-)

The 'Erlang way' is to do run time checks instead of compile time / static checks --
my argument is merely drawing that to it's logical conclusion.

I wasn't advocating profligate use of side effects as a style of programming.
But in cleaning up the language and thus allowing general expressions including
calls of user defined functions in guards, one must also potenitally allow
side effects there. With my examples
I was also pointing out that here might be legitimate uses
of side effects even with a declarative/functional thinking & style.

Torbjorn Tornkvist:

> The hardest problem I find, when debugging
> code, are those that involves side-effects, i.e
> ets, process dict., message sending, etc
> To open up guards to be allowed to do this
> would be a nightmare.

I agree that these kinds of problems are often nightmarish,
but I don't see how generalising guards noticeably worsens
this nightmare.

> User defined guards which is guaranteed to
> be side-effect free may be ok, but then we
> have the termination problem of course.

A *runtime* check & crash when the expression evaluation is doing
something fishy in e.g. guard evaluation in receive!

-- Thomas


Post generated using Mail2Forum (http://m2f.sourceforge.net)
david.nospam.hopwood at b
Posted: Fri Mar 11, 2005 8:50 pm Reply with quote
Guest
osxroolz@mymacmail.com wrote:
> I see no compelling reason to prohibit pointer manipulation in Erlang.
> Just imagine how many really useful things you could do if
> you could manipulate pointers. Communicate with other processes,
> re-examine garbage-collected data and cause behaviour in your program
> which you never imagined possible!!! This would be a real performance
> booster.
> There are many opportunities for the programmer to shoot him/herself
> in the foot, but to hold the programmer in strict harness in this
> particular corner of the language, and nowhere else, I find that
> misguided.

Your implied argument (that allowing arbitrary function guards would
lead to adding bad features such as unrestricted pointer manipulation)
is a variant of the "slippery slope" fallacy:
<http://en.wikipedia.org/wiki/Slippery_slope>

No-one is suggesting adding unrestricted pointers. Unrestricted pointers
substantially change the semantic model of the language, creating the
possibility of undefined behaviour that can be manifested far away from
the construct that caused it. Function guards may have confusing effects
in some cases, but those effects occur immediately, and are equivalent
to similar code written using the 'case' construct. If guards are
specified to be evaluated as-if in order, then the behaviour is always
well-defined (and deterministic if the guard functions are). Please stick
to criticising the specific construct that is being proposed.

--
David Hopwood <david.nospam.hopwood@blueyonder.co.uk>


Post generated using Mail2Forum (http://m2f.sourceforge.net)
osxroolz at mymacmail.com
Posted: Sat Mar 12, 2005 11:51 am Reply with quote
Guest
> Your implied argument (that allowing arbitrary function guards would
> lead to adding bad features such as unrestricted pointer manipulation)
> is a variant of the "slippery slope" fallacy:
> <http://en.wikipedia.org/wiki/Slippery_slope>

You infer incorrectely.

The implication is that the arguments the original poster presented in
favour of his language change, i.e.

* that he can't think of any compelling reason to prohibit it
* that he feels that the restriction is a "strict harness" and is
therefore "misguided"

are insufficient since they can be used to argue in favour of just about
anything.

> Please stick to criticising the specific construct that is being proposed.

Even more talk? Like Elvis, I want action not talk.

Looking through the erlanguage mailing archive, much friday afternoon
talk about language change, but seldom backed by a proof-of-concept
implementation. Should not the burden be on the person proposing the
changes to put in some work and present evidence, rather than demanding
that others show reason why change is not worth implementing?

iMan
--

osxroolz@mymacmail.com


Post generated using Mail2Forum (http://m2f.sourceforge.net)
uffe
Posted: Sat Mar 12, 2005 1:13 pm Reply with quote
User Joined: 02 Mar 2005 Posts: 365 Location: Sweden
Den 2005-03-12 12:16:37 skrev <osxroolz@mymacmail.com>:

> Looking through the erlanguage mailing archive, much friday afternoon
> talk about language change, but seldom backed by a proof-of-concept
> implementation. Should not the burden be on the person proposing the
> changes to put in some work and present evidence, rather than demanding
> that others show reason why change is not worth implementing?

A nice example of this is Joe Armstrong's "bang-bang", i.e. the
!! notation for a synchronous process interaction.

Not only did he implement the language feature -- he wrote
a GUI framework with lots of example code using it.

Not that it was adopted anyway, but a nice example of
someone actually walking the talk it was. (:

/Uffe


Post generated using Mail2Forum (http://m2f.sourceforge.net)
View user's profile Send private message Visit poster's website
ok at cs.otago.ac.nz
Posted: Mon Mar 14, 2005 2:57 am Reply with quote
Guest
"Vlad Dumitrescu" <vlad_dumitrescu@hotmail.com> wrote:
Good point, I think. The language proper should not be
restricted by what are mostly implementation/optimization
issues. And extra power might open possibilities that now are closed.

What is allowed in guards is NEITHER an implementation NOR an optimisation
issue.

What's more, there are *NO* 'possibilities that are now closed'
with the single exception of the 'receive' construct.

Proof: the Haskell report shows how Haskell guards are nothing more than
syntactic sugar and provides explicit transformations which can be used
to eliminate guards entirely. This elimination does not introduce
order-of-magnitude changes in efficiency or expressiveness. Indeed,
many functional programming languages including ML and its relative
have no guards at all. (Nor do Lisp and Scheme, including Kali-Scheme,
a version of Scheme with some similarities to Erlang.)

Erlang was influenced by Prolog and concurrent logic programming languages.
There are technical reasons why committed choice concurrent LP languages
like Parlog, GHC, and FCP place strong constraints on what you can say in
a guard. In the absence of logical variables, not only guards but even
pattern matching are entirely dispensable.

In Haskell, the choice between using guards and using 'if' is entirely
stylistic. That is NOT a necessary truth about all functional programming
languages. In particular, for a language which is supposed to be useful for
soft real time programming, it is useful to know that certain constructions
MUST terminate and in bounded time.

I repeat my earlier observation that the real problem is not that guards
need to be more like expressions in Erlang but that they are already too
MUCH like expressions, and should be restricted further. For example,
length/1 should not be allowed in guards. All the uses of length/1 I've
seen in guards could either be replaced by body code using length/1 (with
an increase in clarity) OR by
<guard expression> length<relop> <constant>
where for example
X length>= 2
is true if X = [_,_|_]. This replacement would in some cases yield a
substantial increase in efficiency. Naturally, this construct would not\
be made available in expressions; guards and expressions *in Erlang*
should be distinct. (This is not a general truth about all functional
programming languages, any more than the converse is.)

I also repeat that abstract patterns give you a way to have user-defined
"predicates" for use in guards that don't break the basic rules, and are
entirely safe to use in 'receive'.


Post generated using Mail2Forum (http://m2f.sourceforge.net)
ok at cs.otago.ac.nz
Posted: Mon Mar 14, 2005 4:05 am Reply with quote
Guest
David Hopwood <david.nospam.hopwood@blueyonder.co.uk> claimed that
osxroolz@mymacmail.com's
... implied argument (that allowing arbitrary function guards would
lead to adding bad features such as unrestricted pointer manipulation)
is a variant of the "slippery slope" fallacy:
<http://en.wikipedia.org/wiki/Slippery_slope>

There are two replies to that.

The first is that while the slippery slope argument is not deductively
sound, it is *empirically* amazingly reliable. It so happens, for
example, that there have been proposals to add mutable data structures
to Erlang. Right now there is a proposal to add traditional assignment
statements to Prolog. I kid you not. Give people a taste of something
familiar and pretty soon they *do* want the whole thing. Not deductively
conclusive, but empirically pretty reliable.

The second is that that's *not* how the implied argument worked, or at
least not how I read it. The way I read it was "disproof by analogy",
that is, showing that an argument has an unsound form.

That is,
"if this FORM of argument is invalid when X='pointer manipulation'
then you can't rely on this form of argument when X='unrestricted guards'.,
The burden of substantive proof that the argument *is* sound in this
case rests with the proposer."
In short, not a slippery slope argument at all.

No-one is suggesting adding unrestricted pointers.

I *will* make a slippery slope argument here, but it's an inductive
generalisation. Time after time after time, I have seen a demand that
this or that programming language be extended to allow C pointers to
be passed around. I have no proof that it _must_ happen, only the
observation that it _does_ happen. (See manual(i-3-9) and
manual(i-3-15-5) in Quintus Prolog 3.4 for a fairly benign version.
For a rather less benign example, see the "structs" package in Quintus
Prolog 3.4, manual(k-10), manual(g-8-3-2), manual(l-3-22), which basically
gives you C-in-Prolog. I could provide similar examples for other languages.)

Given that Erlang is not a lazy language like Haskell or Clean,
it is far from clear to me that there is any advantage in adopting
an aspect of their syntax.


Post generated using Mail2Forum (http://m2f.sourceforge.net)
james.hague at gmail.com
Posted: Wed Mar 16, 2005 3:05 am Reply with quote
Guest
On Sat, 12 Mar 2005 03:16:37 -0800, osxroolz@mymacmail.com wrote:
>
> Even more talk? Like Elvis, I want action not talk.
>
> Looking through the erlanguage mailing archive, much friday afternoon
> talk about language change, but seldom backed by a proof-of-concept
> implementation. Should not the burden be on the person proposing the
> changes to put in some work and present evidence, rather than demanding
> that others show reason why change is not worth implementing?

The reason here is simple. Erlang is a complex beast. I have
submitted (and had accepted) small changes to the Erlang system. But
changes to core language can be far from trivial. If it can be done
as a parse transform or a straighforward compiler-level change, then
that's one thing. But anything that requires a change to the BEAM
emulator or a new BIF or whatnot, that's a big undertaking unless the
person already understands the innards of the compiler and runtime.
It's not like there's lots of documentation about the GC interactions
of various functions in the emulator, for example.

Note: I'm not the person who suggested this change :)

James


Post generated using Mail2Forum (http://m2f.sourceforge.net)

Display posts from previous:  

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

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum