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 >> > >> > >> > >> > >