caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* syntax question
@ 2008-05-29 22:23 Michael Vanier
  2008-05-30  0:32 ` [Caml-list] " Adam Granicz
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Vanier @ 2008-05-29 22:23 UTC (permalink / raw)
  To: caml-list

Hi everyone,

I got bitten by a simple syntax problem:

# let a = (1, 2);;
val a : int * int = (1, 2)
# type testme = Foo of int * int;;
type testme = Foo of int * int
# Foo a;;
The constructor Foo expects 2 argument(s),
but is here applied to 1 argument(s)
# Foo (1, 2);;
- : testme = Foo (1, 2)
# type testme2 = Foo2 of (int * int);;
type testme2 = Foo2 of (int * int)
# Foo2 a;;
- : testme2 = Foo2 (1, 2)

Why does the compiler treat int * int and (int * int) in type definitions so differently?  Is it to 
give clearer error messages in the typical case?

Mike





^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] syntax question
  2008-05-29 22:23 syntax question Michael Vanier
@ 2008-05-30  0:32 ` Adam Granicz
  2008-05-30  1:13   ` Michael Vanier
  0 siblings, 1 reply; 8+ messages in thread
From: Adam Granicz @ 2008-05-30  0:32 UTC (permalink / raw)
  To: caml-list

Hi Michael,

In the type definition

> # type testme = Foo of int * int;;

the constructor Foo takes *two* int arguments (thus, you can not construct  
a testme value supplying only one argument), whereas in

> # type testme2 = Foo2 of (int * int);;

it takes *one* tuple argument.

Regards,
Adam.

On Fri, 30 May 2008 00:23:40 +0200, Michael Vanier  
<mvanier@cs.caltech.edu> wrote:

> Hi everyone,
>
> I got bitten by a simple syntax problem:
>
> # let a = (1, 2);;
> val a : int * int = (1, 2)
> # type testme = Foo of int * int;;
> type testme = Foo of int * int
> # Foo a;;
> The constructor Foo expects 2 argument(s),
> but is here applied to 1 argument(s)
> # Foo (1, 2);;
> - : testme = Foo (1, 2)
> # type testme2 = Foo2 of (int * int);;
> type testme2 = Foo2 of (int * int)
> # Foo2 a;;
> - : testme2 = Foo2 (1, 2)
>
> Why does the compiler treat int * int and (int * int) in type  
> definitions so differently?  Is it to give clearer error messages in the  
> typical case?
>
> Mike
>
>
>
>
> _______________________________________________
> 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



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] syntax question
  2008-05-30  0:32 ` [Caml-list] " Adam Granicz
@ 2008-05-30  1:13   ` Michael Vanier
  2008-05-30  1:48     ` Adam Granicz
                       ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Michael Vanier @ 2008-05-30  1:13 UTC (permalink / raw)
  To: Adam Granicz; +Cc: caml-list

Adam,

I realize that this is how it works, but I don't understand why it should work this way. AFAIK 
elsewhere in ocaml "int * int" always refers to a tuple.  Similarly, if testme's Foo really took two 
int arguments I would expect to be able to create Foos as "Foo 1 2" instead of "Foo (1, 2)" which 
looks like Foo takes a single tuple argument, not two int arguments.  I don't see why "int * int" 
and "(int * int)" are different things.

Mike

