caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
@ 2007-06-20  0:14 Jeremy Yallop
  2007-06-20  8:01 ` [Caml-list] " Nicolas Pouillard
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Jeremy Yallop @ 2007-06-20  0:14 UTC (permalink / raw)
  To: caml-list

I'm pleased to announce an initial release of `deriving', a system for
constructing functions automatically from type definitions.

Deriving extends OCaml with two new operations: a syntax for calling
an "overloaded" function at a particular type:

    C.function<t> v

and the `deriving' construct found in Haskell (and Clean) for
requesting that the implementation generate an instance of an
overloaded function from a type definition:

    type t = r
      deriving (C1, C2)

Deriving provides functions for pretty-printing, dynamic typing,
type-safe structure-sharing marshalling, SML-style equality,
mapping, and more.  Functions can be generated for most OCaml types,
including records, standard and polymorphic variants, tuples, mutually
recursive types, and types that use abstract type constructors defined
elsewhere.  A few more exotic constructs, such as private types and type
replication, are supported.  Derived functions are also extensible: the
user can choose to supply an implementation at a particular type if the
generated version is not to his taste.

You can find deriving (along with preliminary documentation and tests)
at

    http://code.google.com/p/deriving/

Note: you'll need OCaml 3.10.

Some examples of use follow.

Pretty-printing:

    Show.show<int> 3
    =>
    "3"

    let factors = [(10,[2;5]); (11, []);  12, [2;3;4;6]]
    Show.show<(int * int list) list> factors
    =>
    "[(10,[2; 5]); (11, []);  12, [2; 3; 4; 6]]"


    type 'a tree = Leaf of 'a | Branch of 'a tree * 'a * 'a tree
        deriving (Show, Typeable, Eq, Shelve)

    type point = { x : float; y : float }
        deriving (Show, Typeable, Eq, Shelve)

    let points = Branch (Leaf {x=0.0;
                               y=0.0;},
                         {x=2.0; y=2.0},
                         Branch (Leaf {x=1.0; y=1.0},
                                 {x=1.0; y=0.0},
                                 Leaf {x=0.0; y=1.0}))

    Show.show<point tree> points
    =>
    "Branch
       (Leaf {x =193.11; y =132.13}, {x =211.91; y =201.11},
        Branch
          (Leaf {x =113.12; y =1.}, {x =12.7; y =44.1}, Leaf {x =0.; y 
=13.41}))"

Dynamic typing:

    let items =
       [Typeable.mk<int> 3;
        Typeable.mk<float> 3.0;
        Typeable.mk<string tree> (Leaf "three")]
    =>
    [<abstr>; <abstr>; <abstr>]

    Typeable.cast<int> (List.hd items)
    =>
    Some 3

    Typeable.cast<float> (List.hd items)
    =>
    None


Dynamic typing again:

    type 'a seq = [`Nil | `Cons of 'a * 'a seq]
        deriving (Typeable)

    let l = `Cons (3, `Cons (2, `Cons (1, `Nil)))

    Typeable.cast<[`Cons of int * 'a|`Nil] as 'a>
      (Typeable.mk<int seq> l)
    =>
    Some (`Cons (3, `Cons (2, `Cons (1, `Nil))))

Serialisation (marshalling):

    Shelve.shelveS<point tree> points
    =>
 
"\007\003\t\128\128\128\128\128\128\128\248?\t\128\128\128\128\128\128\128\128@\001\000\005\000\001\008\000\001\n\001\003\004\t\003\000\001\012\001\003\006\011\005\005\002\002\000\002\000\002\002\000\000\002\001\001\002\002\002"

    Shelve.unshelveS<point tree> (Shelve.shelveS<point tree> points)
    =>
    Branch
      (Leaf {x =193.11; y =132.13}, {x =211.91; y =201.11},
       Branch
         (Leaf {x =113.12; y =1.}, {x =12.7; y =44.1}, Leaf {x =0.;
                                                             y =13.41}))


    Shelve.unshelveS<int> (Shelve.shelveS<point tree> points)
    =>
    *** Exception

For more see the documentation and test suite.

