caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
To: Goswin von Brederlow <goswin-v-b@web.de>
Cc: OCaML Mailing List <caml-list@inria.fr>
Subject: Re: [Caml-list] A shallow option type
Date: Mon, 7 May 2012 11:34:02 +0900	[thread overview]
Message-ID: <9EAA1066-D3CE-4260-BCBC-9F044F450EB0@math.nagoya-u.ac.jp> (raw)
In-Reply-To: <4A169BB4-3316-437A-9E73-FABEAEDB9D2F@math.nagoya-u.ac.jp>

Sorry, the marshaling part was wrong.
Of course we need to do something about received values.
So here is a version that automatically attempts to internalize values
with tag sopt_tag when we apply either some or arg to them.
This should be safe, as if sopt_tag was used for another
type, this should be in a functional way.

	Jacques

module Sopt : sig
 type +'a t
 val none : 'a t
 val some : 'a -> 'a t
 val is_none : 'a t -> bool
 val arg  : 'a t -> 'a
 val intern : 'a t -> 'a t
 val depth : 'a t -> int
end = struct
 type 'a t = Obj.t
 let sopt_tag = Obj.lazy_tag - 1
 let none = Obj.new_block sopt_tag 0
 let last = 31
 let area = Array.create (last+1) none
 let () =
   for i = 1 to last do
     let stub = Obj.new_block sopt_tag 1 in
     Obj.set_field stub 0 area.(i-1);
     area.(i) <- stub
   done
 let is_none x = (x == none)
 let rec intern_aux x i =
   if i > last || Obj.is_int x || Obj.tag x <> sopt_tag || Obj.size x > 1 then
     invalid_arg "Sopt.intern"
   else
     if Obj.size x = 0 then i else intern_aux (Obj.field x 0) (i+1)
 let intern x = Obj.obj area.(intern_aux (Obj.repr x) 0)
 let rec some_aux x i =
   if i < last then
     if x == area.(i) then area.(i+1) else some_aux x (i+1)
   else (* i = last *)
     if x == area.(last) then invalid_arg "Sopt.some" else
     let i = intern_aux x 0 in
     if i >= last then invalid_arg "Sopt.some" else area.(i+1)
 let some (x : 'a) : 'a t =
   let x = Obj.repr x in
   if Obj.is_int x || Obj.tag x <> sopt_tag then Obj.obj x
   else Obj.obj (some_aux x 0)
 let rec arg_aux x i =
   if i <= last then
     if x == area.(i) then area.(i-1) else arg_aux x (i+1)
   else
     if x == area.(0) then invalid_arg "Sopt.arg" else
     let i = intern_aux x 0 in
     if i = 0 then invalid_arg "Sopt.arg" else area.(i-1)
 let arg (x : 'a t) : 'a =
   let x = Obj.repr x in
   if Obj.is_int x || Obj.tag x <> sopt_tag then Obj.obj x
   else Obj.obj (arg_aux x 1)
 let rec depth_aux x i =
   if i <= last then
     if x == area.(i) then i else depth_aux x (i+1)
   else -1
 let depth x = depth_aux (Obj.repr x) 0
end


On 2012/05/07, at 10:27, Jacques Garrigue wrote:

> Here is another variant using normal values.
> The advantage is that it does no tricks with bits, and supports
> marshaling.
> It is less efficient because the search is linear, but by using as
> tag (lazy_tag -1) we can avoid being too inefficient in most cases.
> Note however that after marshaling the values are going to
> have the same tag, so this is going to be much less efficient.
> 
> Jacques

[...]



  reply	other threads:[~2012-05-07  2:34 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-05 13:33 Goswin von Brederlow
2012-05-05 13:50 ` Gabriel Scherer
2012-05-05 14:48 ` Andreas Rossberg
2012-05-05 15:07   ` Andreas Rossberg
2012-05-05 16:22   ` Goswin von Brederlow
2012-05-05 17:11     ` Gabriel Scherer
2012-05-06 10:12       ` Goswin von Brederlow
2012-05-06 10:20     ` Goswin von Brederlow
2012-05-06 13:01 ` Jacques Garrigue
2012-05-06 15:34   ` Goswin von Brederlow
2012-05-07  0:29     ` Jacques Garrigue
2012-05-07  1:27     ` Jacques Garrigue
2012-05-07  2:34       ` Jacques Garrigue [this message]
2012-05-07  8:11       ` Jacques Garrigue
2012-05-07 17:07         ` Goswin von Brederlow
2012-05-08  0:07           ` Jacques Garrigue

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=9EAA1066-D3CE-4260-BCBC-9F044F450EB0@math.nagoya-u.ac.jp \
    --to=garrigue@math.nagoya-u.ac.jp \
    --cc=caml-list@inria.fr \
    --cc=goswin-v-b@web.de \
    /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).