Ocaml Beginners is a Restricted Group with 1213 members.
 Ocaml Beginners

 Restricted Group,
 1213 members
Execution semantics
Expand Messages
 Where can I find a clear description of how OCaml executes code. In
particular, I want to understand when functions with several values are
evaluated  is the evaluation progressive (during Currying) or is
evaluation delayed until all arguments are present.
For example, are the following equivalent, always?
let example1 a b x =
let a' = f1 a in
let b' = f2 b in
f3 a' b' x
let example2 a b =
let a' = f1 a in
let b' = f2 b in
fun x > f3 a' b' x
let example3 x a b =
let a' = f1 a in
let b' = f2 b in
f3 a' b' x
Thanks,
Andrew

` __ _ __ ___ ___ _____ work web site: http://www.ctio.noao.edu/~andrew
/ _` / _/ _ \/ _ \ / / _) personal web site: http://www.acooke.org/andrew
\__,_\__\___/\___/_\_\___ list: http://www.acooke.org/andrew/compute.html  On Nov 3, 2004, at 11:03 AM, andrew cooke wrote:
> Where can I find a clear description of how OCaml executes code. In
No, for example
> particular, I want to understand when functions with several values are
> evaluated  is the evaluation progressive (during Currying) or is
> evaluation delayed until all arguments are present.
>
> For example, are the following equivalent, always?
>
> let example1 a b x =
> let a' = f1 a in
> let b' = f2 b in
> f3 a' b' x
>
> let example2 a b =
> let a' = f1 a in
> let b' = f2 b in
> fun x > f3 a' b' x
>
> let example3 x a b =
> let a' = f1 a in
> let b' = f2 b in
> f3 a' b' x
# let f1 x = x;;
val f1 : 'a > 'a = <fun>
# let f2 x = x;;
val f2 : int > int = <fun>
# let example1 a b x =
let a' = f1 a in
let b' = f2 b in
f3 a' b' x;;
val example1 : 'a > int > 'b > 'a * int * 'b = <fun>
# let example2 a b =
let a' = f1 a in
let b' = f 2 b in
fun x > f3 a' b' x ;;
val example2 : 'a > int > 'b > 'a * int * 'b = <fun>
# let example3 x a b =
let a' = f1 a in
let b' = f2 b in
f3 a' b' x;;
val example3 : 'a > 'b > int > 'b * int * 'a = <fun>
# example1 1 2 3;;
 : int * int * int = (1, 2, 3)
# example2 1 2 3;;
 : int * int * int = (1, 2, 3)
# example3 1 2 3;;
 : int * int * int = (2, 3, 1)

Issac Trotts
Programmer, NIMH Human Brain Project
University of California, Davis
http://mallorn.ucdavis.edu/conexus  On Wed, 3 Nov 2004 16:03:20 0300 (CLST), andrew cooke
<andrew@...> wrote:>
These two are equivalent. I have a question, however, for the list.
> Where can I find a clear description of how OCaml executes code. In
> particular, I want to understand when functions with several values are
> evaluated  is the evaluation progressive (during Currying) or is
> evaluation delayed until all arguments are present.
>
> For example, are the following equivalent, always?
>
> let example1 a b x =
> let a' = f1 a in
> let b' = f2 b in
> f3 a' b' x
>
> let example2 a b =
> let a' = f1 a in
> let b' = f2 b in
> fun x > f3 a' b' x
Why does example2, when so explicitly curried as such, have a '_a when
curried?
# let a = example2 1 2;;
val a : '_a > int * int * '_a = <fun>
I know why example1 does this, I woul dhave thought example2 would not have.
> let example3 x a b =
The order you pass the arguments in matters in OCaml, since the
> let a' = f1 a in
> let b' = f2 b in
> f3 a' b' x
invoker has no names.
example3 1 2 3
binds 1 to x, 2 to a, and 3 to b.
example1 1 2 3
binds 1 to a, 2 to b, and 3 to x.
> Thanks,