Comments, bug reports, and other feedback will be most welcome.

Jeremy.


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

* Re: [Caml-list] ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
  2007-06-20  0:14 ANN: pretty-printing, type-safe marshalling, dynamic typing for free Jeremy Yallop
@ 2007-06-20  8:01 ` Nicolas Pouillard
       [not found] ` <AB56B84F-A45E-433B-B419-2B49F5D92043@gmail.com>
  2007-07-15  4:03 ` [Caml-list] " Jon Harrop
  2 siblings, 0 replies; 12+ messages in thread
From: Nicolas Pouillard @ 2007-06-20  8:01 UTC (permalink / raw)
  To: Jeremy Yallop; +Cc: caml-list

On 6/20/07, Jeremy Yallop <jeremy.yallop@ed.ac.uk> wrote:
> I'm pleased to announce an initial release of `deriving', a system for
> constructing functions automatically from type definitions.
>

Great, that's really amazing!

No doubt, there is a new camlp4 hacker in the community :)

Cheers,

-- 
Nicolas Pouillard


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

* Re: [Caml-list] ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
       [not found] ` <AB56B84F-A45E-433B-B419-2B49F5D92043@gmail.com>
@ 2007-06-20 10:27   ` Jeremy Yallop
  2007-06-20 18:28     ` Stefan Monnier
  0 siblings, 1 reply; 12+ messages in thread
From: Jeremy Yallop @ 2007-06-20 10:27 UTC (permalink / raw)
  To: Joel Reymont; +Cc: Caml List

Joel Reymont wrote:
> 
> On Jun 20, 2007, at 1:14 AM, Jeremy Yallop wrote:
> 
>> Serialisation (marshalling):
>>
>>    Shelve.shelveS<point tree> points
>>    =>
>> "\007\003\t\128\128\128\128\128\128\128\248?\t\128\128\128\128\128\128\128\128@\001\000\005\000\001\008\000\001\n\001\003\004\t\003\000\001\012\001\003\006\011\005\005\002\002\000\002\000\002\002\000\000\002\001\001\002\002\002" 
>>
> 
> Aha! Now I can implement a Sexp library for 3.10!
> 
> What is the difference between pickling and shelving, though?

In `deriving' Pickle is a fairly naive value-oriented serialiser.  It 
doesn't do any structure sharing: the same value can be repeated several 
times in the output.  It doesn't preserve cycles, so it's not available 
for mutable values.  You can customize Pickle by writing your own 
definition for a particular type.

Shelve handles cycles correctly and minimises values so the output is 
potentially much smaller.  It also provides a different means of 
specialization: by giving a custom definition of equality for a type you 
can increase opportunities for sharing.  It's currently rather slow for 
large values, but I expect that to change in the next release.  Shelve 
is built on top of Pickle, FWIW.

The choice of names is pretty arbitrary: I wrote Pickle first, then I 
needed another name when I wrote Shelve.

Jeremy.


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

* Re: ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
  2007-06-20 10:27   ` Jeremy Yallop
@ 2007-06-20 18:28     ` Stefan Monnier
  2007-06-20 19:38       ` [Caml-list] " Jeremy Yallop
  0 siblings, 1 reply; 12+ messages in thread
From: Stefan Monnier @ 2007-06-20 18:28 UTC (permalink / raw)
  To: caml-list

> In `deriving' Pickle is a fairly naive value-oriented serialiser.

That's an unfortunate choice.  Traditionally, "pickling" was always used for
the structure&cycle preserving form of serialization.  Sometimes "marshalling"
was used to describe the naive no-sharing kind of serialization.

Nowadays, it seems that "pickling" is not used very often and "marshalling"
tends to take care of sharing and cycles as well, tho.

Still, in my mind "pickling" implies "the non-naive kind of serialization".


        Stefan


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

