From madore@news.ens.fr
Path: eleves!not-for-mail
From: madore@news.ens.fr (GroTeXdieck)
Newsgroups: ens.forum.informatique.lang.caml
Subject: Re: Caml c'est de la m***e
Date: 13 Jul 1999 17:39:50 GMT
Lines: 149
Sender: madore@clipper.ens.fr
Message-ID: <7mftl6$1u$3@clipper.ens.fr>
References: <7mdvhu$7cv$1@clipper.ens.fr> <7mfhi0$cqm$1@clipper.ens.fr> <7mfisr$f51$1@clipper.ens.fr> <7mfld2$jde$1@clipper.ens.fr> <7mfols$nts$1@clipper.ens.fr> <7mfpga$nu9$2@clipper.ens.fr>
NNTP-Posting-Host: clipper.ens.fr
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: clipper.ens.fr 931887590 62 129.199.129.1 (13 Jul 1999 17:39:50 GMT)
X-Complaints-To: forum@clipper.ens.fr
NNTP-Posting-Date: 13 Jul 1999 17:39:50 GMT
X-Newsreader: Flrn (0.4pre2 - 05/99)
X-Rumor: Wanted: shopkeepers.  Send a scroll of mail to Mage of Yendor/Level 35/Dungeon. 
X-Number-Of-The-Day: 53 
Xref: eleves ens.forum.informatique.lang.caml:107

Eric Brunet in litteris (informatique.lang.caml:98) scripsit :
> Comme je l'ai déjà dit:
> *) la référence à un objet donné peut se trouver en plusieurs endroits
>    de la mémoire (par exemple let l= [x;x] in ...)

Si on ajoute une indirection de plus, on s'en sort.

> *) changer la taille d'un objet demande dans le cas général une
>    réallocation mémoire.

Normal.  Et alors ?  Java fait ça très bien, je ne vois pas pourquoi
caml n'en serait pas capable.

> *) Une réallocation mémoire a toutes les chances de changer l'adresse
>    de l'objet.

Non.  On peut avoir à l'endroit où se trouve l'objet un truc indiquant
où se trouve *vraiment* l'objet.

Exemple d'implémentation :

Une chaîne est un triplet composé d'un entier naturel, la taille, d'un
pointeur sur un buffer contenant les données de la chaîne
(éventuellement plus long que la chaînes, de sorte que racourcir est
facile), et un pointeur éventuel vers un autre triplet du même genre,
correspondant à la suite de la chaîne.  Pour racourcir la chaîne, on
diminue le premier entier.  Pour la ralonger, on augmente le premier
entier, et s'il dépasse la taille du buffer, on alloue un nouveau
triplet.

Éventuellement, on peut avoir une fonction reorganise qui défragmente
la chaîne.  Ce que normalement on fait quand on a fini d'écrire et
qu'on ne va plus faire que des lectures.

C'est l'implémentation obstack de GNU en C, c'est aussi à ma
connaissance ce que fait Java.  Et, accessoirement, c'est ce que fait
tout système de fichiers.

> *) Le compilo/interpréteur n'a pas assez d'informations pour aller
>    changer la valeur du pointeurs partout dans la mémoire où l'objet
>    utilisé.

C'est exact.

> *) Il est donc impossible de changer la taille d'un objet.

C'est pipo.

> Comment on fait, en C ?
> 
> p = realloc(p, nouvelle_taille);
> 
> Ça ne marche que si p est __le seul__ pointeur sur *p. Cette construction
> n'est valide en C que parce qu'on demande au programmeur de faire
> attention et de garantir lui-même qu'il va mettre à jour tous les
> pointeurs sur sa structure.

Et en pratique, on utilisera non pas un char * mais un char **, et on
fera

*p = realloc (*p, nouvelle_taille);

et même s'il y a d'autres pointeurs ça marche.

En Java c'est plus agréable (je sais, je me répète).

> 	* Tu fais une double indirection. C'est la solution de Valentin 
> 	  à base de ref.

Ah ben voilà, tu y penses.  Mais la double indirection n'impose pas en
théorie, comme elle le fait en caml, de tout recopier à chaque
modification.  Soit on permet des indirections multiples au milieu de
la chaîne (ce que je proposais), ce qui revient *en gros* à une char
list, soit *au moins* on ne fait la réallocation que quand la taille
dépasse la taille maximale autorisée, à la manière de :

struct buffer_s {
  char *data;
  size_t length;
  size_t maxsize;
};

struct buffer_s BUFFER_INITIALIZER = { NULL, 0, 0 };

void
ensure_length (struct buffer_s *buf, size_t len)
{
  size_t newmaxsize;
  if ( len <= buf->maxsize ) return;
  newmaxsize = buf->maxsize;
  while ( len > newmaxsize ) newmaxsize *= 2;
  buf->data = realloc (buf->data, newmaxsize);
  /* Error checking */
  buf->maxsize = newmaxsize;
}

void
buffer_setlength (struct buffer_s *buf, size_t len)
{
  ensure_length (buf, len);
  buf->length = len;
}

void
buffer_put (struct buffer_s *buf, char ch, size_t pos)
{
  if ( pos >= buf->length ) buffer_setlength (buf, pos+1);
  buf->data[pos] = ch;
}

void
buffer_append_char (struct buffer_s *buf, char ch)
{
  buffer_put (buf, ch, buf->length);
}

void
buffer_append_string (struct buffer_s *buf, const char *s)
{
  int i;
  for ( i=0 ; s[i] ; i++ )
    buffer_append_char (buf, s[i]);
}

char *
buffer_copycontents (struct buffer_s *buf)
{
  char *copy;
  copy = malloc (buf->length);
  /* Error checking */
  memcpy (copy, buf->data, buf->length);
  return copy;
}

Exemple :

