[Caml-list] Smells like duck-typing

8 views
Skip to first unread message

Dario Teixeira

unread,
Oct 17, 2007, 9:36:22 AM10/17/07
to caml...@yquem.inria.fr
Hi,

I have been trying to reach a sane modelling in OCaml for a "story"
data structure in a CMS. The problem is that I find myself needing
a degree of expressiveness that I can't find in the language! I do
have a working, tentative solution, but it has a few ugly aspects
that I would very much like to improve. Details follow. (Sorry
for the long post; at least I hope it's not too dense and hard to
follow).

A "full" story record is defined like this:

type full_t =
{
id: int;
title: string;
intro: string;
body: string;
}

(in reality there are other fields, but I'll ommit them for the sake
of clarity). In addition, stories can also come in "blurb" and "fresh"
types, which are essentially (non-disjoint) subsets of the type above:

type blurb_t = type fresh_t =
{ {
id: int; title: string;
title: string; intro: string;
intro: string; body: string;
} }


At last, I have a function "print_metadata" that takes as parameter
either a "full" or a "blurb" story, printing its id and title:

let print_metadata s =
Printf.printf "%d: %s\n" s.id s.title

Now, I have been looking for the best way to model this situation
in OCaml. Here are some options:

a) Use record types, as shown above. However, to avoid namespace clashes,
this would entail putting each record in its own module (neat) or at
least salting each field name (ugly). Suppose that I opt for the former
option and create the modules Full, Blurb, and Fresh, each with a type t:

type story_t = [`Full of Full.t | `Blurb of Blurb.t | `Fresh of Fresh.t]

Note that I have chosen a polymorphic variant because print_metadata only
makes sense for Full.t and Blurb.t types. However, this solution means
there can't be any code sharing between the two branchings, which is just
ridiculous considering they are essentially identical: (and in the real
world, print_metadata is a much bigger function).

let print_metadata = function
| `Full s -> Printf.printf "%d: %s\n" s.Full.id s.Full.title
| `Blurb s -> Printf.printf "%d: %s\n" s.Blurb.id s.Blurb.title

b) Use only full_t and make all fields option types. However, not only is
this cumbersome to use, but is also conceptually wrong, because it does
not capture the fact that, for example, all "blurb" stories have three
*mandatory* fields.

c) Actually put the "Objective" part of OCaml to use. This is the solution
I am using at the moment. This is what it looks like:

class story (id, title, intro, body) =
object
val id: int option = id
val title: string option = title
val intro: string option = intro
val body: string option = body

method id =
match id with
| Some thing -> thing
| None -> failwith "oops"

method title =
match title with
| Some thing -> thing
| None -> failwith "oops"

method intro =
match intro with
| Some thing -> thing
| None -> failwith "oops"

method body =
match body with
| Some thing -> thing
| None -> failwith "oops"
end


class full (id, title, intro, body) =
object
inherit story (Some id, Some title, Some intro, Some body)
end

class blurb (id, title, intro) =
object
inherit story (Some id, Some title, Some intro, None)
end

class fresh (title, intro, body) =
object
inherit story (None, Some title, Some intro, Some body)
end


let print_metadata s =
Printf.printf "%d: %s\n" s#id s#title

This last solution has two big advantages: it provides a relatively
clean interface to users of the module, and allows for code reuse
without duplication. Thanks to the way the object system in OCaml
works, the print_metadata function can operate on any objects that
have the #id and #title methods. It feels almost like the duck-typing
present in languages such as Python (though different, of course).

However, I'm still not completely happy with it, mostly because the
hackery with the optional types inside the story class is ugly. Does
someone have any clever ideas on how this could be modelled/improved?

Thanks,
Dario

___________________________________________________________
Yahoo! Answers - Got a question? Someone out there knows the answer. Try it
now.
http://uk.answers.yahoo.com/

_______________________________________________
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

Daniel Bünzli

unread,
Oct 17, 2007, 10:25:51 AM10/17/07
to Dario Teixeira, caml...@yquem.inria.fr
Use a record with a phantom type (the type must be abstract for this
to work). The record has the common properties as fields and a data
field which is either a list of tagged values (if many kinds of
stories share the same fields) or a variant for the data specific to
a kind of story. If there are operations that are allowed only on
some kind of stories constrain the phantom type in the signature to
enforce this statically.

Best,

Daniel

module Story : sig

type 'a t constraint 'a = [< `Full | `Blurb | `Fresh ]