* Re: [Caml-list] Re: ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
  2007-06-20 18:28     ` Stefan Monnier
@ 2007-06-20 19:38       ` Jeremy Yallop
  2007-06-20 21:06         ` Eric Cooper
  0 siblings, 1 reply; 12+ messages in thread
From: Jeremy Yallop @ 2007-06-20 19:38 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: caml-list

Stefan Monnier wrote:
>> In `deriving' Pickle is a fairly naive value-oriented serialiser.
> 
> That's an unfortunate choice.  Traditionally, "pickling" was always used for
> the structure&cycle preserving form of serialization.  Sometimes "marshalling"
> was used to describe the naive no-sharing kind of serialization.
> 
> Nowadays, it seems that "pickling" is not used very often and "marshalling"
> tends to take care of sharing and cycles as well, tho.
> 
> Still, in my mind "pickling" implies "the non-naive kind of serialization".

Interesting.  Of course, the name "Marshal" is already taken by the 
OCaml standard library.  Do you have any other suggestions for a name 
for naive serialisation?  "Serialise"/"Serialize", perhaps?


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

* Re: [Caml-list] Re: ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
  2007-06-20 19:38       ` [Caml-list] " Jeremy Yallop
@ 2007-06-20 21:06         ` Eric Cooper
  2007-06-21  7:37           ` Nicolas Pouillard
  0 siblings, 1 reply; 12+ messages in thread
From: Eric Cooper @ 2007-06-20 21:06 UTC (permalink / raw)
  To: caml-list

On Wed, Jun 20, 2007 at 08:38:20PM +0100, Jeremy Yallop wrote:
> Do you have any other suggestions for a name for naive
> serialisation?  "Serialise"/"Serialize", perhaps?

Dump?

-- 
Eric Cooper             e c c @ c m u . e d u


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

* Re: [Caml-list] Re: ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
  2007-06-20 21:06         ` Eric Cooper
@ 2007-06-21  7:37           ` Nicolas Pouillard
  2007-06-22  0:05             ` Jeremy Yallop
  0 siblings, 1 reply; 12+ messages in thread
From: Nicolas Pouillard @ 2007-06-21  7:37 UTC (permalink / raw)
  To: caml-list

On 6/20/07, Eric Cooper <ecc@cmu.edu> wrote:
> On Wed, Jun 20, 2007 at 08:38:20PM +0100, Jeremy Yallop wrote:
> > Do you have any other suggestions for a name for naive
> > serialisation?  "Serialise"/"Serialize", perhaps?
>
> Dump?
>

+1

Pickle -> Dump
Shelve -> Pickle

Would be better...

My 0.02€

-- 
Nicolas Pouillard

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

* Re: [Caml-list] Re: ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
  2007-06-21  7:37           ` Nicolas Pouillard
@ 2007-06-22  0:05             ` Jeremy Yallop
  0 siblings, 0 replies; 12+ messages in thread
From: Jeremy Yallop @ 2007-06-22  0:05 UTC (permalink / raw)
  To: caml-list; +Cc: Nicolas Pouillard

Nicolas Pouillard wrote:
> On 6/20/07, Eric Cooper <ecc@cmu.edu> wrote:
>> On Wed, Jun 20, 2007 at 08:38:20PM +0100, Jeremy Yallop wrote:
>> > Do you have any other suggestions for a name for naive
>> > serialisation?  "Serialise"/"Serialize", perhaps?
>>
>> Dump?
> 
> +1
> 
> Pickle -> Dump
> Shelve -> Pickle

Thanks for the suggestions, everyone.  I've uploaded a new version of 
deriving with the name changes you suggested.  There are a few other 
changes: the interfaces of Dump and Pickle are now compatible, deriving 
should now work on 64-bit platforms, and there's a fix for a quotation 
that was causing compilation problems.

I've only had one report of unsuccessful compilation.  I'd be very 
interested to hear if anyone else had problems building deriving or 
running the tests.  Reports of success are welcome too, of course.

Jeremy.


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

* Re: [Caml-list] ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
  2007-06-20  0:14 ANN: pretty-printing, type-safe marshalling, dynamic typing for free Jeremy Yallop
  2007-06-20  8:01 ` [Caml-list] " Nicolas Pouillard
       [not found] ` <AB56B84F-A45E-433B-B419-2B49F5D92043@gmail.com>
