caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* evaluation order
@ 2009-06-14 16:36 Christophe Raffalli
  2009-06-14 17:45 ` Rémi Vanicat
  2009-06-14 19:40 ` [Caml-list] " Jon Harrop
  0 siblings, 2 replies; 35+ messages in thread
From: Christophe Raffalli @ 2009-06-14 16:36 UTC (permalink / raw)
  To: OCaml


Hello,

In OCaml-3.11.1 (I did not try other version),
the following code print 0 when compiled in bytecode and 1 in nativecode
for obvious reason of different evaluation order in the pair ...


let ptr = ref 0
let fn b =
  if b then incr ptr else decr ptr
let c = fn true, !ptr
let _ = print_int (snd c); print_newline ()

Is any difference between ocamlc and ocamlopt a bug ?

Cheers,
Christophe



^ permalink raw reply	[flat|nested] 35+ messages in thread
* RE: [Caml-list] Evaluation Order
@ 2001-06-15 17:00 Manuel Fahndrich
  0 siblings, 0 replies; 35+ messages in thread
From: Manuel Fahndrich @ 2001-06-15 17:00 UTC (permalink / raw)
  To: caml-list


I feel your pain, having run into this problem before. What we need is a
way for the compiler to alert the programmer in contexts where
evaluation order is unspecified, but where the programmer relies on some
order.

The only way I can imagine doing this is if the language contains a
notion of side effecting evaluation. If such a concept is present, then
in any context where evaluation order is undefined, all involved
expressions must be side effect free, which guarantees that the code
will evaluate in the same way no matter what order the actual
implementation chooses.

Of course, the side effect annotations can become burdensome. Also, one
pretty quickly wants to distinguish certain side effects from others.
Evaluation order independence can be guaranteed if the side effects of
two expressions don't interfere. 

In a language with regions (such as Tofte and Talpin) we can obtain some
of this directly:

If we have e1 + e2, and the effects of e1 are E1 and effects of e2 are
E2, then we merely have to check that the intersection of E1 and E2 is
empty. That sounds simple, but it is not, because of possible region
aliasing.

Yet another way to look at it is in terms of heap splitting. If in order
to evaluate e1 + e2, we can split the heap M into disjoint parts M1 + M2
and evaluate e1 under M1 and e2 under M2, then we know they can't
interfere. This is the notion studied in Reynold's syntactic control of
interference, and also in the logic of bunched implications, and in the
capability calculus.

