caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* sequencing
@ 1997-06-03  9:04 Jean.Luc.Paillet
  1997-06-03 11:14 ` sequencing Francois Pessaux
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Jean.Luc.Paillet @ 1997-06-03  9:04 UTC (permalink / raw)
  To: caml-list

   Quelqu'un pourrait-il m'expliquer pourquoi le sequencement d'une fonction
a` effet de bord, telle que "print_string" par exemple, semble inverse'
quand elle est appliquée sur une liste au moyen d'un iterateur.

Par exemple
   map print_string ["a" ; "b"] ;;   produit

    ba- : unit list = [(); ()]
ce qui implique un parcours de la liste de droite a gauche .
Plus curieux, avec une definition recursive "personnelle" de l'iterateur,
telle que

   let rec monmap f liste      match liste  with [] -> [] |
                     head :: tail -> (f head) :: monmap f (tail) ;;

On pourrait s'attendre ici a ce que  "(f head)" soit evalue avant
l'appel recursif. He bien non,
 on obtient encore

   monmap print_string ["a" ; "b"] ;;
    ba- : unit list = [(); ()]

Quelle est mon erreur d'interpretation ?
Doit-on penser que  (f head) est empile jusqu'a ce que la fonction termine ?

   ?????
**********************************************
££  English version  ££

I don't understand why the sequencing of side effects seems to be inverted,
when using "map" , like for example in the following:

     map print_string ["a" ; "b"] ;;   gives
    ba- : unit list = [(); ()]

it means that the list is scanned from the right to the left

More surprising, with a recursive hand made definition of "map", such as

   let rec monmap f liste      match liste  with [] -> [] |
                     head :: tail -> (f head) :: monmap f (tail) ;;


We also obtain

   monmap print_string ["a" ; "b"] ;;
    ba- : unit list = [(); ()]

We could thing that   "(f head)" is evaluated before the recursive call .

What is my mistake ?
Does the term "(f head)" pushed on the recursion stack until terminating
the recursive calls, before being evaluated ?


   Thanks for an explanation

    Kind regards


        Jean-Luc Paillet

(*
------------------------------------------------------------------------
              Jean-Luc PAILLET
              LIM  (URA 1787)
              CMI -   Universite de Provence
              39 r Joliot Curie
              13453  Marseille  Cedex 13   FRANCE
              Tel:  (33) 04 91 11 36 10
              Fax:  (33) 04 91 11 36 02
              e-mail:  Jean.Luc.Paillet@lim.univ-mrs.fr
                       jluc@gyptis.univ-mrs.fr
--------------------------------------------------------------------------
*)







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

* Re: sequencing
  1997-06-03  9:04 sequencing Jean.Luc.Paillet
@ 1997-06-03 11:14 ` Francois Pessaux
  1997-06-03 11:15 ` sequencing Jean-Christophe Filliatre
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Francois Pessaux @ 1997-06-03 11:14 UTC (permalink / raw)
  To: Jean.Luc.Paillet; +Cc: caml-list


>    Quelqu'un pourrait-il m'expliquer pourquoi le sequencement d'une fonction
> a` effet de bord, telle que "print_string" par exemple, semble inverse'
> quand elle est appliquée sur une liste au moyen d'un iterateur.

Il se trouve que l'ordre d'evaluation (droite-gauche ou gauche-droite) n'est
pas specifie pour le compilo Caml. Autrement dit, il ne faut pas compter sur
un ordre particulier pour faire un programme correct. Sur la version de Caml
que tu utilise l'evaluation doit vraissemblablement se faire de droite a
gauche et la fonction map doit etre definie comme :
let rec map f = function
 | [] -> []
 | h :: q -> (f h) :: (map f q) ;;

Pour patcher ca, et ne plus etre dependant de l'ordre d'evaluation, il faut
effectuer explicitement le calcul de f h en premier :
let rec map f = function
    [] -> []
  | h :: q -> let r = f a
               in r :: map f q ;;

C'est d'ailleurs comme ca qu'est codee map en Objective Caml.

-- 
(*                      Francois PESSAUX (Francois.Pessaux@inria.fr) *)
(*                               INRIA Rocquencourt - Projet CRISTAL *)
(*                               (http://pauillac.inria.fr/~pessaux) *)
;;






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

* Re: sequencing
  1997-06-03  9:04 sequencing Jean.Luc.Paillet
  1997-06-03 11:14 ` sequencing Francois Pessaux
@ 1997-06-03 11:15 ` Jean-Christophe Filliatre
  1997-06-03 11:56 ` sequencing Michel Quercia
  1997-06-03 14:47 ` sequencing Vincent Poirriez
  3 siblings, 0 replies; 5+ messages in thread
From: Jean-Christophe Filliatre @ 1997-06-03 11:15 UTC (permalink / raw)
  To: Jean.Luc.Paillet; +Cc: caml-list


>    Quelqu'un pourrait-il m'expliquer pourquoi le sequencement d'une fonction
> a` effet de bord, telle que "print_string" par exemple, semble inverse'
> quand elle est appliquée sur une liste au moyen d'un iterateur.

Ce comportement   est du au  fait que,    lors d'une application,  les
arguments sont évalués de droite à gauche, comme le montre l'exemple

	# (fun _ _ -> ()) (print_string "toto") (print_string "tata");;
	tatatoto- : unit = ()

Dans  ton  exemple, le comportement est   du au  fait  que le deuxième
argument du  cons (l'appel  récursif)  est évalué avant  le premier (f
head).

Cependant,  le manuel de référence indique,  page 64, que : "The order
in which  the   expressions expr1,...,exprn   are  evaluated  is   not
specified."  En   conséquence,  il  vaut    mieux expliciter   l'ordre
d'évaluation en utilisant le séquencement avec ;.

-- 
Jean-Christophe FILLIATRE
  email: Jean-Christophe.Filliatre@ens-lyon.fr
  WWW  : http://www.ens-lyon.fr/~jcfillia


> **********************************************
> ££  English version  ££
> 
> I don't understand why the sequencing of side effects seems to be inverted,
> when using "map" , like for example in the following:

This behavior is due to the order of evaluation of the arguments in an
application,  which is from   right  to left,  as illustrated   by the
following example :

	# (fun _ _ -> ()) (print_string "toto") (print_string "tata");;
	tatatoto- : unit = ()

However, the reference manual indicates,  page 64, that: "The order in
which the expressions expr1,...,exprn are evaluated is not specified."
Consequently, it is   better   to explicitly   specify the order    of
evaluation using a sequence (;).

-- 
Jean-Christophe FILLIATRE
  email: Jean-Christophe.Filliatre@ens-lyon.fr
  WWW  : http://www.ens-lyon.fr/~jcfillia





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

* Re: sequencing
  1997-06-03  9:04 sequencing Jean.Luc.Paillet
  1997-06-03 11:14 ` sequencing Francois Pessaux
  1997-06-03 11:15 ` sequencing Jean-Christophe Filliatre
@ 1997-06-03 11:56 ` Michel Quercia
  1997-06-03 14:47 ` sequencing Vincent Poirriez
  3 siblings, 0 replies; 5+ messages in thread
From: Michel Quercia @ 1997-06-03 11:56 UTC (permalink / raw)
  To: Jean.Luc.Paillet; +Cc: caml-list

