caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* (int * int) <> int*int ?
@ 2006-02-23 17:28 Frédéric Gava
  2006-02-23 18:33 ` [Caml-list] " Eric Cooper
                   ` (3 more replies)
  0 siblings, 4 replies; 34+ messages in thread
From: Frédéric Gava @ 2006-02-23 17:28 UTC (permalink / raw)
  To: caml-list

Hi,

is anybody can semantically explain why this 2 types are differents ?

# type t=A of int*int and  t'= B of (int*int);;
type t = A of int * int
and t' = B of (int * int)

# A (2,3);;
- : t = A (2, 3)
# B (2,3);;
- : t' = B (2, 3)

# let a=2,3;;
val a : int * int = (2, 3)

# (A a);;
The constructor A expects 2 argument(s), but is here applied to 1
argument(s)
# (B a);;
- : t' = B (2, 3)

I understand that it'is force you to have a pair for A and not just a value
of type pair but why this restriction ? It is not easy to explain why
int*int <> (int*int).

Thanks !
Frédéric Gava



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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 17:28 (int * int) <> int*int ? Frédéric Gava
@ 2006-02-23 18:33 ` Eric Cooper
  2006-02-23 19:03   ` Martin Jambon
  2006-02-23 19:07   ` Frédéric Gava
  2006-02-23 18:33 ` Thomas Fischbacher
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 34+ messages in thread
From: Eric Cooper @ 2006-02-23 18:33 UTC (permalink / raw)
  To: caml-list

On Thu, Feb 23, 2006 at 06:28:48PM +0100, Frdric Gava wrote:
> is anybody can semantically explain why this 2 types are differents ?
> 
> # type t=A of int*int and  t'= B of (int*int);;
> type t = A of int * int
> and t' = B of (int * int)
> [...]
> I understand that it'is force you to have a pair for A and not just a value
> of type pair but why this restriction ? It is not easy to explain why
> int*int <> (int*int).

See section 18.3.4 of the manual -- the distinction allows the runtime
representation of t to avoid a level of indirection.  And since the
runtime representations are different, the types have to be different.

-- 
Eric Cooper             e c c @ c m u . e d u


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 17:28 (int * int) <> int*int ? Frédéric Gava
  2006-02-23 18:33 ` [Caml-list] " Eric Cooper
@ 2006-02-23 18:33 ` Thomas Fischbacher
  2006-02-23 18:56 ` David Brown
  2006-02-23 20:58 ` [Caml-list] (int * int) <> int*int ? Jon Harrop
  3 siblings, 0 replies; 34+ messages in thread
From: Thomas Fischbacher @ 2006-02-23 18:33 UTC (permalink / raw)
  To: Frédéric Gava; +Cc: caml-list


> is anybody can semantically explain why this 2 types are differents ?

They are implemented in a different way internally. This is one of the 
dark corners of OCaml. 

(To my understanding, a constructor can carry multiple arguments, but 
depending on whether you put the parens or not, the tuple will be folded 
into a multi-slot constructor, or the constructor will have a single slot, 
which is a tuple.)

And yes, this *can* give you major headache if you first discover it when 
you try to raise a complex exception with sub-structure from within C 
code.

We had this discussion earlier:

http://groups.google.com/group/fa.caml/msg/86fb0679c8d11b1b?hl=en

