Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: [Caml-list] zero-arity constructor
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: bluestorm <bluestorm.dylc@g...>
Subject: Re: [Caml-list] zero-arity constructor
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 <bluestorm.dylc@gmail.com>
 wrote:

> On Sat, Nov 27, 2010 at 10:49 AM, <mark@proof-technologies.com> 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, <mark@proof-technologies.com> 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 <bluestorm.dylc@gmail.com> 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 <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 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
>> >
>> >
>> >
>>
>
>