> Andrew
>
> 
> ` __ _ __ ___ ___ _____ work web site:
> http://www.ctio.noao.edu/~andrew
> / _` / _/ _ \/ _ \ / / _) personal web site: http://www.acooke.org/andrew
> \__,_\__\___/\___/_\_\___ list: http://www.acooke.org/andrew/compute.html
>
>
>
> Archives up to September 30, 2004 are also downloadable at
> http://www.connettivo.net/cntprojects/ocaml_beginners/
> The archives of the very official ocaml list (the seniors' one) can be
> found at http://caml.inria.fr
> Attachments are banned and you're asked to be polite, avoid flames etc.
>
>
>
> Yahoo! Groups Sponsor
>
> ADVERTISEMENT
>
>
> ________________________________
> Yahoo! Groups Links
>
> To visit your group on the web, go to:
> http://groups.yahoo.com/group/ocaml_beginners/
>
> To unsubscribe from this group, send an email to:
> ocaml_beginnersunsubscribe@yahoogroups.com
>
> Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
Seth Fogarty sfogarty@[gmail.comrice.edulivejournal]
Neepneep at large AIM: Sorrath
"I know there are people in this world who do not love their fellow
human beings  and I hate people like that" Tom Lehrer.  Thanks for the reply.
Just to get this straight, because i think I wasn't anything like clear
enough (I was not talking about function signatures, but about when
evaluation occurs), are you saying that for the first two examples:
let f = exampleN 1 2 in
...
let g = f 3
most of the work (ie evaluating f1 and f2) *in both cases* is done before
the dots? So, for example, if "let g = ..." was in a loop, only the
minimum of work would be repeated.
And for example3, where I was clearly way too brief (sorry), I was
assuming that the answer to the above was "yes" and then considering
let f = fun (x > example3 x 1 2) in
...
let g = f 3
Again, if g was evaluated in a loop, would that be as efficient as
examples 1 and 2?
I hope that's a little clearer.
Thanks,
Andrew
Seth J. Fogarty said:>

> On Wed, 3 Nov 2004 16:03:20 0300 (CLST), andrew cooke
> <andrew@...> wrote:
>>
>> Where can I find a clear description of how OCaml executes code. In
>> particular, I want to understand when functions with several values are
>> evaluated  is the evaluation progressive (during Currying) or is
>> evaluation delayed until all arguments are present.
>>
>> For example, are the following equivalent, always?
>>
>> let example1 a b x =
>> let a' = f1 a in
>> let b' = f2 b in
>> f3 a' b' x
>>
>> let example2 a b =
>> let a' = f1 a in
>> let b' = f2 b in
>> fun x > f3 a' b' x
>
> These two are equivalent. I have a question, however, for the list.
> Why does example2, when so explicitly curried as such, have a '_a when
> curried?
>
>
> # let a = example2 1 2;;
> val a : '_a > int * int * '_a = <fun>
>
> I know why example1 does this, I woul dhave thought example2 would not
> have.
>
>> let example3 x a b =
>> let a' = f1 a in
>> let b' = f2 b in
>> f3 a' b' x
>
> The order you pass the arguments in matters in OCaml, since the
> invoker has no names.
>
> example3 1 2 3
> binds 1 to x, 2 to a, and 3 to b.
> example1 1 2 3
> binds 1 to a, 2 to b, and 3 to x.
>
>> Thanks,
>> Andrew
>>
>> 
>> ` __ _ __ ___ ___ _____ work web site:
>> http://www.ctio.noao.edu/~andrew
>> / _` / _/ _ \/ _ \ / / _) personal web site:
>> http://www.acooke.org/andrew
>> \__,_\__\___/\___/_\_\___ list:
>> http://www.acooke.org/andrew/compute.html
>>
>>
>>
>> Archives up to September 30, 2004 are also downloadable at
>> http://www.connettivo.net/cntprojects/ocaml_beginners/
>> The archives of the very official ocaml list (the seniors' one) can be
>> found at http://caml.inria.fr
>> Attachments are banned and you're asked to be polite, avoid flames etc.
>>
>>
>>
>> Yahoo! Groups Sponsor
>>
>> ADVERTISEMENT
>>
>>
>> ________________________________
>> Yahoo! Groups Links
>>
>> To visit your group on the web, go to:
>> http://groups.yahoo.com/group/ocaml_beginners/
>>
>> To unsubscribe from this group, send an email to:
>> ocaml_beginnersunsubscribe@yahoogroups.com
>>
>> Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
>
>
> 
> Seth Fogarty sfogarty@[gmail.comrice.edulivejournal]
> Neepneep at large AIM: Sorrath
> "I know there are people in this world who do not love their fellow
> human beings  and I hate people like that" Tom Lehrer.
>
>
>
> Archives up to September 30, 2004 are also downloadable at
> http://www.connettivo.net/cntprojects/ocaml_beginners/
> The archives of the very official ocaml list (the seniors' one) can be
> found at http://caml.inria.fr
> Attachments are banned and you're asked to be polite, avoid flames etc.
> Yahoo! Groups Links
>
>
>
>
>
>
>
>
` __ _ __ ___ ___ _____ work web site: http://www.ctio.noao.edu/~andrew
/ _` / _/ _ \/ _ \ / / _) personal web site: http://www.acooke.org/andrew
\__,_\__\___/\___/_\_\___ list: http://www.acooke.org/andrew/compute.html  On Wed, 3 Nov 2004 21:54:11 0300 (CLST), andrew cooke
<andrew@...> wrote:>
let example1 a b x =
> Thanks for the reply.
>
> Just to get this straight, because i think I wasn't anything like clear
> enough (I was not talking about function signatures, but about when
> evaluation occurs), are you saying that for the first two examples:
>
> let f = exampleN 1 2 in
> ...
> let g = f 3
let a' = f1 a in
let b' = f2 b in
f3 a' b' x
let example2 a b =
let a' = f1 a in
let b' = f2 b in
fun x > f3 a' b' x
I am not certain of the exactly optimizations used for each of these.
Technically, yes, the first repeats the work and the second doesn't. I
would not be surprised the least if the OCaml compiler optimises them
to the same thing. It has done worse voodoo before.
> And for example3, where I was clearly way too brief (sorry), I was
Baring acts of optimization, no, that would be the least efficient, as
> assuming that the answer to the above was "yes" and then considering
>
> let f = fun (x > example3 x 1 2) in
> ...
> let g = f 3
>
> Again, if g was evaluated in a loop, would that be as efficient as
> examples 1 and 2?
it has another closure, but it would preserve maximum polymorphism
(i.e. if the type of x varied across the loop). Orderwise, same
running time as example1.

Seth Fogarty sfogarty@[gmail.comrice.edulivejournal]
Neepneep at large AIM: Sorrath
"I know there are people in this world who do not love their fellow
human beings  and I hate people like that" Tom Lehrer.  On Wed, 3 Nov 2004, Seth J. Fogarty wrote:
>
You guys can play with the hidden counter example. The problem is:
> On Wed, 3 Nov 2004 21:54:11 0300 (CLST), andrew cooke
> <andrew@...> wrote:
> >
> > Thanks for the reply.
> >
> > Just to get this straight, because i think I wasn't anything like clear
> > enough (I was not talking about function signatures, but about when
> > evaluation occurs), are you saying that for the first two examples:
> >
> > let f = exampleN 1 2 in
> > ...
> > let g = f 3
>
> let example1 a b x =
> let a' = f1 a in
> let b' = f2 b in
> f3 a' b' x
>
> let example2 a b =
> let a' = f1 a in
> let b' = f2 b in
> fun x > f3 a' b' x
>
> I am not certain of the exactly optimizations used for each of these.
> Technically, yes, the first repeats the work and the second doesn't. I
> would not be surprised the least if the OCaml compiler optimises them
> to the same thing. It has done worse voodoo before.
create a function that takes as argument the first value of a
counter that should be created internally and returns two functions:
 one that gives the current value of the counter
 one that increments the counter
This function should therefore have the following signature:
val make_counter : int > (unit > int) * (unit > unit)
You should then be able to write something like:
let (get, step) = make_counter 1
Have fun!
Martin  Thanks! (I hadn't even thought about how you might preserve polymorphism
within the loop).
Andrew
Seth J. Fogarty said:>

> On Wed, 3 Nov 2004 21:54:11 0300 (CLST), andrew cooke
> <andrew@...> wrote:
>>
>> Thanks for the reply.
>>
>> Just to get this straight, because i think I wasn't anything like clear
>> enough (I was not talking about function signatures, but about when
>> evaluation occurs), are you saying that for the first two examples:
>>
>> let f = exampleN 1 2 in
>> ...
>> let g = f 3
>
> let example1 a b x =
> let a' = f1 a in
> let b' = f2 b in
> f3 a' b' x
>
> let example2 a b =
> let a' = f1 a in
> let b' = f2 b in
> fun x > f3 a' b' x
>
> I am not certain of the exactly optimizations used for each of these.
> Technically, yes, the first repeats the work and the second doesn't. I
> would not be surprised the least if the OCaml compiler optimises them
> to the same thing. It has done worse voodoo before.
>
>> And for example3, where I was clearly way too brief (sorry), I was
>> assuming that the answer to the above was "yes" and then considering
>>
>> let f = fun (x > example3 x 1 2) in
>> ...
>> let g = f 3
>>
>> Again, if g was evaluated in a loop, would that be as efficient as
>> examples 1 and 2?
>
> Baring acts of optimization, no, that would be the least efficient, as
> it has another closure, but it would preserve maximum polymorphism
> (i.e. if the type of x varied across the loop). Orderwise, same
> running time as example1.
>
> 
> Seth Fogarty sfogarty@[gmail.comrice.edulivejournal]
> Neepneep at large AIM: Sorrath
> "I know there are people in this world who do not love their fellow
> human beings  and I hate people like that" Tom Lehrer.
>
>
>
> Archives up to September 30, 2004 are also downloadable at
> http://www.connettivo.net/cntprojects/ocaml_beginners/
> The archives of the very official ocaml list (the seniors' one) can be
> found at http://caml.inria.fr
> Attachments are banned and you're asked to be polite, avoid flames etc.
> Yahoo! Groups Links
>
>
>
>
>
>
>
>
` __ _ __ ___ ___ _____ work web site: http://www.ctio.noao.edu/~andrew
/ _` / _/ _ \/ _ \ / / _) personal web site: http://www.acooke.org/andrew
\__,_\__\___/\___/_\_\___ list: http://www.acooke.org/andrew/compute.html  That seems easy to do with a reference, but how does it shed light on the
relative optimisations for examples 1 and 2? Are you saying that the
optimisations used depend on whether there are mutable values (which I'm
sure is true)? Or that OCaml only does optimisations that are safe in the
presence of mutable values (which seems pretty limiting for a functional
language)?
Andrew
Martin Jambon said:>

> On Wed, 3 Nov 2004, Seth J. Fogarty wrote:
>
>>
>> On Wed, 3 Nov 2004 21:54:11 0300 (CLST), andrew cooke
>> <andrew@...> wrote:
>> >
>> > Thanks for the reply.
>> >
>> > Just to get this straight, because i think I wasn't anything like
>> clear
>> > enough (I was not talking about function signatures, but about when
>> > evaluation occurs), are you saying that for the first two examples:
>> >
>> > let f = exampleN 1 2 in
>> > ...
>> > let g = f 3
>>
>> let example1 a b x =
>> let a' = f1 a in
>> let b' = f2 b in
>> f3 a' b' x
>>
>> let example2 a b =
>> let a' = f1 a in
>> let b' = f2 b in
>> fun x > f3 a' b' x
>>
>> I am not certain of the exactly optimizations used for each of these.
>> Technically, yes, the first repeats the work and the second doesn't. I
>> would not be surprised the least if the OCaml compiler optimises them
>> to the same thing. It has done worse voodoo before.
>
> You guys can play with the hidden counter example. The problem is:
> create a function that takes as argument the first value of a
> counter that should be created internally and returns two functions:
>  one that gives the current value of the counter
>  one that increments the counter
>
> This function should therefore have the following signature:
>
> val make_counter : int > (unit > int) * (unit > unit)
>
> You should then be able to write something like:
>
> let (get, step) = make_counter 1
>
>
> Have fun!
>
> Martin
>
>
>
>
>
> Archives up to September 30, 2004 are also downloadable at
> http://www.connettivo.net/cntprojects/ocaml_beginners/
> The archives of the very official ocaml list (the seniors' one) can be
> found at http://caml.inria.fr
> Attachments are banned and you're asked to be polite, avoid flames etc.
> Yahoo! Groups Links
>
>
>
>
>
>
>
>
` __ _ __ ___ ___ _____ work web site: http://www.ctio.noao.edu/~andrew
/ _` / _/ _ \/ _ \ / / _) personal web site: http://www.acooke.org/andrew
\__,_\__\___/\___/_\_\___ list: http://www.acooke.org/andrew/compute.html  On Thu, 4 Nov 2004, andrew cooke wrote:
> That seems easy to do with a reference, but how does it shed light on the
Yes. OCaml is not a pure functional language. It is possible to make a
> relative optimisations for examples 1 and 2? Are you saying that the
> optimisations used depend on whether there are mutable values (which I'm
> sure is true)?
> Or that OCaml only does optimisations that are safe in the
> presence of mutable values (which seems pretty limiting for a functional
> language)?
program compute things in a specified order without difficulties.
And the compiler generally doesn't know which functions perform side
effects.
You can write:
for i = 1 to 100_000_000 do
ignore (1 + 1)
done
This will perform 100 million times the same addition.
These examples have a different semantics:
>> let example1 a b x =
example1 a b just creates an object that is a function that will accept
>> let a' = f1 a in
>> let b' = f2 b in
>> f3 a' b' x
one argument (x) and compute everything after the equal
sign (=)
example1 a b x computes everything after the equal sign
>> let example2 a b =
example2 a b computes everything after the equal sign:
>> let a' = f1 a in
>> let b' = f2 b in
>> fun x > f3 a' b' x
 f1 a
 f2 b
 builds the function which is returned as a result
example2 a b x is strictly equivalent to
(example2 a b) x which computes the following:
 f1 a
 f2 b
 applies (fun x > f3 a' b') to x which may not
involve the creation of a specific object
representing the temporary function because it is
applied immediately (that's a possible optimisation)
Note that example1 can be rewritten as:
let example1' a b =
fun x >
let a' = f1 a in
let b' = f2 b in
f3 a' b' x
example1' a b like before, computes everything after the equal sign,
which only consists in building a function that may even
not exist as a physical object (e.g. if it is applied
immediately).
The following is the example of the counter. It is essential to be sure
when a new counter is created and when not:
[droopy] ~ % ledit ocaml
Objective Caml version 3.08.1
# let make_counter init =
let counter = ref init in
((fun () > !counter), (fun () > incr counter));;
val make_counter : int > (unit > int) * (unit > unit) = <fun>
# let (get1, step1) = make_counter 1;;
val get1 : unit > int = <fun>
val step1 : unit > unit = <fun>
# let (get2, step2) = make_counter 1;;
val get2 : unit > int = <fun>
val step2 : unit > unit = <fun>
# get1 ();;
 : int = 1
# get2 ();;
 : int = 1
# step1 ();;
 : unit = ()
# get1 ();;
 : int = 2
# get2 ();;
 : int = 1
In practice, this kind of things can be useful if a datastructure has to
be initialized, e.g.:
let is_in l =
let tbl = Hashtbl.create (List.length l) in
List.iter (fun aa > Hashtbl.add tbl aa ()) l;
Hashtbl.mem tbl
let is_in_abc = is_in ['a'; 'b'; 'c']
let is_in_123 = is_in [1; 2; 3; 12; 23; 31; 123; 231; 312]
Martin  RE: counter example.
That was easy enough. Still not sure why
# let f1 x = x;;
val f1 : 'a > 'a = <fun>
# let f2 x = x;;
val f2 : 'a > 'a = <fun>
# let f3 a b c = (a,b,c);;
val f3 : 'a > 'b > 'c > 'a * 'b * 'c = <fun>
# let example2 a b =
let a' = f1 a
and b' = f2 b
in (fun x > f3 a' b' x);;
val example2 : 'a > 'b > 'c > 'a * 'b * 'c = <fun>
# let f = example2 1 2;;
val f : '_a > int * int * '_a = <fun>
results in f not being fully polymorphic, but
val example1 : 'a > 'b > 'c > 'a * 'b * 'c = <fun>
let f = fun x > example1 1 2 x;;
val f : 'a > int * int * 'a = <fun>
Does. It seems to me that I should be able to return a (fun x >
blah), and have it be as polymorphic as possible. (not should in the
'right thing' sense, but should in the 'actual way it works' sense,
based on my very poor knowledge of ocaml types and '_a).

Seth Fogarty sfogarty@[gmail.comrice.edulivejournal]
Neepneep at large AIM: Sorrath
"I know there are people in this world who do not love their fellow
human beings  and I hate people like that" Tom Lehrer.  On Thu, 4 Nov 2004, Seth J. Fogarty wrote:
> RE: counter example.
I don't know why it is like this (but I don't want to know :)
> That was easy enough. Still not sure why
>
> # let f1 x = x;;
> val f1 : 'a > 'a = <fun>
> # let f2 x = x;;
> val f2 : 'a > 'a = <fun>
> # let f3 a b c = (a,b,c);;
> val f3 : 'a > 'b > 'c > 'a * 'b * 'c = <fun>
> # let example2 a b =
> let a' = f1 a
> and b' = f2 b
> in (fun x > f3 a' b' x);;
> val example2 : 'a > 'b > 'c > 'a * 'b * 'c = <fun>
> # let f = example2 1 2;;
> val f : '_a > int * int * '_a = <fun>
>
> results in f not being fully polymorphic, but
> val example1 : 'a > 'b > 'c > 'a * 'b * 'c = <fun>
> let f = fun x > example1 1 2 x;;
> val f : 'a > int * int * 'a = <fun>
>
> Does. It seems to me that I should be able to return a (fun x >
> blah), and have it be as polymorphic as possible. (not should in the
> 'right thing' sense, but should in the 'actual way it works' sense,
> based on my very poor knowledge of ocaml types and '_a).
There are a few paragraphs about this topic in the FAQ if you did not read
it yet:
http://caml.inria.fr/FAQ/FAQ_EXPERTeng.html#variables_de_types_faibles
Martin > results in f not being fully polymorphic, but
The monomorphic types '_a and others are needed in order to ensure type
> val example1 : 'a > 'b > 'c > 'a * 'b * 'c = <fun>
> let f = fun x > example1 1 2 x;;
> val f : 'a > int * int * 'a = <fun>
>
> Does. It seems to me that I should be able to return a (fun x >
> blah), and have it be as polymorphic as possible. (not should in the
> 'right thing' sense, but should in the 'actual way it works' sense,
> based on my very poor knowledge of ocaml types and '_a).
safety.
for example :
let id x = x
let f = ref id
> f will be '_a > '_a ref
if it's type was 'a > 'a , that means we can put any unifiable function
into the reference f and call it later with another type :
f := (fun x > x + 1) // would unify since int > int is unifiable with
'a > 'a
!f "hello" // would works since !f would still be 'a > 'a, causing a typing
error since we're actually executing above function
So it's needed to introduce monomorphic variables, they are really
"temporary" polymorphic variables until they're unified. And this limitation
is only required for values " let x = " since polymorphic functions does
not cause any problem.
Nicolas Cannasse I had seen those, yes. Still don't really undersand it. Are the pages
translated?
On Thu, 4 Nov 2004 18:28:21 0800 (PST), Martin Jambon
<martin_jambon@...> wrote:> On Thu, 4 Nov 2004, Seth J. Fogarty wrote:

>
>
>
> > RE: counter example.
> > That was easy enough. Still not sure why
> >
> > # let f1 x = x;;
> > val f1 : 'a > 'a = <fun>
> > # let f2 x = x;;
> > val f2 : 'a > 'a = <fun>
> > # let f3 a b c = (a,b,c);;
> > val f3 : 'a > 'b > 'c > 'a * 'b * 'c = <fun>
> > # let example2 a b =
> > let a' = f1 a
> > and b' = f2 b
> > in (fun x > f3 a' b' x);;
> > val example2 : 'a > 'b > 'c > 'a * 'b * 'c = <fun>
> > # let f = example2 1 2;;
> > val f : '_a > int * int * '_a = <fun>
> >
> > results in f not being fully polymorphic, but
> > val example1 : 'a > 'b > 'c > 'a * 'b * 'c = <fun>
> > let f = fun x > example1 1 2 x;;
> > val f : 'a > int * int * 'a = <fun>
> >
> > Does. It seems to me that I should be able to return a (fun x >
> > blah), and have it be as polymorphic as possible. (not should in the
> > 'right thing' sense, but should in the 'actual way it works' sense,
> > based on my very poor knowledge of ocaml types and '_a).
>
> I don't know why it is like this (but I don't want to know :)
> There are a few paragraphs about this topic in the FAQ if you did not read
> it yet:
> http://caml.inria.fr/FAQ/FAQ_EXPERTeng.html#variables_de_types_faibles
>
>
> Martin
>
>
>
>
>
>
> Archives up to September 30, 2004 are also downloadable at
> http://www.connettivo.net/cntprojects/ocaml_beginners/
> The archives of the very official ocaml list (the seniors' one) can be
> found at http://caml.inria.fr
> Attachments are banned and you're asked to be polite, avoid flames etc.
>
>
>
> Yahoo! Groups Sponsor
>
> ADVERTISEMENT
>
>
> ________________________________
> Yahoo! Groups Links
>
> To visit your group on the web, go to:
> http://groups.yahoo.com/group/ocaml_beginners/
>
> To unsubscribe from this group, send an email to:
> ocaml_beginnersunsubscribe@yahoogroups.com
>
> Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
Seth Fogarty sfogarty@[gmail.comrice.edulivejournal]
Neepneep at large AIM: Sorrath
"I know there are people in this world who do not love their fellow
human beings  and I hate people like that" Tom Lehrer.  On Fri, 5 Nov 2004 11:49:41 +0900, Nicolas Cannasse <warplayer@...> wrote:
>
Thanks... that's the example I needed to fit this in my head.
>
> > results in f not being fully polymorphic, but
> > val example1 : 'a > 'b > 'c > 'a * 'b * 'c = <fun>
> > let f = fun x > example1 1 2 x;;
> > val f : 'a > int * int * 'a = <fun>
> >
> > Does. It seems to me that I should be able to return a (fun x >
> > blah), and have it be as polymorphic as possible. (not should in the
> > 'right thing' sense, but should in the 'actual way it works' sense,
> > based on my very poor knowledge of ocaml types and '_a).
>
> The monomorphic types '_a and others are needed in order to ensure type
> safety.
> for example :
>
> let id x = x
> let f = ref id
I'm still slightly bothered by the fragility with which '_a is
introduced or not.
# let f a b = (a,b);;
val f : 'a > 'b > 'a * 'b = <fun>
# let g = f 1;;
val g : '_a > int * '_a = <fun>
# let g = fun x > f 1 x;;
val g : 'a > int * 'a = <fun>
# let g = ignore 5; fun x > f 1 x;;
val g : '_a > int * '_a = <fun>
# let g = if true then fun x > f 1 x else fun x > f 1 x;;
val g : 'a > int * 'a = <fun>
I cannot figure out when I will get a '_a and when I will not.

Seth Fogarty sfogarty@[gmail.comrice.edulivejournal]
Neepneep at large AIM: Sorrath
"I know there are people in this world who do not love their fellow
human beings  and I hate people like that" Tom Lehrer. > Thanks... that's the example I needed to fit this in my head.
It's easy.
>
> I'm still slightly bothered by the fragility with which '_a is
> introduced or not.
You get monorphic variables every time you having polymorphic variables on
the right side of a let x = ... expression . That means for values and not
for functions. And in some cases the compiler can relieve the monorphics and
turn them polymorphics, in some hard coded special cases known to be
secure  such as simple assignations  at least I think.
Nicolas Cannasse On Wed, 3 Nov 2004 16:03:20 0300 (CLST), andrew cooke
<andrew@...> wrote:>
The awnser of Issac is correct, but I wabt to insist one one thing :
>
> Where can I find a clear description of how OCaml executes code. In
> particular, I want to understand when functions with several values are
> evaluated  is the evaluation progressive (during Currying) or is
> evaluation delayed until all arguments are present.
>
> For example, are the following equivalent, always?
>
> let example1 a b x =
> let a' = f1 a in
> let b' = f2 b in
> f3 a' b' x
>
> let example2 a b =
> let a' = f1 a in
> let b' = f2 b in
> fun x > f3 a' b' x
the ocaml semantic is the more natural one. In the first exemple, you
have define a function that wait for three argument before making any
computation, in the second exemple, you've define a function that wait
for two argument, then do part of the computation then do another
computation. What will happen is what you read.  On Wed, 3 Nov 2004 16:28:00 0600, Seth J. Fogarty <sfogarty@...> wrote:
>
well, when the typer compute the type of an expression, he only know
> On Wed, 3 Nov 2004 16:03:20 0300 (CLST), andrew cooke
>
>
> <andrew@...> wrote:
> >
> > Where can I find a clear description of how OCaml executes code. In
> > particular, I want to understand when functions with several values are
> > evaluated  is the evaluation progressive (during Currying) or is
> > evaluation delayed until all arguments are present.
> >
> > For example, are the following equivalent, always?
> >
> > let example1 a b x =
> > let a' = f1 a in
> > let b' = f2 b in
> > f3 a' b' x
> >
> > let example2 a b =
> > let a' = f1 a in
> > let b' = f2 b in
> > fun x > f3 a' b' x
>
> These two are equivalent. I have a question, however, for the list.
> Why does example2, when so explicitly curried as such, have a '_a when
> curried?
>
> # let a = example2 1 2;;
> val a : '_a > int * int * '_a = <fun>
the type of the part of the computation. So if two function do have
the same type, and you apply it to sthe same argument, you have the
same type as a result.  On 5 Nov 2004, at 08:57, Seth J. Fogarty wrote:
> I'm still slightly bothered by the fragility with which '_a is
It's called 'value restriction'. For full polymorphism, the expression
> introduced or not.
on the right hand side of the '=' sign must be a value.
> # let f a b = (a,b);;
(a,b) is a value.
> val f : 'a > 'b > 'a * 'b = <fun>
> # let g = f 1;;
'f 1' is a partial function application. Not a value. Can be resolved
> val g : '_a > int * '_a = <fun>
by etaexpansion to:
let g x = f 1 x;;
or as below:
> # let g = fun x > f 1 x;;
Lambda expression. This is a value.
> val g : 'a > int * 'a = <fun>
> # let g = ignore 5; fun x > f 1 x;;
Sequence of expressions, the first potentially sideeffecting. Not a
> val g : '_a > int * '_a = <fun>
value.
> # let g = if true then fun x > f 1 x else fun x > f 1 x;;
Evaluates to a lambda expression.
> val g : 'a > int * 'a = <fun>
As has been explained earlier, this restriction on polymorphism has
been made because ML, being an imperative language, allows assignment
to mutable variables, potentially compromising the type system. The
result is somewhat unfortunate, in that polymorphism is denied in many
cases (like the above) where it would be entirely typesafe. In
practice, though, it turns out not to be a problem and can in many
cases be avoided by etaexpansion.
HTH
Alwyn  On Fri, Nov 05, 2004 at 11:49:41AM +0900, Nicolas Cannasse wrote:
> > f will be '_a > '_a ref
And I think it's also true that '_a will only ever appear in the
> if it's type was 'a > 'a , that means we can put any unifiable function
> into the reference f and call it later with another type :
>
> f := (fun x > x + 1) // would unify since int > int is unifiable with
> 'a > 'a
> !f "hello" // would works since !f would still be 'a > 'a, causing a typing
> error since we're actually executing above function
>
> So it's needed to introduce monomorphic variables, they are really
> "temporary" polymorphic variables until they're unified.
toplevel, never when writing proper applications.
Rich.

Richard Jones. http://www.annexia.org/ http://www.jlondon.com/>>> http://www.teamnotepad.com/  collaboration tools for teams <<<
Merjis Ltd. http://www.merjis.com/  improving website return on investment
Use Perl libs in OCaml  http://www.merjis.com/developers/perl4caml
[Nontext portions of this message have been removed]  On Fri, 5 Nov 2004 12:59:29 +0000, Alwyn <dt015a1979@...> wrote:
>
Well not exactly, if the value on the right hand side of the = is an
> On 5 Nov 2004, at 08:57, Seth J. Fogarty wrote:
>
> > I'm still slightly bothered by the fragility with which '_a is
> > introduced or not.
>
> It's called 'value restriction'. For full polymorphism, the expression
> on the right hand side of the '=' sign must be a value.
>
hashtable for example, it is a value, but it won't be polymophic (it
would be realy unsafe). Only imutable value will be generalize (that
is render fully polymorphic). Well, not exactly this, it will be
generalize if the type polymorphisme is covariant (and I believe there
is another restriction).
A type 'a t is covariant with regard to a, if for any type a and b
such that one can coerce any value of type a in a value of type b,
then one can coerce a value of type a t into a value of type b t. For
example the option type is covariant.  On Fri, 5 Nov 2004 13:10:40 +0000, Richard Jones <rich@...> wrote:
>
Not exatly, the fact is that if there is an '_a type in a proper
>
>
> On Fri, Nov 05, 2004 at 11:49:41AM +0900, Nicolas Cannasse wrote:
> > > f will be '_a > '_a ref
> > if it's type was 'a > 'a , that means we can put any unifiable function
> > into the reference f and call it later with another type :
> >
> > f := (fun x > x + 1) // would unify since int > int is unifiable with
> > 'a > 'a
> > !f "hello" // would works since !f would still be 'a > 'a, causing a typing
> > error since we're actually executing above function
> >
> > So it's needed to introduce monomorphic variables, they are really
> > "temporary" polymorphic variables until they're unified.
>
> And I think it's also true that '_a will only ever appear in the
> toplevel, never when writing proper applications.
>
application, this is an error, and the compiler will refuse to compile
it.  On 5 Nov 2004, at 13:19, Remi Vanicat wrote:
> On Fri, 5 Nov 2004 12:59:29 +0000, Alwyn <dt015a1979@...>
I was under the impression that current O'Caml, like SML 97, employed a
> wrote:
> >
> > It's called 'value restriction'. For full polymorphism, the
> expression
> > on the right hand side of the '=' sign must be a value.
>
> Well not exactly, if the value on the right hand side of the = is an
> hashtable for example, it is a value, but it won't be polymophic (it
> would be realy unsafe).
system of value polymorphism as suggested by Andrew Wright in his paper
"Simple Imperative Polymorphism" published in 1995. See:
<http://www.smlnj.org//doc/Conversion/types.html>
<quote>
As in SML '90, we approximate the class of safetogeneralize
expressions conservatively by the simple syntactic notion of a
nonexpansive expression, also known as a value expression or simply a
value. SML '90 defined nonexpansive expressions to include the
following atomic forms:
• constants (e.g. 3),
• nullary constructors (e.g. nil),
• variables (e.g. x, A.x),
• function expressions (e.g. (fn x => x)).
It is clear that the evaluation of any of these forms is safe because
it cannot entail the creation of new data structures (other than the
benign case of creating function closures for function expressions). To
partially compensate for the fact that we are being more restrictive in
our creation of polymorphism, SML '97 enlarges the class of
nonexpansive expressions to include some simple compound expressions:
• records and tuples with nonexpansive fields (e.g. (3,x,nil)),
• constructors (except ref) applied to nonexpansive arguments (e.g.
x::nil).
All other expressions, including function applications, let
expressions, conditionals, etc., are by definition expansive, implying
that their evaluation may entail nontrivial computations that might
lead to the creation of ref cells or other mutable data structures.
</quote>
> Only imutable value will be generalize (that
I haven't been able to find an authoritative source on this subject
> is render fully polymorphic). Well, not exactly this, it will be
> generalize if the type polymorphisme is covariant (and I believe there
> is another restriction).
with regard to O'Caml either in English or in French. Do you know of
any?
Alwyn  Yup. Alright, I will buy that. Still not sure why ; is treated
fundementally different than if..then..else.
On Fri, 5 Nov 2004 13:52:20 +0100, Remi Vanicat <remi.vanicat@...> wrote:
> On Wed, 3 Nov 2004 16:28:00 0600, Seth J. Fogarty <sfogarty@...>
> wrote:
>
>
> >
> > On Wed, 3 Nov 2004 16:03:20 0300 (CLST), andrew cooke
> >
> >
> > <andrew@...> wrote:
> > >
> > > Where can I find a clear description of how OCaml executes code. In
> > > particular, I want to understand when functions with several values
> are
> > > evaluated  is the evaluation progressive (during Currying) or is
> > > evaluation delayed until all arguments are present.
> > >
> > > For example, are the following equivalent, always?
> > >
> > > let example1 a b x =
> > > let a' = f1 a in
> > > let b' = f2 b in
> > > f3 a' b' x
> > >
> > > let example2 a b =
> > > let a' = f1 a in
> > > let b' = f2 b in
> > > fun x > f3 a' b' x
> >
> > These two are equivalent. I have a question, however, for the list.
> > Why does example2, when so explicitly curried as such, have a '_a when
> > curried?
> >
> > # let a = example2 1 2;;
> > val a : '_a > int * int * '_a = <fun>
>
> well, when the typer compute the type of an expression, he only know
> the type of the part of the computation. So if two function do have
> the same type, and you apply it to sthe same argument, you have the
> same type as a result.
>
>
>
>
> Archives up to September 30, 2004 are also downloadable at
> http://www.connettivo.net/cntprojects/ocaml_beginners/
> The archives of the very official ocaml list (the seniors' one) can be
> found at http://caml.inria.fr
> Attachments are banned and you're asked to be polite, avoid flames etc.
>
>
>
> Yahoo! Groups Sponsor
>
> ADVERTISEMENT
>
>
> ________________________________
> Yahoo! Groups Links
>
> To visit your group on the web, go to:
> http://groups.yahoo.com/group/ocaml_beginners/
>
> To unsubscribe from this group, send an email to:
> ocaml_beginnersunsubscribe@yahoogroups.com
>
> Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.

Seth Fogarty sfogarty@[gmail.comrice.edulivejournal]
Neepneep at large AIM: Sorrath
"I know there are people in this world who do not love their fellow
human beings  and I hate people like that" Tom Lehrer.  On Fri, 5 Nov 2004 17:46:54 +0000, Alwyn <dt015a1979@...> wrote:
>
well, I belive that there is this, and some other value, but I've
>
>
> On 5 Nov 2004, at 13:19, Remi Vanicat wrote:
>
> > On Fri, 5 Nov 2004 12:59:29 +0000, Alwyn <dt015a1979@...>
> > wrote:
> > >
> > > It's called 'value restriction'. For full polymorphism, the
> > expression
> > > on the right hand side of the '=' sign must be a value.
> >
> > Well not exactly, if the value on the right hand side of the = is an
> > hashtable for example, it is a value, but it won't be polymophic (it
> > would be realy unsafe).
>
> I was under the impression that current O'Caml, like SML 97, employed a
> system of value polymorphism as suggested by Andrew Wright in his paper
> "Simple Imperative Polymorphism" published in 1995. See:
> <http://www.smlnj.org//doc/Conversion/types.html>
>
> <quote>
> As in SML '90, we approximate the class of safetogeneralize
> expressions conservatively by the simple syntactic notion of a
> nonexpansive expression, also known as a value expression or simply a
> value. SML '90 defined nonexpansive expressions to include the
> following atomic forms:
> • constants (e.g. 3),
> • nullary constructors (e.g. nil),
> • variables (e.g. x, A.x),
> • function expressions (e.g. (fn x => x)).
> It is clear that the evaluation of any of these forms is safe because
> it cannot entail the creation of new data structures (other than the
> benign case of creating function closures for function expressions). To
> partially compensate for the fact that we are being more restrictive in
> our creation of polymorphism, SML '97 enlarges the class of
> nonexpansive expressions to include some simple compound expressions:
> • records and tuples with nonexpansive fields (e.g. (3,x,nil)),
> • constructors (except ref) applied to nonexpansive arguments (e.g.
> x::nil).
> All other expressions, including function applications, let
> expressions, conditionals, etc., are by definition expansive, implying
> that their evaluation may entail nontrivial computations that might
> lead to the creation of ref cells or other mutable data structures.
> </quote>
difficulties to explain when exacltly.
>
there is a bug report about it in the ocaml bug tracking
> > Only imutable value will be generalize (that
> > is render fully polymorphic). Well, not exactly this, it will be
> > generalize if the type polymorphisme is covariant (and I believe there
> > is another restriction).
>
> I haven't been able to find an authoritative source on this subject
> with regard to O'Caml either in English or in French. Do you know of
> any?
http://caml.inria.fr/bin/camlbugs/fixed?id=1692;expression=vanicat;page=2;user=guest
you could also try to find messages on the mailing list speaking about it  On 9 Nov 2004, at 12:23, Remi Vanicat wrote:
> there is a bug report about it in the ocaml bug tracking
Thank you; this led me to Garrigue's publications page at:
> http://caml.inria.fr/bin/camlbugs/fixed?id=1692;expression=vanicat;
> page=2;user=guest
<http://wwwfun.kurims.kyotou.ac.jp/~garrigue/papers/>
I have another question: In Standard ML and Haskell, constructors can
be used as functions. Why is this not the case in CAML?
Alwyn  On Tue, 9 Nov 2004 19:57:38 +0000, Alwyn <dt015a1979@...> wrote:
> I have another question: In Standard ML and Haskell, constructors can
Well, in the 3 said language, construcor are mainly tag that are put
> be used as functions. Why is this not the case in CAML?
in the header of the object, and type declaration for type safety.
Then one can decide to define a function to build such a value. But it
is not automatic. So ocaml choose to not do it, while the two other
said language do. It is a design decision, there is no real good
reason against it (At least in my knowledge)
Your message has been successfully submitted and would be delivered to recipients shortly.