struct buffer_s buf = BUFFER_INITIALIZER;
int i;
buffer_append_string (buf, "Le C est");
for ( i=0 ; i<30000 ; i++ )
  buffer_append_string (buf, " génial");
printf ("%s\n", buffer_copycontents (buf));

(non testé).

Comme je le disais, ça c'est vraiment l'implémentation facile.
L'implémentation plus difficile autorise de la fragmentation.

Tout ceci n'a rien de nouveau.  Ça *devrait* être implémenté en caml.

From madore@news.ens.fr
Path: eleves!not-for-mail
From: madore@news.ens.fr (GroTeXdieck)
Newsgroups: ens.forum.informatique.lang.caml
Subject: Encore une merde de caml
Date: 19 Jul 1999 16:00:01 GMT
Lines: 25
Sender: madore@jonque.ens.fr
Message-ID: <7mvi21$gco$1@clipper.ens.fr>
NNTP-Posting-Host: jonque.ens.fr
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: clipper.ens.fr 932400001 16792 129.199.129.4 (19 Jul 1999 16:00:01 GMT)
X-Complaints-To: forum@clipper.ens.fr
NNTP-Posting-Date: 19 Jul 1999 16:00:01 GMT
X-Newsreader: Flrn (0.4.0 - 07/99)
X-Rumor: Wishing too much may bring you too little. 
X-Number-Of-The-Day: 668 
Xref: eleves ens.forum.informatique.lang.caml:133

Ce système avec les fichiers .cmo et .cmi est parfaitement *débile*.

Supposons que j'ai un programme foobar qui s'obtienne en compilant
titi, tata, toto et tutu, par ocamlc -o foobar titi.cmo tata.cmo
toto.cmo tutu.cmo ; parmi les fichiers sources, les fichiers titi et
tata ont un .ml et un .mli alors que les fichiers toto et tutu ont
seulement un .ml (le .cmi se déduisant du .ml dans ce cas).

Comment fait-on pour dire à make que :
  * foobar s'obtient à partir des divers fichiers .cmo
(vraisemblablement constitués en une variable make $(OBJECTS)),
  * un fichier .cmo dépend *toujours* du fichier .cmi, même si celui-ci
n'existe pas ; mais si le fichier .mli n'existe pas, il n'est pas la
peine de chercher à créer le fichier .cmi, celui-ci apparaîtra tout
seul lors de la création du .cmo (je ne sais pas si vous savez dire ça
à make mais moi ça me dépasse),
  * un fichier .cmi dépend du fichier .mli si celui-ci existe, et sinon
du fichier .ml,
  * il y a des dépendances entre les fichiers : lorsqu'un foo.cmo
dépend d'un bar.cmi alors foo.cmi dépend lui-aussi de bar.cmi...

Bref, quelqu'un a-t-il jamais réussi à écrire un Makefile correct pour
un programme caml ?  (Ceux distribués avec ocaml sont pourris : si on
ne compile pas les targets dans l'ordre précisé dans le README, ça ne
marche pas - ce qui rend make vaguement inutile !)

From madore@news.ens.fr
Path: eleves!not-for-mail
From: madore@news.ens.fr (GroTeXdieck)
Newsgroups: ens.forum.informatique.lang.caml
Subject: Re: caml pas objective
Date: 12 Oct 1999 00:32:37 GMT
Lines: 71
Sender: madore@clipper.ens.fr
Message-ID: <7ttvj5$hd8$1@clipper.ens.fr>
References: <7ttft3$1l7$1@clipper.ens.fr> <7ttgt7$2kf$4@clipper.ens.fr> <7tthhe$29g$2@clipper.ens.fr> <7ttpeo$dds$3@clipper.ens.fr> <7ttr3o$eim$2@clipper.ens.fr>
NNTP-Posting-Host: clipper.ens.fr
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: clipper.ens.fr 939688358 17832 129.199.129.1 (12 Oct 1999 00:32:37 GMT)
X-Complaints-To: forum@clipper.ens.fr
NNTP-Posting-Date: 12 Oct 1999 00:32:37 GMT
X-Newsreader: Flrn (0.4.0 - 07/99)
X-Wisdom-Of-The-Day: honesty can't help avoid the essence of rage 
Xref: eleves ens.forum.informatique.lang.caml:180

Ska in litteris (informatique.lang.caml:178) scripsit :
>  Personnellement, le Wizard Book m'avait puissamment gonflé précisément parce
> que pour illustrer les idées, qui sont propres, tous les exemples sont écrits
> en Scheme, qui est au lambda-calcul ce que Michel Sardou est aux Beatles. Et
> je n'arrêtais pas de réécrire les exemples en CaML et de trouver ça
> immensément plus propre et plus compréhensible, ne serait-ce que
> syntaxiquement...

Tu n'as pas la lambda-nature, c'est tout.  D'ailleurs, rien que de
dire « lambda-nature », on pense tout de suite au Lisp : tu ne vas
quand même pas dire « fun-nature » quand même ?  Ça ferait pas
sérieux.

Sérieusement, tout le monde sait que le Lisp a trop de parenthèses,
mais en fait, quand tu lis, si c'est proprement formaté, ça ne pose
pas de problème, et quand tu écris, avec Emacs dans le bon mode (M-x
show-paren-mode) ça n'en pose pas non plus, tu repères tout de suite
ce qui va avec quoi.  Alors que le caml, quand on en est au cinquième
niveau de « let ... in », je ne trouve pas que ce soit plus clair :
les parenthèses te permettent de voir tout de suite jusqu'où va une
construction alors que dans un « let ... in », tu dois faire toi-même
tout le parsing.