Jean.Luc.Paillet@lim.univ-mrs.fr wrote:
> 
>    Quelqu'un pourrait-il m'expliquer pourquoi le sequencement d'une fonction
> a` effet de bord, telle que "print_string" par exemple, semble inverse'
> quand elle est appliquée sur une liste au moyen d'un iterateur.
> 
> Par exemple
>    map print_string ["a" ; "b"] ;;   produit
> 
>     ba- : unit list = [(); ()]
> ce qui implique un parcours de la liste de droite a gauche .
> Plus curieux, avec une definition recursive "personnelle" de l'iterateur,
> telle que
> 
>    let rec monmap f liste =
>      match liste  with [] -> [] |
>                      head :: tail -> (f head) :: monmap f (tail) ;;

Un coup d'oeil a la bibliotheque sur les listes
(/usr/local/lib/caml-light/list.ml) monter que map est a peu pres defini
comme cela.

> 
> On pourrait s'attendre ici a ce que  "(f head)" soit evalue avant
> l'appel recursif. He bien non,

L'ordre d'evaluation de (expr_a) :: (expr_b) n'est pas specifie dans le
manuel de reference. En pratique, il se trouve que expr_b est evalue
d'abord.
Voici une fonction lr_map produisant une application de gauche a droite
:


>       Caml Light version 0.73

#map print_char [`a`; `b`; `c`];;
cba- : unit list = [(); (); ()]
#let rec lr_map f liste = match liste with
| [] -> []
| t::q -> let t' = f(t) in t' :: (lr_map f q)
;;
lr_map : ('a -> 'b) -> 'a list -> 'b list = <fun>
#lr_map print_char [`a`; `b`; `c`];;
abc- : unit list = [(); (); ()]
#

> **********************************************
> ££  English version  ££
> 
> I don't understand why the sequencing of side effects seems to be inverted,
> when using "map" , like for example in the following:
> 
>      map print_string ["a" ; "b"] ;;   gives
>     ba- : unit list = [(); ()]
> 
> it means that the list is scanned from the right to the left
> 
> More surprising, with a recursive hand made definition of "map", such as
> 
>    let rec monmap f liste =
>      match liste  with [] -> [] |
>                      head :: tail -> (f head) :: monmap f (tail) ;;
> 

Look at the list implementation (/usr/local/lib/caml-light/list.ml),
you'll see that map is roughly defined that way.

> 
> We could thing that   "(f head)" is evaluated before the recursive call .
> 

The order of evaluation of (expr_a) :: (expr_b) is unspecified in the
reference manual. Actually, it turns out that expr_b is evaluated first.
Here is a function lr_map going from left to right :


>       Caml Light version 0.73

#map print_char [`a`; `b`; `c`];;
cba- : unit list = [(); (); ()]
#let rec lr_map f liste = match liste with
| [] -> []
| t::q -> let t' = f(t) in t' :: (lr_map f q)
;;
lr_map : ('a -> 'b) -> 'a list -> 'b list = <fun>
#lr_map print_char [`a`; `b`; `c`];;
abc- : unit list = [(); (); ()]
#


-- 
Michel Quercia
Lycee Carnot  16 bd Thiers  21000 Dijon
mailto:quercia@cal.enst.fr





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

* Re: sequencing
  1997-06-03  9:04 sequencing Jean.Luc.Paillet
                   ` (2 preceding siblings ...)
  1997-06-03 11:56 ` sequencing Michel Quercia
@ 1997-06-03 14:47 ` Vincent Poirriez
  3 siblings, 0 replies; 5+ messages in thread
From: Vincent Poirriez @ 1997-06-03 14:47 UTC (permalink / raw)
  To: Jean.Luc.Paillet; +Cc: caml-list

