From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id LAA32210; Mon, 12 Nov 2001 11:29:33 +0100 (MET) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id LAA31784 for ; Mon, 12 Nov 2001 11:29:32 +0100 (MET) Received: from beaune.inria.fr (beaune.inria.fr [128.93.8.3]) by concorde.inria.fr (8.11.1/8.10.0) with ESMTP id fACATVn25342 for ; Mon, 12 Nov 2001 11:29:31 +0100 (MET) Received: by beaune.inria.fr (8.8.8/1.1.22.3/14Sep99-0328PM) id LAA0000005433; Mon, 12 Nov 2001 11:29:31 +0100 (MET) From: Luc Maranget Message-Id: <200111121029.LAA0000005433@beaune.inria.fr> Subject: Re: [Caml-list] Pattern matching To: FernandezPons@iFrance.com (Diego Olivier Fernandez Pons) Date: Mon, 12 Nov 2001 11:29:31 +0100 (MET) Cc: caml-list@inria.fr (Caml) In-Reply-To: <010501c1698e$bc237f40$182ce8d4@Utilisateur> from "Diego Olivier Fernandez Pons" at nov 10, 2001 03:16:03 MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk > > Fabrice Le Fessant a écrit : > > > (* couples 4 = (1,2) (1,3) (1,4) (2,3) (2,4) (3,4) *) > > let couples = function n -> > > let rec couplesCPS = function > > | (n,_) -> [ ] > > | (i,n) -> (i,n) :: couplesCPS (i+1, i+2) > > | (i,j) -> (i,j) :: couplesCPS (i, j+1) > > in couplesCPS (1,2) > > ;; > [...] > > let succ n = n + 1;; > > Le langage introduit nombre de quantificateurs existentiels ou > universels, ne serait-ce que dans la définition même des fonctions : > je lis la définition de la fonction successeur : « soit successeur la > fonction qui a tout n de N associe (n + 1) ». Cela n'a jamais posé la > moindre difficulté aux programmeurs qui, dans la fonction couple - à > votre image - comprennent tous que n est déjà liée tandis que i et j > ne le sont pas. > > D'accord, j'utilise quand je peux la syntaxe : > let succ = function n -> n + 1;; > (mais le compilateur en n'admettant pas let f = function x y -> vous > force parfois à utiliser cette horreur de syntaxe) Je ne comprends pas trop tous ces arguments. Il n'en reste pas moins que 1. Les fonctions sont des citoyens de première classe en Caml et qu'il n'est pas toujours nécessessaire de leur donner un nom. Dans ce cadre la notation (fun x -> ...) est logique. Mais, comme vous semblez le dire vous même, ``let f = fun x -> ...''. c'est lourd. Il y a donc une notation ``let f x = ... '' Je coupe un example de syntaxe bizarre, sur la base de ce qu'on peut écrire de mauvais programmes dans tous les langages. Je trouve plus intéressant de chercher à définir un style de bonne programmation. > let delta = function > | 0 -> 1 > | _ -> 0 > ;; > D'accord car on a disjoint l'ensemble de définition > > let delta = function > | i when (i = 0) -> 1 > | i -> 0 > ;; > à mettre en parallèle avec : > let delta = function > | i when (i = 0) -> 1 > | j -> 0 > ;; > Etrange car on a attrappé deux fois de suite une variable qui prend > des valeurs sur tout l'ensemble de définition et on ne comprend pas > très bien pourquoi cette variable est muette. Je pense qu'elle est muette parce que c'est comme ça. Et je l'admet en toute modestie (j'exagère bien entendu). > Si l'on accepte cela > (qui est conséquence de l'absence de liaison explicite de i une seule > fois pour toutes), pourquoi n'accepterait-on pas qu'une variable dans > le motif soit déjà liée : ce serait tout aussi pratique. > Ben moi ça ne me choque pas. if blabla then let i = ... else let i = ... ne me pose que peu de problème, parceque les deux i ne coexistent pas. let i = .. in if blabla then let i = ... else ... me fait dresser le sourcil, sans me choquer outre mesure. Tout ça dépend probablement de l'intention du programmeur. Au fond Je ne comprends pas l'argument et je dis que, sur cet exemple l'emploi du filtrage est mal venu. Si j'étais prof (et je le suis) il faut écrire let delta i = if i=0 then 1 else 0 Qui me semble la bonne facon de procéder. (ou alors match i with 0 -> 1 | _ -> 0, tout aussi bien) Je decouvre souvent des matchs sans justification dans des copies d'élèves et je me demande à chaque fois pourquoi ne pas utiliser des constructions simples (ici le if ou le match sans when) partout où elles s'appliquent. Maitenant personne ne veut supprimer le when, nous sommes sans doute d'accord. Mais on les verra ailleurs. > Ou alors adopter pour unique syntaxe quelque chose comme > let couple = function n -> > let rec coupleCPS = function (i,j) -> > match (i,j) with > | (n,_) -> [ ] > | (_,n) -> (i, j) :: coupleCPS (i+1, i+2) > | (_,_) -> (i, j) :: coupleCPS (i, j+1) > in > coupleCPS (1,2) > ;; Sans rire c'est exactement ce que je recommanderais, non pas au concepteurs du compilo, mais aux programmeurs, surtout débutants (et d'ailleurs j'ecris généralement dans ce style). Ne pas utliser le filtrage dans les définitions de fonction, toujours utiliser des match explicites. A part ça, le fait de rigidifier la syntaxe ne change rien à l'affaire de mon point de vue. Les variables des filtres sont liantes comme les autres, c'est une règle simple et compréhensible, que je refuse de laisser tomber pour une amelioration d'expressivité (une égalité cachée) dont je persite à croire qu'elle a fort peu d'intérêt. > > On peut utiliser i, j et n dans les motifs et dans le reste du code > car les trois variables ont été liés correctement au préalable Correctement hum ? Les variables sont liés par les motifs, c'est simple et direct. De toute façon, ça ne correspond pas au langage actuel Aet de loin, car dans Caml actuel, toutes les constructions liantes (ou presque) sont exprimées par des motifs, dont les variables sont tout simplement liantes. l'écriture ``fun (x,y) -> ... ''' revèle que la règle est expression = ... | fun pat -> expression | ... (pat pouvant être une variable d'ailleurs) les variables de pat sont liantes comme partout. Le tout est de le savoir. Je crois comprendre l'idée de privilègier en quelque sorte les variables liées dans un ``fun''. Mais bon, pourquoi alors les deuxièmes liaisons de x dans (fun x -> (fun x -> ...) ) et dans (fun x -> match y with x -> auraient-elles une signification différente ? Sincèrement, ça ne tient pas la route. Ça va trop contre un principe général et bien établi à l'heure actuelle. C'est dur à expliquer et sans grande portée pratique. Ce qui pourrait être admis (pour progresser à petits pas sur l'existant) serait, dans certains circonstances l'interdiction (ou le déconseil par un avertissement) de l'introduction de variables homonymes. Genre (fun x -> match y with x -> ...) ^^ | Warning: pas bo, dangereux. Mais bof c'est certainement moins simple à bien spécifier que ça en a l'air. > > < alors le simple fait de definir 'i' avant la fonction > < change le sens de la fonction par rapport a quand > < 'i' n'etait pas defini ? > > Voyez un peu le code de Madore ! L'égalité change de sens dans chacune > des propositions > let f x = x+1;; > lot f x = x+1;; Madore a fait une erreur, la syntaxe ne l'aide pas, mais bon. Elle est du même ordre que = / == en C. En conclusion j'insisterait sur la nécessité pour chacun de se définir un style propre (dans les deux sens) d'écriture qui limite ce type de danger. Bizarrement (cf. l'exemple du if) cela revient souvent à choisir la construction de programmation adaptée à ce que l'on shouhaite exprimer et, parfois, à s'abstenir de traits avancés. (Soit si ya pas de motif pourquoi utiliser un match). Rapelons au passage que filtrer c'est d'abord destructurer. D'autre part, lorsque l'on a effectivement besoin de ces traits avancés, il vaut mieux, je crois, se contraindre à les exprimer toujours de la même façon simple. Ensuite et j'enfonce le clou. Chaque fois que j'utilise des variables de même nom (y compris dans des liasons qui ne semble pas poser de pb, comme les let) j'arrête la programmation en mode automatique et je me pose la question de pourquoi je fais ça, c'est à chaque fois une situation qui demande de toute façon d'y regarder à deux fois, (en particulier parceque la résistances aux modifications ultérieures chute) et la réponse est rarement qu'il y a égalité implicite entre variables homonymes. --Luc ------------------- Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr