caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Re: [Caml-list] Width subtyping
@ 2009-05-30 15:36 Dario Teixeira
  2009-05-31  5:18 ` Dave Benjamin
  0 siblings, 1 reply; 16+ messages in thread
From: Dario Teixeira @ 2009-05-30 15:36 UTC (permalink / raw)
  To: Till Varoquaux; +Cc: caml-list


Hi,

> There must be something that escapes me.... This seems to be an
> example where ocaml objects really shine because of the structural
> typing (i.e. an object is defined by the its structure):

You are right.  I was probably too fixated on the OOP way of doing this,
translating record fields into object fields and the functions acting on
records into object methods.  Your solution, where record fields become object
methods and external functions act on objects that match a certain structure,
does solve the inconveniences I mentioned before.  But objects are still
a somewhat heavier solution, right?

In the meantime I also investigated Polymap, and it is close to being the
ideal solution.  It has one huge drawback, though: type inconsistencies
cannot be detected at compile-time, producing instead runtime exceptions.
The example below illustrates this; note that function printx should accept
both m1 and m2, but not m3.  However, the mistake in 'foobar' is not reported
until runtime:  (In fairness, there's probably no easy technical fix for this.)

let printx m = Printf.printf "X is %d and Y is %s\n" m.`x m.`y

let m1 = `{x=1; y="foo"}
let m2 = `{x=2; y="bar"; z=true}
let m3 = `{y="ola"; z=false}

let foobar =
        printx m1;
        printx m2;
        printx m3

Cheers,
Dario






^ permalink raw reply	[flat|nested] 16+ messages in thread
* Re: [Caml-list] Width subtyping
@ 2009-06-01 13:56 Dario Teixeira
  2009-06-01 14:21 ` David Allsopp
  0 siblings, 1 reply; 16+ messages in thread
From: Dario Teixeira @ 2009-06-01 13:56 UTC (permalink / raw)
  To: yminsky; +Cc: caml-list


Hi,

> If you're willing to give up some of the syntactic
> niceties of records (and the ability to pattern-match) you
> can get what you want using an abstract type.

Thanks -- that is also an interesting solution.  I'm guessing it will
be faster, though it might consume more memory in cases where only one
field is actually used.  I'll have to try it side-by-side with the object
based solution to see how they compare in the real world with my actual
problem...


> Here, we've chosen to use a default value for fields
> that we don't fill in.  We could just as well have used
> options here.  The performance of the above will be roughly
> the same as the performance of a simple record.  Obviously,
> all of the different "subtypes" have the full
> record stored at a physical level.

Which might turn out to be not that big a deal.  After all, the object
based solution also adds some default overhead per object created, right?

Cheers,
Dario Teixeira






^ permalink raw reply	[flat|nested] 16+ messages in thread
* RE: [Caml-list] Width subtyping
@ 2009-05-31 23:08 Dario Teixeira
  2009-06-01 11:34 ` Yaron Minsky
  0 siblings, 1 reply; 16+ messages in thread
From: Dario Teixeira @ 2009-05-31 23:08 UTC (permalink / raw)
  To: David Allsopp; +Cc: caml-list


Hi,

> > Heavier in terms of efficiency, or syntax?
>
> My concern is the former. The extra two fields per "record" and the heavier
> runtime calls make them so systemically slower that (to me, at least) it
> just feels "wrong" to use objects just to achieve a little syntactic clarity
> and a small reduction in the amount of code written. Polymorphic variants
> (which use only slightly more memory than regular variant values) otherwise
> perform at the same speed as their normal counterparts.

I also meant "heavier" in terms of efficiency.  And like David said, it does
feel wrong to carry the performance penalty of the object system solely because
I need the structural subtyping features.  Ideally, what I should be using
is "record subtyping": something along the lines of the Polymap extension
(which I advise everyone to take a look at), but with compile-time checking.

However, my guess is that proper record subtyping cannot be tacked onto the
language by means of Camlp4, and it probably needs to be a builtin feature
(though I would gladly be proven wrong).  Which leads to the obvious question:
is there any theoretical reason why record subtyping is not available in Ocaml?
Or is the answer simply "just use the object system; it's not as heavy as you
think it is"?...

Cheers,
Dario Teixeira






^ permalink raw reply	[flat|nested] 16+ messages in thread
* Re: [Caml-list] Width subtyping
@ 2009-05-29 15:50 Dario Teixeira
  0 siblings, 0 replies; 16+ messages in thread
From: Dario Teixeira @ 2009-05-29 15:50 UTC (permalink / raw)
  To: Richard Jones; +Cc: caml-list


Hi,

> I've very tired at the moment, but I think that Garrigue's
> polymap syntax extension does what you want:
> 
> http://www.math.nagoya-u.ac.jp/~garrigue/code/ocaml.html
> 
> If not, just ignore me!