Jean.Luc.Paillet@lim.univ-mrs.fr wrote:
> 
>    Quelqu'un pourrait-il m'expliquer pourquoi le sequencement d'une fonction
> a` effet de bord, telle que "print_string" par exemple, semble inverse'

il n'est pas inversé puisqu'il n'est pas spécifié!!!

Le sens naturel, pour nous autres, est l'évaluation de gauche à droite,
ce n'est pas le même dans d'autres cultures et certaines raisons
(efficacité de compilation par exmple) font que certains compilateurs
évaluent de droite à gauche, c'est le cas pour ocaml.

Si vous voulez controler l'ordre d'exécution utilisez l'opérateur
de séquencement ";" ou, ce qui est équivalent pour votre exemple, les
itérateurs "impératifs"
 
Ce qui donne
 Objective Caml version 1.05

# List.iter;; 
- : ('a -> 'b) -> 'a list -> unit = <fun>
# List.iter print_string ["a" ; "b"];;
ab- : unit = ()
# let rec iter f = function
   [] -> ()
  | h::t -> f h; iter f t;;
val iter : ('a -> 'b) -> 'a list -> unit = <fun>
# iter print_string ["a" ; "b"];;
ab- : unit = ()
# 
au lieu de votre code
> quand elle est appliquée sur une liste au moyen d'un iterateur.
> 
> Par exemple
>    map print_string ["a" ; "b"] ;;   produit
> 
>     ba- : unit list = [(); ()]
> ce qui implique un parcours de la liste de droite a gauche .
> Plus curieux, avec une definition recursive "personnelle" de l'iterateur,
> telle que
> 
>    let rec monmap f liste =
>      match liste  with [] -> [] |
>                      head :: tail -> (f head) :: monmap f (tail) ;;
> 
> On pourrait s'attendre ici a ce que  "(f head)" soit evalue avant
> l'appel recursif. He bien non,
>  on obtient encore
> 
>    monmap print_string ["a" ; "b"] ;;
>     ba- : unit list = [(); ()]
> 
> Quelle est mon erreur d'interpretation ?
> Doit-on penser que  (f head) est empile jusqu'a ce que la fonction termine ?
> 
>    ?????
> **********************************************
> ££  English version  ££
> 
> I don't understand why the sequencing of side effects seems to be inverted,
It is not inverted is it is not specified!!!
The natural way, "for us" is to evaluate from left to right
but it is not the same in other cultures and for some
deep reasons (efficiency for example) some compilers evaluate
from right to left, it is the case for ocaml.

If you need to control the order of evaluation you have to use
the operator ";" or, which is simpler for your example,
the predifined "imperatif" iterator:

This leads to 
 Objective Caml version 1.05

# List.iter;; 
- : ('a -> 'b) -> 'a list -> unit = <fun>
# List.iter print_string ["a" ; "b"];;
ab- : unit = ()
# let rec iter f = function
   [] -> ()
  | h::t -> f h; iter f t;;
val iter : ('a -> 'b) -> 'a list -> unit = <fun>
# iter print_string ["a" ; "b"];;
ab- : unit = ()
# 

instead of your code
>


> when using "map" , like for example in the following:
> 
>      map print_string ["a" ; "b"] ;;   gives
>     ba- : unit list = [(); ()]
> 
> it means that the list is scanned from the right to the left
> 
> More surprising, with a recursive hand made definition of "map", such as
> 
>    let rec monmap f liste =
>      match liste  with [] -> [] |
>                      head :: tail -> (f head) :: monmap f (tail) ;;
> 
> We also obtain
> 
>    monmap print_string ["a" ; "b"] ;;
>     ba- : unit list = [(); ()]
> 
> We could thing that   "(f head)" is evaluated before the recursive call .
> 
> What is my mistake ?
> Does the term "(f head)" pushed on the recursion stack until terminating
> the recursive calls, before being evaluated ?
> 
>    Thanks for an explanation
> 
>     Kind regards
> 
>         Jean-Luc Paillet
> 
Vincent Poirriez

-- 
Tel: (33) {0}3 27 14 13 33   Fax: (33) {0}3 27 14 12 94
mailto:Vincent.Poirriez@univ-valenciennes.fr
 http://www.univ-valenciennes.fr/limav/poirriez
ISTV Université de Valenciennes Le Mont Houy BP 311 F59304 Valenciennes
CEDEX





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

end of thread, other threads:[~1997-06-03 15:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-06-03  9:04 sequencing Jean.Luc.Paillet
1997-06-03 11:14 ` sequencing Francois Pessaux
1997-06-03 11:15 ` sequencing Jean-Christophe Filliatre
1997-06-03 11:56 ` sequencing Michel Quercia
1997-06-03 14:47 ` sequencing Vincent Poirriez

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