(* Story creators *)
val full : ... -> `Full t
val blurb : ... -> `Blurb t
val fresh : ... -> `Fresh t

val print_meta_data : [< `Full | `Blurb ] t -> unit

end = struct

type 'a t = {


id : int;
title : string;
intro : string;

data : ...
}
...
end

Chris King

unread,
Oct 17, 2007, 10:34:08 AM10/17/07
to Dario Teixeira, caml...@yquem.inria.fr

Why not have different object types for each of the story types? e.g.

type full = < id: int; title: string; intro: string; body: string >
type blurb = < id: int; title: string; intro: string >
type fresh = < title: string; intro: string; body: string >

print_metadata can remain as is in your object example. In order to
allow functions that operate differently depending on which story type
they're given, use a polymorphic variant like in your first example.
If you wanted print_metadata to take such a type, it could be written
as:

let print_metadata s =
let s' =
match s with
| `Full f -> (f :> < id: int; title: string >)
| `Blurb f -> (f :> < id: int; title: string >)
in
Printf.printf "%d: %s\n" s'#id s'#title

(Note the match gook is unfortunately needed to get the typing right...)

If on the other hand you wanted to ditch objects entirely, you could
do a similar thing using modules and functors. E.g.:

module Full = struct
type t = { id: int; title: string; intro: string; body: string }
let id s = s.id
let title s = s.title
let intro s = s.intro
let body s = s.body
end

(* etc. *)

module Print_metadata(S: sig type t val id: t -> string val title: t
-> string) = struct
let f s = Printf.printf "%d: %s\n" (S.id s) (S.title s)
end

Of course, since calls to print_metadata now look like
"Print_metadata(Full).f story", you're essentially forced to write out
the types of everything, which is probably what you wanted to avoid
anyway.

HTH,
Chris

Dario Teixeira

unread,
Oct 17, 2007, 10:48:10 AM10/17/07
to caml...@yquem.inria.fr
> I think your solution is to fully use the "Objective" part of OCaml,
> that is, using subtyping (technically it's polymorphic rows typing) :

Hi,

Yes, you're right. Doing away with the inheritance -- while having the
disadvantage of forcing the redeclaration of all common fields -- does
allow me to throw away the ugliness of the option types. It is in the
end the lesser of two evils...

Cheers,
Dario

___________________________________________________________
Want ideas for reducing your carbon footprint? Visit Yahoo! For Good http://uk.promotions.yahoo.com/forgood/environment.html

Dario Teixeira

unread,
Oct 17, 2007, 10:59:36 AM10/17/07
to Chris King, caml...@yquem.inria.fr
Hi,

> Why not have different object types for each of the story types? e.g.

Yes, other people have suggested the same, and while not a perfect
solution (because of the reduplication of fields), the object subtyping
feature of OCaml (the bit that smells a lot like duck-typing...)
is powerful enough to avoid the code duplication in functions such
as print_metadata. More important, it avoids the ugly hackery with
option types.


> If on the other hand you wanted to ditch objects entirely, you could
> do a similar thing using modules and functors. E.g.:

That is actually an interesting approach. If I'm not mistaken, the
semantics for the parameter to a functor is "a module whose signature
contains at least this", which is again similar to duck-typing...

Cheers,
Dario

___________________________________________________________
Yahoo! Answers - Got a question? Someone out there knows the answer. Try it
now.
http://uk.answers.yahoo.com/

_______________________________________________

Dario Teixeira

unread,
Oct 17, 2007, 11:02:23 AM10/17/07
to Francisco Jos? Valverde Albacete, caml...@yquem.inria.fr
> To me your problems looks like a good candidate for XML-modelling and
> reusing all the tools for working in XML. The more so because XML was
> made... exactly for that! Why don't you give it at least a somewhat
> serious thought?

Hi,

You mean like CDuce and/or OCamlduce?

skaller

unread,
Oct 17, 2007, 11:04:07 AM10/17/07
to Daniel Bünzli, caml...@yquem.inria.fr

On Wed, 2007-10-17 at 16:25 +0200, Daniel Bünzli wrote:
> Use a record with a phantom type (the type must be abstract for this
> to work).

I would use something weaker, and I wouldn't use objects
either. To me, this is essentially a dynamic scenario,
so the data type should be dynamic. For example:

type field_t = [
| `Title of string
| `Intro of string
| `Body of string
| `Field of string * string
]

type story_t = field_t list


--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

Dario Teixeira

unread,
Oct 17, 2007, 11:14:03 AM10/17/07
to skaller, Daniel Bünzli, caml...@yquem.inria.fr
> I would use something weaker, and I wouldn't use objects
> either. To me, this is essentially a dynamic scenario,
> so the data type should be dynamic. For example:
>
> type field_t = [
> | `Title of string
> | `Intro of string
> | `Body of string
> | `Field of string * string
> ]
>
> type story_t = field_t list
>

Hi,

Interesting idea, but how would you access the fields in a convenient
manner? Note that nothing beats record access (say, story.title) or even
object method call (story#title) in convenience and readability.

(I guess the convenience aspect could be sorted out with a syntax
extension, but then we're moving into far more complex territory
than I hope is necessary...)

Cheers,
Dario


___________________________________________________________
Want ideas for reducing your carbon footprint? Visit Yahoo! For Good http://uk.promotions.yahoo.com/forgood/environment.html

_______________________________________________

Zheng Li

unread,
Oct 17, 2007, 11:24:39 AM10/17/07
to caml...@inria.fr

Hi,

I would vote for the object solution. However, both record and object have
their own pros and cons. The actual solution should depends on your requirement
and taste. Just for an example, the following data structure is a possibility:

# type +'a t = {title:string; intro:string; extra:'a} constraint 'a = < .. >;;
# let fresh (title,intro,(body:string)) =
{title=title; intro=intro; extra=object method body=body end};;
# let blurb ((id:int),title,intro) =
{title=title; intro=intro; extra=object method id=id end};;
# let print_metadata s = Printf.printf "%d: %s\n" s.extra#id s.title;;
val print_metadata : < id : int; .. > t -> unit = <fun>

Dario Teixeira <dariot...@yahoo.com> writes:
> I have been trying to reach a sane modelling in OCaml for a "story"
> data structure in a CMS. The problem is that I find myself needing
> a degree of expressiveness that I can't find in the language! I do
> have a working, tentative solution, but it has a few ugly aspects
> that I would very much like to improve. Details follow. (Sorry
> for the long post; at least I hope it's not too dense and hard to
> follow).

--
Zheng Li
http://www.pps.jussieu.fr/~li

Vincent Aravantinos

unread,
Oct 17, 2007, 11:24:43 AM10/17/07
to Dario Teixeira, caml...@yquem.inria.fr

Le 17 oct. 07 à 15:35, Dario Teixeira a écrit :

> I have been trying to reach a sane modelling in OCaml for a "story"
> data structure in a CMS.

(...)


> Does someone have any clever ideas on how this could be
> modelled/improved?

Also take a look at:

http://tech.groups.yahoo.com/group/ocaml_beginners/message/8654

Cheers,
V.

Arnaud Spiwack

unread,
Oct 17, 2007, 11:26:35 AM10/17/07
to caml...@yquem.inria.fr
First, let us emphasize that this goes down to the original "option"
thing, but in a more dynamic fashion. It is very possible to wrap it
back with phantom types, which would probably be a good idea in this case.

My taste for this sort of thing is to make all this a finite map of some
sort (might be implemented as a list, but the primitive should ensure a
form of unicity, therefore an additional layer of abstract datatype).

Then you would need a type to query over :
"field_field = [ `Title | `Intro | `Body | `Field ].

Implement a function "fetch" that returns you a field_t or raises an
exception (you can do similarily a function "mem" etc).

Then you can define

let title m = let `Title s = fetch `Title m in s;;
and give it type [> `Title ] story -> string (to be sure not to raise
an exception, modulo right phantom type invariants).