-- 
regards,               tf@cip.physik.uni-muenchen.de              (o_
 Thomas Fischbacher -  http://www.cip.physik.uni-muenchen.de/~tf  //\
(lambda (n) ((lambda (p q r) (p p q r)) (lambda (g x y)           V_/_
(if (= x 0) y (g g (- x 1) (* x y)))) n 1))                  (Debian GNU)


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 17:28 (int * int) <> int*int ? Frédéric Gava
  2006-02-23 18:33 ` [Caml-list] " Eric Cooper
  2006-02-23 18:33 ` Thomas Fischbacher
@ 2006-02-23 18:56 ` David Brown
  2006-02-23 19:24   ` Frédéric Gava
                     ` (2 more replies)
  2006-02-23 20:58 ` [Caml-list] (int * int) <> int*int ? Jon Harrop
  3 siblings, 3 replies; 34+ messages in thread
From: David Brown @ 2006-02-23 18:56 UTC (permalink / raw)
  To: Frédéric Gava; +Cc: caml-list

On Thu, Feb 23, 2006 at 06:28:48PM +0100, Frédéric Gava wrote:

> I understand that it'is force you to have a pair for A and not just a value
> of type pair but why this restriction ? It is not easy to explain why
> int*int <> (int*int).

As others have explained the represenatation is different.  The constructed
types themselves can contain multiple values (represented the same way as a
tuple).

Consider

  type a = A of int * int
         | B of (int * int)

The result of   A (3, 4)  will be a two element tuple type tagged
appropriately for 'A' (in this case 0).

The result of   B (3, 4)  will be a one element tuple type tagged for B,
with the single element referring to the two element tuple containing (3,
4).

Because tuples are generally immutable, there is little semantic
difference, but the compiler does have to keep track of which is which.  In
most cases I would guess that 'A' would be more efficient (unless there are
lots of larger constructors sharing the same tuple).

Dave


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 18:33 ` [Caml-list] " Eric Cooper
@ 2006-02-23 19:03   ` Martin Jambon
  2006-02-23 19:07   ` Frédéric Gava
  1 sibling, 0 replies; 34+ messages in thread
From: Martin Jambon @ 2006-02-23 19:03 UTC (permalink / raw)
  To: Eric Cooper; +Cc: caml-list

On Thu, 23 Feb 2006, Eric Cooper wrote:

> On Thu, Feb 23, 2006 at 06:28:48PM +0100, Frdric Gava wrote:
>> is anybody can semantically explain why this 2 types are differents ?
>>
>> # type t=A of int*int and  t'= B of (int*int);;
>> type t = A of int * int
>> and t' = B of (int * int)
>> [...]
>> I understand that it'is force you to have a pair for A and not just a value
>> of type pair but why this restriction ? It is not easy to explain why
>> int*int <> (int*int).
>
> See section 18.3.4 of the manual -- the distinction allows the runtime
> representation of t to avoid a level of indirection.  And since the
> runtime representations are different, the types have to be different.

See also how this issue is handled by the revised syntax:
   http://caml.inria.fr/pub/docs/manual-camlp4/manual007.html#toc24


Martin

--
Martin Jambon, PhD
http://martin.jambon.free.fr

Visit http://wikiomics.org, the Bioinformatics Howto Wiki


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 18:33 ` [Caml-list] " Eric Cooper
  2006-02-23 19:03   ` Martin Jambon
@ 2006-02-23 19:07   ` Frédéric Gava
  2006-02-23 20:15     ` Brian Hurt
                       ` (2 more replies)
  1 sibling, 3 replies; 34+ messages in thread
From: Frédéric Gava @ 2006-02-23 19:07 UTC (permalink / raw)
  To: caml-list, Eric Cooper

> # type t=A of int*int and  t'= B of (int*int);;
> type t = A of int * int
> and t' = B of (int * int)
> See section 18.3.4 of the manual -- the distinction allows the runtime
> representation of t to avoid a level of indirection.

Thanks for your anwser but I am not convinced that is a good reason. If "t"
is better why " t' " is not automatically tranform into "t" (it is easy, you
just delete the global parens). ok (int->int)->int <> int->int->int or
int*int*int<>int*(int*int) . Morever I think that int*int=(int*int)
"everywhere" in ML...
# type t=int*int;;
type t = int * int
# type t'=(int*int);;
type t' = int * int

>And since the runtime representations are different, the types have to be
different.
Wrong, you can the same representation but different types (e.g. int, char
or many other examples)

Best,
FG



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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 18:56 ` David Brown
@ 2006-02-23 19:24   ` Frédéric Gava
  2006-02-23 19:37   ` Frédéric Gava
  2006-02-24  8:27   ` also for tagged records? [Was: Re: [Caml-list] (int * int) <> int*int ?] Sebastian Egner
  2 siblings, 0 replies; 34+ messages in thread
From: Frédéric Gava @ 2006-02-23 19:24 UTC (permalink / raw)
  To: David Brown; +Cc: caml-list

> Because tuples are generally immutable, there is little semantic
> difference, but the compiler does have to keep track of which is which.

Thanks, but which differnce ?

>In most cases I would guess that 'A' would be more efficient (unless there
are
> lots of larger constructors sharing the same tuple).
Peraps in patter mathching:

# type t = A of int*int | B of (int*int);;
type t = A of int * int | B of (int * int)

# fun x -> match x with A (a,b) -> (a,b) | B a -> a;;
- : t -> int * int = <fun>

where the case of B will be more efficient since the are not need to rebuild
a pair

Best,
FG



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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 18:56 ` David Brown
  2006-02-23 19:24   ` Frédéric Gava
@ 2006-02-23 19:37   ` Frédéric Gava
  2006-02-23 19:45     ` Frédéric Gava
  2006-02-24  8:27   ` also for tagged records? [Was: Re: [Caml-list] (int * int) <> int*int ?] Sebastian Egner
  2 siblings, 1 reply; 34+ messages in thread
From: Frédéric Gava @ 2006-02-23 19:37 UTC (permalink / raw)
  To: caml-list

> Because tuples are generally immutable, there is little semantic
> difference,

And it does not justify why
# type t=A of int*int
type t = A of int * int
# let a=2,3;;
val a : int * int = (2, 3)
# (A a);;
The constructor A expects 2 argument(s), but is here applied to 1
argument(s)

You have build "a" of type int * int which is the parameter of A and it is
not good ;-( (I understand the idea of the difference that  the constructor
take n arguments or 1 argument of n values (i.e curryied or not) but despite
that you could not write (A 1 2), I do not understand why there is a
difference). For performance issues, is there a way to not have the rebuild
of the pair in
# type t = A of int*int | B of (int*int);;
# fun x -> match x with A (a,b) -> (a,b) | B a -> a;;

?

FG



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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 19:37   ` Frédéric Gava
@ 2006-02-23 19:45     ` Frédéric Gava
  2006-02-24  0:01       ` Jacques Garrigue
  0 siblings, 1 reply; 34+ messages in thread
From: Frédéric Gava @ 2006-02-23 19:45 UTC (permalink / raw)
  To: caml-list

< For performance issues, is there a way to not have the rebuild
> of the pair in
> # type t = A of int*int | B of (int*int);;
> # fun x -> match x with A (a,b) -> (a,b) | B a -> a;;
>
> ?
Peraps this idea:
if (all the time) A of (int*int) ==> A of int*int then in pattern mathching
"A a" the "a" is directly built as a tuple from the tuple of the concrete
type (just a little modification of the tag). Is it not a good idea ;-) ?

