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 26FB2BBAF for ; Sat, 27 Nov 2010 11:32:06 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArADAC1t8EzRVditkGdsb2JhbACUWoYpAYgACBYBAQEJCQwHEQMfiCycBYlkghiESi6IVgEBAwWFQgSBXIkFhgCDLQ X-IronPort-AV: E=Sophos;i="4.59,266,1288566000"; d="scan'208";a="80314449" Received: from mail-qy0-f173.google.com ([209.85.216.173]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-MD5; 27 Nov 2010 11:32:05 +0100 Received: by qyk1 with SMTP id 1so6653586qyk.18 for ; Sat, 27 Nov 2010 02:32:03 -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=ieY6uhIMyQEskWiobFoW7VFDCyx1xjhsAA0I98KSdG4=; b=cAKnFxKp8cboiyespk7Xsd2zX3YelgjhUUWVqqY9XV0s1ckg95fkP/foBln1RmM4ug jMWN/H44KnYW/zc1FQFTYfOkvt/lpblOpvg2Bd58CrCADaWXNm3ufeGsUHcsHrfB+J6w Q3NzJ3rDLINVwpV0caW69SonL1bvT04rrNL1c= 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=hhUReWJoJw2HWjUMGvlUaDPzOr+MpOr+DhJ9/QpoUKtisKbsBu/r/JQkdHdjwntiJF 4cHLj6UjQH2A1EKTxdGwRUwBQx9C/o5CQFfEK3D0jsOo19d5ymbZtEOLpSTFHpZgO6yB dsoOCt5QbfcsKC9Xfr1AUMPSBiMFo0GhojlSI= Received: by 10.229.189.4 with SMTP id dc4mr2625012qcb.106.1290853921804; Sat, 27 Nov 2010 02:32:01 -0800 (PST) MIME-Version: 1.0 Sender: gabriel.scherer@gmail.com Received: by 10.229.253.135 with HTTP; Sat, 27 Nov 2010 02:31:41 -0800 (PST) In-Reply-To: <1290851344516@names.co.uk> References: <1290851344516@names.co.uk> From: bluestorm Date: Sat, 27 Nov 2010 11:31:41 +0100 X-Google-Sender-Auth: 51zNVAO8aUcVYY5tWATdMUSJwaA 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=0016361e815c7750fd0496065984 X-Spam: no; 0.00; syntax:01 syntax:01 camlp:01 constructors:01 foo:01 -like:01 -like:01 foo:01 explicitely:01 haskell:01 ad-hoc:01 haskell:01 bug:01 frisch:01 ocaml:01 --0016361e815c7750fd0496065984 Content-Type: text/plain; charset=ISO-8859-1 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 > > > > > > > --0016361e815c7750fd0496065984 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable On= Sat, Nov 27, 2010 at 10:49 AM,=A0<mark@proof-technologies.com>=A0wr= ote:
Surely it's preferable to use a syntactically distinct mechanism for th= is
subtly different concept.

Agreed.
=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 syntax ac= cepted in parallel with the old one, but I wouldn't hope of changing th= e current syntax which would break a large amount of code. Reversing the sp= ecific 0-ary modification suggested by Alain is probably easier, as I suspe= ct 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 diff= erent 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, 20= 10 at 10:49 AM, <mark@proof-technologies.com> wrote:
Surely it's preferable to use a syntactically distinct mechanism for th= is
subtly different concept. =A0Given that we're talking about patterns an= d 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 compatibili= ty
dictates that this cannot be changed?

type ty =3D A | B

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

Mark 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 change an= d were
> baffled to find out that "it's not a bug, it's a feature&= quot;.
>
> The change was asked for by Alain Frisch in 2006 (
> http://caml.inria.fr/mantis/view.php?id=3D4052 ) and finally add= ed 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<= br> > 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= 9;s the
> constructor K, I don't care about the arguments" is much easi= er as you
don't
> have to carry =A0arity information around.
>
> The downside of this behaviour is that the universal pattern _ has an<= br> > different meaning in this setting. It does not only matches any value = (as
> the manual says : http://caml.inria.fr/pub/docs/manual-oca= ml/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 lost.
> Note that this was already the case before the change suggested by Ala= in
> Frisch : _ would work for two-arguments constructors as well, while a<= br> 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 o= f
> 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 =3D A | B
>
> let test =3D function
> | A _ -> ()
> | B -> ()
>
> $ ocaml -w +28 test.ml
> File "
test.ml&qu= ot;, line 4, characters 4-5:
> Warning 28: wildcard pattern given as argument to a constant construct= or
>
> 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 <julia@diku.dk> 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 co= mpile 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=3D4675 (an= d other related
>> > bugreports).
>>
>> OK, thanks. =A0I 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-li= st
>> Archives: http:= //caml.inria.fr
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginner= s
>> 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://ca= ml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports:
http://caml.inria.fr/bin/caml-bugs
>
>
>

--0016361e815c7750fd0496065984--