That's my own methodology for this sort of types.

Arnaud Spiwack


Dario Teixeira a écrit :

Daniel Bünzli

unread,
Oct 17, 2007, 11:33:06 AM10/17/07
to Dario Teixeira, caml...@yquem.inria.fr, skaller

Le 17 oct. 07 à 17:13, Dario Teixeira a écrit :

>> type field_t = [
>> | `Title of string
>> | `Intro of string
>> | `Body of string
>> | `Field of string * string
>> ]
>>
>> type story_t = field_t list
>>

> Interesting idea,

If this is right for you then what you want is property lists and
these two solutions [1,2] may be of interest to you.

Daniel

[1] http://mlton.org/PropertyList
[2] http://caml.inria.fr/pub/ml-archives/caml-list/
2005/07/1b7a28921aa0a0e002df9e67ace7b60e.fr.html

Chris King

unread,
Oct 17, 2007, 12:22:08 PM10/17/07
to Daniel Bünzli, caml...@yquem.inria.fr, skaller
On 10/17/07, Daniel Bünzli <daniel....@epfl.ch> wrote:
> [2] http://caml.inria.fr/pub/ml-archives/caml-list/2005/07/1b7a28921aa0a0e002df9e67ace7b60e.fr.html

See also Jacques' follow up, where he provides a syntax extension for
these "polymorphic maps" (essentially type-safe property lists):
http://caml.inria.fr/pub/ml-archives/caml-list/2005/07/314a9eb55585d32e7876ef424f5994ae.fr.html