La syntaxe du caml est crade, je ne crois pas qu'on puisse le
contester ; déjà son lexer est moche (les identificateurs ne vérifient
pas une regexp très jolie, c'est le moins qu'on puisse dire).  Tout
est complètement ad hoc, façon Pascal, alors que la syntaxe du Lisp
est minimale jusqu'à l'extrême : c'est peut-etre lourd, mais au moins
on ne peut pas dire que ce soit crade.

La grande force du Lisp, c'est son côté réflexif : les expressions du
langage sont des listes, et c'est justement le type de données que le
Lisp sait bien manipuler.  Le caml n'a rien de la sorte.  L'ennui
c'est que ce n'est pas toujours très commode que (lambda (foo) bar)
ressemble à s'y méprendre à une application...

La grande force du caml, c'est son typage.  Le Lisp n'a rien de la
sorte.  L'ennui, c'est que ce typage est désespéramment statique, sans
aucune citoyenneté de première classe des types.  Enfin, c'est quand
même le grand point sur lequel le caml gagne par rapport au Scheme -
et non la syntaxe.  Autre supériorité du caml à mon avis : les données
mutables sont explicitement déclarées comme telles.

Comme supériorité du Scheme, en revanche, il y a aussi le call/cc,
i.e. l'existance de continuations montantes, qui ^@est comme chacun
sait la différence entre logique intuitionniste et logique
classique^West quand même une instruction très importante, que le
SML/NJ et le Scheme ont mais pas le caml.

En ce qui concerne le Wizard Book, je trouve que c'est la syntaxe du
Scheme qui fait une partie de sa beauté, justement.  Abelson et
Sussman programment comme ils respirent, et les parenthèses en
deviennent presque poétiques.  Le fait d'avoir une syntaxe abstraite
précuite et directement manipulable, ça leur permet de torcher
carrément dans leurs interpréteurs divers.

Cela dit, quand j'ai écrit mes variations sur un interpréteur
fonctionnel (dans ftp://quatramaran.ens.fr/pub/madore/interp/ ), je
jes ai écrites en ocaml et non en Scheme, parce que franchement le
ocaml se prétait mieux à ce genre de jeu (la syntaxe abstraite n'est
pas précuite, elle est définissable par un type explicite, donc le
pattern-matching permet des choses plus agréables).  Mais dans leur
bouquin « Elements of Porgramming Languages » (une excellente suite
possible possible au Wizard Book), Friedman, Wand et Haynes prouvent
qu'on peut aussi faire ça en Scheme avec une certaine élégance -
simplement, je n'ai pas leur talent.

>  Ska, qui compte les différences de religion entre GroTeXdieck et lui :
> murien/antimurien, umask 002/022, Scheme/CaML, ça commence à chiffrer

Les blonds / les bru...  AÏE !  PAS TAPER !

From madore@news.ens.fr
Path: eleves!not-for-mail
From: madore@news.ens.fr (GroTeXdieck)
Newsgroups: ens.forum.informatique.lang.caml
Subject: Re: caml pas objective
Date: 12 Oct 1999 17:24:38 GMT
Lines: 243
Sender: madore@clipper.ens.fr
Message-ID: <7tvqsm$8jp$1@clipper.ens.fr>
References: <7ttft3$1l7$1@clipper.ens.fr> <7tthhe$29g$2@clipper.ens.fr> <7ttpeo$dds$3@clipper.ens.fr> <7ttr3o$eim$2@clipper.ens.fr> <7ttvj5$hd8$1@clipper.ens.fr> <7tvlaa$nj8$1@clipper.ens.fr>
NNTP-Posting-Host: clipper.ens.fr
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: clipper.ens.fr 939749078 8825 129.199.129.1 (12 Oct 1999 17:24:38 GMT)
X-Complaints-To: forum@clipper.ens.fr
NNTP-Posting-Date: 12 Oct 1999 17:24:38 GMT
X-Newsreader: Flrn (0.4.0 - 07/99)
X-Wisdom-Of-The-Day: to be honest, humor might not cause a lot of silence 
Xref: eleves ens.forum.informatique.lang.caml:207

Ska in litteris (informatique.lang.caml:185) scripsit :
>  With a sigh, Duke takes his gun again and prepares his return to the fray.

Amen.

[À propos de lambda/fun]
>  Une différence de nom d'identificateur... Si tu insistes, tu peux même
> préprocesser le source CaML pour remplacer lambda par function, et ton
> code initial aura lambda x -> f(x) , et tu seras content.

Si j'insiste je peux transformer tout code caml en code Scheme et vice
versa, en fait.  D'ailleurs, si j'insiste, je peux écrire Tunes, en
fait.  D'ailleurs, c'est ce que je suis en train de faire, en fait.
Donc, ton argument ne tient pas, en fait.  Et en fait, tu aurais pu te
rendre compte que là je plaisantais, en fait.

[À propos des parenthèses]
>  Ça fait une condition en trop. Je ne veux pas dépendre d'un mode particulier
> d'un éditeur particulier pour écrire du code.

N'importe quel éditeur (digne de ce nom) peut marquer spécialement les
parenthèses qui vont ensemble.

>  Mauvaise foi, changer de foi. En Lisp, tu dis toi-même avoir besoinx de
> formater proprement le code pour le lire : c'est valable pour quasiment
> n'importe quel langage, CaML y compris. L'indentation, plus que les
> parenthèses, te permet d'avoir une vision d'ensemble de la structure de ta
> phrase : il suffit d'indenter correctement les let...in et tout va bien.

Pour le lire, oui.  Mais pour l'écrire c'est autre chose, il faut se
souvenir de ce qu'il faut mettre pour terminer telle ou telle
construction bizarre.  En Scheme, c'est facile, c'est toujours une
parenthèse.

Et les conventions standard d'indentation du Lisp elles sont très
simples.  Celles du ML, j'attends encore qu'on me les explique.

[Concernant la définition des identificateurs]
>  Preuve que les regexp ne sont pas forcément adaptées à l'expression de ce qui
> est humainement intuitif.

Heu...  Elle est intuitive, la définition d'un identificateur, en ML ?
Déjà le coup de la distinction majuscule/minuscule sur la première
lettre, ça me hérisse.  Les n namespaces différents, ça me scie,
aussi.

[Concernant la syntaxe]
>>  Tout est complètement ad hoc, façon Pascal,
> 
>  Des exemples ! des exemples !

Valentin en a donné de bons.  D'ailleurs, tu prends à peu près
n'importe quelles deux constructions du caml et tu les regarde côte à
côte.

>> alors que la syntaxe du Lisp
>> est minimale jusqu'à l'extrême : c'est peut-etre lourd, mais au moins
>> on ne peut pas dire que ce soit crade.
> 
>  Si, car ce minimalisme va à l'encontre de la puissance d'expression. Lisp ne

Non.  Ce n'est pas le cas.  Et au contraire, il permet d'avoir un
lanage de macro qui ne chie pas comme celui du C, et qui existe,
contrairement à celui du ML.

> se donne pas les moyens d'exprimer proprement tout ce qu'il veut exprimer, et
> est donc obligé de recourir à des lourdeurs syntaxiques. Un exemple ? les
> instructions impératives. Tu peux écrire un programme impératif en Caml de
> façon parfaitement naturelle : le point-virgule a une sémantique claire et le
> type unit est parfaitement adapté. En Lisp, tu fais comment ? tu alignes, sans
> séparateur à la sémantique non ambiguë, des expressions qui retournent plus ou
> moins une valeur et tu ne sais pas exactement où sont les effets de bord.
>  D'accord, Lisp n'est pas fait pour ça, c'est un langage fonctionnel. Manque de
> bol, juxtaposer des expressions, ça arrive souvent ; et Caml aussi est un
> langage fonctionnel. L'impératif n'est qu'un exemple parmi d'autres.

Je ne vois pas ce qui n'est pas clair dans un

(begin
  (write "Le Scheme torsche.")
  (write "Le CAML aussi, d'ailleurs.")
  (set! answer 42)
  (if (eqv? answer 42)
      (begin
        (write "Deep Thought was right!")
        (write "Hurray, hurray!")
      )
  )
)

>> La grande force du Lisp, c'est son côté réflexif : les expressions du
>> langage sont des listes, et c'est justement le type de données que le
>> Lisp sait bien manipuler.  Le caml n'a rien de la sorte.
> 
>  Non, ce n'est pas fort. À la rigueur ( et encore, je ne suis pas d'accord )
> on peut dire que c'est beau. Mais c'est un gadget : tu évalues souvent des
> listes que tu composes toi-même par programme ? Franchement, je ne vois pas en

Oui, ça te permet d'inclure un évaluateur Scheme dans ton programme en
trois coups de cuiller à pot.

Et même si tu ne veux pas faire ce genre de choses, ça permet que le
langage de macros (le préprocesseur, quoi) soit propre, pour une fois.

> quoi c'est une force : ça ne sert que si tu fais du dynamisme à outrance, ce
> qui casse plein de choses bien plus utiles comme les analyses statiques -
> dont le typage.

Le dynamisme c'est bien.  Le statique n'est qu'un cas particulier du
dynamisme, une optimisation utile mais pas fondamentalement
importante.  Il faut que la structure du langage le reflète, relis mon
rant sur Tunes (ens.forum.informatique.lang:159, Message-ID:
<7mt6li$a81$1@clipper.ens.fr>) pour bien le comprendre.

>>  L'ennui c'est que ce n'est pas toujours très commode que (lambda (foo) bar)
>> ressemble à s'y méprendre à une application...
> 
>  Ben oui... et justement, je trouve cette construction à elle seule nettement
> plus crade et ambiguë que tous les petits défauts de Caml - dont j'attends
> encore des exemples. Qu'on puisse ne serait-ce que syntaxiquement confondre
> une construction _diamétralement opposée_ à l'application avec une
> application me semble le comble de l'aberration et ceux qui sont passés
> outre méritent d'être pendus par les pieds jusqu'à repentir sincère.

Argh.  Là, ta confusion d'idées est totale.  L'abstraction n'est pas
_diamétralement opposée_ (sic) à l'application, car on peut très bien
la voir comme un cas particulier de celle-ci.  Pour plus de précision,
relis le rant sus-mentionné (et notamment sa partie II), ou bien
récupère mon jeu de variations sur un interpréteur fonctionnel et fais
un checkout sur le tag « first », il s'agit d'un langage où le lambda
est une fonction comme toutes les autres.  (Dans une optique
complètement différent, je peux signaler le Unlambda qui n'a même pas
de lambda, mais ce serait là de la mauvaise foi.)  On peut
complètement éliminer les formes spéciales et utiliser de la pure
application, même sans faire un truc comme du Unlambda.

Ce n'est pas au niveau fondamental que portait ma critique, mais au
niveau syntaxe.  Moi j'aurais préféré une syntaxe comme (@lambda (foo)
bar), et faire de @lambda, non un symbole, mais un atome irrésoluble.

>> La grande force du caml, c'est son typage.  Le Lisp n'a rien de la
>> sorte.  L'ennui, c'est que ce typage est désespéramment statique, sans
>> aucune citoyenneté de première classe des types.
> 
>  C'est vrai. Mais garder un typage propre en faisant des objets des types,
> c'est _difficile_. Et ce n'est pas le but de Caml, ce me semble. Je crois
> bien que seul Tunes garde toute l'expressivité du typage en permettant le
> dynamisme, la réflexivité et tout ce qui va avec. On attend.

Il y a des langages qui ne sont pas Tunes et qui font très bien du
typage dynamique.

