caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Anthony Tavener <anthony.tavener@gmail.com>
To: caml-list@yquem.inria.fr
Subject: Subtyping structurally-equivalent records, or something like it?
Date: Sat, 1 May 2010 23:04:21 +0700	[thread overview]
Message-ID: <t2t42b3ba3b1005010904s755fcedahe938f98cb1c75f89@mail.gmail.com> (raw)

[-- 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 --]

             reply	other threads:[~2010-05-01 16:04 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-01 16:04 Anthony Tavener [this message]
2010-05-01 16:51 ` [Caml-list] " Stéphane Lescuyer
2010-05-02  2:59   ` Anthony Tavener
2010-05-07  9:42     ` AUGER
2010-05-01 19:55 Dario Teixeira
2010-05-01 20:01 ` Sylvain Le Gall
     [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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=t2t42b3ba3b1005010904s755fcedahe938f98cb1c75f89@mail.gmail.com \
    --to=anthony.tavener@gmail.com \
    --cc=caml-list@yquem.inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).