skaller

unread,
Oct 17, 2007, 12:52:53 PM10/17/07
to Dario Teixeira, caml...@yquem.inria.fr, Daniel Bünzli

On Wed, 2007-10-17 at 16:13 +0100, Dario Teixeira wrote:
> > I would use something weaker, and I wouldn't use objects
> > either. To me, this is essentially a dynamic scenario,
> > so the data type should be dynamic. For example:
> >
> > type field_t = [
> > | `Title of string
> > | `Intro of string
> > | `Body of string
> > | `Field of string * string
> > ]
> >
> > type story_t = field_t list
> >
>
> Hi,
>
> Interesting idea, but how would you access the fields in a convenient
> manner?

let rec get_title ls = match ls with
| `Title s :: _ -> s
| _ ::t -> get_title t
| [] -> raise Not_found (* sucks.. *)


--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

skaller

unread,
Oct 17, 2007, 12:58:20 PM10/17/07
to Daniel Bünzli, caml...@yquem.inria.fr

On Wed, 2007-10-17 at 17:32 +0200, Daniel Bünzli wrote:
> Le 17 oct. 07 à 17:13, Dario Teixeira a écrit :
>
> >> type field_t = [
> >> | `Title of string
> >> | `Intro of string
> >> | `Body of string
> >> | `Field of string * string
> >> ]
> >>
> >> type story_t = field_t list
> >>
> > Interesting idea,
>
> If this is right for you then what you want is property lists and
> these two solutions [1,2] may be of interest to you.

Yes, my 'solution' is just a hint. Felix actually uses
something similar to the above structure to record properties
of functions, eg 'pure', 'inline', etc.

This kind of data structure is weakly typed, but that's
part of the idea. Someone probably has an actual representation
of BibTeX data, which is similar in spirit.

Perhaps this weak typing is too weak and can be beefed up,
for example if the title is mandatory, a record PLUS
a property list.

--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

Robert Fischer

unread,
Oct 17, 2007, 12:59:45 PM10/17/07
to skaller, caml...@yquem.inria.fr, Daniel Bünzli
If you go with this approach, why wouldn't you just use a map?

~~ Robert.

> let rec get_title ls = match ls with
> | `Title s :: _ -> s
> | _ ::t -> get_title t
> | [] -> raise Not_found (* sucks.. *)
>
>
>

_______________________________________________

Richard Jones

unread,
Oct 17, 2007, 4:00:12 PM10/17/07
to Dario Teixeira, caml...@yquem.inria.fr
Sounds a bit like this rather lengthy thread:

