caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] const equivalent for mutable types?
@ 2004-07-31  8:56 Christopher A. Gorski
  2004-07-31  9:24 ` Jean-Marie Gaillourdert
                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Christopher A. Gorski @ 2004-07-31  8:56 UTC (permalink / raw)
  To: caml-list

In my code I find that I'm passing a lot of mutable values to functions. 
  Some functions merely read the values.  Others modify the values.  Is 
there a method in OCaml for reproducing behavior similar in spirit to 
the const declaration in C?

Here is a specific case of the general problem:

let t=ref 0
let change r = incr r
let nochange r = Printf.printf "test:%d\n" !r

The problem is that in complex programs I often get confused over what 
functions are modifying values and what functions are not.  I feel like 
I should be able to do something like

let result = change (const r)

and have the compiler give me a type error.

Is there a way to do this in OCaml?  Should I change my programming 
style?  Am I asking a naive question that's already been answered many 
times over in a different form?

-- 
Chris Gorski - http://cgorski.org

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 26+ messages in thread
* Phantom types
@ 2010-05-17 14:59 Thomas Braibant
  2010-05-17 16:37 ` [Caml-list] " Goswin von Brederlow
  0 siblings, 1 reply; 26+ messages in thread
From: Thomas Braibant @ 2010-05-17 14:59 UTC (permalink / raw)
  To: caml-list

Hi list,

Following on the thread "Subtyping structurally-equivalent records, or
something like it?", I made some experimentations with phantom types.
Unfortunately, I turns out that I do not understand the results I got.

Could someone on the list explain why the first piece of code is well
typed, while the second one is not ?


type p1
type p2

type 'a t = float
let x : p1 t = 0.0
let id : p2 t -> p2 t = fun x -> x
let _ = id x (* type checks with type p2 t*)

type 'a t = {l: float}
let x : p1 t = {l = 0.0}
let id : p2 t -> p2 t = fun x -> x
let _ = id x (* ill typed *)

Any thoughts ?

thomas



2010/5/1 Stéphane Lescuyer <stephane.lescuyer@inria.fr>:
> Hi Anthony,
> I think that maybe using phantom types could do the trick : consider
> defining empty types for all the different "kinds" of similar
> constructs that you have, and then define the kinematic record with a
> phantom parameter type.
>
> type position
> type acceleration
> type force
>
> type 'a kinematic = {lin : Vec.t; ang: Vec.t}
>
> By adding some extra typing annotations, you can then constraint your
> functions to accept (or produce) only a given kind of construct, say
> for example a position kinematic :
>
> let pos_0 : position kinematic = {lin = Vec.origin; ang = Vec.origin }
>
> let double_force (v : force kinematic) : force kinematic = {lin =
> Vec.mult 2. v.lin; ang = v.ang }
>
> double_force pos_0 -> does not type check
>
> You can write generic functions as add, norm, products, etc : they are
> just polymorphic with respect to the phantom type parameter. By the
> way you ensure that you are not multiplying apples and carrots :
> let plus (v : 'a kinematic) (v' : 'a kinematic) : 'a kinematic = ...
>
> Of course, the overhead is that you have to explicitely write some
> type annotations, especially for constructors, but the runtime
> overhead is exactly 0. And also, one limitation is that you can't use
> different projection names for the different cosntructs, since it is
> really always the same record type that you are using.
>
> I hope this helps,
>
> Stéphane L.
>
> On Sat, May 1, 2010 at 6:04 PM, Anthony Tavener
> <anthony.tavener@gmail.com> wrote:
>> 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
>>
>> _______________________________________________
>> 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
>>
>>
>
>
>
> --
> I'm the kind of guy that until it happens, I won't worry about it. -
> R.H. RoY05, MVP06
>
> _______________________________________________
> 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
>


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

end of thread, other threads:[~2010-05-17 16:37 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-31  8:56 [Caml-list] const equivalent for mutable types? Christopher A. Gorski
2004-07-31  9:24 ` Jean-Marie Gaillourdert
2004-07-31 10:24   ` Jean-Marie Gaillourdert
2004-07-31 10:50   ` Markus Mottl
2004-07-31 14:31     ` Brian Hurt
2004-07-31 15:51       ` Markus Mottl
2004-07-31 17:05       ` skaller
2004-07-31 10:34 ` Markus Mottl
2004-07-31 13:44   ` Jon Harrop
2004-07-31 16:31     ` [Caml-list] Phantom types Markus Mottl
2004-08-23  9:49       ` Jon Harrop
2004-08-23 12:25         ` [Caml-list] Why does ocaml use custom buffering? Daan Leijen
2004-08-23 15:16         ` [Caml-list] Phantom types Jon Harrop
2004-08-27  9:03           ` Jacques GARRIGUE
2004-08-25 21:03         ` brogoff
2004-07-31 16:35     ` [Caml-list] const equivalent for mutable types? skaller
2004-07-31 17:23       ` [Caml-list] Functional arrays Jon Harrop
2004-07-31 18:45         ` skaller
2004-08-02  5:07           ` brogoff
2004-08-02  7:45         ` Diego Olivier Fernandez Pons
2004-08-05 16:42           ` Daniel Ortmann
2004-08-05 17:02             ` Diego Olivier Fernandez Pons
2004-08-05 17:16             ` Diego Olivier Fernandez Pons
2004-07-31 17:45   ` [Caml-list] const equivalent for mutable types? Chris Gorski
2004-07-31 14:11 ` Brian Hurt
2010-05-17 14:59 Phantom types Thomas Braibant
2010-05-17 16:37 ` [Caml-list] " Goswin von Brederlow

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