caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: bluestorm <bluestorm.dylc@gmail.com>
To: mark@proof-technologies.com
Cc: julia@diku.dk, mehdi.dogguy@pps.jussieu.fr, caml-list@yquem.inria.fr
Subject: Re: [Caml-list] zero-arity constructor
Date: Sat, 27 Nov 2010 14:38:34 +0100	[thread overview]
Message-ID: <AANLkTimBLv8d5BzU_4XeUMbd02Gw+aAWRQ4CgkJkXG4r@mail.gmail.com> (raw)
In-Reply-To: <AANLkTik4=DG1aGWWY8_XZ3+4KmrUgXRrndaq=_8wFp49@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 8275 bytes --]

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

[-- Attachment #2: Type: text/html, Size: 11755 bytes --]

  parent reply	other threads:[~2010-11-27 13:38 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-27  9:49 mark
2010-11-27 10:15 ` David Allsopp
2010-11-27 10:31 ` bluestorm
2010-11-27 12:23   ` Julia Lawall
2010-11-28  7:40     ` Martin Jambon
2010-11-27 13:38   ` bluestorm [this message]
2010-11-28 11:13   ` Alain Frisch
     [not found]   ` <1221507223.79937.1290942833987.JavaMail.root@zmbs1.inria.fr>
2010-12-01 14:22     ` Damien Doligez
     [not found] ` <118427264.71248.1290853319356.JavaMail.root@zmbs1.inria.fr>
2010-12-01 14:29   ` Damien Doligez
  -- strict thread matches above, loose matches on Subject: below --
2010-11-26 21:46 Julia Lawall
2010-11-26 21:51 ` [Caml-list] " Mehdi Dogguy
2010-11-26 22:02   ` Julia Lawall
2010-11-26 22:32     ` bluestorm

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AANLkTimBLv8d5BzU_4XeUMbd02Gw+aAWRQ4CgkJkXG4r@mail.gmail.com \
    --to=bluestorm.dylc@gmail.com \
    --cc=caml-list@yquem.inria.fr \
    --cc=julia@diku.dk \
    --cc=mark@proof-technologies.com \
    --cc=mehdi.dogguy@pps.jussieu.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).