http://caml.inria.fr/pub/ml-archives/caml-list/2004/12/a0924032de03d517cb8cb8f2adde6c94.en.html

Rich.

--
Richard Jones
Red Hat

Alain Frisch

unread,
Oct 17, 2007, 4:23:15 PM10/17/07
to Dario Teixeira, caml...@yquem.inria.fr, Francisco Jos? Valverde Albacete
Dario Teixeira wrote:
>> To me your problems looks like a good candidate for XML-modelling and
>> reusing all the tools for working in XML. The more so because XML was
>> made... exactly for that! Why don't you give it at least a somewhat
>> serious thought?
>
> Hi,
>
> You mean like CDuce and/or OCamlduce?

I'm not particularly encouraging the use of OCamlduce here, but FWIW, a
solution would look like:

type title = {{ { title=Latin1 ..} }}
type intro = {{ { intro=Latin1 ..} }}
type blurb_t = {{ { id=Int .. } ++ title ++ intro }}
type fresh_t = {{ { body=Latin1 .. } ++ title ++ intro }}
type full_t = {{ blurb_t & fresh_t }} (* intersection type *)

let print_metadata s =
Printf.printf "%d: %s\n" {:s.id:} {:s.title:}

If you're ok duplicating fields, the type definitions can be simplified:

type blurb_t = {{ {id=Int title=Latin1 intro=Latin1 ..} }}
type fresh_t = {{ {body=Latin1 title=Latin1 intro=Latin1 ..} }}
type full_t = {{ {id=Int body=Latin1 title=Latin1 intro=Latin1 ..} }}


-- Alain

Dario Teixeira

unread,
Oct 17, 2007, 4:24:31 PM10/17/07
to caml...@yquem.inria.fr
Hi,