Best,
FG



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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 19:07   ` Frédéric Gava
@ 2006-02-23 20:15     ` Brian Hurt
  2006-02-23 21:30       ` Frédéric Gava
  2006-02-24  8:38     ` Alessandro Baretta
  2006-02-24 12:59     ` Damien Doligez
  2 siblings, 1 reply; 34+ messages in thread
From: Brian Hurt @ 2006-02-23 20:15 UTC (permalink / raw)
  To: Frédéric Gava; +Cc: caml-list, Eric Cooper

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1387 bytes --]



On Thu, 23 Feb 2006, Frédéric Gava wrote:

>> # type t=A of int*int and  t'= B of (int*int);;
>> type t = A of int * int
>> and t' = B of (int * int)
>> See section 18.3.4 of the manual -- the distinction allows the runtime
>> representation of t to avoid a level of indirection.
>
> Thanks for your anwser but I am not convinced that is a good reason. If "t"
> is better why " t' " is not automatically tranform into "t" (it is easy, you
> just delete the global parens). ok (int->int)->int <> int->int->int or
> int*int*int<>int*(int*int) . Morever I think that int*int=(int*int)
> "everywhere" in ML...

This isn't correct- the same problem shows up in the difference between:
int*int*int and int*(int*int)- i.e. the difference between (1,2,3) and 
(1,(2,3)).  In the first case (in both examples) I have a three element 
tuple, in the second case I have a two element tuple whose second element 
is also a two element tuple (and thus I have the layer of indirection).

Also, sometimes I want one and sometimes I want the other.  I can often 
save copying information (and storing the duplicate information) if I can 
add the level of indirection- this is important if I'm copying the 
information a lot.  On the other hand, if the information isn't being 
duplicated a lot, then I can save memory by not having the extra level of 
indirection.

Brian

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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 17:28 (int * int) <> int*int ? Frédéric Gava
                   ` (2 preceding siblings ...)
  2006-02-23 18:56 ` David Brown
@ 2006-02-23 20:58 ` Jon Harrop
  2006-02-23 21:36   ` Frédéric Gava
  3 siblings, 1 reply; 34+ messages in thread
From: Jon Harrop @ 2006-02-23 20:58 UTC (permalink / raw)
  To: caml-list

On Thursday 23 February 2006 17:28, Frédéric Gava wrote:
> is anybody can semantically explain why this 2 types are differents ?
>
> # type t=A of int*int and  t'= B of (int*int);;
> type t = A of int * int
> and t' = B of (int * int)

Only historical reasons, AFAIK. I do not believe this is necessary or that 
there is a logical reason for doing so.

> Morever I think that int*int=(int*int) in ML

Yes. I think it is logical to expect that.

> > And since the runtime representations are different, the types have to be
> > different.
>
> Wrong, you can the same representation but different types (e.g. int, char
> or many other examples)

I also believe that statement was wrong but I don't think you have provided 
counter-examples because the run-time representations are the same for the 
different types that you cite (rather than the converse).

Perhaps this is a better counterexample: the following functions "f" and "g" 
use different run-time representations but still have the same type:

# let f (a, b) = a+b
  let g (a, b as x) = a+b;;
val f : int * int -> int = <fun>
val g : int * int -> int = <fun>

camlT2__f_58:
.L100:
	lea	-1(%eax, %ebx), %eax
	ret
	.text
	.align	16
	.globl	camlT2__g_61
	.type	camlT2__g_61,@function
camlT2__g_61:
.L101:
	movl	4(%eax), %ebx
	movl	(%eax), %eax
	lea	-1(%eax, %ebx), %eax
	ret
	.text
	.align	16
	.globl	camlT2__entry
	.type	camlT2__entry,@function

I suspect a similar transformation could be done for variant type 
constructors.

Also, note that this behaviour does not appear with polymorphic variants, 
where int * int <=> (int * int):

# type t = A of int * int | B of (int * int);;
type t = A of int * int | B of (int * int)
# type t = [ `A of int * int | `B of (int * int) ];;
type t = [ `A of int * int | `B of int * int ]

I assume the arguments of a polymorphic variant are always boxed...

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 20:15     ` Brian Hurt
@ 2006-02-23 21:30       ` Frédéric Gava
  2006-02-23 21:57         ` Brian Hurt
  0 siblings, 1 reply; 34+ messages in thread
From: Frédéric Gava @ 2006-02-23 21:30 UTC (permalink / raw)
  To: Brian Hurt; +Cc: caml-list

>This isn't correct- the same problem shows up in the difference between:
>int*int*int and int*(int*int)- i.e. the difference between (1,2,3) and
>(1,(2,3)).  In the first case (in both examples) I have a three element
>tuple, in the second case I have a two element tuple whose second element
>is also a two element tuple (and thus I have the layer of indirection).

Hum, no...here we have three (int) or two (one int and one pair) elements.
In the concrete type case, we have two elements (and both cases pair because
in both case A (2,3) works fine) and it is a problem of curryfication which
is not justify. (int*int*int)=int*int*int everywhere and also
(int*(int*int))=int*(int*int). But not in the concrete type case...

>Also, sometimes I want one and sometimes I want the other.
Sure

>  I can often
>save copying information (and storing the duplicate information) if I can
>add the level of indirection- this is important if I'm copying the
>information a lot.  On the other hand, if the information isn't being
>duplicated a lot, then I can save memory by not having the extra level of
>indirection.

This is why I thinks that the case (int*int) is not justify if there is no
partial application of the concrete constructors (because the level of
indirection could be avoid at the time of pattern-matching : you quickly
modify the data of the concrete type to have a tuple...).

FG




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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 20:58 ` [Caml-list] (int * int) <> int*int ? Jon Harrop
@ 2006-02-23 21:36   ` Frédéric Gava
  0 siblings, 0 replies; 34+ messages in thread
From: Frédéric Gava @ 2006-02-23 21:36 UTC (permalink / raw)
  To: caml-list; +Cc: Jon Harrop

>Only historical reasons, AFAIK. I do not believe this is necessary or that
>there is a logical reason for doing so.
Peraps. I do not know. Peraps also to keep safe old programs...

>I also believe that statement was wrong but I don't think you have provided
>counter-examples because the run-time representations are the same for the
>different types that you cite (rather than the converse).

I just want to say that in or char have the same representation but
different types (contraposition)

>Also, note that this behaviour does not appear with polymorphic variants,
>where int * int <=> (int * int):

># type t = A of int * int | B of (int * int);;
>type t = A of int * int | B of (int * int)
># type t = [ `A of int * int | `B of (int * int) ];;
>type t = [ `A of int * int | `B of int * int ]

>I assume the arguments of a polymorphic variant are always boxed...

This is why you could not have more than 255 constructor in concrete
variants and many more in polymorphic ones.