[Au sujet du call/cc]
>  Le Caml ne l'a pas, en effet. Et franchement, je m'en bats les coudes.
> Parce que intrinsèquement, le call/cc, je trouve ça laid, anti-intuitif, laid,
> abominable, laid, contraire à tous les principes de la programmation
> structurées, laid, difficile à implémenter autrement que par un hack ad hoc à
> base de setjmp ( bleuargh )... ai-je mentionné que c'était laid ?
          ^^^^^^
Non.  setjmp() ne permet que les continuations descendantes, pas les
continuations montantes.  I.e. que les exceptions (à la CAML) mais pas
les vraies continuations (à la Scheme).

>  Bon, là, je te sens choqué : comment, mais le call/cc, c'est splendide, c'est
> magnifiquement puissant, etc. etc. D'accord : je donne ici la définition du
> call/cc selon toi-même ( informatique.lang: 149 ) :

Exactement.

<snip rant de moi>
>  Je n'ai pas réagi à l'époque parce que M.*x s'en est très bien chargé. Et
> j'étais très rassuré parce que je n'étais pas le seul à avoir du mal avec
> cette phrase. En réfléchissant très fort sur tes exemples, j'arrive à peu
> près à voir ce qui se passe, mais l'idée elle-même me paraît d'une clarté
> très relative.
>  L'intérêt de l'informatique, c'est de manipuler des choses compliquées avec
> des concepts _simples_ a priori. Si le call/cc est assez anti-intuitif pour
> que M.*x et moi pétions les plombs quand on en voit un, c'est qu'il ne faut

Je ne sais pas si David M.*x pète les plombs quand il voit un call/cc,
mais c'est quand même grâce à lui que j'ai compris que l'élimination
du call/cc par CPS était l'équivalent informatique du plongement de
Gödel de la logique classique dans la logique intuitionniste, ou
encore d'un module dans son bidual.

> pas l'utiliser sous peine de risque de bugs capilloarrachatoires. Le concept
> de flot de contrôle est quelque chose de suffisamment général pour qu'on ne
> s'amuse pas à le torturer sous prétexte de puissance.
>  Bref, poser le call/cc comme supériorité d'un langage revient à faire
> l'apologie d'Intercal parce que le shuffle en est une opération de base.

Non, pas du tout.

Le call/cc n'est peut-être pas *intuitif*, mais (sans aller jusqu'à
savoir s'il est simple), il est *atomique*, i.e. on ne peut pas le
réaliser à base d'éléments plus basiques.  Si ton langage ne l'a pas
tu ne peux pas le synthétiser sauf à réécrire tout le programme en
CPS, ce qui n'est, dirons-nous, pas très heureux.  Avoir un langage
sans call/cc c'est exactement l'analogue de vouloir faire des maths en
logique intuitionniste, c'est *chiant*.  Et ta difficulté à le
comprendre s'apparente à celle des mathématiciens du XIXe devant les
démonstrations par l'absurde.  (C'est une analogie très précise, bien
entendu : le call/cc *est* le raisonnement par l'absurde sous
Curry-Howard.)

Tu aimes les exceptions, n'est-ce pas ?  Les exceptions c'est bien,
n'est-ce pas ?  C'est indispensable, non ?  Eh bien, il ne t'est
jamais arrivé, après le traitement d'une exception, d'avoir envie de
reprendre l'exécution du programme là où tu l'avais interrompue
(p.e. si le gestionnaire d'exception s'est contenté d'afficher un
simple warning) ?  Ça c'est du call/cc, et ce n'est possible qu'avec
des exceptions montantes.

Même le multitasking c'est une forme d'appels de continuations
imbriqués, simulés par des mécanismes de bas niveau, mais c'en est
tout de même.

>> simplement, je n'ai pas leur talent.
> 
>  À d'autres. Tu as utilisé Caml parce qu'il était tout simplement plus
> adapté à ce que tu voulais écrire. Cela t'aurait coûté plus d'efforts de
> faire tes interpréteurs aussi proprement en Scheme ; te connaissant, que tu
> aies renoncé prouve que c'est _vraiment_ difficile. Tu avoues toi-même que
> Caml est plus pratique en utilisation réelle ( pourquoi j'ai l'impression
> que Max et Valentin sont explosés de rire, là ? )

Toutes les applications réelles ne sont pas des écritures
d'interpréteurs comme je l'ai fait.

De toute façon, en ce moment je refais ça en C.  Vas-tu en conclure
que c'est parce que le C est plus pratique ?

>> Les blonds / les bru...  AÏE !  PAS TAPER !
> 
>  Pourquoi ? je l'ai omise, mais elle est bien, cette différence. Non
> seulement elle prouve que tu n'as aucun goût mais en plus elle m'arrange :)
                                    ^^^^^^^^^^
Parce que je préfère les blonds aux bruns ou parce que je préfère les
blonds aux blondes ?

>  Ska, qui raccroche provisoirement son tomahawk.

C'est une erreur de te retourner pour faire ça, dear.

From madore@news.ens.fr
Path: eleves!not-for-mail
From: madore@news.ens.fr (GroTeXdieck)
Newsgroups: ens.forum.informatique.lang.caml
Subject: Re: caml pas objective
Date: 12 Oct 1999 22:14:53 GMT
Lines: 59
Sender: madore@clipper.ens.fr
Message-ID: <7u0bst$4il$1@clipper.ens.fr>
References: <7ttft3$1l7$1@clipper.ens.fr> <7tvns3$um$1@clipper.ens.fr> <7tvoce$nj8$4@clipper.ens.fr> <7tvp6m$381$1@clipper.ens.fr> <7tvv3a$dsj$4@clipper.ens.fr> <7tvvsn$ga0$1@clipper.ens.fr>
NNTP-Posting-Host: clipper.ens.fr
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: clipper.ens.fr 939766493 4693 129.199.129.1 (12 Oct 1999 22:14:53 GMT)
X-Complaints-To: forum@clipper.ens.fr
NNTP-Posting-Date: 12 Oct 1999 22:14:53 GMT
X-Newsreader: Flrn (0.4.0 - 07/99)
X-Wisdom-Of-The-Day: to be honest, humor might not cause a lot of silence 
Xref: eleves ens.forum.informatique.lang.caml:229

