caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] extensible records?
@ 2004-02-27  0:45 Michael Vanier
  2004-02-27  1:04 ` Kenneth Knowles
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Michael Vanier @ 2004-02-27  0:45 UTC (permalink / raw)
  To: caml-list


Hi everyone!

I'm having a problem figuring out how to implement something in ocaml, and
I'd like to solicit advice.  I'm writing a little dynamically-typed language
in ocaml, and I want to be able to add new types to the language without
having to add new primitive types to the system.  So, for instance, my basic
type definition looks something like this:

    type data =
        Int of int
      | Float of float
      | ...

Now let's say I want to add a type for files.  I don't want this to be a type
at the same level as ints or floats, because I want users to be able to add
their own types to the language without hacking the core type definition
(which is possible in, for instance, python).  So my ideal solution would be
something like this (not real ocaml code):

    (* types.mli *)
    type data =
        Int of int
      | Float of float
      | ...
      | Extension of extension

    type extension = []  (* nothing yet, not valid ocaml *)

    (* files.mli *)
    extension File of out_channel  (* not valid ocaml *)

    (* files.ml *)
    let close (d : data) =
      match data with
        Extension ext ->
          (match ext with
               File f -> (* close the file *)
             | _ -> raise (Failure "invalid type"))
        | _ -> raise (Failure "invalid type")

I can see two ways I can do this already, but both involve abusing the
exception system.  Way 1:

    (* types.mli *)
    type data =
        Int of int
      | Float of float
      | ...
      | Extension of unit -> unit


    (* files.ml *)
    exception File of out_channel

    let open_file filename =
      (* open the file as new_file *)
      raise (File new_file)

    let close (d : data) =
      match data with
        Extension ext ->
          try ext ()
          with ext' ->
            (match ext' with 
                File f -> (* close the file *)
              | _ -> raise (Failure "invalid type"))
        | _ -> raise (Failure "invalid type")

Aside from abusing the exception system, I've been told that this would be
slow due to the exception handling overhead.  A more direct way would be:

    (* types.mli *)
    type data =
        Int of int
      | Float of float
      | ...
      | Extension of exn


    (* files.ml *)
    exception File of out_channel

    let close (d : data) =
      match data with
        Extension ext ->
          (match ext with 
              File f -> (* close the file *)
            | _ -> raise (Failure "invalid type")))
        | _ -> raise (Failure "invalid type")

This would (I think) work, and wouldn't involve excessive overhead.  But
really, all I'm doing is abusing the fact that exceptions are the one kind of
extensible record type built in to ocaml.  What I want to know is: is there a
better way to do this?

I thought of using polymorphic variant types, but my (limited) understanding
is that you either declare all possible variants straight up in the .mli file
(which totally defeats my purpose) or you don't declare anything and let the
compiler infer the type (which I don't know how to write into a .mli file).
If this can be done with polymorphic variants, how would I do it?
Alternatively, if this can be done with objects, how would I do it?  Or
should I just stick with abusing exceptions?

Cheers,

Mike

-------------------
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] 5+ messages in thread

* Re: [Caml-list] extensible records?
  2004-02-27  0:45 [Caml-list] extensible records? Michael Vanier
@ 2004-02-27  1:04 ` Kenneth Knowles
  2004-02-27  8:39 ` Aleksey Nogin
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Kenneth Knowles @ 2004-02-27  1:04 UTC (permalink / raw)
  To: Michael Vanier; +Cc: caml-list

Hi Mike,

What I did, which may or not be powerful enough for you, was to use classes.
I'm actually hoping that this thread comes up with something better for me to
use:


class type opaque_type =
object(s)
	... various methods required of all data items ...
end

type datavalue =
	| Int of int
	| Float of float
	| Opaque of opaque_type


So it is fairly easy to add a new type, or some kind of weird opaque reference.
I haven't really used it much, so I don't know of its limitations.

Kenn

-------------------
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] 5+ messages in thread

* Re: [Caml-list] extensible records?
  2004-02-27  0:45 [Caml-list] extensible records? Michael Vanier
  2004-02-27  1:04 ` Kenneth Knowles