I should have suspected this discussion would eventually lead
to something out of Jacques Garrigue's magic hat! :-)

But on a first glance, yes, it does look like it might be of interest.
I'll explore it further, thanks!

Cheers,
Dario






^ permalink raw reply	[flat|nested] 16+ messages in thread
* Re: [Caml-list] Width subtyping
@ 2009-05-29 15:45 Dario Teixeira
  2009-05-29 16:06 ` Till Varoquaux
  0 siblings, 1 reply; 16+ messages in thread
From: Dario Teixeira @ 2009-05-29 15:45 UTC (permalink / raw)
  To: Jacques Carette; +Cc: caml-list


Hi,

> The dual of sums is products.  Open (labelled) sums
> are "polymorphic variants".  Their duals are open
> (labelled) products are "rows" (which O'Caml already
> supports, through its objects).

Yes, as I mentioned, for some classes of this particular problem the object
system can be put to good use -- when there is a clear tree for inheritance,
for example.  Unfortunately that is always not the case; there are problems
where you would end up with a tangled web of multiple inheritances just for
the sake of avoiding duplicating methods.

Cheers,
Dario






^ permalink raw reply	[flat|nested] 16+ messages in thread
* RE: [Caml-list] Width subtyping
@ 2009-05-29 15:38 Dario Teixeira
  0 siblings, 0 replies; 16+ messages in thread
From: Dario Teixeira @ 2009-05-29 15:38 UTC (permalink / raw)
  To: David Allsopp; +Cc: 'OCaml List'


Hi,

> This way you're always dealing with the same product type,
> but the sum type tells you which fields are actually valid.
> Of course, it relies on there being an obvious sentinel
> value for unused fields (otherwise you just end up with 'a
> option everywhere) and I still don't think it's that neat as
> you can still match against fields which aren't valid but at
> least the type system prevents you from being handed an
> illegal value. The benefit is that you don't need special
> "get" functions (just a match on type t to extract the t'
> value from each constructor). I can't get my head around how
> private polymorphic variants work to see if they can refine
> this further...

This is indeed a reasonable solution for many classes of problems.
However, the need for a sentinel value for unused fields makes it
somewhat heavyweight for those record variants where just one field
is valid.  Moreover, this solution requires outside functions that
should only operate on T1 (for example) to "voluntarily" check by
pattern matching that the t they are getting is indeed a T1 (and
presumably raise failure otherwise).  The object-based solution can
at least automatically take care of this (though it has other problems).

Cheers,
Dario






^ permalink raw reply	[flat|nested] 16+ messages in thread
* Width subtyping
@ 2009-05-29 14:10 Dario Teixeira
  2009-05-29 14:21 ` [Caml-list] " Jacques Carette
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Dario Teixeira @ 2009-05-29 14:10 UTC (permalink / raw)
  To: caml-list


Hi,

Though it is probably been-there-done-that material for the veterans in this list,
for the sake of the not-so-veterans I have to ask: how do you guys typically model
width subtyping in Ocaml?   Consider for example three record types that share some
of their fields:

type t1 = {a: int; b: int; c: int;        }
type t2 = {a: int; b: int; c: int; d: int;}
type t3 = {        b: int; c: int; d: int;}

In some circumstances, the object system can be put to good use for this kind of problem.
Not always though, so I'm curious about other approaches people use.  One approach
I've considered is to create a superset record where each field is an optional type,
and then creating constructors/getters for each valid subset.  Unfortunately this
solution feels a bit kludgy, even if it reduces code duplication.  For safety reasons
I'm therefore currently just declaring each record type independently (concerns about
duplication be damned).

In other words, polymorphic variants provide a very elegant solution for subtyping
with sum types.  Is there some brilliant idea that could do the same for product types?

Best regards,
Dario Teixeira







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

end of thread, other threads:[~2009-06-01 17:04 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-30 15:36 [Caml-list] Width subtyping Dario Teixeira
2009-05-31  5:18 ` Dave Benjamin
2009-05-31  7:34   ` David Allsopp
2009-06-01  4:21   ` Jacques Garrigue
  -- strict thread matches above, loose matches on Subject: below --
2009-06-01 13:56 Dario Teixeira
2009-06-01 14:21 ` David Allsopp
2009-06-01 17:04   ` Peng Zang
2009-05-31 23:08 Dario Teixeira
2009-06-01 11:34 ` Yaron Minsky
2009-05-29 15:50 Dario Teixeira
2009-05-29 15:45 Dario Teixeira
2009-05-29 16:06 ` Till Varoquaux
2009-05-29 15:38 Dario Teixeira
2009-05-29 14:10 Dario Teixeira
2009-05-29 14:21 ` [Caml-list] " Jacques Carette
2009-05-29 14:43 ` David Allsopp
2009-05-29 15:33 ` Richard Jones

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