Roger Espel Llima in litteris (informatique.lang.caml:217) scripsit :
> est-ce que tu en as un du même style pour les call/cc non lineaires?

Ben tu peux vouloir appeler plusieurs fois le même handler d'exception
de manière réentrante sans avoir à rafraîchir la continuation
(i.e. refaire un call/cc en sortie et repositionner la variable
globale qui désigne la continuation associée au handler).

> je dois avouer que je vois mal l'interet pratique pour un programme de
> revenir deux fois au même état à travers la même continuation.  j'ai
> l'impression que c'est un contrainte excessivement forte sur tout
> l'environnement runtime, et je ne vois pas trop ce qu'on y gagne.

Dépend de ce que les continuations sont censé sauvegarder
précisément.  Il est clair qu'elles ne peuvent pas défaire tous les
effets de bord qu'on aura pu faire entre temps, et même les choses non
fonctionnelles comme un set! ne seront pas défaites.

Voir une discussion sur le dynamic-wind pour plus de précisions.

En tout cas, je ne pense pas que ça fasse des contraintes
excessivement fortes.  De toute façon, on peut fabriquer un vrai
call/cc linéaire à partir d'un call/cc normal en faisant

(define (linear-call/cc proc)
  (let ((saved-cont #f))
    (let ((saved-val (call/cc
                       (lambda (cont)
                         (set! saved-cont cont)
                         (proc (lambda (val) (saved-cont val)))))))
       (set! saved-cont #f)
       saved-val)))

Là, une fois que tu as appliqué la continuation une fois, elle change
sa valeur (en l'unique endroit où celle-ci était stockée) en #f pour
t'empêcher de la réutiliser.  Si le GC est bien fait, il va virer la
continuation et tout ce vers quoi elle pointait lors de la prochaine
collecte des déchets.

> (a moins bien sur qu'on veuille fabriquer tout le flot de controle d'un
> programme a base de call/cc, en sortant du modele structure de base avec
> des fonctions, des modules et des exceptions...  mais bon, ca me semble
> a peu pres aussi clair que de faire tout un programme a base de 'comefrom').

On imagine même un OS qui fait le scheduling à base d'appels de
continuations.  D'ailleurs, c'est ce que font les OS actuels
simplement c'est à bas niveau.  Mais pour cela, les continuations
linéaires suffisent.

> enfin bon, qu'est-ce que je fous moi a poster dans lang.caml, alors que
> je suis tellement obtus que je n'ai toujours rien trouve de beau a caml
> ou a scheme, que l'arbitrariete syntaxique ne me derange pas
> particulierement du moment que ce soit relativement pratique et que j'y
> sois habitue, que je trouve penible de programmer dans des langages
> fonctionnels, et que meme quand on m'explique que c'est relativement
> facile d'y tranposer ses habitudes de programmeur imperatif, je n'en
> vois pas du tout l'interet.  bref, continuez sans moi.

La différence c'est que toi tu es modeste et honnête, nous non.

From madore@news.ens.fr
Path: eleves!not-for-mail
From: madore@news.ens.fr (GroTeXdieck)
Newsgroups: ens.forum.informatique.lang.caml
Subject: Re: caml pas objective
Date: 12 Oct 1999 23:01:58 GMT
Lines: 216
Sender: madore@clipper.ens.fr
Message-ID: <7u0el6$7em$1@clipper.ens.fr>
References: <7ttft3$1l7$1@clipper.ens.fr> <7ttr3o$eim$2@clipper.ens.fr> <7ttvj5$hd8$1@clipper.ens.fr> <7tvlaa$nj8$1@clipper.ens.fr> <7tvqsm$8jp$1@clipper.ens.fr> <7tvvel$gkm$1@clipper.ens.fr>
NNTP-Posting-Host: clipper.ens.fr
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: clipper.ens.fr 939769318 7638 129.199.129.1 (12 Oct 1999 23:01:58 GMT)
X-Complaints-To: forum@clipper.ens.fr
NNTP-Posting-Date: 12 Oct 1999 23:01:58 GMT
X-Newsreader: Flrn (0.4.0 - 07/99)
X-Wisdom-Of-The-Day: to be honest, humor might not cause a lot of silence 
Xref: eleves ens.forum.informatique.lang.caml:233

Ska in litteris (informatique.lang.caml:216) scripsit :
>> Si j'insiste je peux transformer tout code caml en code Scheme et vice
>> versa, en fait.  D'ailleurs, si j'insiste, je peux écrire Tunes, en
>> fait. 
> 
>  Et si ON insiste, tu peux l'écrire, aussi ?

Je *suis* en train de l'écrire.  Et pour faire chier Faré je
bootstrappe en C.  Va voir dans ~madore/c/tunes/

Ah oui, j'oubliais : c'est trop tard, j'ai déjà implémenté le
call/cc ; c'était nécessaire pour la manière dont je fais le
multitasking.

>> Heu...  Elle est intuitive, la définition d'un identificateur, en ML ?
>> Déjà le coup de la distinction majuscule/minuscule sur la première
>> lettre, ça me hérisse.  Les n namespaces différents, ça me scie,
>> aussi.
> 
>  C'est dans la norme, ça, maintenant ? Erreur. Avant, c'était des conventions
> et ça fonctionnait très bien comme ça...

Oui, c'est dans la norme (si on peut parler de norme).

>> Valentin en a donné de bons.  D'ailleurs, tu prends à peu près
>> n'importe quelles deux constructions du caml et tu les regarde côte à
>> côte.
> 
> <foi attr="mauvaise">
> 
> ( function x -> (+) 1 x ) 3
> let p = ref 3 in ( p := (+) 1 !p ; !p )

Tu veux dire, ( function p -> p := (+) 1 !p; !p ) ( ref 3 ), bien
entendu.

> let x = 3 in match x with _ -> x+1
> 
>  Je vois ces trois constructions et je ne vois pas où est le problème.
> 
> </foi>

Bien, je suis heureux de voir que tu as un certain sens de
l'esthétique et que tu écris du code Propre (tm).  Continue.  « Tu
seras un homme, mon fils. »

> (define f (lambda (x) (+ x 1)))
> (f 3)
> 
> Entre l'application de f et l'"application" de define, ou de lambda, il y a
> quoi comme différence visuelle ?

Pas plus que comme différence dans

# let x = 42;;
val x : int = 42
# let lot f x = 
  print_string "Madame Irma va maintenant répondre à la grande question:\n"; 
  print_string "Le CAML a-t-il une syntaxe aberrante?";
  x+1;;
val lot : 'a -> int -> int = <fun>
# let f x = x+1;;
val f : int -> int = <fun>
# lot f x = x+1;;
Madame Irma va maintenant répondre à la grande question:
Le CAML a-t-il une syntaxe aberrante?- : bool = true

Parce que le « let » est un mot-clé, le « = » change de syntaxe un peu
plus loin.  Et comme tu vois, si « let » était une fonction « lot »,
les choses seraient singulièrement différentes.

>> Oui, ça te permet d'inclure un évaluateur Scheme dans ton programme en
>> trois coups de cuiller à pot.
> 
>  Bon, à part se masturber intellectuellement et apprendre la programmation, ça
> sert à quoi d'implémenter en L un interpréteur de L ?

Apo a bien répondu.

(define (plot-function f) ...)

(define (main argv)
  (display "Enter the function to plot:")
  (plot-function (eval (read))))

et le type peut entrer (lambda (x) (x)) par exemple...

>> Et même si tu ne veux pas faire ce genre de choses, ça permet que le
>> langage de macros (le préprocesseur, quoi) soit propre, pour une fois.
> 
>  Tu me fais penser au plombier qui débarque dans une maison inondée, la
> baignoire a les robinets ouverts à fond et déborde violemment, et le plombier
> remarque une goutte d'eau qui suinte d'un tuyau et diagnostique :
> « c'est un joint qui fuit. »

L'apartement c'est Ska, et le joint qui fuit c'est ta
non-compréhension du Scheme, c'est ça ?  ;-)

> Juste fais-le. Juste écris Tunes.

Moi au moins j'essaye (sous-entendu : pas comme Faré).

>  C'est vrai. J'ai été trop rapide. Mais franchement, crois-tu qu'un truc à
> base de combinateurs SKK, ou de réseaux d'interaction, ou de je ne sais quoi
> encore, puisse fournir un paradigme raisonnable à la programmation
> fonctionnelle ? Le lambda-calcul n'est pas minimal, d'accord, mais c'est un

Je ne parlais pas des combinateurs SKI (enfin, juste entre
parenthèses).  Je signalais, comme tu l'as d'ailleurs fait dans un
message ultérieur que tu peux faire

(define (functional-lambda args body)
  (eval `(lambda ,args ,body)))

et à partir de là tu peux faire du Scheme en fonctionnel pur : (lambda
(foo) bar) se réécrit (functional-lambda '(foo) 'bar), et comme
functional-lambda est une fonction, tu ne vas plus te plaindre.  En
fait, ce n'est pas encore bon, car '(foo) c'est (quote (foo)), et
qu'il faudrait donc réécrire ça en (list 'foo), ou, mieux, en (list
(string->symbol "foo")), voire en (list (string->symbol (list->string
(list #f #o #o)))), voire en (list (string->symbol (list->string (list
(number->char 102) (number->char 111) (number->char 111))))), voire le
102 en (+ one one one ...) avec one variable prédéfinie comme étant
égale à 1.  Mais comme je sais que tu es raisonable, '(foo) te
conviendra aussi bien que tout ça puisque le ' marque « clairement »
qu'il s'agit d'une forme spéciale.

> excellent compromis entre le minimalisme et la clarté. Et dans l'optique de
> ce compromis, permettre la confusion entre l'abstraction et l'application est
> une MAUVAISE idée.

Et si je renomme « lambda » en « -> » (lequel est un symbole valide en
Scheme), tu seras content ?  Sinon, tu es de mauvaise foi parce que
« fun x -> 3 » on peut bien comprendre ça comme « fun agissant sur x
agissant sur -> agissant sur 3 ».

>> Il y a des langages qui ne sont pas Tunes et qui font très bien du
>> typage dynamique.
> 
>  Ah oui, tiens, le typage dynamique, je l'oubliais celui-là. Je l'oubliais pour
> une non-raison, une absurdité, une négligeabilité absolue : la performance...

<troll>
Ceux qui veulent de la performance n'ont qu'à pas programmer dans les
langages fonctionnels.  Et vingt ans plus tard ils se retrouveront
comme Knuth aujourd'hui qui continue à écrire à la main de
l'assembleur alors que tout le monde se fout de lui.
</troll>

>  Le || d'Esterel est atomique aussi, n'est-ce pas ?

Tu m'expliques ce que c'est, je ne connais pas ?

>  Zut alors, on ne peut pas s'en servir, ni en Caml, ni en Scheme. Ben tiens,
> ils ne sont pas faits pour ça : ce sont des langages _fonctionnels_. Et le
> but d'un tel langage n'est pas forcément d'avoir toutes les opérations
> atomiques imaginables.

Mais merde, il est utile le call/cc.  C'est pas parce qu'on peut s'en
passer qu'il le faut.  Le gc aussi tu peux t'en passer, ça n'empêche
que c'est chiant.  Ben c'est pareil pour le call/cc.  Pas ma faute si
tu n'as jamais compris comment on le maniait.  Essaye un peu de faire
un beau programme de recherche de minimax (par exemple) et vois à quel
point le call/cc te simplifie la vie.  Ou bien lis n'importe quel
bouquin sur le sujet.

>> Tu aimes les exceptions, n'est-ce pas ?  Les exceptions c'est bien,
>> n'est-ce pas ?  C'est indispensable, non ?
> 
>  C'est bien, oui. Ce n'est pas indispensable, non. C'est juste propre.
> Si je veux, je peux toujours émuler une exception en ajoutant des booléens
> et des tests partout dans la structure de mon programme.

Et tu peux surtout te planter en beauté.

Le call/cc c'est pareil, tu peux l'émuler grâce au CPS (par exemple).
Le gc aussi tu peux t'en passer.

Rappel : ce n'est pas parce que c'est utile que ce n'est _pas_
indispensable.

>>  Eh bien, il ne t'est jamais arrivé, après le traitement d'une exception,
>> d'avoir envie de reprendre l'exécution du programme là où tu l'avais
>> interrompue (p.e. si le gestionnaire d'exception s'est contenté d'afficher un
>> simple warning) ?
> 
>  Ben non, ça ne m'est jamais arrivé, justement. Pourquoi ? parce que je fais
> de la programmation _structurée_, ce qu'on m'a appris à faire dans les
> "petites classes", et ce que je sais faire, et pour l'instant ça répond à
> mes besoins.

En quoi n'est-ce pas structuré d'appeler une exception et de
redescendre dans le corps du programme ?  Ou d'écrire des coroutines ?

>> De toute façon, en ce moment je refais ça en C.  Vas-tu en conclure
>> que c'est parce que le C est plus pratique ?
> 
>  Oui. Plus pratique au sens plus efficace/rapide/... , en tout cas, plus
> adapté à tes besoins du moment. Ou alors, déclare tout de suite ta flamme à
> Valentin, ça te coûtera moins d'efforts.

Valentin, je te donne le droit de taper Ska.

>>> aucun goût
>>  ^^^^^^^^^^
>> Parce que je préfère les blonds aux bruns ou parce que je préfère les
>> blonds aux blondes ?
> 
>  Parce que tu préfère les blonds aux brunes, tiens.

J'oublais que tu ne sais peut-être pas ce que c'est qu'un diagramme
commutatif.

>  Ska, qui va aller dîner parce que bon.

Bon appétit.

From madore@news.ens.fr
Path: eleves!not-for-mail
From: madore@news.ens.fr (GroTeXdieck)
Newsgroups: ens.forum.informatique.lang.caml
Subject: Caml c'est de la m***e
Date: 12 Jul 1999 23:59:58 GMT
Lines: 34
Sender: madore@clipper.ens.fr
Message-ID: <7mdvhu$7cv$1@clipper.ens.fr>
NNTP-Posting-Host: clipper.ens.fr
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: clipper.ens.fr 931823998 7583 129.199.129.1 (12 Jul 1999 23:59:58 GMT)
X-Complaints-To: forum@clipper.ens.fr
NNTP-Posting-Date: 12 Jul 1999 23:59:58 GMT
X-Newsreader: Flrn (0.4pre2 - 05/99)
X-Rumor: A glowing potion is too hot to drink. 
X-Number-Of-The-Day: 451 
Xref: eleves ens.forum.informatique.lang.caml:83

Et un langage de plus, le caml cette fois-ci, qui rejoint ma blacklist
des langages de daube.

Vous avez déjà essayé de manipuler des chaînes de caractères en caml ? 
Vous pouviez imaginer un langage pire que le C dans ce domaine ?  Non ?
Eh bien les gars de l'INRIA l'ont fait !

Récapitulons.  Des chaînes de longueur fixe : ça torsche pas mal, ça,
on peut modifier la chaîne après sa création mais pas sa longueur.  (Il
est question dans la doc d'un fantomatique module Buffer, mais celui-ci
est aux abonnés absents.)  Aucun constructeur digne de ce nom.  Pas de
list_of_string ni de string_of_list (alors que même le Scheme, qui
pourtant est très bien placé en ce qui concerne les bibliothèques
d'exécution merdiques, a tout ce qu'il faut).  Pas de moyen d'obtenir
une référence vers une chaîne privée de son premier élément (ce qui
serait drôlement pratique pour lire récursivement une chaîne élément
par élément).  Pas de façon de convertir une chaîne en un stream de ses
éléments.  Et j'en passe des plus belles.

Peut-être, direz-vous, que je ne sais pas me servir des fonctions
effectivement fournies, et que c'est pour ça que ça me paraît pénible. 
Si vous pensez ça, je vous conseille de regarder le code de « escaped »
dans la bibliothèque String de ocaml (dans stdlib/string.ml).  C'est
carrément du code impératif puant et ignoble - et très long qui plus
est pour un truc aussi merdique : on commence par calculer la longueur
de la chaîne produite, puis on la produit effectivement (redondance
dans le code => source de bugs).

Bref, tout ce qu'on gagne avec un langage de haut niveau comme ça, on
le perd à patauger dans de la programmation pseudo-impérative
trébuchante faute de bibliothèque digne de ce nom.  Le Java, en
comparaison, est d'une élégance extrême.

Common Lisp, anyone ?