FG



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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 21:30       ` Frédéric Gava
@ 2006-02-23 21:57         ` Brian Hurt
  2006-02-23 22:30           ` Frédéric Gava
  0 siblings, 1 reply; 34+ messages in thread
From: Brian Hurt @ 2006-02-23 21:57 UTC (permalink / raw)
  To: Frédéric Gava; +Cc: caml-list

[-- Attachment #1: Type: TEXT/PLAIN, Size: 2639 bytes --]



On Thu, 23 Feb 2006, Frédéric Gava wrote:

>> This isn't correct- the same problem shows up in the difference between:
>> int*int*int and int*(int*int)- i.e. the difference between (1,2,3) and
>> (1,(2,3)).  In the first case (in both examples) I have a three element
>> tuple, in the second case I have a two element tuple whose second element
>> is also a two element tuple (and thus I have the layer of indirection).
>
> Hum, no...here we have three (int) or two (one int and one pair) elements.
> In the concrete type case, we have two elements (and both cases pair because
> in both case A (2,3) works fine) and it is a problem of curryfication which
> is not justify. (int*int*int)=int*int*int everywhere and also

No.  There are cases where (int*int*int) is not the same as int*int*int. 
Specifically, int*(int*int*int) is different than int*int*int*int.

So, in terms of representation:
type t = A of int * int
is represented in memory as
     tag * int * int
while
type t' = B of (int * int)
is represented in memory as
     tag * (int * int)
where in both cases tag is the tagging information added by the compiler. 
Note that in the first case it's a three word structure (two ints and a 
tag), while in the second case it's a two word structure (a tag and a 
reference to a tuple of two ints).

You keep trying to assume that the parentheses are purely syntactic-
they're not.

>>  I can often
>> save copying information (and storing the duplicate information) if I can
>> add the level of indirection- this is important if I'm copying the
>> information a lot.  On the other hand, if the information isn't being
>> duplicated a lot, then I can save memory by not having the extra level of
>> indirection.
>
> This is why I thinks that the case (int*int) is not justify if there is no
> partial application of the concrete constructors (because the level of
> indirection could be avoid at the time of pattern-matching : you quickly
> modify the data of the concrete type to have a tuple...).

No.  Because in the case of B, I can snag the tuple as an independent 
peice of data.  For example, I can write:
 	let f = function B x -> fst x;;
and it works.  On the other hand, if I try to write:
 	let g = function A x -> fst x;;
this doesn't work- because the "tuple" in A doesn't really exist as an 
independent data structure (it's been unboxed).  Here, Ocaml is refusing 
to allow a pointer into the middle of a structure (the GC algorithm thanks 
you), and doesn't want to have to allocate a tuple to hold x (this 
seriously complicates pattern matching).

Brian

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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 21:57         ` Brian Hurt
@ 2006-02-23 22:30           ` Frédéric Gava
  2006-02-23 22:50             ` Brian Hurt
  0 siblings, 1 reply; 34+ messages in thread
From: Frédéric Gava @ 2006-02-23 22:30 UTC (permalink / raw)
  To: Brian Hurt; +Cc: caml-list

>No.  There are cases where (int*int*int) is not the same as int*int*int.
>Specifically, int*(int*int*int) is different than int*int*int*int.

As a sub-part of a type, ok but I speak about general parentheses...

>You keep trying to assume that the parentheses are purely syntactic-
>they're not.

I have never say that...you can read that i have write int->int->int <>
(int->int)->int

>So, in terms of representation:
>type t = A of int * int
>is represented in memory as
>     tag * int * int
>while
>type t' = B of (int * int)
>is represented in memory as
>     tag * (int * int)
>where in both cases tag is the tagging information added by the compiler.
>Note that in the first case it's a three word structure (two ints and a
>tag), while in the second case it's a two word structure (a tag and a
>reference to a tuple of two ints).

But where tag could represent information both int*int and (int*int) which
is the same things (modulo an indirection which could be deleted at
pattern-mathching). Morever, as Jon points of, variant types do not have
this curious things due to boxed values...Also when you have build a pair,
semantically you want to apply the constructor on this pair...because,
there no partial applications of the constructors : for a constructor A of
int*int you can not write (A 3) of type int->t (as in mini-ML or Haskell). I
understand (and agree) the performances reasons, but I thinks that could be
deleted since the only (that i see) case where the performances are
differents is in the case of pattern-matching...


>No.  Because in the case of B, I can snag the tuple as an independent
>peice of data.  For example, I can write:
>  let f = function B x -> fst x;;
>and it works.  On the other hand, if I try to write:
>  let g = function A x -> fst x;;
>this doesn't work- because the "tuple" in A doesn't really exist as an
>independent data structure (it's been unboxed).  Here, Ocaml is refusing
>to allow a pointer into the middle of a structure (the GC algorithm thanks
>you), and doesn't want to have to allocate a tuple to hold x (this
>seriously complicates pattern matching).

Peraps it complicates the pattern-matching but in the second case, x could
be quickly and automatically build from (A x) because tags of tuples and of
concrete types are close...and you avoid this curious construction  (many
years that I program in ocaml and curiously, never saw this things because
always build the different parameters of the concrete constructor in
different "variables" ;-)  so I think that it is not a problem that appear
many times in ocaml programs...some one always used the two differents
constructions ?)


FG




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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 22:30           ` Frédéric Gava
@ 2006-02-23 22:50             ` Brian Hurt
  2006-02-23 23:07               ` Frédéric Gava
  0 siblings, 1 reply; 34+ messages in thread
From: Brian Hurt @ 2006-02-23 22:50 UTC (permalink / raw)
  To: Frédéric Gava; +Cc: caml-list

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: TEXT/PLAIN; CHARSET=X-UNKNOWN; FORMAT=flowed, Size: 716 bytes --]



On Thu, 23 Feb 2006, Frédéric Gava wrote:

> But where tag could represent information both int*int and (int*int) which
> is the same things (modulo an indirection which could be deleted at
> pattern-mathching). Morever, as Jon points of, variant types do not have
> this curious things due to boxed values...

Variant types always box.  They always have the reference.  I understand 
you're arguing that type constructors should work the same way.

Well, maybe they should have.  I'm not sure I'd like it if that was 
changed now, however.  Working code wouldn't cease to work- it'd just be 
less memory efficient.  But you'd always have the extra reference, even if 
you didn't need it.

Brian

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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 22:50             ` Brian Hurt
@ 2006-02-23 23:07               ` Frédéric Gava
  0 siblings, 0 replies; 34+ messages in thread
From: Frédéric Gava @ 2006-02-23 23:07 UTC (permalink / raw)
  To: Brian Hurt; +Cc: caml-list

>I understand you're arguing that type constructors should work the same
way.
It is just i think: the difference with int*int and (int*int) seems (to me)
a hack (but i am peraps an extremist ;-) )

>Well, maybe they should have.
I also do not know. Peraps another solution would be that
#type t= A of int*int
#let a=(1,2) in (A a)
works by automatically transforming "a": tag*(int*int) to tag*int*int...but
peraps it is too hard for just some little cases and it takes many memory
for the copy (ok, I can write let (a1,a2)=(1,2) in (A (a1,a2)) but it takes
much times...;-) )

>I'm not sure I'd like it if that was changed now, however.  Working code
wouldn't cease to work- it'd just be
>less memory efficient.  But you'd always have the extra reference, even if
>you didn't need it.

I understand your problem and i have no good solution :-(

Good night !
FG



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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 19:45     ` Frédéric Gava
@ 2006-02-24  0:01       ` Jacques Garrigue
  2006-02-24  0:18         ` Lukasz Stafiniak
  0 siblings, 1 reply; 34+ messages in thread
