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 DDF91BC58 for ; Sat, 27 Nov 2010 13:31:23 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsQEAEyJ8EyC4WBcgWdsb2JhbACUWo4yFQEBFiIiiCy2MoVHBJBh X-IronPort-AV: E=Sophos;i="4.59,266,1288566000"; d="scan'208";a="80317163" Received: from mgw2.diku.dk ([130.225.96.92]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 27 Nov 2010 13:30:56 +0100 Received: from localhost (localhost [127.0.0.1]) by mgw2.diku.dk (Postfix) with ESMTP id E0E6D19BD4A; Sat, 27 Nov 2010 13:30:54 +0100 (CET) Received: from mgw2.diku.dk ([127.0.0.1]) by localhost (mgw2.diku.dk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 15507-19; Sat, 27 Nov 2010 13:30:50 +0100 (CET) Received: from nhugin.diku.dk (nhugin.diku.dk [130.225.96.140]) by mgw2.diku.dk (Postfix) with ESMTP id 2B4884DC0ED; Sat, 27 Nov 2010 13:23:13 +0100 (CET) Received: from ask.diku.dk (ask.diku.dk [130.225.96.225]) by nhugin.diku.dk (Postfix) with ESMTP id 882B56DF823; Sat, 27 Nov 2010 13:19:06 +0100 (CET) Received: by ask.diku.dk (Postfix, from userid 3767) id 0BCF1200A7; Sat, 27 Nov 2010 13:23:12 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by ask.diku.dk (Postfix) with ESMTP id E8D7D474E3; Sat, 27 Nov 2010 13:23:12 +0100 (CET) Date: Sat, 27 Nov 2010 13:23:12 +0100 (CET) From: Julia Lawall To: bluestorm Cc: mark@proof-technologies.com, mehdi.dogguy@pps.jussieu.fr, caml-list@yquem.inria.fr Subject: Re: [Caml-list] zero-arity constructor In-Reply-To: Message-ID: References: <1290851344516@names.co.uk> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Spam: no; 0.00; ocaml:01 camlp:01 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 In my case, I originally thought that the constructor should take an argument, then changed my mind. I would have hoped that OCaml would have found the inconsistency. That's what static typing is for. Thus, I find the change quite disappointing. Perhaps it would have been nicer to have an option to allow the behavior that is useful in the camlp4 case, rather than making it the default. julia On Sat, 27 Nov 2010, 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 > > > > > > > > > > > >