caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Reed Wilson <cedilla@gmail.com>
To: Caml List <caml-list@inria.fr>
Cc: Leo White <leo@lpw25.net>,
	mandrykin@ispras.ru, Jeremy Yallop <yallop@gmail.com>
Subject: Re: [Caml-list] Type generalization confusion
Date: Wed, 10 May 2017 11:14:11 -0700	[thread overview]
Message-ID: <CALLFq5TXUaHnr6zeSGdogh6_c9ECFgtqyd51pgGfxBth8oM33Q@mail.gmail.com> (raw)
In-Reply-To: <CAAxsn=EgzfTjHWF_xM7KnggEoA0kfT9MV+ttw9NwQ8R4LJTwHg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2856 bytes --]

On Tue, May 9, 2017 at 1:54 PM, Jeremy Yallop <yallop@gmail.com> wrote:

> On 9 May 2017 at 20:56, Reed Wilson <cedilla@gmail.com> wrote:
> > The current issue I'm actually facing is trying to create a lookup table
> for
> > these templates, which only differ by the length of some of the fields.
> For
> > example:
> >
> >   let lookup_array = [| String (0, End); String (1, End) |]
>
> The value restriction prevents generalization here, since arrays are
> mutable.  If bindings of array expressions were generalized then the
> following program, which writes to the array at one type (int option)
> and reads from the array at a different type (string option), would be
> allowed.
>
>    let array = [| None |] in                   (* val array : 'a option
> array *)
>    let () = array.(0) <- Some 3 in
>    let Some x = array.(0) in                (* val x : 'a *)
>    "abc" ^ x
>
> So it's essential for soundness that the types of array values are not
> generalized.
>

I suppose I should have known why the array didn't work, I just didn't
realize it since nothing I have defines a type that would have made that
unsoundness cause problems.


On Wed, May 10, 2017 at 6:29 AM, Mikhail Mandrykin <mandrykin@ispras.ru>
 wrote:

> type (_, _) field =
>   | Int8 : ('a, 'b) field -> ((int -> 'a),'b) field
>   | String : int * ('a, 'b) field -> ((string -> 'a), 'b) field
>   | End : ('b, 'b) field
> type 'a lookup_param = { f : 'b. ('a -> 'b, 'b) field } [@@unboxed]
> let lookup_array = [| { f = String (0, End) }; { f = String (1, End) } |]
> let lookup i = match lookup_array.(i) with { f } -> f
> let of_chan : ('a, 'b) field -> 'a -> in_channel -> 'b = fun _ _ _ ->
> assert
> false
> let x = of_chan (lookup 0) (fun s -> int_of_string s) stdin
> let y = of_chan (lookup 0) (fun s -> s) stdin
>

This is an interesting work-around. I had to tweak it a bit since it would
only work with templates that have one "field". For example:

  let lookup_array = [| {f = Int8 (String (0, End))} |]

fails with:

Error: This expression has type (int -> string -> 'a, 'a) field
       but an expression was expected of type
         (int -> string -> 'a, string -> 'a) field
       The type variable 'a occurs inside string -> 'a

Luckily, that's not a problem in my case since I only need this for one
field type, so I changed it to be a bit less general:

  type lookup_param = { f : 'b. (int -> string -> 'b, 'b) field }

And everything works fine. This will let me test the speed difference
between an extra pointer lookup vs. allocating ~15 words per loop for my
actual code. Honestly, my guess is that this is all academic since OCaml is
so good at small allocations, but I really wanted to know why things
weren't working.

Thanks again to everyone who responded!

-- 
ç

[-- Attachment #2: Type: text/html, Size: 4812 bytes --]

  reply	other threads:[~2017-05-10 18:14 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-08 18:32 Reed Wilson
2017-05-09  3:49 ` Gabriel Scherer
2017-05-09  5:43   ` Reed Wilson
2017-05-09  8:54     ` Leo White
2017-05-09 19:56       ` Reed Wilson
2017-05-09 20:54         ` Jeremy Yallop
2017-05-10 18:14           ` Reed Wilson [this message]
2017-05-10 13:29         ` Mikhail Mandrykin

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=CALLFq5TXUaHnr6zeSGdogh6_c9ECFgtqyd51pgGfxBth8oM33Q@mail.gmail.com \
    --to=cedilla@gmail.com \
    --cc=caml-list@inria.fr \
    --cc=leo@lpw25.net \
    --cc=mandrykin@ispras.ru \
    --cc=yallop@gmail.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).