From: Jacques Garrigue @ 2006-02-24  0:01 UTC (permalink / raw)
  To: gava; +Cc: caml-list

From: Frédéric Gava <gava@univ-paris12.fr>
> < For performance issues, is there a way to not have the rebuild
> > of the pair in
> > # type t = A of int*int | B of (int*int);;
> > # fun x -> match x with A (a,b) -> (a,b) | B a -> a;;
> >
> > ?
> Peraps this idea:
> if (all the time) A of (int*int) ==> A of int*int then in pattern mathching
> "A a" the "a" is directly built as a tuple from the tuple of the concrete
> type (just a little modification of the tag). Is it not a good idea ;-) ?

You can't do this, because values are shared: if you replace the A tag
by 0, you have really changed the original value for x, and subsequent
pattern-matching will be wrong.
Interestingly, it would be safe to just return x itself: when you
access a tuple you never look at its tag. However, this would still be
incorrect because of polymorphic equality: A(a,b) is not structurally
equal to 0(a,b) (assuming A is not the first tag.)

So there's no solution here.

By the way, the answer to your original question is that the syntax
for datatypes is wrong. A datatype does not take a tuple as argument,
but a fixed number of independent values. As somebody already pointed,
the revised syntax corrects this. The standard syntax is just a
consequence of history.
This unfortunate syntax has consequences down to polymorphic variants,
which otherwise could be represented more efficiently.

