From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 0A64FBBAF for ; Sat, 27 Nov 2010 14:38:56 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjQCAIaY8EzRVdg0kGdsb2JhbACUWoYpAYc2SggVAQEBAQkJDAcRAx+ILJ0biWSCGIQ4LohWAQEDBYVCBIFciQWGAIMt X-IronPort-AV: E=Sophos;i="4.59,266,1288566000"; d="scan'208";a="80318529" Received: from mail-qw0-f52.google.com ([209.85.216.52]) by mail4-smtp-sop.national.inria.fr with ESMTP; 27 Nov 2010 14:38:55 +0100 Received: by qwf7 with SMTP id 7so2334757qwf.39 for ; Sat, 27 Nov 2010 05:38:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:mime-version:sender:received :in-reply-to:references:from:date:x-google-sender-auth:message-id :subject:to:cc:content-type; bh=B/g8ab36Yzqa88W7iKZ3kdv1nsScI4D+xciwqxRUB9w=; b=RNMVTPHdqzTYCBIS8347Tx+6Jxm41dEqOQQIZuv46Un0TBGBEL0WfFktujeXcY6Xv6 6Bp4fz/hdbSpG/vxoZ+eskKtO0wr5QeGsJUPn2B7EnXbne3HsSTtUoOgE1i/ryU7U+NS fUxzhs9xhqxbO2gViZ5+uFlFm3eAgaioYtSf8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:from:date :x-google-sender-auth:message-id:subject:to:cc:content-type; b=aPL9gBk/5Xi4WZwrTuFjl9cqTcn+M8L6A6O0WGcSiWo3LLlXsTcW7OR2XoavVrtwfZ bYaThEHirq6FmqHqqOUUimC+Sx/H9kPjpNMzf3d8I6GiXjfAD40Icn1vvHIgjPeB18cX 7Du7fQswmPqdT2d2e46WHwzf9Dzy3zEKqlqRg= Received: by 10.229.183.135 with SMTP id cg7mr2751114qcb.296.1290865134215; Sat, 27 Nov 2010 05:38:54 -0800 (PST) MIME-Version: 1.0 Sender: gabriel.scherer@gmail.com Received: by 10.229.253.135 with HTTP; Sat, 27 Nov 2010 05:38:34 -0800 (PST) In-Reply-To: References: <1290851344516@names.co.uk> From: bluestorm Date: Sat, 27 Nov 2010 14:38:34 +0100 X-Google-Sender-Auth: 11Wh3yCCW5-04VE4LoP7sGF1SgY Message-ID: Subject: Re: [Caml-list] zero-arity constructor To: mark@proof-technologies.com Cc: julia@diku.dk, mehdi.dogguy@pps.jussieu.fr, caml-list@yquem.inria.fr Content-Type: multipart/alternative; boundary=0016364d2c91c721d7049608f513 X-Spam: no; 0.00; syntax:01 foo:01 foo:01 syntax:01 constructors:01 ocaml:01 ocaml:01 constructors:01 camlp:01 -like:01 -like:01 explicitely:01 haskell:01 ad-hoc:01 haskell:01 --0016364d2c91c721d7049608f513 Content-Type: text/plain; charset=ISO-8859-1 A quick follow-up on my post, about a discontinuity in the current syntax. It is possible to write a pattern to ignore the two parameters of a constructor, but fail if the constructor has a different number of parameter : Foo (_, _). To my knowledge, it is not possible to ignore one parameter, but fail if the constructor has a different number of parameter : (Foo (_)) is parsed exactly like (Foo _), so it will accept any number of parameters; and this is good, because we probably want to property that p and (p) are equivalent patterns. A solution might be to use a special syntax for 1-parameter constructors such as (x,), and to allow the 1-ary pattern (Foo (_,)). There is no risk of conflict with other extended meanings for this syntax -- a Haskeller might want to see a partial application of tupling operator -- because of the general ocaml convention that an additional optional delimiters in sequences is possible: [a;], {a=b;}... Due to this convention, any other meaning for (1,2,) than (1,2) would be a bad idea, and it is therefore future-safe to expect (a,) to mean a 1-ary construction. Note that there is no "1-tuple" construct in OCaml; I'm describing patterns algebraic constructors with one parameter, not constructors with one 1-tuple parameter. (But it would not be a problem if they were added: as OCaml is strict, the pattern _ and (_,) would be equivalent on one-tuples). On Sat, Nov 27, 2010 at 11:31 AM, bluestorm wrote: > On Sat, Nov 27, 2010 at 10:49 AM, wrote: > > Surely it's preferable to use a syntactically distinct mechanism for this >> subtly different concept. > > > Agreed. > > >> Perhaps something like '*' to mean 0 or more. Or is it already too late >> because '_' has already been incorporated and backwards compatibility >> dictates that this cannot be changed? >> > > I suppose that it is too late. You might get a new syntax accepted in > parallel with the old one, but I wouldn't hope of changing the current > syntax which would break a large amount of code. Reversing the specific > 0-ary modification suggested by Alain is probably easier, as I suspect most > users don't use that one much, but Alain probably makes use of it; but that > would not achieve your goal of using different syntax for different > meanings. > > What you might do, if you're interested in this change for your personal > use, is to write a camlp4 extension to modify the syntax accordingly. I > think it would be quite easy to do : support the new syntax (in terms of the > old one), and add a warning or an error when the old one is used. There is > one important problem however: as Alain pointed out, a syntax extension > cannot easily keep track of constructor arities -- think of constructors > declared in other modules -- so a reasonable syntax extension would *also* > raise a warning/error for the 1-ary case. When it encounters (Foo _), it > cannot know if this is a *-like _ for a n-ary constructor, or a _-like _ for > a 1-ary constructor. The most reasonable thing to do would be to forget (Foo > _) altogether, and use (Foo (_)) in your code when you explicitely want to > ignore one parameter. That has syntactic costs you may not wish to pay. > > > Finally, I'd like to point out that Haskell has a similar, not well-known, > ad-hoc syntactic rule, though it is arguably less confusing, and certainly > better documented. In haskell 98, you can use a (Foo {}) pattern to ignore > the parameters of any n-ary constructor. This is an extension of the > record-matching syntax {}, extension that works even when the constructor > was not defined using named fields (the Haskell way of doing records, which > is mostly a syntaxic sugar above tuples). > > > On Sat, Nov 27, 2010 at 10:49 AM, wrote: > >> Surely it's preferable to use a syntactically distinct mechanism for this >> subtly different concept. Given that we're talking about patterns and not >> general expressions here, surely there's plenty of space in the syntax. >> Perhaps something like '*' to mean 0 or more. Or is it already too late >> because '_' has already been incorporated and backwards compatibility >> dictates that this cannot be changed? >> >> type ty = A | B >> >> let test = function >> | A * -> () >> | B -> () >> >> Mark Adams >> >> on 26/11/10 10:35 PM, bluestorm wrote: >> >> > A quick summary for those like me that didn't follow the change and were >> > baffled to find out that "it's not a bug, it's a feature". >> > >> > The change was asked for by Alain Frisch in 2006 ( >> > http://caml.inria.fr/mantis/view.php?id=4052 ) and finally added in >> ocaml >> > 3.11. The rationale is to make it easy to mechanically -- think camlp4 >> or >> > another preprocessor -- generate pattern clauses to test for the head >> > constructor of a data type, ignoring it's parameter. >> > Before that change, (K _) would work for all constructors K of arity >> greater >> > than 1, but not for arity 0. After the change, (K _) work even for >> constant >> > constructors. Generating a match clause that says "looks if it's the >> > constructor K, I don't care about the arguments" is much easier as you >> don't >> > have to carry arity information around. >> > >> > The downside of this behaviour is that the universal pattern _ has an >> > different meaning in this setting. It does not only matches any value >> (as >> > the manual says : >> http://caml.inria.fr/pub/docs/manual-ocaml/patterns.html >> > ), >> > but also "matches any number of arguments, possibly 0". The nice >> > compositional interpretation of patterns -- K (p1, .., pN) matches a >> value >> > with constructor K and whose N arguments match p1..pN -- is lost. >> > Note that this was already the case before the change suggested by Alain >> > Frisch : _ would work for two-arguments constructors as well, while a >> named >> > variable wouldn't -- this is well-known subtle difference between (Foo >> of >> a >> > * b) and (Foo of (a * b)). The pattern _ ignored any non-zero number of >> > arguments. >> > >> > Note that since ocaml 3.12, there is a warning available for this very >> > error. >> > >> > $ ocaml -warn-help >> > [...] >> > 28 Wildcard pattern given as argument to a constant constructor. >> > [...] >> > >> > $ cat test.ml >> > type ty = A | B >> > >> > let test = function >> > | A _ -> () >> > | B -> () >> > >> > $ ocaml -w +28 test.ml >> > File "test.ml", line 4, characters 4-5: >> > Warning 28: wildcard pattern given as argument to a constant constructor >> > >> > I think than, in the end, it's all a matter of compromise. >> > >> > Thanks to Julia and Mehdi for casting light on the dark corners of the >> ocaml >> > syntax! >> > >> > PS : I haven't found that behaviour documented anywhere. Maybe it would >> be >> > good to describe that special behaviour of _ on constructors in the >> manual? >> > >> > On Fri, Nov 26, 2010 at 11:02 PM, Julia Lawall wrote: >> > >> >> On Fri, 26 Nov 2010, Mehdi Dogguy wrote: >> >> >> >> > On 11/26/2010 10:46 PM, Julia Lawall wrote: >> >> > > The following code compiles in 3.12.0 but doesn't compile in >> 3.10.2. >> >> > > Is it a bug or a feature? >> >> > > >> >> > >> >> > It's a feature that was implemented in 3.11.0 (iirc). >> >> > >> >> > See: http://caml.inria.fr/mantis/view.php?id=4675 (and other related >> >> > bugreports). >> >> >> >> OK, thanks. I agree wth those that don't like the change... >> >> >> >> julia >> >> >> >> _______________________________________________ >> >> Caml-list mailing list. Subscription management: >> >> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list >> >> Archives: http://caml.inria.fr >> >> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners >> >> Bug reports: http://caml.inria.fr/bin/caml-bugs >> >> >> > >> > >> > >> > ---------------------------------------- >> > _______________________________________________ >> > Caml-list mailing list. Subscription management: >> > http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list >> > Archives: http://caml.inria.fr >> > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners >> > Bug reports: http://caml.inria.fr/bin/caml-bugs >> > >> > >> > >> > > --0016364d2c91c721d7049608f513 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
A quick fol= low-up on my post, about a discontinuity in the current syntax.
<= br>
It is possible to write a pattern to ignore the two parameter= s of a constructor, but fail if the constructor has a different number of p= arameter : Foo (_, _).
To my knowledge, it is not possible to ignore one parameter, but fail = if the constructor has a different number of parameter : (Foo (_)) is parse= d exactly like (Foo _), so it will accept any number of parameters; and thi= s is good, because we probably want to property that p and (p) are equivale= nt patterns.

A solution might be to use a special syntax for 1-param= eter constructors such as (x,), and to allow the 1-ary pattern (Foo (_,)). = There is no risk of conflict with other extended meanings for this syntax -= - a Haskeller might want to see a partial application of tupling operator -= - because of the general ocaml convention that an additional optional delim= iters in sequences is possible: [a;], {a=3Db;}... Due to this convention, a= ny other meaning for (1,2,) than (1,2) would be a bad idea, and it is there= fore future-safe to expect (a,) to mean a 1-ary construction.

Note that there is no "1-tuple" construct in = OCaml; I'm describing patterns algebraic constructors with one paramete= r, not constructors with one 1-tuple parameter. (But it would not be a prob= lem if they were added: as OCaml is strict, the pattern _ and (_,) would be= equivalent on one-tuples).

On Sa= t, Nov 27, 2010 at 11:31 AM, bluestorm=A0<bluestorm.dylc@gmail.com>=A0w= rote:
On Sat, Nov 27, 2010 at 10:49 AM,=A0<mark@proof-technologies.com= >=A0wrote:

Surely it's preferable to use a syntactically distinct mechanism for th= is
subtly different concept.

Agree= d.
=A0
Perhaps something like '*' to mean 0 or more. =A0Or is it already t= oo late
because '_' has already been incorporated and backwards = compatibility
dictates that this cannot be changed?

I suppose that it is too late. You might get a new syn= tax accepted in parallel with the old one, but I wouldn't hope of chang= ing the current syntax which would break a large amount of code. Reversing = the specific 0-ary modification suggested by Alain is probably easier, as I= suspect most users don't use that one much, but Alain probably makes u= se of it; but that would not achieve your goal of using different syntax fo= r different meanings.

What you might do, if you're interested in this cha= nge for your personal use, is to write a camlp4 extension to modify the syn= tax accordingly. I think it would be quite easy to do : support the new syn= tax (in terms of the old one), and add a warning or an error when the old o= ne is used. There is one important problem however: as Alain pointed out, a= syntax extension cannot easily keep track of constructor arities -- think = of constructors declared in other modules -- so a reasonable syntax extensi= on would *also* raise a warning/error for the 1-ary case. When it encounter= s (Foo _), it cannot know if this is a *-like _ for a n-ary constructor, or= a _-like _ for a 1-ary constructor. The most reasonable thing to do would = be to forget (Foo _) altogether, and use (Foo (_)) in your code when you ex= plicitely want to ignore one parameter. That has syntactic costs you may no= t wish to pay.


Finally, I'd like to point out that = Haskell has a similar, not well-known, ad-hoc syntactic rule, though it is = arguably less confusing, and certainly better documented. In haskell 98, yo= u can use a (Foo {}) pattern to ignore the parameters of any n-ary construc= tor. This is an extension of the record-matching syntax {}, extension that = works even when the constructor was not defined using named fields (the Has= kell way of doing records, which is mostly a syntaxic sugar above tuples).<= /div>


On Sat, Nov 27, 2010 at 10:49 AM,=A0<= mark@proof= -technologies.com>=A0wrote:
Surely it's preferable to use a syntactically distinct mechanism for th= is
subtly different concept. =A0Given that we're talking about patte= rns and not
general expressions here, surely there's plenty of space= in the syntax.
Perhaps something like '*' to mean 0 or more. =A0Or is it already t= oo late
because '_' has already been incorporated and backwards = compatibility
dictates that this cannot be changed?

type ty = =3D A | B

let test =3D function
| A * -> ()
| B -> ()

Ma= rk Adams

on 26/11/10 10:35 PM, bluestorm <bluestorm.dylc@= gmail.com> wrote:

> A quick summary for those like me that didn't follow the chang= e and were
> baffled to find out that "it's not a bug, it= 9;s a feature".
>
> The change was asked for by Alain Fris= ch in 2006 (
>=A0http://caml.inria.fr/mantis/view.php?id=3D4052=A0) and finally= added in ocaml
> 3.11. The rationale is to make it easy to mechanica= lly -- think camlp4 or
> another preprocessor -- generate pattern clauses to test for the head<= br>> constructor of a data type, ignoring it's parameter.
> Be= fore that change, (K _) would work for all constructors K of arity
greater
> than 1, but not for arity 0. After the change, (K _) work even for
= constant
> constructors. Generating a match clause that says "lo= oks if it's the
> constructor K, I don't care about the argum= ents" is much easier as you
don't
> have to carry =A0arity information around.
>
>= ; The downside of this behaviour is that the universal pattern _ has an
= > different meaning in this setting. It does not only matches any value = (as
> the manual says :=A0http://caml.inria.fr/pub/docs/manual-o= caml/patterns.html
> ),
> but also "matches any number= of arguments, possibly 0". The nice
> compositional interpretation of patterns -- K (p1, .., pN) matches a v= alue
> with constructor K and whose N arguments match p1..pN -- is lo= st.
> Note that this was already the case before the change suggested= by Alain
> Frisch : _ would work for two-arguments constructors as well, while a<= br>named
> variable wouldn't -- this is well-known subtle differe= nce between (Foo of
a
> * b) and (Foo of (a * b)). The pattern _ i= gnored any non-zero number of
> arguments.
>
> Note that since ocaml 3.12, there is a warn= ing available for this very
> error.
>
> $ ocaml -warn-he= lp
> [...]
> 28 Wildcard pattern given as argument to a constan= t constructor.
> [...]
>
> $ cat=A0test.ml
> type ty =3D A | B
>
> let test =3D fu= nction
> | A _ -> ()
> | B -> ()
>
> $ ocaml = -w +28=A0test.ml
> File "test.ml&q= uot;, line 4, characters 4-5:
> Warning 28: wildcard pattern given as= argument to a constant constructor
>
> I think than, in the en= d, it's all a matter of compromise.
>
> Thanks to Julia and Mehdi for casting light on the dark corner= s of the
ocaml
> syntax!
>
> PS : I haven't found = that behaviour documented anywhere. Maybe it would be
> good to descr= ibe that special behaviour of _ on constructors in the
manual?
>
> On Fri, Nov 26, 2010 at 11:02 PM, Julia Lawall <= julia@diku.dk> wr= ote:
>
>> On Fri, 26 Nov 2010, Mehdi Dogguy wrote:
>&g= t;
>> > On 11/26/2010 10:46 PM, Julia Lawall wrote:
>> > = > The following code compiles in 3.12.0 but doesn't compile in 3.10.= 2.
>> > > Is it a bug or a feature?
>> > > >> >
>> > It's a feature that was implemented in 3= .11.0 (iirc).
>> >
>> > See:=A0http://caml.inria.= fr/mantis/view.php?id=3D4675=A0(and other related
>> > bugreports).
>>
>> OK, thanks. =A0I agree w= th those that don't like the change...
>>
>> julia>>
>> _______________________________________________
>> Caml-list mailing list. Subscription management:
>>=A0http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
&g= t;> Archives:=A0http= ://caml.inria.fr
>> Beginner's list:=A0http://groups.yahoo.com/group/ocaml_beginn= ers
>> Bug reports:=A0http://caml.inria.fr/bin/caml-bugs
>>
>
>
>
> ----------------------= ------------------
> ___________________________= ____________________
> Caml-list mailing list. Subscription managemen= t:
>=A0http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list=
> Archives:=A0http://caml.inria.fr
> Beginner's list:=A0http://groups.yahoo.com/group/ocaml_beginners<= /a>
> Bug reports:=A0
http://caml.inria.fr/bin/caml-bugs
>
>
>

--0016364d2c91c721d7049608f513--