* Re: [Caml-list] Subtyping structurally-equivalent records, or something like it?
@ 2010-05-01 19:55 Dario Teixeira
2010-05-01 20:01 ` Sylvain Le Gall
0 siblings, 1 reply; 14+ messages in thread
From: Dario Teixeira @ 2010-05-01 19:55 UTC (permalink / raw)
To: caml-list, Anthony Tavener
Hi,
> type kinematic = { lin: Vec.t; ang: Vec.t }
>
> Which I've been using to represent a medley of physical attributes (force, > momentum, velocity, etc.).
I second Stéphane's suggestion of using phantom types; moreover,
I recommend you read an article that discusses them to some detail
and covers their use for precisely this sort of problem:
http://camltastic.blogspot.com/2008/05/phantom-types.html
Cheers,
Dario Teixeira
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Subtyping structurally-equivalent records, or something like it?
2010-05-01 19:55 [Caml-list] Subtyping structurally-equivalent records, or something like it? Dario Teixeira
@ 2010-05-01 20:01 ` Sylvain Le Gall
2010-05-04 10:33 ` [Caml-list] " AUGER Cédric
[not found] ` <4429.86797211251$1272970133@news.gmane.org>
0 siblings, 2 replies; 14+ messages in thread
From: Sylvain Le Gall @ 2010-05-01 20:01 UTC (permalink / raw)
To: caml-list
On 01-05-2010, Dario Teixeira <darioteixeira@yahoo.com> wrote:
> Hi,
>
>> type kinematic = { lin: Vec.t; ang: Vec.t }
>>
>> Which I've been using to represent a medley of physical attributes (force, > momentum, velocity, etc.).
>
> I second Stéphane's suggestion of using phantom types; moreover,
> I recommend you read an article that discusses them to some detail
> and covers their use for precisely this sort of problem:
> http://camltastic.blogspot.com/2008/05/phantom-types.html
>
I really like the use of private type abbreviation for phantom type:
http://ocaml.janestreet.com/?q=node/77
Regards,
Sylvain Le Gall
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Caml-list] Re: Subtyping structurally-equivalent records, or something like it?
2010-05-01 20:01 ` Sylvain Le Gall
@ 2010-05-04 10:33 ` AUGER Cédric
[not found] ` <4429.86797211251$1272970133@news.gmane.org>
1 sibling, 0 replies; 14+ messages in thread
From: AUGER Cédric @ 2010-05-04 10:33 UTC (permalink / raw)
Cc: caml-list
I am not expert in Ocaml, is the following the same in terms
of performances as the phantom types?
type kinematic = ...
type force = Force of kinematic
type momentum = Moment of kinematic
...
That is does the constructor introduce an overhead or not?
As there is only one constructor, no overhead should be done in an
optimized compiler.
So general functions should use a kinematic -> [Type]
and a specialized function, force -> [Type] and so on...
I understand this version is not as handy as the phantom types, as we
need to use "match ... with Force f -> ..." or at least "let Force f
= ... in ...", but my question is only in terms of efficiency;
obviously phantom types are more or equally efficient than what I
exposed, but does the reciproque also holds?
^ permalink raw reply [flat|nested] 14+ messages in thread
[parent not found: <4429.86797211251$1272970133@news.gmane.org>]
* Re: Subtyping structurally-equivalent records, or something like it?
[not found] ` <4429.86797211251$1272970133@news.gmane.org>
@ 2010-05-04 11:53 ` Sylvain Le Gall
2010-05-04 12:47 ` [Caml-list] " rossberg
2010-05-04 13:37 ` Edgar Friendly
0 siblings, 2 replies; 14+ messages in thread
From: Sylvain Le Gall @ 2010-05-04 11:53 UTC (permalink / raw)
To: caml-list
On 04-05-2010, AUGER Cédric <Cedric.Auger@lri.fr> wrote:
> I am not expert in Ocaml, is the following the same in terms
> of performances as the phantom types?
>
> type kinematic = ...
>
> type force = Force of kinematic
> type momentum = Moment of kinematic
> ...
>
> That is does the constructor introduce an overhead or not?
> As there is only one constructor, no overhead should be done in an
> optimized compiler.
>
The variants are represented using a block. If you introduce a single
variant, it will create a block that points to kinematic. E.g. "Force of
kinematic" will create a pointer to the kinematic structure.
Your construction of force and momentum will add a level of indirection
for every use of the kinematic structure.
Phantom type doesn't add a level of indirection and left no trace in the
generated assembler.
This is not about optimized compiler in this case but about data
representation. Even if you use an optimized compiler (which is not
really the case with ocamlopt), you won't change datastructure
representation to optimize.
Regards,
Sylvain Le Gall
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Caml-list] Re: Subtyping structurally-equivalent records, or something like it?
2010-05-04 11:53 ` Sylvain Le Gall
@ 2010-05-04 12:47 ` rossberg
2010-05-04 13:42 ` Sylvain Le Gall
2010-05-05 9:31 ` Goswin von Brederlow
2010-05-04 13:37 ` Edgar Friendly
1 sibling, 2 replies; 14+ messages in thread
From: rossberg @ 2010-05-04 12:47 UTC (permalink / raw)
To: Sylvain Le Gall; +Cc: caml-list
"Sylvain Le Gall" <sylvain@le-gall.net>:
>
> This is not about optimized compiler in this case but about data
> representation. Even if you use an optimized compiler (which is not
> really the case with ocamlopt), you won't change datastructure
> representation to optimize.
What do you mean? There is no reason in general why a compiler cannot
optimize data representations, and some do in cases like this.
/Andreas
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Subtyping structurally-equivalent records, or something like it?
2010-05-04 12:47 ` [Caml-list] " rossberg
@ 2010-05-04 13:42 ` Sylvain Le Gall
2010-05-04 15:18 ` [Caml-list] " Fabrice Le Fessant
2010-05-05 9:31 ` Goswin von Brederlow
1 sibling, 1 reply; 14+ messages in thread
From: Sylvain Le Gall @ 2010-05-04 13:42 UTC (permalink / raw)
To: caml-list
On 04-05-2010, rossberg@mpi-sws.org <rossberg@mpi-sws.org> wrote:
> "Sylvain Le Gall" <sylvain@le-gall.net>:
>>
>> This is not about optimized compiler in this case but about data
>> representation. Even if you use an optimized compiler (which is not
>> really the case with ocamlopt), you won't change datastructure
>> representation to optimize.
>
> What do you mean? There is no reason in general why a compiler cannot
> optimize data representations, and some do in cases like this.
>
Anyway, if it comes to data alignement and things like that, the
compiler should optimize data representations. But in this case, I
really don't think we are talking about data alignement.
Regards,
Sylvain Le Gall
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Caml-list] Re: Subtyping structurally-equivalent records, or something like it?
2010-05-04 13:42 ` Sylvain Le Gall
@ 2010-05-04 15:18 ` Fabrice Le Fessant
0 siblings, 0 replies; 14+ messages in thread
From: Fabrice Le Fessant @ 2010-05-04 15:18 UTC (permalink / raw)
To: Sylvain Le Gall; +Cc: caml-list
"ocamlopt" does optimize data representation: for example, it can unbox
floats into registers, or into arrays of floats. However, there is a
tradeoff between such optimizations and efficiency: when you do too much
representation optimisation, you might end up performing a lot of tests
because a given type can be represented in multiple formats, and
performing a lot of transformations between the representations,
especially as the FFI (Ocaml interface to C) specifies the
representation of data.
Of course, I am not saying it is not possible to do better: it requires
a lot of energy, the compiler code becomes more complex, and the
improvement on speed is not clear.
--Fabrice
Sylvain Le Gall wrote, On 05/04/2010 03:42 PM:
> On 04-05-2010, rossberg@mpi-sws.org <rossberg@mpi-sws.org> wrote:
>> "Sylvain Le Gall" <sylvain@le-gall.net>:
>>> This is not about optimized compiler in this case but about data
>>> representation. Even if you use an optimized compiler (which is not
>>> really the case with ocamlopt), you won't change datastructure
>>> representation to optimize.
>> What do you mean? There is no reason in general why a compiler cannot
>> optimize data representations, and some do in cases like this.
>>
>
> Anyway, if it comes to data alignement and things like that, the
> compiler should optimize data representations. But in this case, I
> really don't think we are talking about data alignement.
>
> Regards,
> Sylvain Le Gall
>
> _______________________________________________
> 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
>
--
Fabrice LE FESSANT
Chercheur, Equipe ASAP
(As Scalable As Possible)
http://www.lefessant.net/
INRIA-Futurs, Bat P - 112
Parc Orsay Université
2-4, rue Jacques Monod
F-91893 Orsay Cedex, FRANCE
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Caml-list] Re: Subtyping structurally-equivalent records, or something like it?
2010-05-04 12:47 ` [Caml-list] " rossberg
2010-05-04 13:42 ` Sylvain Le Gall
@ 2010-05-05 9:31 ` Goswin von Brederlow
2010-05-05 12:12 ` rossberg
1 sibling, 1 reply; 14+ messages in thread
From: Goswin von Brederlow @ 2010-05-05 9:31 UTC (permalink / raw)
To: rossberg; +Cc: Sylvain Le Gall, caml-list
rossberg@mpi-sws.org writes:
> "Sylvain Le Gall" <sylvain@le-gall.net>:
>>
>> This is not about optimized compiler in this case but about data
>> representation. Even if you use an optimized compiler (which is not
>> really the case with ocamlopt), you won't change datastructure
>> representation to optimize.
>
> What do you mean? There is no reason in general why a compiler cannot
> optimize data representations, and some do in cases like this.
How could it? At least for any type that is public in a module.
The data representation is part of the ABI. As such it is fixed and can
in no way be optimized by the compiler. Only thing you can do is change
the ABI and define a more optimized representation in the first place.
As example
type foo = { x : int; y : int; }
type bar = Bar of foo
Currently a bar is represented as
foo {
tag = 0
size = 2
field[0] = int(x)
field[1] = int(y)
}
bar {
tag = 0 (for Bar)
size = 1
field[0] = &foo
}
2 Blocks taking up 5 words.
A better representation would be to combine the two:
bar {
tag = 0 (for Bar)
size = 2
field[0] = int(x)
field[1] = int(y)
}
A single block of 3 words.
This also works for
type bar = Foo of foo | Blub of foo | Blubber of foo
but not for
type baz = Baz of bar
There are lots of cases where the representation could be improved for
special cases. But ocaml I think only does that for float arrays or
records that only contain floats. But that is a design decision and not
something the compiler can just optimize.
MfG
Goswin
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Caml-list] Re: Subtyping structurally-equivalent records, or something like it?
2010-05-05 9:31 ` Goswin von Brederlow
@ 2010-05-05 12:12 ` rossberg
2010-05-05 16:46 ` Goswin von Brederlow
0 siblings, 1 reply; 14+ messages in thread
From: rossberg @ 2010-05-05 12:12 UTC (permalink / raw)
To: Goswin von Brederlow; +Cc: caml-list
"Goswin von Brederlow" <goswin-v-b@web.de>:
>
>>> This is not about optimized compiler in this case but about data
>>> representation. Even if you use an optimized compiler (which is not
>>> really the case with ocamlopt), you won't change datastructure
>>> representation to optimize.
>>
>> What do you mean? There is no reason in general why a compiler cannot
>> optimize data representations, and some do in cases like this.
>
> How could it? At least for any type that is public in a module.
>
> The data representation is part of the ABI. As such it is fixed and can
> in no way be optimized by the compiler. Only thing you can do is change
> the ABI and define a more optimized representation in the first place.
Yes, and I didn't say that OCaml easily could, given external constraints
like the one you mention. I only was objecting to the statement that this is
not an optimization.
> A better representation would be to combine the two:
>
> bar {
> tag = 0 (for Bar)
> size = 2
> field[0] = int(x)
> field[1] = int(y)
> }
That is called flattening or unboxing, and in degenerate use cases it can
actually be costly because you have to copy the record if you extract it
first-class. However, for the original case there would be a much simpler
optimization: if a data type has only one constructor (more precisely, one
except for nullary ones), you don't need to represent its tag at all, so the
whole indirection is unnecessary.
/Andreas
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Caml-list] Re: Subtyping structurally-equivalent records, or something like it?
2010-05-05 12:12 ` rossberg
@ 2010-05-05 16:46 ` Goswin von Brederlow
0 siblings, 0 replies; 14+ messages in thread
From: Goswin von Brederlow @ 2010-05-05 16:46 UTC (permalink / raw)
To: rossberg; +Cc: Goswin von Brederlow, caml-list
rossberg@mpi-sws.org writes:
> "Goswin von Brederlow" <goswin-v-b@web.de>:
>>
>>>> This is not about optimized compiler in this case but about data
>>>> representation. Even if you use an optimized compiler (which is not
>>>> really the case with ocamlopt), you won't change datastructure
>>>> representation to optimize.
>>>
>>> What do you mean? There is no reason in general why a compiler cannot
>>> optimize data representations, and some do in cases like this.
>>
>> How could it? At least for any type that is public in a module.
>>
>> The data representation is part of the ABI. As such it is fixed and can
>> in no way be optimized by the compiler. Only thing you can do is change
>> the ABI and define a more optimized representation in the first place.
>
> Yes, and I didn't say that OCaml easily could, given external constraints
> like the one you mention. I only was objecting to the statement that this is
> not an optimization.
>
>> A better representation would be to combine the two:
>>
>> bar {
>> tag = 0 (for Bar)
>> size = 2
>> field[0] = int(x)
>> field[1] = int(y)
>> }
>
> That is called flattening or unboxing, and in degenerate use cases it can
> actually be costly because you have to copy the record if you extract it
> first-class. However, for the original case there would be a much simpler
> optimization: if a data type has only one constructor (more precisely, one
> except for nullary ones), you don't need to represent its tag at all, so the
> whole indirection is unnecessary.
>
> /Andreas
Actualy in this case you don't. In foo the "tag" part of the block is
unused and in bar it is the constructor id. (foo) and (Bar foo) just
happen to have the same representation. Extracting a foo from a bar
means you just ignore the tag part, which is already ignored anyway.
The case of only having one constructor can be seen as special case for
this in the case of records. But type gnarf = Gnarf of int could be
represented as plain int as you say. The idea is the same.
The reason ocaml does not do this is that defining lots of exception for
the representation of data makes the compiler much more complicated and
ocamls compiler aims at being simple. At least that's what has been said
in the past.
MfG
Goswin
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Caml-list] Re: Subtyping structurally-equivalent records, or something like it?
2010-05-04 11:53 ` Sylvain Le Gall
2010-05-04 12:47 ` [Caml-list] " rossberg
@ 2010-05-04 13:37 ` Edgar Friendly
2010-05-05 9:33 ` Goswin von Brederlow
2010-05-05 11:10 ` Yaron Minsky
1 sibling, 2 replies; 14+ messages in thread
From: Edgar Friendly @ 2010-05-04 13:37 UTC (permalink / raw)
To: caml-list
On 05/04/2010 07:53 AM, Sylvain Le Gall wrote:
> On 04-05-2010, AUGER Cédric<Cedric.Auger@lri.fr> wrote:
>> type momentum = Moment of kinematic
>>
>> That is does the constructor introduce an overhead or not?
>> As there is only one constructor, no overhead should be done in an
>> optimized compiler.
>>
> This is not about optimized compiler in this case but about data
> representation. Even if you use an optimized compiler (which is not
> really the case with ocamlopt), you won't change datastructure
> representation to optimize.
>
The OCaml compiler *could* special-case this kind of constructor, but as
there's the syntax:
type momentum = kinematic
Which produces the non-boxed kinematic values, the authors probably
decided to follow the maxim "Do what the programmer says" for singleton
variant types. The question becomes whether phantom types solve this
problem sufficiently or do we need another type-level construct -
explicit subtyping relationships. Forever ago I suggested this to
achieve a similar goal, and was given yet another solution:
module M : sig
type momentum
val of_kin : kinematic -> momentum
val to_kin : momentum -> kinematic
end = struct
type momentum = kinematic
let of_kin x = x
let to_kin x = x
end
Yes, it's a lot of boilerplate for each type, but you only have to write
it once (per type), and cross-module inlining should give zero runtime
cost. If not, use "%identity", and expose it in the interface. This
method is along the lines of Anthony's proposal #4.
E.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Caml-list] Re: Subtyping structurally-equivalent records, or something like it?
2010-05-04 13:37 ` Edgar Friendly
@ 2010-05-05 9:33 ` Goswin von Brederlow
2010-05-05 11:10 ` Yaron Minsky
1 sibling, 0 replies; 14+ messages in thread
From: Goswin von Brederlow @ 2010-05-05 9:33 UTC (permalink / raw)
To: Edgar Friendly; +Cc: caml-list
Edgar Friendly <thelema314@gmail.com> writes:
> On 05/04/2010 07:53 AM, Sylvain Le Gall wrote:
>> On 04-05-2010, AUGER Cédric<Cedric.Auger@lri.fr> wrote:
>>> type momentum = Moment of kinematic
>>>
>>> That is does the constructor introduce an overhead or not?
>>> As there is only one constructor, no overhead should be done in an
>>> optimized compiler.
>>>
>> This is not about optimized compiler in this case but about data
>> representation. Even if you use an optimized compiler (which is not
>> really the case with ocamlopt), you won't change datastructure
>> representation to optimize.
>>
> The OCaml compiler *could* special-case this kind of constructor, but
> as there's the syntax:
>
> type momentum = kinematic
>
> Which produces the non-boxed kinematic values, the authors probably
> decided to follow the maxim "Do what the programmer says" for
> singleton variant types. The question becomes whether phantom types
> solve this problem sufficiently or do we need another type-level
> construct -
> explicit subtyping relationships. Forever ago I suggested this to
> achieve a similar goal, and was given yet another solution:
>
> module M : sig
> type momentum
> val of_kin : kinematic -> momentum
> val to_kin : momentum -> kinematic
> end = struct
> type momentum = kinematic
> let of_kin x = x
> let to_kin x = x
> end
I think that can be cut down to:
module M = struct
type momentum = private kinematic
let of_kin = %identity
let to_kin = %identity
end
> Yes, it's a lot of boilerplate for each type, but you only have to
> write it once (per type), and cross-module inlining should give zero
> runtime cost. If not, use "%identity", and expose it in the
> interface. This method is along the lines of Anthony's proposal #4.
>
> E.
MfG
Goswin
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Caml-list] Re: Subtyping structurally-equivalent records, or something like it?
2010-05-04 13:37 ` Edgar Friendly
2010-05-05 9:33 ` Goswin von Brederlow
@ 2010-05-05 11:10 ` Yaron Minsky
1 sibling, 0 replies; 14+ messages in thread
From: Yaron Minsky @ 2010-05-05 11:10 UTC (permalink / raw)
To: Edgar Friendly; +Cc: caml-list
[-- Attachment #1: Type: text/plain, Size: 1052 bytes --]
On Tue, May 4, 2010 at 9:37 AM, Edgar Friendly <thelema314@gmail.com> wrote:
> module M : sig
> type momentum
> val of_kin : kinematic -> momentum
> val to_kin : momentum -> kinematic
> end = struct
> type momentum = kinematic
> let of_kin x = x
> let to_kin x = x
> end
>
> Yes, it's a lot of boilerplate for each type, but you only have to write it
> once (per type), and cross-module inlining should give zero runtime cost.
> If not, use "%identity", and expose it in the interface. This method is
> along the lines of Anthony's proposal #4.
You can do the above solution with essentially no boilerplate:
module M = struct
type t = kinematic
val to_kin x = x
val of_kin x = x
end
module type S = sig
type t
val to_kin : t -> kinematic
val of_kin : kinematic -> t
end
module Momentum : S = M
module Position : S = M
module Force : S = M
and so on. Just one line per kinematic-like type you want to create.
That said, I still think the phantom type solution will end up cleaner.
y
[-- Attachment #2: Type: text/html, Size: 1479 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Subtyping structurally-equivalent records, or something like it?
@ 2010-05-01 16:04 Anthony Tavener
0 siblings, 0 replies; 14+ messages in thread
From: Anthony Tavener @ 2010-05-01 16:04 UTC (permalink / raw)
To: caml-list
[-- Attachment #1: Type: text/plain, Size: 4235 bytes --]
I have this:
type kinematic = { lin: Vec.t; ang: Vec.t }
Which I've been using to represent a medley of physical attributes (force,
momentum, velocity, etc.).
As the physics code becomes increasingly substantial I'm running into
possible human-error, like passing a momentum where a force is expected, or
a mass instead of inverse-mass (mass is also a record though different, but
inv-mass has the same structure as mass). So I'd like to make distinct
types, such as:
type position = { r: Vec.t; theta: Vec.t }
type acceleration = { a: Vec.t; alpha: Vec.t }
type force = { f: Vec.t; tau: Vec.t }
They are structurally equivalent, and ideally I'd like to be able to treat
these as 'kinematic' too, since that is how I would express the arithmetic
and common functions on these types (add, mul, etc).
I'm sure I've seen posts on this before but I can't find them now (though
what I remember are questions about having distinct 'float' types, such as
for degrees vs radians, rather than records).
I know OCaml doesn't have subtypes for records, which is effectively what
I'm looking for. Though this case is a bit more specialized that that... all
the subtypes and base type are structurally equivalent. Code for one of
these types would technically work on any... but is there a way to inform
the type system of my intentions?
I hope someone has a better option than those I've considered, or that I
have a grave misunderstanding somewhere and one of these options is actually
good:
1. Objects. Subtyping makes these a natural fit, but in this case I don't
need anything else which objects provide, and a certainly don't need the
poor performance or method-calling mixed in with my computational code
(aesthetically... yucky, to me). Again, each type is structurally
equivalent. Just some functions want certain types.
2. Using distinct records for each type, but no 'kinematic' base type, so
all common operations are duplicated for each new type. No performance hit.
But the redundant code is horrible -- makes extensions a pain, and a
potential bug-source.
2b. Same as above, but putting the common code in a functor which we apply
on all the different types. I think this will add some overhead, since the
signature of the types (below) would demand accessor functions for the
record fields, in order to uniformly get the fields from the different types
(again, even though they are structurally equivalent) -- these calls
probably wouldn't get optimized out. But maybe there is a better way to do
this?
module type KINEMATIC = sig
type t
val lin : t -> Vec.t
val ang : t -> Vec.t
end
3. Making all the other types different aliases of 'kinematic'; then using
explicit type declarations in function parameters and coercion to
'kinematic' when needed. This makes some ugly code, and the added-typesafety
is almost illusory. This is kind-of like 'typesafe' C code doing typecasting
gymnastics.
4. Adapter functions: 'kinematic_of_force: force -> kinematic', etc. as a
way to use the common set of 'kinematic' functions. This is clunky and comes
with a big performance hit unless these functions became like
type-coercions. If there is a way this can be done with zero runtime cost,
I'd accept the clunkiness. :)
Any thoughts?
I've been using OCaml for a few years now, but this is my first post. I feel
many of you are familiar online personae through reading archives, blogs,
and websites. Thank-you for all the help I've absorbed through those various
channels. And thanks to those making the language I favor for most tasks!
Briefly introducing myself: I've been a professional video-game developer
for 15 years, most recently specializing in AI. I quit my last job almost
two years ago to travel and program (95% in OCaml!), and am developing a
game now. I've seen indications over the years of other game developers
taking the plunge and then parting ways with OCaml, surely back to C++. I
see OCaml as viable and certainly more pleasurable, even with avoiding
mutation. But within a pressure-cooker environment (working for $$ from
someone else) people fall back on what they are most familiar with... also
you can't go too rogue while still being part of a team. :)
-Anthony Tavener
[-- Attachment #2: Type: text/html, Size: 4546 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2010-05-05 16:46 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-01 19:55 [Caml-list] Subtyping structurally-equivalent records, or something like it? Dario Teixeira
2010-05-01 20:01 ` Sylvain Le Gall
2010-05-04 10:33 ` [Caml-list] " AUGER Cédric
[not found] ` <4429.86797211251$1272970133@news.gmane.org>
2010-05-04 11:53 ` Sylvain Le Gall
2010-05-04 12:47 ` [Caml-list] " rossberg
2010-05-04 13:42 ` Sylvain Le Gall
2010-05-04 15:18 ` [Caml-list] " Fabrice Le Fessant
2010-05-05 9:31 ` Goswin von Brederlow
2010-05-05 12:12 ` rossberg
2010-05-05 16:46 ` Goswin von Brederlow
2010-05-04 13:37 ` Edgar Friendly
2010-05-05 9:33 ` Goswin von Brederlow
2010-05-05 11:10 ` Yaron Minsky
-- strict thread matches above, loose matches on Subject: below --
2010-05-01 16:04 Anthony Tavener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox