caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "Till Varoquaux" <till.varoquaux@gmail.com>
To: "Dario Teixeira" <darioteixeira@yahoo.com>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Issues with Sexplib (#1)
Date: Sat, 29 Nov 2008 12:01:17 -0500	[thread overview]
Message-ID: <9d3ec8300811290901l4d2596a9mef88e5f0f4bcb956@mail.gmail.com> (raw)
In-Reply-To: <110907.37517.qm@web111509.mail.gq1.yahoo.com>

This is not really a bug; I'd qualify this as an "undesirable"
feature: sexplib erases type information; for instance the
representation of None* will always be the same and therefore will be
desexpable to any other option type. You may also note that some other
type have compatible representations. In practice it would be really
hard for a camlp4 extension to keep track of types. In you case you
could use custom converters and save the phantom type in the sexp.

Till

*well more or less: you could be using a custom converter or an old
version of sexplib
On Sat, Nov 29, 2008 at 11:40 AM, Dario Teixeira
<darioteixeira@yahoo.com> wrote:
> Hi,
>
> I have found a couple of issues with Sexplib/Type-conv.  I am not sure they
> are bugs or features, but to me they come across as unexpected, regardless.
> In this message I'll report the first one;  the second follows momentarily.
>
> Consider the Foobar module defined below.  It uses a phantom type to annotate
> values of type Foobar.t, defined recursively.  The idea is that constructors
> A and C are deemed "basic" while B and D are "complex".  Functions make_basic
> and make_complex are used to "freeze" the structure.  Because the complex
> phantom value propagates across a structure, one cannot apply make_basic to
> a structure that uses any of the complex constructors.  On the other hand,
> make_complex can be applied to any structure.
>
> module Foobar:
> sig
>    type foobar_t =
>        | A
>        | B
>        | C of foobar_t
>        | D of foobar_t
>        with sexp
>
>    type basic_t = [ `Basic ] with sexp
>    type complex_t = [ `Complex ] with sexp
>
>    type 'a t with sexp
>
>    val make_a: unit -> [> `Basic ] t
>    val make_b: unit -> [> `Complex ] t
>    val make_c: 'a t -> 'a t
>    val make_d: 'a t -> [> `Complex ] t
>
>    val make_basic: [< `Basic ] t -> [ `Basic ] t
>    val make_complex: [< `Basic | `Complex ] t -> [ `Complex ] t
> end =
> struct
>    type foobar_t =
>        | A
>        | B
>        | C of foobar_t
>        | D of foobar_t
>        with sexp
>
>    type basic_t = [ `Basic ] with sexp
>    type complex_t = [`Complex ] with sexp
>
>    type 'a t = foobar_t with sexp
>
>    let make_a () = A
>    let make_b () = B
>    let make_c foobar = C foobar
>    let make_d foobar = D foobar
>
>    let make_basic x = x
>    let make_complex x = x
> end
>
>
> So far so good; now consider the code below, which serialises and then
> unserialises a value of type Foobar.t.  Note how a "complex" structure
> can be unserialised as "basic" without any consequences.  Therefore, the
> (de)serialisation process can be used to circumvent the restrictions imposed
> by the phantom type.
>
> open Foobar
>
> let foobar = make_complex (make_c (make_b ()))
>
> let doc =
>     let sexp = sexp_of_t sexp_of_complex_t foobar in
>     let str = Sexplib.Sexp.to_string_hum sexp
>     in print_endline str;
>     let sexp2 = Sexplib.Sexp.of_string str in
>     let doc = t_of_sexp basic_t_of_sexp sexp2
>     in doc
>
>
> The resulting types are:
>
> val foobar : Document.Foobar.complex_t Document.Foobar.t    (* Complex *)
> val doc : Document.Foobar.basic_t Document.Foobar.t         (* Basic *)
>
> I understand that phantom types have only a compile-time significance,
> with no runtime expression at all (hence their name).  Therefore, it's not
> altogether surprising that the S-expression builder would simply ignore them.
> Still, is there a way to make them explicit in the serialised data, such
> that the unserialiser would cause a runtime error in the above example?
> Note that the serialiser is already passed sexp_of_complex_t though it
> doesn't seem to put it into any actual use.
>
> Thanks for your time!
> Best regards,
> Dario Teixeira
>
>
>
>
>
> _______________________________________________
> 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
>


  reply	other threads:[~2008-11-29 17:01 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-29 16:40 Dario Teixeira
2008-11-29 17:01 ` Till Varoquaux [this message]
2008-11-29 17:17   ` [Caml-list] " Dario Teixeira
2008-12-02 19:14 ` Markus Mottl

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=9d3ec8300811290901l4d2596a9mef88e5f0f4bcb956@mail.gmail.com \
    --to=till.varoquaux@gmail.com \
    --cc=caml-list@yquem.inria.fr \
    --cc=darioteixeira@yahoo.com \
    /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).