@ 2007-07-15  4:03 ` Jon Harrop
  2007-07-17  3:05   ` Jon Harrop
  2 siblings, 1 reply; 12+ messages in thread
From: Jon Harrop @ 2007-07-15  4:03 UTC (permalink / raw)
  To: caml-list

On Wednesday 20 June 2007 01:14:42 Jeremy Yallop wrote:
> I'm pleased to announce an initial release of `deriving', a system for
> constructing functions automatically from type definitions.
>
> Deriving extends OCaml with two new operations: a syntax for calling
> an "overloaded" function at a particular type:
>
>     C.function<t> v
>
> and the `deriving' construct found in Haskell (and Clean) for
> requesting that the implementation generate an instance of an
> overloaded function from a type definition:
>
>     type t = r
>       deriving (C1, C2)
>
> Deriving provides functions for pretty-printing, dynamic typing,
> type-safe structure-sharing marshalling, SML-style equality,
> mapping, and more.

I don't know how I managed to miss this awesome announcement!

The idea of retrofitting equality types onto OCaml interests me greatly. Any 
chance you could elaborate on how this is done and what errors look like? :-)

Many thanks,
-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
The OCaml Journal
http://www.ffconsultancy.com/products/ocaml_journal/?e


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

* Re: [Caml-list] ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
  2007-07-15  4:03 ` [Caml-list] " Jon Harrop
@ 2007-07-17  3:05   ` Jon Harrop
  2007-07-19  0:20     ` Jeremy Yallop
  0 siblings, 1 reply; 12+ messages in thread
From: Jon Harrop @ 2007-07-17  3:05 UTC (permalink / raw)
  To: caml-list

On Sunday 15 July 2007 05:03:16 Jon Harrop wrote:
> The idea of retrofitting equality types onto OCaml interests me greatly.
> Any chance you could elaborate on how this is done and what errors look
> like? :-)

Incidentally, another rather cool application of this kind of functionality 
would be to mimic .NET's PropertyGrid class. This class uses reflection to 
convert a data structure into a Windows Forms control that allows you to edit 
that data structure.

This is quite profilic in the developer-facing GUIs from Microsoft, such as 
the properties subwindow that you get in Visual Studio's GUI designer. 
Essentially it provides a very easy way to lash up totally unergonomic GUIs. 
An idea that is very close to my heart. ;-)

You could take an OCaml data type and translate it into GTK widgets that let 
you edit its contents.

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
OCaml for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists/?e


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

* Re: [Caml-list] ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
  2007-07-17  3:05   ` Jon Harrop
@ 2007-07-19  0:20     ` Jeremy Yallop
  2007-07-20  6:24       ` Jon Harrop
  0 siblings, 1 reply; 12+ messages in thread
From: Jeremy Yallop @ 2007-07-19  0:20 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list

Jon,

Apologies for the delay in replying!

Jon Harrop wrote:
 > On Wednesday 20 June 2007 01:14:42 Jeremy Yallop wrote:
 > > Deriving provides functions for pretty-printing, dynamic typing,
 > > type-safe structure-sharing marshalling, SML-style equality,
 > > mapping, and more.
 >
 > I don't know how I managed to miss this awesome announcement!
 >
 > The idea of retrofitting equality types onto OCaml interests me
 > greatly. Any chance you could elaborate on how this is done and what
 > errors look like?  :-)

Sure!  I suppose "SML-style equality" can be understood to include
various things:

   (1) an equality predicate that tests for physical equality at mutable
       types and structural equality at immutable types.

         SOME 3 = SOME 3
         => true

         SOME (ref 3) = SOME (ref 3)
         => false

   (2) a compile-time error if you try to use equality at a type for
       which it's not defined (an abstract or functional type)

         - op o = op o;;
         stdIn:4.1-4.12 Error: operator and operand don't agree
         [equality type required]

   (3) a means to write functions that are polymorphic over equality
       types:

         - fn x => x = x;;
         val it = fn : ''a -> bool

With `deriving' you get (1) and (2).  You can simulate (3) using
functors if you squint a bit.  In all cases you have to be explicit
about types, i.e. you have to write

    Eq.eq<int ref option> (Some (ref 3)) (Some (ref 3))

