caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: james woodyatt <jhw@wetware.com>
To: brogoff <brogoff@speakeasy.net>, Ocaml Trade <caml-list@inria.fr>
Subject: [Caml-list] kaplan-okasaki-tarjan deque (was "looping recursion")
Date: Fri, 30 Jul 2004 11:25:56 -0700	[thread overview]
Message-ID: <E6358338-E255-11D8-995D-000A958FF2FE@wetware.com> (raw)
In-Reply-To: <Pine.LNX.4.58.0407300948350.31375@shell2.speakeasy.net>

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

On 30 Jul 2004, at 10:07, brogoff wrote:
>
> I would like to see an implementation of the catenable deques only
> using simple list ops (not laziness) described by Kaplan and Tarjan,
> in OCaml.

Sure.  Here is the basic implementation I did for performance 
comparisons.

	

[-- Attachment #2: cf_kotdeque.ml --]
[-- Type: application/octet-stream, Size: 18773 bytes --]

(*---------------------------------------------------------------------------*
  IMPLEMENTATION  cf_kotdeque.ml

  Copyright (c) 2003, James H. Woodyatt
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

    Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

    Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in
    the documentation and/or other materials provided with the
    distribution

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  OF THE POSSIBILITY OF SUCH DAMAGE. 
 *---------------------------------------------------------------------------*)

type 'a buffer =
    | B1 of 'a
    | B2 of 'a * 'a
    | B3 of 'a * 'a * 'a
    | B4 of 'a * 'a * 'a * 'a
    | B5 of 'a * 'a * 'a * 'a * 'a
    | B6 of 'a * 'a * 'a * 'a * 'a * 'a
    | B7 of 'a * 'a * 'a * 'a * 'a * 'a * 'a
    | B8 of 'a * 'a * 'a * 'a * 'a * 'a * 'a * 'a

let pushBufferL x = function
    | B1 a -> B2 (x,a)
    | B2 (a,b) -> B3 (x,a,b)
    | B3 (a,b,c) -> B4 (x,a,b,c)
    | B4 (a,b,c,d) -> B5 (x,a,b,c,d)
    | B5 (a,b,c,d,e) -> B6 (x,a,b,c,d,e)
    | B6 (a,b,c,d,e,f) -> B7 (x,a,b,c,d,e,f)
    | B7 (a,b,c,d,e,f,g) -> B8 (x,a,b,c,d,e,f,g)
    | B8 _ as y -> assert (not true); y

let pushBufferR x = function
    | B1 a -> B2 (a,x)
    | B2 (a,b) -> B3 (a,b,x)
    | B3 (a,b,c) -> B4 (a,b,c,x)
    | B4 (a,b,c,d) -> B5 (a,b,c,d,x)
    | B5 (a,b,c,d,e) -> B6 (a,b,c,d,e,x)
    | B6 (a,b,c,d,e,f) -> B7 (a,b,c,d,e,f,x)
    | B7 (a,b,c,d,e,f,g) -> B8 (a,b,c,d,e,f,g,x)
    | B8 _ as y -> assert (not true); y

let popBufferL = function
    | B1 _ -> assert false
    | B2 (x,a) -> x, B1 a
    | B3 (x,a,b) -> x, B2 (a,b)
    | B4 (x,a,b,c) -> x, B3 (a,b,c)
    | B5 (x,a,b,c,d) -> x, B4 (a,b,c,d)
    | B6 (x,a,b,c,d,e) -> x, B5 (a,b,c,d,e)
    | B7 (x,a,b,c,d,e,f) -> x, B6 (a,b,c,d,e,f)
    | B8 (x,a,b,c,d,e,f,g) -> x, B7 (a,b,c,d,e,f,g)

let popBufferR = function
    | B1 _ -> assert false
    | B2 (a,x) -> x, B1 a
    | B3 (a,b,x) -> x, B2 (a,b)
    | B4 (a,b,c,x) -> x, B3 (a,b,c)
    | B5 (a,b,c,d,x) -> x, B4 (a,b,c,d)
    | B6 (a,b,c,d,e,x) -> x, B5 (a,b,c,d,e)
    | B7 (a,b,c,d,e,f,x) -> x, B6 (a,b,c,d,e,f)
    | B8 (a,b,c,d,e,f,g,x) -> x, B7 (a,b,c,d,e,f,g)

type 'a t =
    | Z
    | Y of 'a buffer
    | U of 'a buffer * 'a triple t * ('a * 'a) * 'a triple t * 'a buffer
and 'a triple =
    | T1 of 'a buffer
    | T2 of 'a buffer * 'a buffer
    | T3 of 'a buffer * 'a triple t * 'a buffer        

let popLeftNaive = function
    | Z ->
        assert false
    | Y (B1 x) ->
        x, Z
    | Y b ->
        let x, b = popBufferL b in x, Y b
    | U (pr, ld, mid, rd, sf) ->
        let x, pr = popBufferL pr in x, U (pr, ld, mid, rd, sf)

let popRightNaive = function
    | Z ->
        assert false
    | Y (B1 x) ->
        x, Z
    | Y b ->
        let x, b = popBufferR b in x, Y b
    | U (pr, ld, mid, rd, sf) ->
        let x, sf = popBufferR sf in x, U (pr, ld, mid, rd, sf)
           
let rec pushLeft x = function
    | Z ->
        Y (B1 x)
    | Y (B8 (a,b,c,d,e,f,g,h)) ->
        U (B4 (x,a,b,c), Z, (d,e), Z, B3 (f,g,h))
    | Y b ->
        Y (pushBufferL x b)
    | U (pr, ld, mid, rd, sf) as d ->
        match pr with
        | B6 _ ->
            let pr, ld, mid, rd, sf = greenLeft pr ld mid rd sf in
            U (pushBufferL x pr, ld, mid, rd, sf)
        | _ -> 
            U (pushBufferL x pr, ld, mid, rd, sf)

and pushRight x = function
    | Z ->
        Y (B1 x)
    | Y (B8 (a,b,c,d,e,f,g,h)) ->
        U (B3 (a,b,c), Z, (d,e), Z, B4 (f,g,h,x))
    | Y b ->
        Y (pushBufferR x b)
    | U (pr, ld, mid, rd, sf) as d ->
        match sf with
        | B6 _ ->
            let pr, ld, mid, rd, sf = greenRight pr ld mid rd sf in
            U (pr, ld, mid, rd, pushBufferR x sf)
        | _ -> 
            U (pr, ld, mid, rd, pushBufferR x sf)

and greenLeft pr ld mid rd sf =
    match pr with
    | B6 (e1,e2,e3,e4,e5,e6) ->
        let ld = (Obj.magic pushLeft) (T1 (B2 (e5,e6))) ld in
        B4 (e1,e2,e3,e4), ld, mid, rd, sf
    | B3 _ ->
        begin
            match ld, rd with
            | Y _, _
            | U _, _ ->
                let t, l =
                    let t, _ = popLeftNaive ld in
                    match t with
                    | T1 (B3 _)
                    | T2 (B3 _, _)
                    | T3 _ ->
                        popLeftNaive ld
                    | _ ->
                        match (Obj.magic popLeft) ld with
                        | Some (x,y) -> x, y
                        | None -> assert false
                in
                let (T1 x | T2 (x,_) | T3 (x,_,_)) = t in begin
                    match x with
                    | B3 (e1,e2,e3) ->
                        let p = pushBufferR e1 pr in
                        let x' = B2 (e2,e3) in
                        let l0 =
                            match t with
                            | T3 (_, d', y) -> T3 (x', d', y)
                            | T2 (_, y) -> T2 (x', y)
                            | T1 _ -> T1 x'
                        in
                        let ld = (Obj.magic pushLeft) l0 l in
                        p, ld, mid, rd, sf
                    | B2 (e1,e2) ->
                        let p = pushBufferR e2 (pushBufferR e1 pr) in
                        let l' =
                            match t with
                            | T3 (_, d', y) ->
                                let l = (Obj.magic pushLeft) (T1 y) l in
                                (Obj.magic catenate) d' l
                            | T1 _ ->
                                l
                            | _ ->
                                assert false
                        in
                        p, l', mid, rd, sf
                    | _ ->
                        assert false
                end
            | Z, Y _
            | Z, U _ ->
                let t, r =
                    let t, _ = popLeftNaive rd in
                    match t with
                    | T1 (B3 _)
                    | T2 (B3 _, _)
                    | T3 _ ->
                        popLeftNaive rd
                    | _ ->
                        match (Obj.magic popLeft) rd with
                        | Some (x,y) -> x, y
                        | None -> assert false
                in
                let m1, m2 = mid in
                let (T1 x | T2 (x,_) | T3 (x,_,_)) = t in begin
                    match x with
                    | B3 (e1,e2,e3) ->
                        let p = pushBufferR m1 pr in
                        let mid = m2, e1 in
                        let x' = B2 (e2,e3) in
                        let r0 =
                            match t with
                            | T3 (_, d', y) -> T3 (x', d', y)
                            | T2 (_, y) -> T2 (x', y)
                            | T1 _ -> T1 x'
                        in
                        let rd = (Obj.magic pushLeft) r0 r in
                        p, ld, mid, rd, sf
                    | B2 (e1,e2) ->
                        let p = pushBufferR m2 (pushBufferR m1 pr) in
                        let mid = e1, e2 in
                        let r' =
                            match t with
                            | T3 (_, d', y) ->
                                let r = (Obj.magic pushLeft) (T1 y) r in
                                (Obj.magic catenate) d' r
                            | T1 _ ->
                                r
                            | _ ->
                                assert false
                        in
                        p, Z, mid, r', sf
                    | _ ->
                        assert false
                end
            | _ ->
                assert false
        end
    | _ ->
        assert false

and greenRight pr ld mid rd sf =
    match sf with
    | B6 (e6,e5,e4,e3,e2,e1) ->
        let rd = (Obj.magic pushRight) (T1 (B2 (e6,e5))) rd in
        pr, ld, mid, rd, B4 (e4,e3,e2,e1)
    | B3 _ ->
        begin
            match ld, rd with
            | _, Y _
            | _, U _ ->
                let t, r =
                    let t, _ = popRightNaive rd in
                    match t with
                    | T1 (B3 _)
                    | T2 (_, B3 _)
                    | T3 _ ->
                        popRightNaive rd
                    | _ ->
                        match (Obj.magic popRight) rd with
                        | Some (x,y) -> x, y
                        | None -> assert false
                in
                let (T1 x | T2 (_,x) | T3 (_,_,x)) = t in begin
                    match x with
                    | B3 (e3,e2,e1) ->
                        let p = pushBufferL e1 sf in
                        let x' = B2 (e3,e2) in
                        let r0 =
                            match t with
                            | T3 (y, d', _) -> T3 (y, d', x')
                            | T2 (y, _) -> T2 (y, x')
                            | T1 _ -> T1 x'
                        in
                        let rd = (Obj.magic pushRight) r0 r in
                        pr, ld, mid, rd, p
                    | B2 (e2,e1) ->
                        let p = pushBufferL e2 (pushBufferL e1 sf) in
                        let r' =
                            match t with
                            | T3 (y, d', _) ->
                                let r = (Obj.magic pushRight) (T1 y) r in
                                (Obj.magic catenate) r d'
                            | T1 _ ->
                                r
                            | _ ->
                                assert false
                        in
                        pr, ld, mid, r', p
                    | _ ->
                        assert false
                end
            | Y _, Z
            | U _, Z ->
                let t, l =
                    let t, _ = popRightNaive ld in
                    match t with
                    | T1 (B3 _)
                    | T2 (_, B3 _)
                    | T3 _ ->
                        popRightNaive ld
                    | _ ->
                        match (Obj.magic popRight) ld with
                        | Some (x,y) -> x, y
                        | None -> assert false
                in
                let m2, m1 = mid in
                let (T1 x | T2 (_,x) | T3 (_,_,x)) = t in begin
                    match x with
                    | B3 (e3,e2,e1) ->
                        let p = pushBufferL m1 sf in
                        let mid = e1, m2 in
                        let x' = B2 (e3,e2) in
                        let l0 =
                            match t with
                            | T3 (y, d', _) -> T3 (y, d', x')
                            | T2 (y, _) -> T2 (y, x')
                            | T1 _ -> T1 x'
                        in
                        let ld = (Obj.magic pushRight) l0 l in
                        pr, ld, mid, rd, p
                    | B2 (e2,e1) ->
                        let p = pushBufferL m2 (pushBufferL m1 sf) in
                        let mid = e2, e1 in
                        let l' =
                            match t with
                            | T3 (y, d', _) ->
                                let l = (Obj.magic pushRight) (T1 y) l in
                                (Obj.magic catenate) l d'
                            | T1 _ ->
                                l
                            | _ ->
                                assert false
                        in
                        pr, l', mid, Z, p
                    | _ ->
                        assert false
                end
            | _ ->
                assert false
        end
    | _ ->
        assert false

and popLeft = function
    | Z ->
        None
    | Y (B1 x) ->
        Some (x, Z)
    | Y b ->
        let x, b = popBufferL b in
        Some (x, Y b)
    | U ((B4 _ | B5 _ | B6 _ as pr), ld, mid, rd, sf) ->
        let x, pr = popBufferL pr in
        Some (x, U (pr, ld, mid, rd, sf))
    | U ((B3 (x,e1,e2) as pr), Z, (m1,m2), Z, sf) ->
        let y =
            match sf with
            | B3 (f1,f2,f3) ->
                Y (B7 (e1,e2,m1,m2,f1,f2,f3))
            | _ ->
                let f', sf = popBufferL sf in
                U (B3 (e1,e2,m1), Z, (m2,f'), Z, sf)
        in
        Some (x, y)
    | U ((B3 _ as pr), ld, mid, rd, sf) ->
        let pr, ld, mid, rd, sf = greenLeft pr ld mid rd sf in
        Some (popLeftNaive (U (pr, ld, mid, rd, sf)))
    | _ ->
        assert false

and popRight = function
    | Z ->
        None
    | Y (B1 x) ->
        Some (x, Z)
    | Y b ->
        let x, b = popBufferR b in
        Some (x, Y b)
    | U (pr, ld, mid, rd, (B4 _ | B5 _ | B6 _ as sf)) ->
        let x, sf = popBufferR sf in
        Some (x, U (pr, ld, mid, rd, sf))
    | U (pr, Z, (m2,m1), Z, (B3 (e2,e1,x) as sf)) ->
        let y =
            match pr with
            | B3 (p3,p2,p1) ->
                Y (B7 (p3,p2,p1,m2,m1,e2,e1))
            | _ ->
                let f', pr = popBufferR pr in
                U (pr, Z, (f',m2), Z, B3 (m1,e2,e1))
        in
        Some (x, y)
    | U (pr, ld, mid, rd, (B3 _ as sf)) ->
        let pr, ld, mid, rd, sf = greenRight pr ld mid rd sf in
        Some (popRightNaive (U (pr, ld, mid, rd, sf)))
    | _ ->
        assert false

and catenate d1 d2 =
    match d1, d2 with
    | Z, _ ->
        d2
    | _, Z ->
        d1
    | Y b, _ ->
        begin
            match b with
            | B1 x -> pushLeft x d2
            | _ -> let x, b = popBufferR b in catenate (Y b) (pushLeft x d2)
        end
    | _, Y b ->
        begin
            match b with
            | B1 x -> pushRight x d1
            | _ -> let x, b = popBufferL b in catenate (pushRight x d1) (Y b)
        end
    | U (pr1, ld1, mid1, rd1, sf1), U (pr2, ld2, mid2, rd2, sf2) ->
        let y, pr2 = popBufferL pr2 and x, sf1 = popBufferR sf1 in
        let mid = x, y in
        let ld =
            let m1,m2 = mid1 in
            let pRight = Obj.magic pushRight in
            match sf1 with
            | B2 _
            | B3 _ ->
                pRight (T3 (B2 (m1,m2), rd1, sf1)) ld1
            | B4 (e1,e2,e3,e4) ->
                let ld'1 = pRight (T3 (B2 (m1,m2), rd1, B2 (e1,e2))) ld1 in
                pRight (T1 (B2 (e3,e4))) ld'1
            | B5 (e1,e2,e3,e4,e5) ->
                let s'1 = B3 (e1,e2,e3) in
                let ld'1 = pRight (T3 (B2 (m1,m2), rd1, s'1)) ld1 in
                pRight (T1 (B2 (e4,e5))) ld'1
            | _ ->
                assert false
        in
        let rd =
            let m2,m1 = mid2 in
            let pLeft = Obj.magic pushLeft in
            match pr2 with
            | B2 _
            | B3 _ ->
                pLeft (T3 (pr2, ld2, B2 (m2,m1))) rd2
            | B4 (e4,e3,e2,e1) ->
                let rd'1 = pLeft (T3 (B2 (e2,e1), ld2, B2 (m2,m1))) rd2 in
                pLeft (T1 (B2 (e4,e3))) rd'1
            | B5 (e5,e4,e3,e2,e1) ->
                let s'1 = B3 (e3,e2,e1) in
                let rd'1 = pLeft (T3 (s'1, ld2, B2 (m2,m1))) rd2 in
                pLeft (T1 (B2 (e5,e4))) rd'1
            | _ ->
                assert false
        in
        U (pr1, ld, mid, rd, sf2)

let nil = Z

module type Direction_T = sig
    val push: 'a -> 'a t -> 'a t
    val pop: 'a t -> ('a * 'a t) option
end

module A = struct
    let push = pushLeft
    let pop = popLeft
end

module B = struct
    let push = pushRight
    let pop = popRight
end

let sprintB ff = function
    | B1 a ->
        let a = ff a in
        Printf.sprintf "%s" a
    | B2 (a,b) ->
        let a = ff a in
        let b = ff b in
        Printf.sprintf "%s,%s" a b
    | B3 (a,b,c) ->
        let a = ff a in
        let b = ff b in
        let c = ff c in
        Printf.sprintf "%s,%s,%s" a b c
    | B4 (a,b,c,d) ->
        let a = ff a in
        let b = ff b in
        let c = ff c in
        let d = ff d in
        Printf.sprintf "%s,%s,%s,%s" a b c d
    | B5 (a,b,c,d,e) ->
        let a = ff a in
        let b = ff b in
        let c = ff c in
        let d = ff d in
        let e = ff e in
        Printf.sprintf "%s,%s,%s,%s,%s" a b c d e
    | B6 (a,b,c,d,e,f) ->
        let a = ff a in
        let b = ff b in
        let c = ff c in
        let d = ff d in
        let e = ff e in
        let f = ff f in
        Printf.sprintf "%s,%s,%s,%s,%s,%s" a b c d e f
    | B7 (a,b,c,d,e,f,g) ->
        let a = ff a in
        let b = ff b in
        let c = ff c in
        let d = ff d in
        let e = ff e in
        let f = ff f in
        let g = ff g in
        Printf.sprintf "%s,%s,%s,%s,%s,%s,%s" a b c d e f g 
    | B8 (a,b,c,d,e,f,g,h) ->
        let a = ff a in
        let b = ff b in
        let c = ff c in
        let d = ff d in
        let e = ff e in
        let f = ff f in
        let g = ff g in
        let h = ff h in
        Printf.sprintf "%s,%s,%s,%s,%s,%s,%s,%s" a b c d e f g h

let rec sprint f = function
    | Z ->
        "{}"
    | Y b ->
        Printf.sprintf "{%s}" (sprintB f b)
    | U (pr, ld, (m1,m2), rd, sf) ->
        let g = sprintT f in
        let pr = sprintB f pr in
        let ld = (Obj.magic sprint) g ld in
        let mid = sprintB f (B2 (m1,m2)) in
        let rd = (Obj.magic sprint) g rd in
        let sf = sprintB f sf in
        Printf.sprintf "{%s;%s;%s;%s;%s}" pr ld mid rd sf

and sprintT f = function
    | T1 b -> Printf.sprintf "<%s>" (sprintB f b)
    | T2 (b1,b2) -> Printf.sprintf "(%s/%s)" (sprintB f b1) (sprintB f b2)
    | T3 (b1,q,b2) ->
        let b1 = sprintB f b1 in
        let q = (Obj.magic sprint) (fun x -> sprintT f x) q in
        let b2 = sprintB f b2 in
        Printf.sprintf "[%s|%s|%s]" b1 q b2

(*--- End of File [ cf_kotdeque.ml ] ---*)

[-- Attachment #3: cf_kotdeque.mli --]
[-- Type: application/octet-stream, Size: 1845 bytes --]

(*---------------------------------------------------------------------------*
  INTERFACE  cf_kotdeque.mli

  Copyright (c) 2003, James H. Woodyatt
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

    Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

    Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in
    the documentation and/or other materials provided with the
    distribution

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  OF THE POSSIBILITY OF SUCH DAMAGE. 
 *---------------------------------------------------------------------------*)

type 'a t

val nil: 'a t

module type Direction_T = sig
    val push: 'a -> 'a t -> 'a t
    val pop: 'a t -> ('a * 'a t) option
end

module A: Direction_T
module B: Direction_T

val catenate: 'a t -> 'a t -> 'a t
val sprint: ('a -> string) -> 'a t -> string

(*--- End of File [ cf_kotdeque.mli ] ---*)

[-- Attachment #4: Type: text/plain, Size: 1593 bytes --]



> If I remember, the algorithm was described using nonuniform
> data types, so that's yet another plug for supporting this more 
> directly in
> OCaml, meaning, without having to use recursive modules, record field
> polymorphism, or polymorphic records to work around the ability to
> directly write such functions.

The structure uses "bootstrapping" and so does my [Cf_deque] structure. 
  I have handled bootstrapping in [Cf] with judicious use of [Obj.magic] 
to cast functions into the appropriate type at the recursion.

Note: My [Cf] library is loaded with calls to [Obj.magic].  There are 
lots of places where the only way I could solve a problem was by 
hammering something deeply weird into a shape that would fit into the 
Ocaml type system.   Mostly, that happens where I have an interface to 
C library stuff and I'm using shadow type annotations.  But the 
bootstrapped data structures are another place.  And the [Cf_gadget] 
module needs to do something similar (which was well known in the 
original Haskell code where that idea started).

Every time the Ocaml team updates the compiler, I'm worried they're 
going to change something that invalidates my assumptions about what 
[Obj.magic] can and cannot do for me.  I'm *not* saying they didn't 
warn me.  I knew the job was dangerous.

I'd be more exercised about the 'looping recursion' problem with 
List.map exploding on large data sets if I were not in the habit of 
using my [Cf] structures to avoid all that.


-- 
j h woodyatt <jhw@wetware.com>
that's my village calling... no doubt, they want their idiot back.

  reply	other threads:[~2004-07-30 18:26 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-07-27 23:43 [Caml-list] looping recursion briand
2004-07-28  0:27 ` John Prevost
2004-07-28  0:38   ` John Prevost
2004-07-28  1:17     ` skaller
2004-07-28  1:05   ` briand
2004-07-28  1:43     ` Brian Hurt
2004-07-28  2:49       ` briand
2004-07-28  3:12         ` Brian Hurt
2004-07-28  3:20         ` Brian Hurt
2004-07-28  5:54         ` brogoff
2004-07-28  7:22           ` Alex Baretta
2004-07-28 16:38             ` brogoff
2004-07-28 19:40               ` Jon Harrop
2004-07-28 20:18                 ` Brandon J. Van Every
2004-07-29  6:01                   ` Alex Baretta
2004-07-28 21:22                 ` brogoff
2004-07-29  9:13                   ` Daniel Andor
2004-07-29  9:25                     ` Keith Wansbrough
2004-07-29  9:41                       ` Nicolas Cannasse
2004-07-29  9:57                       ` Xavier Leroy
2004-07-29 10:44                         ` Daniel Andor
2004-07-29 12:56                           ` brogoff
2004-07-29 10:11                     ` skaller
2004-07-29 12:41                     ` brogoff
2004-07-29  6:28               ` Alex Baretta
2004-07-29 14:58                 ` brogoff
2004-07-29 16:12                   ` Brian Hurt
2004-07-29 17:49                     ` james woodyatt
2004-07-29 19:25                       ` Brian Hurt
2004-07-29 20:01                         ` brogoff
2004-07-30  4:42                           ` james woodyatt
2004-07-29 17:44                   ` james woodyatt
2004-07-29 23:12                     ` skaller
2004-07-29 22:42                   ` Alex Baretta
2004-07-30  2:38                     ` Corey O'Connor
     [not found]                     ` <200407300136.14042.jon@jdh30.plus.com>
2004-07-30 12:45                       ` Alex Baretta
2004-07-30 17:07                     ` brogoff
2004-07-30 18:25                       ` james woodyatt [this message]
2004-07-30 21:20                         ` [Caml-list] kaplan-okasaki-tarjan deque (was "looping recursion") brogoff
2004-07-31  5:37                           ` james woodyatt
2004-07-28  7:27       ` [Caml-list] looping recursion skaller
2004-07-28 14:36         ` Brian Hurt
2004-07-28 22:05           ` skaller
2004-07-28  0:37 ` skaller

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=E6358338-E255-11D8-995D-000A958FF2FE@wetware.com \
    --to=jhw@wetware.com \
    --cc=brogoff@speakeasy.net \
    --cc=caml-list@inria.fr \
    /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).