@ 2004-02-27  8:39 ` Aleksey Nogin
  2004-02-27  8:39 ` Nicolas Cannasse
  2004-02-27 11:17 ` Alexander S. Usov
  3 siblings, 0 replies; 5+ messages in thread
From: Aleksey Nogin @ 2004-02-27  8:39 UTC (permalink / raw)
  To: Caml List

On 26.02.2004 16:45, Michael Vanier wrote:

> I thought of using polymorphic variant types, but my (limited) understanding
> is that you either declare all possible variants straight up in the .mli file
> (which totally defeats my purpose) or you don't declare anything and let the
> compiler infer the type (which I don't know how to write into a .mli file).

I have to admit that I have never used polymorphic variant types myself, 
but the way I understand them, they should probably work for you. If I 
understand it correctly ou do not have to declare them _exactly_ in the 
.mli file - e.g. you could use [> ] in the .mli file and something more 
specific in the .ml file.

Consider

% ocaml

         Objective Caml version 3.06

# type 'a data = Int of int | Ext of 'a;;
type 'a data = Int of int | Ext of 'a
# let open_file f =
      match f with
         Ext `File f -> print_string ("Opening file" ^ f)
       | _ -> raise (Invalid_argument "open_file")
   ;;
val open_file : [> `File of string] data -> unit = <fun>
# let run ( f :  [> ] data -> unit) = f (Ext (`Foo 1));;
val run : ([> `Foo of int] data -> unit) -> unit = <fun>
# run open_file;;
Exception: Invalid_argument "open_file".

Note that open_file does have the type
   [> ] data -> unit
(in addition to having the inferred type
   [> `File of string] data -> unit
) - passing it to run is not a type error.

So with something like the data type definition above you can use  [> ] 
data as an input type in your .mli and use a more specific type as an 
output type in your .mli

P.S. In your examples you use nested "match" statements instead nested 
patterns. It's ugly to read (IMHO) and less efficient (AFAIK).

-- 
Aleksey Nogin

Home Page: http://nogin.org/
E-Mail: nogin@cs.caltech.edu (office), aleksey@nogin.org (personal)
Office: Jorgensen 70, tel: (626) 395-2907

-------------------
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] 5+ messages in thread

* Re: [Caml-list] extensible records?
  2004-02-27  0:45 [Caml-list] extensible records? Michael Vanier
  2004-02-27  1:04 ` Kenneth Knowles
  2004-02-27  8:39 ` Aleksey Nogin
@ 2004-02-27  8:39 ` Nicolas Cannasse
  2004-02-27 11:17 ` Alexander S. Usov
  3 siblings, 0 replies; 5+ messages in thread
From: Nicolas Cannasse @ 2004-02-27  8:39 UTC (permalink / raw)
  To: Michael Vanier, caml-list

[...]
> I thought of using polymorphic variant types, but my (limited)
understanding
> is that you either declare all possible variants straight up in the .mli
file
> (which totally defeats my purpose) or you don't declare anything and let
the
> compiler infer the type (which I don't know how to write into a .mli
file).
> If this can be done with polymorphic variants, how would I do it?
> Alternatively, if this can be done with objects, how would I do it?  Or
> should I just stick with abusing exceptions?

There is a nice paper from Jacques Garrigue about extensions using
polymorphic variants.
"Code reuse through polymorphic variants. "
http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/papers/
That might be what you're loooking for.

Regards,
Nicolas Cannasse

-------------------
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] 5+ messages in thread

* Re: [Caml-list] extensible records?
  2004-02-27  0:45 [Caml-list] extensible records? Michael Vanier
                   ` (2 preceding siblings ...)
  2004-02-27  8:39 ` Nicolas Cannasse
@ 2004-02-27 11:17 ` Alexander S. Usov
  3 siblings, 0 replies; 5+ messages in thread
From: Alexander S. Usov @ 2004-02-27 11:17 UTC (permalink / raw)
  To: Michael Vanier; +Cc: caml-list

On Friday 27 February 2004 01:45, you wrote:
> Hi everyone!
>
> I'm having a problem figuring out how to implement something in ocaml, and
> I'd like to solicit advice.  I'm writing a little dynamically-typed
> language in ocaml, and I want to be able to add new types to the language
> without having to add new primitive types to the system.  So, for instance,
> my basic type definition looks something like this:
>
>     type data =
>         Int of int
>
>       | Float of float
>       | ...
>
> Mike

I am not hundred percent sure, but you can use parametrized definition.
Like this:

type 'a data =
	Int of int
	| Float of float
	| .....
	| Extension of 'a ;;

-- 
Best regards,
  Alexander.

-------------------
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] 5+ messages in thread

end of thread, other threads:[~2004-02-27 11:17 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-02-27  0:45 [Caml-list] extensible records? Michael Vanier
2004-02-27  1:04 ` Kenneth Knowles
2004-02-27  8:39 ` Aleksey Nogin
2004-02-27  8:39 ` Nicolas Cannasse
2004-02-27 11:17 ` Alexander S. Usov

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