Jacques


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-24  0:01       ` Jacques Garrigue
@ 2006-02-24  0:18         ` Lukasz Stafiniak
  2006-02-24  2:17           ` Jacques Garrigue
  0 siblings, 1 reply; 34+ messages in thread
From: Lukasz Stafiniak @ 2006-02-24  0:18 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: caml-list

On 2/24/06, Jacques Garrigue <garrigue@math.nagoya-u.ac.jp> wrote:
> This unfortunate syntax has consequences down to polymorphic variants,
> which otherwise could be represented more efficiently.
>
This is interesting, could you explain it shortly?

Thank You,
Lukasz Stafiniak


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-24  0:18         ` Lukasz Stafiniak
@ 2006-02-24  2:17           ` Jacques Garrigue
  2006-02-24 13:07             ` Alain Frisch
  2006-02-24 13:39             ` [Caml-list] (int * int) <> int*int ? Nicolas Cannasse
  0 siblings, 2 replies; 34+ messages in thread
From: Jacques Garrigue @ 2006-02-24  2:17 UTC (permalink / raw)
  To: lukstafi; +Cc: caml-list

From: "Lukasz Stafiniak" <lukstafi@gmail.com>
> > This unfortunate syntax has consequences down to polymorphic variants,
> > which otherwise could be represented more efficiently.
> >
> This is interesting, could you explain it shortly?

The tuple based syntax for constructors is ambiguous: there is no way
to know syntactically whether a constructor takes as argument a tuple
or separate arguments. This is the reason for this whole discussion.

For datatypes, the ambiguity is solved by looking-up the definition.

With polymorphic variants, there is no definition, so one is forced to
use a uniform representation, namely all constructors have either 0 or
1 argument. This means that `A(arg1,arg2) has to be represented
internally as [|`A; [|arg1; arg2|] |].
With a non-ambiguous syntax, like (`A arg1 arg2), it would be possible
to use a more compact internal representation: [|`A; arg1; arg2|].

This is not a big problem, just an historical hiccup.

Jacques


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

* also for tagged records? [Was: Re: [Caml-list] (int * int) <> int*int ?]
  2006-02-23 18:56 ` David Brown
  2006-02-23 19:24   ` Frédéric Gava
  2006-02-23 19:37   ` Frédéric Gava
@ 2006-02-24  8:27   ` Sebastian Egner
  2006-02-24 14:01     ` Thomas Fischbacher
  2 siblings, 1 reply; 34+ messages in thread
From: Sebastian Egner @ 2006-02-24  8:27 UTC (permalink / raw)
  To: caml-list

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

> Consider
> 
>   type a = A of int * int
>          | B of (int * int)
> 
> The result of   A (3, 4)  will be a two element tuple type tagged
> appropriately for 'A' (in this case 0).
> 
> The result of   B (3, 4)  will be a one element tuple type tagged for B,
> with the single element referring to the two element tuple containing 
(3,
> 4).
> 
> Because tuples are generally immutable, there is little semantic
> difference, but the compiler does have to keep track of which is which. 
In
> most cases I would guess that 'A' would be more efficient (unless there 
are
> lots of larger constructors sharing the same tuple).

Is there a similar way as 'A' above for records?

This isn't valid Ocaml:

type a = A of {mutable xA: int; mutable yA: int}
       | B of xyB
and xyB = {mutable xB: int; mutable yB: int}

Background: I had a case (a search tree data strucuture) where 
the additional indirection results in a 30% runtime penalty,
due to increased pointer chasing (cache misses). It is the
way it is in Ocaml and probably hard to change, but I would
like to understand if there are fundamental reasons for it to
be necessary or not. See also:

http://caml.inria.fr/pub/ml-archives/caml-list/2005/11/9a6dcbcb4f3b4c0ebe9cdf28ac3d289b.en.html

Sebastian.

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

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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 19:07   ` Frédéric Gava
  2006-02-23 20:15     ` Brian Hurt
@ 2006-02-24  8:38     ` Alessandro Baretta
  2006-02-24 12:59     ` Damien Doligez
  2 siblings, 0 replies; 34+ messages in thread
From: Alessandro Baretta @ 2006-02-24  8:38 UTC (permalink / raw)
  To: Frédéric Gava; +Cc: caml-list

Frédéric Gava wrote:
>>And since the runtime representations are different, the types have to be
>>different.
> Wrong, you can the same representation but different types (e.g. int, char
> or many other examples)

Be careful when you reason about a proposition like "if A then B" in negated 
terms. You are stating that "if (runtime representations are different) then 
(types are different)" is false because "if not (runtime representations are 
different) then not (types are different)" is false, but the second proposition 
is not equivalent to the first.

***

Back to the original topic: this is a syntactic issue. DdR has solved the issue 
in revised syntax, by making it very clear that 'a * 'b is a tuple, while an 
n-ary constructor takes n distinct formal parameters--by no means an n-uple. 
This is one of the very few spots where revised syntax is really more attractive 
than the original one.

 > type t = [ A of t1 and t2 ]
 > type t' = [ A of (t1 * t2) ]

Alex

-- 
*********************************************************************

Ing. Alessandro Baretta

Studio Baretta
http://studio.baretta.com/

Consulenza Tecnologica e Ingegneria Industriale
Technological Consulting and Industrial Engineering

tel. +39 02 370 111 55
fax. +39 02 370 111 54


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-23 19:07   ` Frédéric Gava
  2006-02-23 20:15     ` Brian Hurt
  2006-02-24  8:38     ` Alessandro Baretta
@ 2006-02-24 12:59     ` Damien Doligez
  2 siblings, 0 replies; 34+ messages in thread
From: Damien Doligez @ 2006-02-24 12:59 UTC (permalink / raw)
  To: caml-list


On Feb 23, 2006, at 20:07, Frédéric Gava wrote:

> Morever I think that int*int=(int*int) "everywhere" in ML...

This is definitely not true.  Consider the following example:

$ ocaml
         Objective Caml version 3.09.2+dev4 (2006-02-09)

# let int = 0;;
val int : int = 0
# let t = [| 1 |];;
val t : int array = [|1|]
# t.(int*int);;
- : int = 1
# t.int*int;;
Unbound record field label int
#

This example is very similar to your problem.  The substring "int*int"
appears in your program, but it is not _by_itself_ a subexpression of  
your
program, so there is no reason why it should be equivalent to  
"(int*int)".

As Jacques said, what we have here is an unfortunate choice of syntax  
for
the declaration of n-ary constructors, combined with overloading of
constructor applications, to n arguments or to one tuple argument.

-- Damien


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-24  2:17           ` Jacques Garrigue
@ 2006-02-24 13:07             ` Alain Frisch
  2006-02-25 17:42               ` Vincent Balat
  2006-02-24 13:39             ` [Caml-list] (int * int) <> int*int ? Nicolas Cannasse
  1 sibling, 1 reply; 34+ messages in thread
From: Alain Frisch @ 2006-02-24 13:07 UTC (permalink / raw)
  To: caml-list

Jacques Garrigue wrote:
> The tuple based syntax for constructors is ambiguous: there is no way
> to know syntactically whether a constructor takes as argument a tuple
> or separate arguments. This is the reason for this whole discussion.

In a sense, the same applies to functions. When a function is called,
there is no way to know statically whether it expects more arguments
(the call creates a closure) or not (the body of the function can be
evaluated now). As you know, this is solved dynamically.

One could imagine the same for variants. Applying a constructor
with several syntactical arguments `A(arg1,arg2) would create a block
[| `A; arg1; arg2 |] whereas "let x = (arg1,arg2) in `A x" would create
a block [| `A; [| arg1; arg2 |] |]. Then it is up to pattern matching to
be more clever and deal with the two possible cases at runtime (maybe
one wants to use a non-zero tag for the block [| `A; arg1; arg2 |]),
possibly creating new tuples as in "match `A(arg1,arg2) with `A x -> x".

I'm not claiming that it is worth the extra complexity nor
that it would really improve anything, though...


-- Alain


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-24  2:17           ` Jacques Garrigue
  2006-02-24 13:07             ` Alain Frisch
@ 2006-02-24 13:39             ` Nicolas Cannasse
  2006-02-24 14:49               ` Frédéric Gava
  1 sibling, 1 reply; 34+ messages in thread
From: Nicolas Cannasse @ 2006-02-24 13:39 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: lukstafi, caml-list

>>>This unfortunate syntax has consequences down to polymorphic variants,
>>>which otherwise could be represented more efficiently.
>>>
>>
>>This is interesting, could you explain it shortly?
> 
> 
> The tuple based syntax for constructors is ambiguous: there is no way
> to know syntactically whether a constructor takes as argument a tuple
> or separate arguments. This is the reason for this whole discussion.

Yes this is not a very big problem but is quite often reported.
The reason I see is that (int * int) and int * int are perceived the 
same because parenthesis are optional when applying the * operator in 
calculus.

In order to fix this, I choose to always have parenthesis for multiple 
arguments constructors in NekoML :

type a {
    A : int;
    B : (int , int); // 2 arguments
    C : ((int , int)); // 1 tuple argument
}

It is then more easy to understand the difference between B and C, 
although this is in the end just a matter of using an appropriate 
syntax. The parenthesis are just abusely used in different manners in 
most of languages syntax.

Nicolas


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

* Re: also for tagged records? [Was: Re: [Caml-list] (int * int) <> int*int ?]
  2006-02-24  8:27   ` also for tagged records? [Was: Re: [Caml-list] (int * int) <> int*int ?] Sebastian Egner
@ 2006-02-24 14:01     ` Thomas Fischbacher
  0 siblings, 0 replies; 34+ messages in thread