And a big thanks to everyone -- you've really given me a lot of interesting
ideas. For the time being, I am going for the no-inheritance object solution:
it avoids the option type mess, provides a clean interface to users of the
module, and allows code reuse thanks to OCaml's structural subtyping feature
(the "duck" in this thread's title). Moreover, while obviously not as concise
as a record, the declaration of each story variant is still quite economical:

class full (id, title, intro, body) =
object

method id: int = id
method title: string = title
method intro: string = intro
method body: string = body
end

class blurb (id, title, intro) =
object

method id: int = id
method title: string = title
method intro: string = intro
end


Etc, etc. I can live with this.

Cheers,
Dario

___________________________________________________________
Want ideas for reducing your carbon footprint? Visit Yahoo! For Good http://uk.promotions.yahoo.com/forgood/environment.html

_______________________________________________

Stefano Zacchiroli

unread,
Oct 18, 2007, 3:29:05 AM10/18/07
to caml...@yquem.inria.fr
On Wed, Oct 17, 2007 at 12:21:39PM -0400, Chris King wrote:
> See also Jacques' follow up, where he provides a syntax extension for
> these "polymorphic maps" (essentially type-safe property lists):
> http://caml.inria.fr/pub/ml-archives/caml-list/2005/07/314a9eb55585d32e7876ef424f5994ae.fr.html

Do you know if that syntax extension is still working with ocaml/camlp4
3.10?

Thanks for your pointer, Cheers.

--
Stefano Zacchiroli -*- PhD in Computer Science ............... now what?
zack@{cs.unibo.it,debian.org,bononia.it} -%- http://www.bononia.it/zack/
(15:56:48) Zack: e la demo dema ? /\ All one has to do is hit the
(15:57:15) Bac: no, la demo scema \/ right keys at the right time

Stefano Zacchiroli

unread,
Oct 18, 2007, 3:38:13 AM10/18/07
to caml...@yquem.inria.fr
On Wed, Oct 17, 2007 at 09:24:05PM +0100, Dario Teixeira wrote:
> ideas. For the time being, I am going for the no-inheritance object solution:

Uhm sorry, why aren't you going for the object *with* inheritance
solution? The one you're proposing here is more lightweight than the
initial one due to the lack of option types, not due to the lack of
inheritance.

Can't you just go for:

class blurb (id, title, intro) =
object
method id: int = id
method title: string = title
method intro: string = intro
end

class full (id, title, intro, body) =
object
inherit blurb (id, title, intro)


method body: string = body
end

that way you would also gain code reuse and can maybe define printing
functions on top of each other.

Cheers.

--
Stefano Zacchiroli -*- PhD in Computer Science ............... now what?
zack@{cs.unibo.it,debian.org,bononia.it} -%- http://www.bononia.it/zack/
(15:56:48) Zack: e la demo dema ? /\ All one has to do is hit the
(15:57:15) Bac: no, la demo scema \/ right keys at the right time

_______________________________________________

Jacques Garrigue

unread,
Oct 18, 2007, 4:34:17 AM10/18/07
to za...@bononia.it, caml...@yquem.inria.fr
I've just added versions of pa_oo and pa_polymap working with 3.10.
Sorry for the long delay...

http://www.math.nagoya-u.ac.jp/~garrigue/code/ocaml.html

Jacques Garrigue


From: Stefano Zacchiroli <za...@bononia.it>
> On Wed, Oct 17, 2007 at 12:21:39PM -0400, Chris King wrote:
> > See also Jacques' follow up, where he provides a syntax extension for
> > these "polymorphic maps" (essentially type-safe property lists):
> > http://caml.inria.fr/pub/ml-archives/caml-list/2005/07/314a9eb55585d32e7876ef424f5994ae.fr.html
>
> Do you know if that syntax extension is still working with ocaml/camlp4
> 3.10?

_______________________________________________

Dario Teixeira

unread,
Oct 18, 2007, 6:32:02 AM10/18/07
to Stefano Zacchiroli, caml...@yquem.inria.fr
Hi,

> Uhm sorry, why aren't you going for the object *with* inheritance
> solution? The one you're proposing here is more lightweight than the
> initial one due to the lack of option types, not due to the lack of
> inheritance.
>
> Can't you just go for:
>
> class blurb (id, title, intro) =
> object
> method id: int = id
> method title: string = title
> method intro: string = intro
> end
>
> class full (id, title, intro, body) =
> object
> inherit blurb (id, title, intro)
> method body: string = body
> end

While that would indeed involve a little bit of less typing, it's also
conceptually wrong, because a Full story is not a derivation of a Blurb
with an extra field.

Ideally, I should be able to declare a "platonic" Story that includes
all fields that describe a story. A Full story is just the real-world
clone of the platonic ideal, while a Blurb is a Story with the constraint
that there is no "body" field declared (and so on).

Cheers,
Dario

___________________________________________________________
Want ideas for reducing your carbon footprint? Visit Yahoo! For Good http://uk.promotions.yahoo.com/forgood/environment.html

_______________________________________________

Stefano Zacchiroli

unread,
Oct 18, 2007, 6:38:03 AM10/18/07
to caml...@yquem.inria.fr
On Thu, Oct 18, 2007 at 11:31:34AM +0100, Dario Teixeira wrote:
> > class full (id, title, intro, body) =
> > object
> > inherit blurb (id, title, intro)
> > method body: string = body
> > end
>
> While that would indeed involve a little bit of less typing, it's also
> conceptually wrong, because a Full story is not a derivation of a Blurb
> with an extra field.

Well, remember that in ocaml inheritance is not an instance of "is a"
relationship among classes, but rather "method inclusion" (if you really
want a name for this :)). So you can imagine that blurb (or call it
otherwise) is just a set of methods denoting how a blurb-like class
should behave, and here you have back the duck-typing mentioned in the
subject, and than you "inherit" from it both in the actual blurb class
and in the full class.

Just my 0.02€,
Cheers.

--
Stefano Zacchiroli -*- PhD in Computer Science ............... now what?
zack@{cs.unibo.it,debian.org,bononia.it} -%- http://www.bononia.it/zack/
(15:56:48) Zack: e la demo dema ? /\ All one has to do is hit the
(15:57:15) Bac: no, la demo scema \/ right keys at the right time

_______________________________________________

Robert Fischer

unread,
Oct 18, 2007, 9:29:24 AM10/18/07
to Dario Teixeira, caml...@yquem.inria.fr, Stefano Zacchiroli