rather than (say)

    Eq.eq (Some (ref 3)) (Some (ref 3))

Specifying types is perhaps a bit of a nuisance, but to make up for it
you get a bit more flexibility: equality can be customized at
particular types.  For example, if you define an abstract type of
integer sets represented as unordered lists then you can give an
appropriate definition of equality rather than just inheriting the
definition for lists:

    module IntSet : sig
      type t
        deriving (Eq)

      val empty : t
      val add : int -> t -> t
      ...
    end =
    struct
      type t = int list
      module Eq =
      struct
        type a = t
        val eq l r = (List.sort compare l) = (List.sort compare r)
      end

      let empty = []
      let add item set = item :: set
      ...
    end

and your definition will be used whenever sets are compared

    module I = IntSet

    Eq.eq<I.t list> [I.add 1 (I.add 2 I.empty)]
                    [I.add 2 (I.add 1 I.empty)]
    => true

If you just want the "standard" definition of equality for your types
you can add `deriving (Eq)' to the definition and you'll be able to
use Eq.eq at that type.

    type colour = Red | Green | Blue
        deriving (Eq)

    Eq.eq<colour> Red Blue
    => false

    type a = A of int list | B of a
        deriving (Eq)

    Eq.eq<a> = B (A [1;2;3]) = B (A [1;2;3])
    => true

As the IntSet example suggests, `deriving' works by generating a
module definition for each derived function at each type.  For
example, for the `colour' type, you'll get a definition that looks
something like this:

    module Eq : Eq.Eq with type a = colour
    struct
      type a = colour
      let eq l r = match l, r with
        | Red, Red
        | Green, Green
        | Blue, Blue -> true
        | _ -> false
    end

which conforms to the signature for `Eq':

   module type Eq =
   sig
     type a
     val eq : a -> a -> bool
   end

More complicated types give rise to more complicated definitions: for
instance, a parameterized type will generate a functor whose argument
is a module that implements Eq for the type parameter.  Constructing
instances of `Eq' at instantiated types is then just a matter of
functor application: the definition at `int option ref' is obtained by
the fragment

   Eq_ref(Eq_option(Eq_ref))

