seafood_ has quit [Read error: 110 (Connection timed out)]
<palomer>
ah, gotcha
seafood_ has joined #ocaml
kate_ has joined #ocaml
ryosei has joined #ocaml
ryosei has left #ocaml []
seafood has quit [Read error: 110 (Connection timed out)]
seafood has joined #ocaml
seafood__ has joined #ocaml
seafood_ has quit [Connection timed out]
seafood has quit [Success]
seafood has joined #ocaml
kate_ has quit [Success]
seafood_ has joined #ocaml
seafood__ has quit [Read error: 110 (Connection timed out)]
seafood_ has quit [Client Quit]
jamii__ has joined #ocaml
ched_ has joined #ocaml
Ched has quit [Read error: 110 (Connection timed out)]
seafood has quit [Read error: 110 (Connection timed out)]
* palomer
is starting to think he's a little old to still be a student
<palomer>
26!
kate_ has joined #ocaml
seafood has joined #ocaml
seafood has quit []
AxleLonghorn2 has joined #ocaml
seafood has joined #ocaml
hsuh has quit [Remote closed the connection]
<mrvn>
palomer: ocaml is right to deny you to cast (ref self :> ref too) in your.
<mrvn>
palomer: Consider what happens if you make the reference a instance variable (self_ref) and derive a class too2 from it. too2#self_ref would be type too2 ref but too2#teetoo := new too would assign a too to it.
ygrek has joined #ocaml
AxleLonghorn2 has left #ocaml []
kate__ has joined #ocaml
kate_ has quit [Read error: 104 (Connection reset by peer)]
seafood has quit [Read error: 110 (Connection timed out)]
ttamttam has joined #ocaml
ttamttam has left #ocaml []
seafood has joined #ocaml
Alpounet has joined #ocaml
seafood has quit [Read error: 110 (Connection timed out)]
_zack has joined #ocaml
_zack has quit [Remote closed the connection]
_zack has joined #ocaml
<Alpounet>
hi _zack :)
manju_ has joined #ocaml
manju__ has quit [Remote closed the connection]
<_zack>
Alpounet: heya, welcome
s4tan has joined #ocaml
seafood has joined #ocaml
ygrek has quit [Remote closed the connection]
mishok13 has quit ["Stopping IRC chat... [OK]"]
mishok13 has joined #ocaml
Yoric[DT] has joined #ocaml
filp has joined #ocaml
gim has quit []
komar_ has quit [Remote closed the connection]
verte has joined #ocaml
<Camarade_Tux_>
so, caml_page_table_lookup takes most of the cpu time. great, now I only have to figure what this function does ><
<Yoric[DT]>
:/
kate__ has quit [Read error: 110 (Connection timed out)]
<mrvn>
Camarade_Tux_: in what project?
<Camarade_Tux_>
mrvn, it's in a weird list structure (though it's not using the weird part currently)
<Camarade_Tux_>
basically it defines a list with a record, with mutable fields, and I am trying to optimize the merge sort a bit
hkBst has joined #ocaml
<mrvn>
a mutable list then
<mrvn>
In my list merge sort I started out with List.map (fun x -> [x]) list and then recursively merge them pairwise into larger lists till only [x] remains and then return x.
<tsuyoshi>
iirc caml_page_table_lookup is mostly called by the garbage collector
<Camarade_Tux_>
currently the GC takes about 45% of the time, especially caml_page_table_lookup, that's what I'm trying to optimize right now
<tsuyoshi>
my guess is.. you're mutating things too much
<Camarade_Tux_>
tsuyoshi, yeah, it is defined in memory.c, but I'm not sure what it does
<Camarade_Tux_>
tsuyoshi, mutations is my first bet too
<tsuyoshi>
well, when the gc looks at a pointer, it checks the page table to see if it is an ocaml pointer or something else that it can't collect
ygrek has joined #ocaml
<tsuyoshi>
it might be worth trying a different version of ocaml to see if the performance is different, because the page table code (on amd64 at least) changed in 3.11
<Camarade_Tux_>
I'm on 3.11, 64bits
<tsuyoshi>
if you hit a bad case in the new code, I bet xavier would be interested to know about it
sanxiyn has joined #ocaml
OChameau has joined #ocaml
<Camarade_Tux_>
reading the mailing-list and the bug report again, it seems I'm simply making the Gc work too much and this is appears because ocaml now uses a hash table instead of a simple array
<flux>
camarade_tux_, did you try to repeat the issue with an older ocaml version?
<Camarade_Tux_>
unfortunately I don't have any available
<Camarade_Tux_>
I guess I'll just run godi and give it another prefix
<Camarade_Tux_>
but the numbers I'm seeing seem consistent with the lenght of my lists (currently 1M elements)
komar_ has joined #ocaml
sanxiyn has left #ocaml []
ygrek has quit [Remote closed the connection]
<mfp>
Camarade_Tux_: does caml_modify represent a substantial amount of your profile?
komar_ has quit [Read error: 104 (Connection reset by peer)]
<Camarade_Tux_>
mfp, yes it does
<Camarade_Tux_>
I've been trying to reduce the number of allocations but I don't know if that'll be possible
<mfp>
then you know it's not the GC that's killing you, but mutation
<mfp>
specifically foo := bar
<mfp>
caml_modify updates the remembered set when you change a ref in the major heap to point to a value in the minor one
<mfp>
(it thus calls caml_page_table_lookup to classify the pointer)
<Yoric[DT]>
Well, Batteries Beta 1 is officially out.
<Yoric[DT]>
mfp: I'm counting on your reddit expertise :)
<mfp>
uh instead of using caml_page_table_lookup to search the page table, it could compare with caml_young_start/end first; would be faster when the dest is in minor
<mfp>
hmm let's see
<mfp>
+1 gives you 10th, +4 6th
<mfp>
and the new Q goes to 8H
Camarade_Tux_ has quit [Read error: 60 (Operation timed out)]
Camarade_Tux_ has joined #ocaml
* Camarade_Tux_
hates that livebox
<Camarade_Tux_>
my bet was that mutating a single element in a record was faster than allocating a record with two ints and four pointers
<mfp>
not a bad moment to submit
<Camarade_Tux_>
well, I'll come back to that later if it happens to be a bottleneck, performance is a bit frustrating but alright
seafood has quit [Read error: 110 (Connection timed out)]
<mrvn>
Camarade_Tux_: Even if the record is in the generational heap?
* Camarade_Tux
tries allocation instead of mutation
<mfp>
Camarade_Tux: here's an example where a functional set (encoded using lists) is faster than one with mutable lists http://eigenclass.org/misc/beust.ml
<Yoric[DT]>
mfp: thanks
<Yoric[DT]>
I'm now waiting for the official announcement of the Debian package.
<mfp>
Yoric[DT]: > The interpreter may now be called as a library -> what's this?
<Yoric[DT]>
We have a function [Compiler.ocaml], which can be used to launch the interpreter.
<Yoric[DT]>
It's quite rough for the moment, and used only for testing, but it's a start.
<mfp>
just runs as an external process, no real in-process compilation, I suppose?
<Yoric[DT]>
Indeed.
<mfp>
k, thought for a second you'd merged the bytecode interpreter written in OCaml
<Yoric[DT]>
Nah.
<Yoric[DT]>
Do you think I should reformulate?
<kaustuv>
If I want to traverse a cyclic web of blocks from C and don't trigger the GC with any caml_alloc_*, is there an efficient way to mark the blocks to detect loops?
<tsuyoshi>
kaustuv: yeah, mark them with the color blue
<mrvn>
kaustuv: mutable color : bool
<mfp>
Yoric[DT]: hmm "call the toplevel programmatically"?
<kaustuv>
tsuyoshi: where is blue defined?
<tsuyoshi>
kaustuv: the marshalling code does this.. I also patched ancient to do the same thing
<mrvn>
tsuyoshi: color as in the color bis in the header of blocks?
<mfp>
Yoric[DT]: toplevel evoques the REPL, interpreter makes me think of huh [let eval env t = ...]
<mrvn>
s/bis/bits/
<tsuyoshi>
yeah in the header, there's 4 bits for a color
<mrvn>
Is that specified anywhere that one may do that?
<tsuyoshi>
it is used by the gc.. the "blue" color is for free blocks
<tsuyoshi>
no, I just noticed that the marshal code did it
<tsuyoshi>
so maybe some day this will break
<kaustuv>
according to caml/mlvalues.h there are only two bits for the colour
<mrvn>
or when one thread marshals while you collor.
<tsuyoshi>
oh right.. 2 bits, 4 colors
<Alpounet>
Yoric[DT], ocamlfind batteries/ocamlc is ocamlc with batteries libraries linked, right ?
<kaustuv>
I take it blue is 0b10 because that's the only one I haven't seen so far in experiments
<tsuyoshi>
mrvn: well, there's a lock somewhere, isn't there? to make sure only one threads runs at a time?
<mrvn>
tsuyoshi: so? Somewhere in the middle of the marshaling the task can switch.
<tsuyoshi>
I don't think so
<mrvn>
Doesn't it have codepoints where it switches if a task has run for too long, like when the GC gets invoked or something?
<tsuyoshi>
I mean if you are doing this completely independently of ocaml in a separate thread, sure you can screw things up
<kaustuv>
mrvn: the GC is only called on allocation
<mrvn>
kaustuv: which happens often enough
<kaustuv>
but not from marshal, poly compare, etc. which are outside the GC's control
<mfp>
oh noes, make all opt top syntax install does generate the docs
<tsuyoshi>
if you're writing an ocaml primitive in c and you don't allocate, fooling with the headers will work
<tsuyoshi>
I was about to say it's safe.. but not really.. it's pretty hard to debug
<mfp>
Yoric[DT]: even though, according to README, [If you do not want the documentation generation, remove "install-doc" from the previous commands.], they are being generated
<mrvn>
I was assuming the graph traversal would be in ocaml and not c.
<Yoric[DT]>
Alpounet: well, it's ocamlc with the appropriate options to use batteries libraries & syntax.
<tsuyoshi>
oh yeah.. keeping ocaml code from allocating is impossible
<kaustuv>
tsuyoshi: thanks, that seems to work.
<Yoric[DT]>
mfp: what is being generated?
<Yoric[DT]>
Ah, ok.
<mfp>
the docs
<Yoric[DT]>
Sounds like an error in Makefile.in .
<mfp>
the Makefile is regenerated when I ./configure, right? Or did I have to do something else before rebuilding?
<Yoric[DT]>
No, nothing else.
<mfp>
ah the problem is in README, all includes doc
<mfp>
well, or in Makefile.in, depending on how you look at it
<mfp>
ifeq ($(HAS_GODI),yes)
<mfp>
all: config.ml install-doc
<mfp>
if not HAS_GODI, all: config.ml seems that should be the case for both?
<kaustuv>
If I'm looking at a custom block, is there any way to tell that it was created for an Int32, an Int64 or a Nativeint?
<Yoric[DT]>
mfp: there are good reasons to make it different between HAS_GODI and not HAS_GODI.
<mfp>
k
<Yoric[DT]>
Although the criterium should perhaps be ifeq($(INSTALLATION), "GODI") or something such.
<Yoric[DT]>
Essentially, it's the only way we have found of forcing the construction of documentation with GODI.
LeCamarade has joined #ocaml
manju_ has quit ["Leaving"]
Spiwack has joined #ocaml
hto has quit ["leaving"]
Yoric[DT] has quit ["Ex-Chat"]
thelema has quit [Read error: 110 (Connection timed out)]
th5 has joined #ocaml
OChameau-bis has joined #ocaml
thelema has joined #ocaml
vuln has joined #ocaml
sparta has joined #ocaml
gim has joined #ocaml
<Camarade_Tux>
muhahaha, I had Gc parameters lost in my source code and they made the code twice slower
<Alpounet>
is it that funny for you ? :-p
<Camarade_Tux>
well, yes since I've been beaten to my own game playing with the GC parameters ;)
<flux>
camarade_tux, so I guess the amount spent in gc was dropped dramatically?
<flux>
from 40% to 10%?-o
RowanD` has joined #ocaml
<Camarade_Tux>
not really, still about 40%
OChameau-bis has quit ["Leaving"]
RowanD has quit [Read error: 101 (Network is unreachable)]
<Alpounet>
flux, ping
<Alpounet>
If I have a class c defined in a module M, and I link m.cmo/a when building the program, I shouldn't get "Unbound class M.c" right ?
<mrvn>
Alpounet: the order is important
<Alpounet>
I think the order is ok, but will do some tests. Thanks.
<thelema>
If anything that depends on M gets linked before M, you'll get that error
<Alpounet>
nothing but my main .ml file depends on it
<Alpounet>
and I've put m.cmo/a just before my main .ml file on the compilation line
<thelema>
I guess it's possible that in M, there's references to an M module...
<thelema>
but within M, the module M doesn't exist
<mrvn>
thelema: too bad you can't write something like module M : sig ... end = SELF
<thelema>
mrvn: what would that do?
<mrvn>
Give the .ml file that signature and make M. available.
<thelema>
within M?
<mrvn>
Probably would give rise to some interesting recursions.
<Alpounet>
thelema, don't think so...
<Alpounet>
Moreover, the problem is "Unbound class M.c"
<mrvn>
Using M.c in m.ml certainly does that.
<mrvn>
or the dreaded m.* and m.* have different interfaces
* mrvn
wants record subtyping. *whine*
<_zack>
is ocamlbuild unable to generate .cmxs files?
<_zack>
I can't find the "usual" magic tag for that ...
ygrek has joined #ocaml
svenl_ has quit []
svenl has joined #ocaml
vuln has quit ["leaving"]
<kaustuv>
A quick summary of what's different in batteries/ocamlbuild and vanilla ocamlbuild?
<kaustuv>
For any Debian OCaml maintainers reading, libbatteries-ocaml-dev is apparently missing a dependency on libocamlnet-ocaml-dev (or whichever package provides netstring).
willb has joined #ocaml
th5 has quit []
kate__ has joined #ocaml
ygrek has quit [Remote closed the connection]
kaustuv is now known as kaustuv_
wsmith84 has joined #ocaml
<palomer>
batteries is huge!
<Camarade_Tux>
he, there's a bug report about that
_zack has quit ["Leaving."]
kobook has joined #ocaml
Amorphous has quit [Read error: 104 (Connection reset by peer)]
RowanD` has quit [Read error: 60 (Operation timed out)]
seafood has joined #ocaml
Amorphous has joined #ocaml
<mrvn>
palomer: And still missing things
<mrvn>
Can one use a functor expecting a type t with an 'a t?
<hcarty>
rwmjones: What is the URL for the Fedora OCaml packaging repository? (.spec files and patches)
<Alpounet>
I should bring mlbot here soon, the need is here :-p
willb has quit [Read error: 60 (Operation timed out)]
<mbishop>
whatever happened to rwmjones' xavierbot?
<rwmjones>
I think Alpounet wrote a pure ocaml one
<mbishop>
wasn't yours some perl monstrosity? :P
<Alpounet>
rwmjones, yes.
<Alpounet>
1/ it is an interesting project for getting more and more familiar with OCaml and 2/ having an OCaml bot entirely written in OCaml sounded good to me and 3/ xavierbot hasn't come here for long, right ?
ygrek has joined #ocaml
filp has quit ["Bye"]
willb has joined #ocaml
<Alpounet>
If I use "use_file" function from the Toploop module, over the "batteries.ml" file... Will Batteries be available through mlbot ?
kate__ has joined #ocaml
<Alpounet>
I mean, there is everything in batteries.ml, right ?
<hcarty>
Alpounet: I think you'd want to use the Batteries toplevel init file
<hcarty>
Or something similar to that
<Alpounet>
ok
<Alpounet>
I'll take a look at it
* palomer
thinks it would be pretty cool if you could be polymorphic in type constructors!
<mrvn>
kaustuv: That only prooves that in that case the execution order is such.
<mrvn>
palomer: like type 'a t = Foo of 'a?
<palomer>
I was thinking something like 'b . 'c . 'b 'c
<palomer>
or 'c. int 'c
<mattam>
palomer: Oh yes.
Yoric[DT] has joined #ocaml
<palomer>
hullo yoric!
<hcarty>
rwmjones: I don't know if you have plans to package Jane St.'s bin-prot, but gcc 4.4 chokes on some C macros under F11/rawhide
<hcarty>
rwmjones: Removing the -pedantic gcc flag gets around it -- 12:48 < rwmjones> I think Alpounet wrote a pure ocaml one
<hcarty>
whoops
<rwmjones>
ok ... I think I packaged it, but possibly not uploaded it
<kaustuv>
palomer: you want higher kinded types? Haskell has them.
Spiwack has quit [Remote closed the connection]
<palomer>
haskell has all kinds of craziness
OChameau has quit ["Leaving"]
<kaustuv>
not all kinds, just the good kinds
hardcoding has joined #ocaml
<hardcoding>
Hello I would like to transform a char list such as : ['1';'2';'3';' ';' ';'3';'2';' ';'3'] to ['123';'32';'3'], can somebody help me please?
<hardcoding>
sorry, I meant [['123'];['32'];['3']] ..
<Camarade_Tux>
well, it creates a string list but the idea is there :p
<hardcoding>
Str.split or String.split Camarade_Tux ?
<Camarade_Tux>
there's no String.split !
<hardcoding>
isn't there a way to write an simpler function with recursivity?? I thought about doing it with a condition expression such as : e::r -> if e <> ' ' then e::[]@[] else function(r) or something like that
kobook has quit [Read error: 104 (Connection reset by peer)]
<mrvn>
hardcoding: let conv list = let rec loop res acc = function [] -> List.rev ([acc]::res) | x when (x >= '0') && (x <= '9') -> loop res (acc ^ (String.make 1 x)) | ';'::xs -> loop ([acc]::res) "" xs | _::xs -> loos res acc xs in loop [] "" list
<mrvn>
Sorry, let conv list = let rec loop res acc = function [] -> List.rev ([acc]::res) | x::xs when (x >= '0') && (x <= '9') -> loop res (acc ^ (String.make 1 x)) xs | ';'::xs -> loop ([acc]::res) "" xs | _::xs -> loop res acc xs in loop [] "" list
<mrvn>
- : string list list = [["123"]; [""]; ["32"]; ["3"]]
<mrvn>
If you don't want the "" then you need to test for acc = "" in the ' ' case.
<hardcoding>
conv ['1';'2';'3';' ';' ';'5';'3'];;- : string list list = [["12353"]]
<mrvn>
hardcoding: s/;/ /
<mrvn>
hardcoding: I used the wrong seperator.
<hardcoding>
I can't see where, and there are several things I don't understand in your code, like how can you compare characters like if x <= '9' for example?
<hardcoding>
when*
wsmith84 has joined #ocaml
<Camarade_Tux>
hardcoding, it relates to their ascii code
<hardcoding>
I thought you had to compare their int_of_char then ^^
<Camarade_Tux>
this is the definition of Char.code (which is the same as int_of_char) : external code: char -> int = "%identity"
<Camarade_Tux>
it basically means it is made to satisfy the type checker (well, basically)
<Camarade_Tux>
and the conversion between the two is completely straight-forward so <= gives the order you'd expect from ints
<mrvn>
hardcoding: <= compares the bit pattern of the structure of any type. In case of chars if gives a nice order a<b<c<...<z, 0<1<2<..<9, A<B<...<Z.
<hardcoding>
I'm starting to understand your code! I'm surprised that there is no recursivity!
<mrvn>
Camarade_Tux: What does <= give for chars on a non ascii system? Does ocaml support any?
<mrvn>
hardcoding: there is. loop is recursive
<hardcoding>
how come it works with no rec at the beginning?
<mrvn>
hardcoding: I don't get why you want a string list list though? A string list would suffice.
<mrvn>
hardcoding: because conv is not recursive, only loop.
<Camarade_Tux>
mrvn, the question would be "on non-iso-8859-1" systems ;)
* Camarade_Tux
tries again because he has forgotten the exact answer
<hardcoding>
I wanted a string list list because I've made a function to convert strings into char lists
<hardcoding>
Camarade_Tux, I'm not on an iso-8859-1 system and it works
<mrvn>
hardcoding: let explode str = Array.to_list (Array.of_string str)
<hardcoding>
doesn't work
<mrvn>
hmm, didn't the std lib have a string -> char array function?
<flux>
no
<mrvn>
let explode str = Array.to_list (Array.init (String.length str) (fun i -> str.[i]))
<mrvn>
Or use batteries.
wsmith84 has quit [Read error: 60 (Operation timed out)]
<hardcoding>
well my function to convert strings into char lists works ^^
<mrvn>
or let explode str = let rec loop acc = function -1 -> acc | x -> loop (str.[x]::acc) (x-1) in loop [] (String.length str - 1)
<mrvn>
Still don't see why you want a string list list though.
<flux>
sometimes lists are nice
<hardcoding>
yeah you're right I realize it's blocking me haha I thought it'd be easier like that
<Camarade_Tux>
mrvn, I've found ocaml's simplicity wrt strings (and not looking at the content at the string) makes it work with different encodings without problem in my experience
<flux>
(lists of characters that is)
<Camarade_Tux>
it works for me too
<mrvn>
flux: I'm missing Sring.fold_*. A lot of cases where you convert to char list would be covered by that.
<mrvn>
Camarade_Tux: just like C
<mrvn>
The string type is more a byte array anyway.
<Camarade_Tux>
mrvn, \00 is really problematic for C and unicode
<mrvn>
Does batteries have localized string functions? Things like isalpha, isnumeric, ... that honor the locales?
<mrvn>
Camarade_Tux: That is the one big difference to C strings. :)
slash_ has joined #ocaml
<mrvn>
The other is that String.length is O(1)
<mrvn>
anyway, gotta go. *wave*
<Camarade_Tux>
see you mrvn
<hardcoding>
me too! bye!
hardcoding has quit ["Leaving"]
wsmith84 has joined #ocaml
komar_ has joined #ocaml
slash_ has quit [Client Quit]
slash_ has joined #ocaml
kaustuv_ has left #ocaml []
kaustuv_ has joined #ocaml
thelema has quit [Read error: 110 (Connection timed out)]
kaustuv has quit [Nick collision from services.]
kaustuv_ is now known as kaustuv
jonafan_ is now known as jonafan
seafood has joined #ocaml
<Alpounet>
good night all
Alpounet has left #ocaml []
jeanbon has quit ["J'y trouve un goût d'pomme."]
seafood has quit [Read error: 110 (Connection timed out)]
ygrek has quit [Remote closed the connection]
oriba has joined #ocaml
Camarade_Tux has quit [Remote closed the connection]
Camarade_Tux has joined #ocaml
thelema has joined #ocaml
willb has quit [Read error: 110 (Connection timed out)]
bjorkintosh has joined #ocaml
jsk has joined #ocaml
ryosei has joined #ocaml
Yoric[DT] has quit ["Ex-Chat"]
<bjorkintosh>
is ocaml used much in embedded systems?
wsmith84 has quit [Read error: 60 (Operation timed out)]
<kaustuv>
Are garbage-collected languages used at all in embedded systems?
verte has joined #ocaml
<bjorkintosh>
i have no idea.
<bjorkintosh>
but i imagined there might be a scheme where the language spat out the necessary asm code...
jamii__ has quit [Read error: 60 (Operation timed out)]
<palomer>
do you guys also feel iffy about using (=) ?
<hcarty>
bjorkintosh: There has been noise about such things on the mailing list, but I don't have any specific examples
<bjorkintosh>
ah okay.
<hcarty>
palomer: I feel fully justified in using ( = ), as long as it's appropriate!
<hcarty>
The definition of appropriate may not always be clear, of course
<palomer>
even when appropriate, I still feel iffy
<palomer>
here's an example
komar_ has quit [Remote closed the connection]
<palomer>
I want to write a function g that takes an (a,a) either list and returns a function f : 'b list -> ('b,'b) either list and an a list lst such that g x x = x
oriba has left #ocaml []
<palomer>
my first reflex is to use ( = )
<palomer>
err, make that : (let (f,lst) = g x in f lst) equals x
<palomer>
which is equivalent to 'a * [`Left | `Right]
<thelema>
now what's this about returning f: 'b list -> ('b * bool) list?
<thelema>
I follow up to that point, but "and a list lst such that g x x = x"?
<palomer>
g x x = x was false
<palomer>
the invariant is :
<palomer>
(let (f,lst) = g x in f lst) equals x
<thelema>
[g x] returns a function and a value, and you want that function applied to that value to be x?
<palomer>
it returns a function and a list of values
<palomer>
example:
wsmith84 has joined #ocaml
<palomer>
let (f,lst) = g [`Left 1; `Right 2; `Right 5]
<palomer>
then lst = [1;2;3]
<thelema>
[1;2;5]?
<palomer>
and f ["a","b","c"] is [`Left "a";`Right "b"; `Left "c"]
<palomer>
yeah, make that [1;2;5]
* thelema
is curious about how g produces f
<thelema>
is the idea to put the tags into f, and the values into lst?
<thelema>
and rejoin them later?
<palomer>
tags?
<palomer>
I'll put up my solution in a bit
<palomer>
but it's a little ugly
<thelema>
yes, ocaml's variants are all tagged unions.
<palomer>
oh, well I could put the tags in `F and just iterate through it
verte is now known as verte-work
<palomer>
the only problem is that (a,a) either list is a simplification
<palomer>
my actual datatype is a little bit more complicated
<palomer>
what I'm doing is collecting the leaves, numbering them, and then creating the function with that
<thelema>
you're dividing the 'information content' of your data structure into two pieces, a function and some values, and want the function to rebuild your original structure when applied to those values
<kaustuv>
why not map over the values, incrementing a ref cell as you go?
<kaustuv>
or use zippers or delimited continuations or whatever masturbatory fantasy you subscribe to