> Ideally, I should be able to declare a "platonic" Story that includes
> all fields that describe a story. A Full story is just the real-world
> clone of the platonic ideal, while a Blurb is a Story with the constraint
> that there is no "body" field declared (and so on).
>
That seems backwards from the way OO inheritance is supposed to work.
You don't go from a more feature-rich case to a less feature-rich case
-- it's the other way around.

If you s/blurb/header/g or s/blurb/summary/g, then a Full story arguably
is-a blurb with a body tacked on.

~~ Robert.

Dario Teixeira

unread,
Oct 18, 2007, 10:11:17 AM10/18/07
to Robert Fischer, caml...@yquem.inria.fr, Stefano Zacchiroli
Hi,

> That seems backwards from the way OO inheritance is supposed to work.
> You don't go from a more feature-rich case to a less feature-rich case
> -- it's the other way around.

Of course it is -- that is precisely why inheritance is the wrong
formalism for my problem! What I need is a "reverse inheritance"
formalism, where a fully defined data structure sits at the root,
and whose descendants are PRUNED versions of the parent.

If sound (and I let the theoreticians decide on that), such a
formalism would be an interesting solution to the type of problem
that originated this thread.

Cheers,
Dario

___________________________________________________________
Yahoo! Answers - Got a question? Someone out there knows the answer. Try it
now.
http://uk.answers.yahoo.com/

_______________________________________________

Brian Hurt

unread,
Oct 18, 2007, 10:19:19 AM10/18/07
to Dario Teixeira, caml...@yquem.inria.fr
Dario Teixeira wrote:

>Hi,
>
>
>
>>That seems backwards from the way OO inheritance is supposed to work.
>>You don't go from a more feature-rich case to a less feature-rich case
>>-- it's the other way around.
>>
>>
>
>Of course it is -- that is precisely why inheritance is the wrong
>formalism for my problem! What I need is a "reverse inheritance"
>formalism, where a fully defined data structure sits at the root,
>and whose descendants are PRUNED versions of the parent.
>
>

The problem with this is that it violates one of the assumptions of
typing, that if type A is (also) a type B, than anywhere you can use a
type B, you can also use a type A. This isn't an assumption limited to
object oriented languages. And this isn't true in your example- if type
A is lacking members type B has, then it's possible to write situations
where a "real" type B can be used, but not a type A- just use a field of
type B that type A doesn't have.

I think I'd recommend rethinking your approach to the problem.

Brian

Arnaud Spiwack

unread,
Oct 18, 2007, 10:29:49 AM10/18/07
to caml...@yquem.inria.fr
Brian Hurt a écrit :
Well, what he is suggesting is to be able to derive a supertype A given
a type B. This is not fundamentaly incorrect. However I fail to find any
reasoning where it is made use of, in usual mathematics. So I am,
personnally, a bit puzzled by the suggestion, unable to say if it might
make sense or not (method exclusion is natural in the setting of
incomplete objets or traits, but it doesn't fit the situation very much,
since it usually produces something that requires to be completed).


Arnaud Spiwack

Brian Hurt

unread,
Oct 18, 2007, 10:46:31 AM10/18/07
to Arnaud Spiwack, caml...@yquem.inria.fr
Arnaud Spiwack wrote:

Saying that A is a supertype of B is the equivelent of saying B is a
subtype of A. Same relation, different direction. In OO lingo, how
they say "B is a subtype of A" is that "B inherits from (is a subclass
of) A".

In either case, while all B's are A's, not all A's are B's. What he
wants is a case where not all A's are B's, but because of the magic
mindreading feature of the language (in conjunction with the DWIM
feature of the hardware), you can treat all A's as B's, with the system
magically filling in the missing values and methods. This is what the
mind reading is needed for- to know how to fill in the missing values.

I will note that Ocaml's row-level polymorphism allows you to invent new
supertypes of a given subtype as needed (a real nice feature, IMHO).
But what he's asking for is fundamentally nonsensical.

Brian

Robert Fischer

unread,
Oct 18, 2007, 10:59:24 AM10/18/07
to Dario Teixeira, caml...@yquem.inria.fr, Stefano Zacchiroli

Arnaud Spiwack

unread,
Oct 18, 2007, 11:03:01 AM10/18/07