There are strong parallels with Haskell's type classes in all this:
module signatures fulfill the role of classes, modules of instances,
and so on.  (The correspondence between modules and classes is
explored in various places in "the literature", e.g. Dreyer, Harper,
and Chakravarty's POPL 2007 paper, "Modular Type Classes").

Your question about error messages is a good one.  Syntactic
abstractions tend to be particularly leaky, so it shouldn't come as
too much of a surprise if the implementation is exposed occasionally
when you write the wrong thing.  Nonetheless, I think error messages
are generally fairly good.  If you misspell a type name then you get a
reasonable message

    Eq.eq<color> Red Blue
    =>
    File "color.ml", line 6, characters 2-14:
    Unbound type constructor color

An attempt to derive a class at a type that's not supported by
`deriving' results in a quite specific message.  For example,

    type 'a t = A | B of ('a * 'a) t
      deriving (Eq)
    =>
    File "nonreg.ml", line 3, characters 0-48 (end at line 4,
                                               character 15):
    The following types contain non-regular recursion:
       t
    deriving does not support non-regular types

or

    type t = int -> int deriving (Eq)

    File "fun.ml", line 2, characters 0-33:
    Eq cannot be derived for function types

Using an overloaded function at a type that doesn't match the annotation
results in just the error you'd expect:

    Eq.eq<int list> 0 1

    File "intlist.ml", line 4, characters 24-25:
    This expression has type int but is here used with type int list

If you forget to add `deriving Eq' to your type definition then the
error message is a little obscure when you come to use the type:

    type 'a t = A | B of 'a t

    Eq.eq<int t list>

    File "t.ml", line 8, characters 0-17:
    Unbound module Eq_t

I hope this helps a bit.  The documentation on the website gives more
examples.  There'll also be a paper out soon which should explain
things in more depth.

Jeremy.


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

* Re: [Caml-list] ANN: pretty-printing, type-safe marshalling, dynamic typing for free.
  2007-07-19  0:20     ` Jeremy Yallop
@ 2007-07-20  6:24       ` Jon Harrop
  0 siblings, 0 replies; 12+ messages in thread
From: Jon Harrop @ 2007-07-20  6:24 UTC (permalink / raw)
  To: caml-list

On Thursday 19 July 2007 01:20:48 you wrote:
> Sure!  I suppose "SML-style equality" can be understood to include
> various things:
>
>    (1) an equality predicate that tests for physical equality at mutable
>        types and structural equality at immutable types.
>
>          SOME 3 = SOME 3
>          => true
>
>          SOME (ref 3) = SOME (ref 3)
>          => false

I forgot about this. I prefer OCaml's approach (physical and structural) 
actually. I use physical equality a lot as an optimization and I think that 
makes sense in an impure FPL.

>    (2) a compile-time error if you try to use equality at a type for
>        which it's not defined (an abstract or functional type)
>
>          - op o = op o;;
>          stdIn:4.1-4.12 Error: operator and operand don't agree
>          [equality type required]

This is what I was thinking of.

>    (3) a means to write functions that are polymorphic over equality
>        types:
>
>          - fn x => x = x;;
>          val it = fn : ''a -> bool

and this.

> With `deriving' you get (1) and (2).  You can simulate (3) using
> functors if you squint a bit.  In all cases you have to be explicit
> about types, i.e. you have to write
>
>     Eq.eq<int ref option> (Some (ref 3)) (Some (ref 3))
>
> rather than (say)
>
>     Eq.eq (Some (ref 3)) (Some (ref 3))
>
> Specifying types is perhaps a bit of a nuisance, but to make up for it
> you get a bit more flexibility: equality can be customized at
> particular types.

Ah, I did not realise you had to add type annotations everywhere by hand. I 
was rather hoping you could spot existing incorrect applications like:

  lazy 3 = lazy 3

This is simply because I want to apply it to an existing code base.

> I hope this helps a bit.  The documentation on the website gives more
> examples.  There'll also be a paper out soon which should explain
> things in more depth.

That's great, thank you. This is a beautiful piece of work but I think what 
I'm after requires a different approach.

I'm not quite sure how it could be done, short of altering the type system in 
the OCaml compiler. Maybe by adding a phantom type variable to every type, 
but I think that would require higher-order types:

  val ( = ) : [> `eq] 'a -> [> `eq] 'a -> bool

F# takes the Haskell approach of carrying an equality function in a dictionary 
with every type. That is a burden but it is probably a preferable solution 
overall (you just override the equality type when necessary). Some 
inconsistencies remain though, as you don't want to create a new list type 
every time you use a different comparison function, so Set assumes the 
equality from the dictionary whereas List.sort still uses an explicitly 
specified total order.

I can't believe how often I fall for this stupid bug. Even my first attempt at 
writing a GUI Sudoku solver for the OCaml Journal made the classic mistake of 
applying = to a pair of Maps. It would be very nice indeed if OCaml would 
catch such errors...

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
OCaml for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists/?e


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

end of thread, other threads:[~2007-07-20  7:44 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-06-20  0:14 ANN: pretty-printing, type-safe marshalling, dynamic typing for free Jeremy Yallop
2007-06-20  8:01 ` [Caml-list] " Nicolas Pouillard
     [not found] ` <AB56B84F-A45E-433B-B419-2B49F5D92043@gmail.com>
2007-06-20 10:27   ` Jeremy Yallop
2007-06-20 18:28     ` Stefan Monnier
2007-06-20 19:38       ` [Caml-list] " Jeremy Yallop
2007-06-20 21:06         ` Eric Cooper
2007-06-21  7:37           ` Nicolas Pouillard
2007-06-22  0:05             ` Jeremy Yallop
2007-07-15  4:03 ` [Caml-list] " Jon Harrop
2007-07-17  3:05   ` Jon Harrop
2007-07-19  0:20     ` Jeremy Yallop
2007-07-20  6:24       ` Jon Harrop

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