(shameless plug)
In VAULT (http://research.microsoft.com/vault) we have a notion of
non-aliasing for regions, thus there are situations where we can decide
the above non-interference.

-Maf


-----Original Message-----
From: David McClain [mailto:dmcclain1@mindspring.com] 
Sent: Saturday, June 09, 2001 9:00 AM
To: caml-list@inria.fr
Subject: [Caml-list] Evaluation Order

I thought I would share an experience with all of you to solicit your
*constructive* comments.

I just rewrote my block convolution routine in pure OCaml native
compiled
along with the inner loop in C/C++. This is necessarily a side effecting
program since it must alter the outside world of data. I had a statement
in
OCaml that went something like this:

    let ans = fnx () + fny ()

where both fnx and fny are side effecting closures.

I consider myself a very experienced OCaml programmer, and I am so
accustomed to getting pristine results from OCaml, that I spent many
hours
going through my C/C++ code looking for the error. I was getting
anomalous
output values at the front of my convolution records, but everything
else
worked just fine. I was convinced something was awry with my C code ---
whenever a problem occurs that's almost always where it is -- never in
the
OCaml code.

I had forgotten about the evaluation ordering in OCaml being from right
to
left. I am aware of the reasons for this, having studied the Zinc paper
some
time ago. But the tendency to read implicit temporal ordering of
operations
as left to right is a very strong psychological factor here. The
problem,
once tracked down, was easily fixed by restating the routine as

    let ans = fnx() in
        ans + fny()

to force evaluation of fnx before fny.

I suppose if Hebrew or Arabic were my native tongue then the opposite
expectation would be true and I would have naturally written

    let ans = fny() + fnx()

and I would be no wiser about evaluation order here, since everything
would
have worked properly.

I don't have a good answer to this problem, but I did want to point out
the
one and only place where OCaml forced me to spend hours debugging a
problem
caused solely by a clash of psychology and OCaml semantics. All of my
other
debugging activities have, and will probably continue, to focus on C/C++
as
the likely culprit.

This problem will be permanently etched into my mind from now on, and I
will
be sure to remember to avoid order dependent syntax.

The same problem occurs regularly in C, and I have become quite
accustomed
and adept at avoiding these ordering problems. Good examples are to be
found
among C preprocessor macrology. I just now have to remember that the
same is
true of OCaml.

I had been lulled into a belief that OCaml was nearly perfect, while
C/C++
is definitely not. The problem is not one of OCaml, but rather a clash
between normal psychological expectations and the programming language
at
hand.

Since embedded realtime systems are chock full of temporally ordered
operations this must be one of the severe weak points in software
control
systems. There must be a better way to guide human thinking here. Just
as
OCaml has provided a system to look over our shoulders and force us to
write
the correct things, there must be a way of doing something similar for
temporally dependent clauses.

Any thoughts? (other than that I was boneheaded here!)

- DM


-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ:
http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives:
http://caml.inria.fr
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 35+ messages in thread
* Re: [Caml-list] Evaluation Order
@ 2001-06-10 17:59 Damien Doligez
  2001-06-10 18:28 ` Dave Mason
  0 siblings, 1 reply; 35+ messages in thread
From: Damien Doligez @ 2001-06-10 17:59 UTC (permalink / raw)
  To: caml-list

>From: Brian Rogoff <bpr@best.com>

>No, this is a language problem. Lots of people who teach OCaml have mentioned 
>that this is an issue. If the clash with expectation is so great then that
>You should always be careful about sequencing in imperative style programming, 
>but IMO this is one of those few things that SML does right that OCaml does 
>not. As you say, there is a very strong expectation that events occur in
>the order that we read them. The original arguments about optimizations
>and parallelism don't seem to have borne fruit, so it would be good to fix
>this.

The original argument about optimizations is still as valid as it ever
was.  The real problem is that there is a conflict between
left-to-right evaluation order and currying.  Consider the expression:

   f e1 e2 e3

It only looks like the application of f to 3 arguments.  In reality,
it is a nested expression with three function applications.  If you
want to evaluate it in left-to-right order, you have to do the
following:

1. evaluate f
2. evaluate e1
3. evaluate f (e1)   (call the result f1)
4. evaluate e2
5. evaluate f1 (e2)  (call the result f2)
6. evaluate e3
7. evaluate f2 (e3)

If you want to optimize this to get something as efficient as O'Caml
currently is, you have to know that f doesn't do any side-effect
before receiving all its arguments, which is generally impossible.
With right-to-left, the compiler doesn't have to know anything about f.

For years I thought that the only solution to this problem would be to
move away from currying by changing the preferred programming style to
passing tuples or records (as SML does).  But people at INRIA are
overly fond of currying for some reason.

Now I think there's another solution.  Let's just have different
semantics for  (f e1 e2 e3)  and  ((f e1) e2 e3) :

f e1 e2 e3 should evaluate f, then e1, then e2, then e3, then do a
ternary application.

(f e1) e2 e3 should evaluate f, then e1, then do a unary application,
then evaluate e2, then e3, then do a binary application.


I think this solution should work, and retain all the efficiency of
O'Caml.  The question is, how much does it interfere with labels and
optional arguments ?

-- Damien
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 35+ messages in thread
* [Caml-list] Evaluation Order
@ 2001-06-10  2:44 David McClain
  2001-06-10  2:48 ` Patrick M Doane
  0 siblings, 1 reply; 35+ messages in thread
From: David McClain @ 2001-06-10  2:44 UTC (permalink / raw)
  To: caml-list

Earlier, I stated that there were no reference vars in the program. That's
strictly true only of the OCaml portion of the code. However, the C/C++ core
does maintain a mutable state and that is the reason for evaluation order
dependencies.

It would seem that the compiler could automatically spot side effecting
functions and propagate that attribute by noticing when reference vars are
modified, when arrays and structures are mutated, etc. Hence explicit
declaration should be unnecessary -- except! for those declared "external"
routines that have side effects. Those need to be flagged explicitly to the
compiler.

- DM


-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 35+ messages in thread
* [Caml-list] Evaluation Order
@ 2001-06-09 15:59 David McClain
  2001-06-09 20:17 ` Brian Rogoff
  2001-06-09 23:19 ` John Max Skaller
  0 siblings, 2 replies; 35+ messages in thread
From: David McClain @ 2001-06-09 15:59 UTC (permalink / raw)
  To: caml-list

I thought I would share an experience with all of you to solicit your
*constructive* comments.

I just rewrote my block convolution routine in pure OCaml native compiled
along with the inner loop in C/C++. This is necessarily a side effecting
program since it must alter the outside world of data. I had a statement in
OCaml that went something like this:

    let ans = fnx () + fny ()

where both fnx and fny are side effecting closures.

I consider myself a very experienced OCaml programmer, and I am so
accustomed to getting pristine results from OCaml, that I spent many hours
going through my C/C++ code looking for the error. I was getting anomalous
output values at the front of my convolution records, but everything else
worked just fine. I was convinced something was awry with my C code ---
whenever a problem occurs that's almost always where it is -- never in the
OCaml code.

I had forgotten about the evaluation ordering in OCaml being from right to
left. I am aware of the reasons for this, having studied the Zinc paper some
time ago. But the tendency to read implicit temporal ordering of operations
as left to right is a very strong psychological factor here. The problem,
once tracked down, was easily fixed by restating the routine as

    let ans = fnx() in
        ans + fny()

to force evaluation of fnx before fny.

I suppose if Hebrew or Arabic were my native tongue then the opposite
expectation would be true and I would have naturally written

    let ans = fny() + fnx()

and I would be no wiser about evaluation order here, since everything would
have worked properly.

I don't have a good answer to this problem, but I did want to point out the
one and only place where OCaml forced me to spend hours debugging a problem
caused solely by a clash of psychology and OCaml semantics. All of my other
debugging activities have, and will probably continue, to focus on C/C++ as
the likely culprit.

This problem will be permanently etched into my mind from now on, and I will
be sure to remember to avoid order dependent syntax.

The same problem occurs regularly in C, and I have become quite accustomed
and adept at avoiding these ordering problems. Good examples are to be found
among C preprocessor macrology. I just now have to remember that the same is
true of OCaml.

I had been lulled into a belief that OCaml was nearly perfect, while C/C++
is definitely not. The problem is not one of OCaml, but rather a clash
between normal psychological expectations and the programming language at
hand.

Since embedded realtime systems are chock full of temporally ordered
operations this must be one of the severe weak points in software control
systems. There must be a better way to guide human thinking here. Just as
OCaml has provided a system to look over our shoulders and force us to write
the correct things, there must be a way of doing something similar for
temporally dependent clauses.

Any thoughts? (other than that I was boneheaded here!)

- DM


-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2009-06-14 21:08 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-14 16:36 evaluation order Christophe Raffalli
2009-06-14 17:45 ` Rémi Vanicat
2009-06-14 19:40 ` [Caml-list] " Jon Harrop
2009-06-14 21:12   ` Christophe Raffalli
  -- strict thread matches above, loose matches on Subject: below --
2001-06-15 17:00 [Caml-list] Evaluation Order Manuel Fahndrich
2001-06-10 17:59 Damien Doligez
2001-06-10 18:28 ` Dave Mason
2001-06-10  2:44 David McClain
2001-06-10  2:48 ` Patrick M Doane
2001-06-10  5:51   ` David McClain
2001-06-09 15:59 David McClain
2001-06-09 20:17 ` Brian Rogoff
2001-06-09 23:12   ` David McClain
2001-06-09 23:28     ` David McClain
2001-06-10  1:04       ` Dave Mason
2001-06-10  2:25         ` David McClain
2001-06-11 13:03           ` Dave Mason
2001-06-12 17:55             ` John Max Skaller
2001-06-13 16:54               ` Frederick Smith
2001-06-13 21:43                 ` John Max Skaller
2001-06-10  1:06       ` Charles Martin
2001-06-10  2:27         ` David McClain
2001-06-10 11:18         ` Tore Lund
2001-06-10 13:11           ` Tore Lund
2001-06-10 14:31           ` John Max Skaller
2001-06-12 15:12             ` Pierre Weis
2001-06-10 10:40       ` Joerg Czeranski
2001-06-10 14:06       ` John Max Skaller
2001-06-11 12:59         ` Dave Mason
2001-06-12 17:34           ` John Max Skaller
2001-06-10 13:47   ` John Max Skaller
2001-06-10 16:47     ` Brian Rogoff
2001-06-10 17:27       ` Dave Mason
2001-06-12 16:10       ` John Max Skaller
2001-06-09 23:19 ` John Max Skaller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).