From: Thomas Fischbacher @ 2006-02-24 14:01 UTC (permalink / raw)
  To: Sebastian Egner; +Cc: caml-list


On Fri, 24 Feb 2006, Sebastian Egner wrote:

> This isn't valid Ocaml:
> 
> type a = A of {mutable xA: int; mutable yA: int}
>        | B of xyB
> and xyB = {mutable xB: int; mutable yB: int}
> 
> Background: I had a case (a search tree data strucuture) where 
> the additional indirection results in a 30% runtime penalty,

There now are quite a few cases where this "forced extra indirection" 
business becomes a nuisance. See for example the older discussion in the 
archives on implementing a binary heap properly on the basis of a 
variable-length array. The recommended solution is to use a Z option 
array, for some type Z.

To a certain extent, this may be considered an issue of mandatory static 
type checking and the insistence on minimizing the tagging for in-memory 
representations. If static type checking were advisory, and more tag bits 
would be used internally, many of these problems could be solved. Besides, 
this would offer library implementors the freedom to use somewhat cleaner 
dirty tricks under the hood, while still providing a nice and tidy type-safe 
interface to the outside.

-- 
regards,               tf@cip.physik.uni-muenchen.de              (o_
 Thomas Fischbacher -  http://www.cip.physik.uni-muenchen.de/~tf  //\
(lambda (n) ((lambda (p q r) (p p q r)) (lambda (g x y)           V_/_
(if (= x 0) y (g g (- x 1) (* x y)))) n 1))                  (Debian GNU)


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-24 13:39             ` [Caml-list] (int * int) <> int*int ? Nicolas Cannasse
@ 2006-02-24 14:49               ` Frédéric Gava
  0 siblings, 0 replies; 34+ messages in thread
From: Frédéric Gava @ 2006-02-24 14:49 UTC (permalink / raw)
  To: Nicolas Cannasse; +Cc: caml-list

> type a {
>     A : int;
>     B : (int , int); // 2 arguments
>     C : ((int , int)); // 1 tuple argument
> }

Personnaly, I prefer the "revisited syntax of ocaml" solution with "B:int
and int" but I would like to write my programs with (B 1 2) instead of (B
(1,2)) which is too close to "C (1,2)" and maybe its more efficient since we
do not have to build the pair (1,2)...and it seems to me more "logic"  to
have a constructor with n arguments to be apply to n arguments instead of a
nuple of arguments...(I remenber that the ZINC could optimize the code when
the function is apply to all its arguments and that the ZINC works better
with currified functions...is not true ?)

FG



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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-24 13:07             ` Alain Frisch
@ 2006-02-25 17:42               ` Vincent Balat
  2006-02-25 18:30                 ` Nicolas Pouillard
  0 siblings, 1 reply; 34+ messages in thread
From: Vincent Balat @ 2006-02-25 17:42 UTC (permalink / raw)
  To: caml-list

To add more confusion on the debate, look at this example:
;-)

        Objective Caml version 3.09.1

# type t = A of int * int;;
type t = A of int * int
# A 1 2;;
Syntax error
# `A 1 2;;
Syntax error
# #load "camlp4o.cma";;
        Camlp4 Parsing version 3.09.1

# A 1 2;;
Toplevel input:
# A 1 2;;
  ^^^^^