Adam Granicz wrote:
> Hi Michael,
> 
> In the type definition
> 
>> # type testme = Foo of int * int;;
> 
> the constructor Foo takes *two* int arguments (thus, you can not 
> construct a testme value supplying only one argument), whereas in
> 
>> # type testme2 = Foo2 of (int * int);;
> 
> it takes *one* tuple argument.
> 
> Regards,
> Adam.
> 
> On Fri, 30 May 2008 00:23:40 +0200, Michael Vanier 
> <mvanier@cs.caltech.edu> wrote:
> 
>> Hi everyone,
>>
>> I got bitten by a simple syntax problem:
>>
>> # let a = (1, 2);;
>> val a : int * int = (1, 2)
>> # type testme = Foo of int * int;;
>> type testme = Foo of int * int
>> # Foo a;;
>> The constructor Foo expects 2 argument(s),
>> but is here applied to 1 argument(s)
>> # Foo (1, 2);;
>> - : testme = Foo (1, 2)
>> # type testme2 = Foo2 of (int * int);;
>> type testme2 = Foo2 of (int * int)
>> # Foo2 a;;
>> - : testme2 = Foo2 (1, 2)
>>
>> Why does the compiler treat int * int and (int * int) in type 
>> definitions so differently?  Is it to give clearer error messages in 
>> the typical case?
>>
>> Mike
>>
>>
>>
>>
>> _______________________________________________
>> 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


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] syntax question
  2008-05-30  1:13   ` Michael Vanier
@ 2008-05-30  1:48     ` Adam Granicz
  2008-05-30  1:54     ` Gordon Henriksen
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Adam Granicz @ 2008-05-30  1:48 UTC (permalink / raw)
  To: caml-list

Hi Mike,

I suspect this was a choice made by the compiler writers - by  
special-casing constructors (thus making them different from ordinary  
functions) you avoid some "complications" (and create new ones), for  
instance no partial constructors (although IMHO there is a valid case for  
them - instead you have to resort to eta expansion) - this forces that  
each constructor fulfills its "arity".

AFAIK, the revised syntax takes care of the above issues and you can  
construct testme values as Foo 1 2.

Regards,
Adam.

On Fri, 30 May 2008 03:13:09 +0200, Michael Vanier  
<mvanier@cs.caltech.edu> wrote:

> Adam,
>
> I realize that this is how it works, but I don't understand why it  
> should work this way. AFAIK elsewhere in ocaml "int * int" always refers  
> to a tuple.  Similarly, if testme's Foo really took two int arguments I  
> would expect to be able to create Foos as "Foo 1 2" instead of "Foo (1,  
> 2)" which looks like Foo takes a single tuple argument, not two int  
> arguments.  I don't see why "int * int" and "(int * int)" are different  
> things.
>
> Mike
>
> Adam Granicz wrote:
>> Hi Michael,
>>  In the type definition
>>
>>> # type testme = Foo of int * int;;
>>  the constructor Foo takes *two* int arguments (thus, you can not  
>> construct a testme value supplying only one argument), whereas in
>>
>>> # type testme2 = Foo2 of (int * int);;
>>  it takes *one* tuple argument.
>>  Regards,
>> Adam.
>>  On Fri, 30 May 2008 00:23:40 +0200, Michael Vanier  
>> <mvanier@cs.caltech.edu> wrote:
>>
>>> Hi everyone,
>>>
>>> I got bitten by a simple syntax problem:
>>>
>>> # let a = (1, 2);;
>>> val a : int * int = (1, 2)
>>> # type testme = Foo of int * int;;
>>> type testme = Foo of int * int
>>> # Foo a;;
>>> The constructor Foo expects 2 argument(s),
>>> but is here applied to 1 argument(s)
>>> # Foo (1, 2);;
>>> - : testme = Foo (1, 2)
>>> # type testme2 = Foo2 of (int * int);;
>>> type testme2 = Foo2 of (int * int)
>>> # Foo2 a;;
>>> - : testme2 = Foo2 (1, 2)
>>>
>>> Why does the compiler treat int * int and (int * int) in type  
>>> definitions so differently?  Is it to give clearer error messages in  
>>> the typical case?
>>>
>>> Mike
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> 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



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] syntax question
  2008-05-30  1:13   ` Michael Vanier
  2008-05-30  1:48     ` Adam Granicz
@ 2008-05-30  1:54     ` Gordon Henriksen
  2008-05-30  7:03     ` Christophe TROESTLER
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Gordon Henriksen @ 2008-05-30  1:54 UTC (permalink / raw)
  To: caml-list

Michael,

A of a * a is more memory efficient than A of (a * a). In effect, a  
variant IS a tuple. If you wish to restrict yourself to restrict  
yourself to unary constructors in your programs, you're free to do so  
at the cost of extra allocations.

On 2008-05-29, at 21:13, Michael Vanier wrote:

> Adam,
>
> I realize that this is how it works, but I don't understand why it  
> should work this way. AFAIK elsewhere in ocaml "int * int" always  
> refers to a tuple.  Similarly, if testme's Foo really took two int  
> arguments I would expect to be able to create Foos as "Foo 1 2"  
> instead of "Foo (1, 2)" which looks like Foo takes a single tuple  
> argument, not two int arguments.  I don't see why "int * int" and  
> "(int * int)" are different things.
>
> Mike
>
> Adam Granicz wrote:
>> Hi Michael,
>> In the type definition
>>> # type testme = Foo of int * int;;
>> the constructor Foo takes *two* int arguments (thus, you can not  
>> construct a testme value supplying only one argument), whereas in
>>> # type testme2 = Foo2 of (int * int);;
>> it takes *one* tuple argument.
>> Regards,
>> Adam.
>> On Fri, 30 May 2008 00:23:40 +0200, Michael Vanier <mvanier@cs.caltech.edu 
>> > wrote:
>>> Hi everyone,
>>>
>>> I got bitten by a simple syntax problem:
>>>
>>> # let a = (1, 2);;
>>> val a : int * int = (1, 2)
>>> # type testme = Foo of int * int;;
>>> type testme = Foo of int * int
>>> # Foo a;;
>>> The constructor Foo expects 2 argument(s),
>>> but is here applied to 1 argument(s)
>>> # Foo (1, 2);;
>>> - : testme = Foo (1, 2)
>>> # type testme2 = Foo2 of (int * int);;
>>> type testme2 = Foo2 of (int * int)
>>> # Foo2 a;;
>>> - : testme2 = Foo2 (1, 2)
>>>
>>> Why does the compiler treat int * int and (int * int) in type  
>>> definitions so differently?  Is it to give clearer error messages  
>>> in the typical case?
>>>
>>> Mike
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> 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
>
> _______________________________________________
> 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



— Gordon


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] syntax question
  2008-05-30  1:13   ` Michael Vanier
  2008-05-30  1:48     ` Adam Granicz
  2008-05-30  1:54     ` Gordon Henriksen
@ 2008-05-30  7:03     ` Christophe TROESTLER
  2008-05-30  7:06     ` Luc Maranget
  2008-05-30 12:17     ` Damien Doligez
  4 siblings, 0 replies; 8+ messages in thread
From: Christophe TROESTLER @ 2008-05-30  7:03 UTC (permalink / raw)
  To: mvanier; +Cc: granicz.adam, caml-list

On Thu, 29 May 2008 18:13:09 -0700, Michael Vanier wrote:
> 
> I realize that this is how it works, but I don't understand why it
> should work this way. AFAIK elsewhere in ocaml "int * int" always
> refers to a tuple.  Similarly, if testme's Foo really took two int
> arguments I would expect to be able to create Foos as "Foo 1 2"
> instead of "Foo (1, 2)" which looks like Foo takes a single tuple
> argument, not two int arguments.  I don't see why "int * int" and
> "(int * int)" are different things.

Curried constructors are available in the revised syntax.  But since
the original syntax uses ``Foo (1, 2)'' for a constructor of 2
arguments, it is declared ``Foo of int * int'' by analogy with
products.  Hence the small glitch you noticed (in general that causes
no problems however).

My 0.02€,
ChriS


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] syntax question
  2008-05-30  1:13   ` Michael Vanier
                       ` (2 preceding siblings ...)
  2008-05-30  7:03     ` Christophe TROESTLER
@ 2008-05-30  7:06     ` Luc Maranget
  2008-05-30 12:17     ` Damien Doligez
  4 siblings, 0 replies; 8+ messages in thread
From: Luc Maranget @ 2008-05-30  7:06 UTC (permalink / raw)
  To: Michael Vanier; +Cc: Adam Granicz, caml-list

> Adam,
> 
> I realize that this is how it works, but I don't understand why it should 
> work this way. AFAIK elsewhere in ocaml "int * int" always refers to a 
> tuple.  Similarly, if testme's Foo really took two int arguments I would 
> expect to be able to create Foos as "Foo 1 2" instead of "Foo (1, 2)" which 

You understanding of constructors is correct : they take n arguments.
Yes, the concrete syntax does not properly reflect the underlying
semantics, with its fake tuple.

Why is this so ? Why ask ? 

In case you are just curious, it can probably be tracked back to the
original Caml where constructors took 0 or 1 arguments, and where
tuples were primitive.

Now, this is so for historical reasons and we live with it.

Alternatives can be considered, best of which probably is the
curried notation. But it is much too late to change that
(but as pointed by others, there is an alternative, "revised", syntax).



> 
> Mike
> 

--Luc


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] syntax question
  2008-05-30  1:13   ` Michael Vanier
                       ` (3 preceding siblings ...)
  2008-05-30  7:06     ` Luc Maranget
@ 2008-05-30 12:17     ` Damien Doligez
  4 siblings, 0 replies; 8+ messages in thread
From: Damien Doligez @ 2008-05-30 12:17 UTC (permalink / raw)
  To: caml users

On 2008-05-30, at 03:13, Michael Vanier wrote:

> I realize that this is how it works, but I don't understand why it  
> should work this way. AFAIK elsewhere in ocaml "int * int" always  
> refers to a tuple.

Almost, but not quite:

   # let int = 2;;
   val int : int = 2
   # int * int;;
   - : int = 4

Seriously, it's only an ergonomy problem in the syntax of type  
definitions.
Some better alternatives would be:

   type testme = Foo (int, int);;

or, if you like keyword-oriented syntax:

   type testme = Foo of int and int;;

But in any case, it's way too late to fix this problem now, so we have  
to
live with it, at least in the classic syntax.

-- Damien


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-05-30 12:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-29 22:23 syntax question Michael Vanier
2008-05-30  0:32 ` [Caml-list] " Adam Granicz
2008-05-30  1:13   ` Michael Vanier
2008-05-30  1:48     ` Adam Granicz
2008-05-30  1:54     ` Gordon Henriksen
2008-05-30  7:03     ` Christophe TROESTLER
2008-05-30  7:06     ` Luc Maranget
2008-05-30 12:17     ` Damien Doligez

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