Parse error: currified constructor
# `A 1 2;;
- : [> `A of int * int ] = `A (1, 2)     (* !!!!! *)


(This is _not_ the revised syntax, but a strange bug/feature of camlp4o ...)


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-25 17:42               ` Vincent Balat
@ 2006-02-25 18:30                 ` Nicolas Pouillard
  2006-02-25 19:09                   ` Richard Jones
                                     ` (2 more replies)
  0 siblings, 3 replies; 34+ messages in thread
From: Nicolas Pouillard @ 2006-02-25 18:30 UTC (permalink / raw)
  To: Vincent Balat; +Cc: caml-list

On 2/25/06, Vincent Balat <Vincent.Balat@pps.jussieu.fr> wrote:
> To add more confusion on the debate, look at this example:
> ;-)
>
>         Objective Caml version 3.09.1
>
> # type t = A of int * int;;
> type t = A of int * int
> # A 1 2;;
> Syntax error
> # `A 1 2;;
> Syntax error
> # #load "camlp4o.cma";;
>         Camlp4 Parsing version 3.09.1
>
> # A 1 2;;
> Toplevel input:
> # A 1 2;;
>   ^^^^^
> Parse error: currified constructor
> # `A 1 2;;
> - : [> `A of int * int ] = `A (1, 2)     (* !!!!! *)
>
>
> (This is _not_ the revised syntax, but a strange bug/feature of camlp4o ...)
>

Arg... One more, the bug is in ast2pt.ml where a transformation is
done for Pexp_construct and Ppat_construct but not for Pexp_variant
and Ppat_variant. It will be fixed (note: I'am working on a renovation
of camlp4 as an internship).

--
Nicolas Pouillard

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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-25 18:30                 ` Nicolas Pouillard
@ 2006-02-25 19:09                   ` Richard Jones
  2006-03-01 12:48                     ` Nicolas Pouillard
  2006-02-25 23:17                   ` Christophe TROESTLER
  2006-02-27 11:14                   ` camlp4 renovation [was: [Caml-list] (int * int) <> int*int ?] Hendrik Tews
  2 siblings, 1 reply; 34+ messages in thread
From: Richard Jones @ 2006-02-25 19:09 UTC (permalink / raw)
  To: Nicolas Pouillard; +Cc: Vincent Balat, caml-list

On Sat, Feb 25, 2006 at 07:30:41PM +0100, Nicolas Pouillard wrote:
> and Ppat_variant. It will be fixed (note: I'am working on a renovation
> of camlp4 as an internship).

Can you make camlp4 use the ordinary syntax?!  As in:
http://wwwtcs.inf.tu-dresden.de/~tews/ocamlp4/ocamlp4.html

Rich.

-- 
Richard Jones, CTO Merjis Ltd.
Merjis - web marketing and technology - http://merjis.com
Team Notepad - intranets and extranets for business - http://team-notepad.com


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-25 18:30                 ` Nicolas Pouillard
  2006-02-25 19:09                   ` Richard Jones
@ 2006-02-25 23:17                   ` Christophe TROESTLER
  2006-03-01 13:01                     ` Nicolas Pouillard
  2006-02-27 11:14                   ` camlp4 renovation [was: [Caml-list] (int * int) <> int*int ?] Hendrik Tews
  2 siblings, 1 reply; 34+ messages in thread
From: Christophe TROESTLER @ 2006-02-25 23:17 UTC (permalink / raw)
  To: nicolas.pouillard; +Cc: OCaml Mailing List

On Sat, 25 Feb 2006, "Nicolas Pouillard" <nicolas.pouillard@inria.fr> wrote:
> 
>  I'am working on a renovation of camlp4 as an internship).

In view of the recent discussion, how about to bundle with camlp4 a
curried syntax for constructors (independent of the revised syntax)
and see if people prefer it?

My 0.2€,
ChriS


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

* camlp4 renovation [was: [Caml-list] (int * int) <> int*int ?]
  2006-02-25 18:30                 ` Nicolas Pouillard
  2006-02-25 19:09                   ` Richard Jones
  2006-02-25 23:17                   ` Christophe TROESTLER
@ 2006-02-27 11:14                   ` Hendrik Tews
  2 siblings, 0 replies; 34+ messages in thread
From: Hendrik Tews @ 2006-02-27 11:14 UTC (permalink / raw)
  To: Nicolas Pouillard, caml-list

Nicolas Pouillard <nicolas.pouillard@inria.fr> writes:

   (note: I'am working on a renovation of camlp4 as an internship).
   
Can you give some details on plans and goals? Or do we have to
wait until it is released? Where can we send out wish lists to? 

Bye,

Hendrik


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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-25 19:09                   ` Richard Jones
@ 2006-03-01 12:48                     ` Nicolas Pouillard
  0 siblings, 0 replies; 34+ messages in thread
From: Nicolas Pouillard @ 2006-03-01 12:48 UTC (permalink / raw)
  To: Richard Jones; +Cc: Vincent Balat, caml-list

On 2/25/06, Richard Jones <rich@annexia.org> wrote:
> On Sat, Feb 25, 2006 at 07:30:41PM +0100, Nicolas Pouillard wrote:
> > and Ppat_variant. It will be fixed (note: I'am working on a renovation
> > of camlp4 as an internship).
>
> Can you make camlp4 use the ordinary syntax?!  As in:
> http://wwwtcs.inf.tu-dresden.de/~tews/ocamlp4/ocamlp4.html
>

We have plans to improve the quotation system, but I can't tell you
more for now.

--
Nicolas Pouillard aka Ertai

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

* Re: [Caml-list] (int * int) <> int*int ?
  2006-02-25 23:17                   ` Christophe TROESTLER
@ 2006-03-01 13:01                     ` Nicolas Pouillard
  0 siblings, 0 replies; 34+ messages in thread
From: Nicolas Pouillard @ 2006-03-01 13:01 UTC (permalink / raw)
  To: Christophe TROESTLER; +Cc: OCaml Mailing List

On 2/26/06, Christophe TROESTLER <Christophe.Troestler@umh.ac.be> wrote:
> On Sat, 25 Feb 2006, "Nicolas Pouillard" <nicolas.pouillard@inria.fr> wrote:
> >
> >  I'am working on a renovation of camlp4 as an internship).
>
> In view of the recent discussion, how about to bundle with camlp4 a
> curried syntax for constructors (independent of the revised syntax)
> and see if people prefer it?
>

Perhaps as a little extension.

--
Nicolas Pouillard aka Ertai

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

end of thread, other threads:[~2006-03-01 13:01 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-02-23 17:28 (int * int) <> int*int ? Frédéric Gava
2006-02-23 18:33 ` [Caml-list] " Eric Cooper
2006-02-23 19:03   ` Martin Jambon
2006-02-23 19:07   ` Frédéric Gava
2006-02-23 20:15     ` Brian Hurt
2006-02-23 21:30       ` Frédéric Gava
2006-02-23 21:57         ` Brian Hurt
2006-02-23 22:30           ` Frédéric Gava
2006-02-23 22:50             ` Brian Hurt
2006-02-23 23:07               ` Frédéric Gava
2006-02-24  8:38     ` Alessandro Baretta
2006-02-24 12:59     ` Damien Doligez
2006-02-23 18:33 ` Thomas Fischbacher
2006-02-23 18:56 ` David Brown
2006-02-23 19:24   ` Frédéric Gava
2006-02-23 19:37   ` Frédéric Gava
2006-02-23 19:45     ` Frédéric Gava
2006-02-24  0:01       ` Jacques Garrigue
2006-02-24  0:18         ` Lukasz Stafiniak
2006-02-24  2:17           ` Jacques Garrigue
2006-02-24 13:07             ` Alain Frisch
2006-02-25 17:42               ` Vincent Balat
2006-02-25 18:30                 ` Nicolas Pouillard
2006-02-25 19:09                   ` Richard Jones
2006-03-01 12:48                     ` Nicolas Pouillard
2006-02-25 23:17                   ` Christophe TROESTLER
2006-03-01 13:01                     ` Nicolas Pouillard
2006-02-27 11:14                   ` camlp4 renovation [was: [Caml-list] (int * int) <> int*int ?] Hendrik Tews
2006-02-24 13:39             ` [Caml-list] (int * int) <> int*int ? Nicolas Cannasse
2006-02-24 14:49               ` Frédéric Gava
2006-02-24  8:27   ` also for tagged records? [Was: Re: [Caml-list] (int * int) <> int*int ?] Sebastian Egner
2006-02-24 14:01     ` Thomas Fischbacher
2006-02-23 20:58 ` [Caml-list] (int * int) <> int*int ? Jon Harrop
2006-02-23 21:36   ` Frédéric Gava

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