<gasche>
kaustuv: "acknowledge" mostly means that someone took care to confirm that this is a sensible issue, to reduce the number of "new" (still-to-be-triaged) bugs
<gasche>
"confirmed" generally includes the acknowledgment (no pun intended) that the issue is worth fixing
<gasche>
that said, bug triagers are not necessarily consistent in this regard
<kaustuv>
Hmm, I use "record" as a variable name in my code. If it is going to become a keyword I should plan ahead
<gasche>
you probably don't have to worry about that
<gasche>
introducing a new keyword is still unheard of (I don't think this will happen)
<flux>
would it have been better to pick a bunch of potentially reserved keywords when 4.0 came out?
<flux>
but that extension is going to be pretty nice it seems
<flux>
especially for code dealing with 2d and 3d vectors
mcclurmc has joined #ocaml
<gasche>
you are both talking about wojciech's "extensible records" proposal
<gasche>
I haven't seen much endorsment for it yet, and I have no reason to believe it will actually end up in the language
<flux>
assigned probably means 'under research' in this context
<gasche>
in any case, certainly not with the proposed syntax
<gasche>
Wojciech is very enthusiastic about new ideas, but other developers are often more conservative
<gasche>
I don't know how well he knows the type-checker internals, but I wouldn't expect such a feature to be possible without Jacques' involvment, and an important amount of work
<asmanur>
the gain of performance is not so clear is it ? because i believe that subtyping will have a runtime cost absent with objects ?
<gasche>
(Leo P. White's extensible sum types work looks like a more credible potential candidate for inclusion medium-term, as the implementation is done)
<kaustuv>
also re performance, I seem to recall that vtable lookups were cached in the implementation of objects...
<kaustuv>
but if you were creating a lot of objects at runtime caching might still not be enough
<gasche>
SML records are structural, but I think they don't have subtyping
<kaustuv>
right, SML has no record polymorphism
<kaustuv>
err, no row polymorphism
<gasche>
so you can just sort the record fields and statically decide the field offset
<gasche>
which is as efficient as OCaml's, I believe
ocp has joined #ocaml
<gasche>
if you introduce row polymorphism but no reordering of field, you can get something efficient, but probably less convenient than what people want
<gasche>
once you have a construct to hide fields, things get tough
<gasche>
I think that syntactic sugar to make object values lighter to define would probably go a long way
<kaustuv>
Is the general use case just something vaguely graphicsy? Because I think most graphics programs use homogeneous (4d) records everywhere
<kaustuv>
What I miss from SML in OCaml is the general nth projection for tuples (i.e., #3 (x, y, z) = z, etc.)
ousado has quit [Quit: --]
<kaustuv>
But I honestly think that record projections are better in OCaml
<gasche>
nth-projection is a hack
<gasche>
hm
<gasche>
ok, it's actually equivalent to 4.01' type-directed record field disambiguation
<gasche>
(... if we had made the sane choice of defining ('a * 'b * 'c) as syntactic sugar for {0: 'a; 1: 'b; 2: 'c})
<kaustuv>
Actually this function is not legal in SML: fun third x = #3 x
<kaustuv>
So you need to know the full arity of the tuple. In other words, #3 is not a function
<gasche>
indeed
pippijn_ is now known as pippijn
<kaustuv>
So it is exactly the same as record fields. You can't say this in SML either: fun field_foo x = #foo x
<gasche>
type-directed disambiguitation doesn't make the construct first-class; for that, you need to move to type-classes (or more generally qualified types)
<gasche>
I generally think that type-classes / implicits are the right way to handle syntactic overloading
<gasche>
but there is an arguable case for having a second-class mechanism that enforces static resolution, instead of dynamic resolution, for performance-sensitive aspects of the language
<gasche>
you could also have something equally convenient with only a type-class mechanism, but good features to control static application (and specialization) of non-operator-polymorphic code
<kaustuv>
Well, sometimes these syntactic categories can be lifted to functions. E.g., you can say this in SML: List.foldr #2 0 [1, 2, 3]
<gasche>
my understanding is that #n is always lifted to a function, but there is a failure if type inference did not determine the record/tuple shape
<kaustuv>
type classes as long as instances are properly scoped and tracked would be great to have.
ousado has joined #ocaml
<kaustuv>
I think the ocaml toplevel needs a -no-init-file comamnd even though I can fake it with -init /dev/null
<kaustuv>
s/command/flag/
skchrko has quit [Quit: Leaving]
dsheets has quit [Ping timeout: 264 seconds]
eikke has quit [Ping timeout: 246 seconds]
Drup has joined #ocaml
dsheets has joined #ocaml
Drup has quit [Ping timeout: 246 seconds]
zpe has joined #ocaml
skchrko has joined #ocaml
eikke has joined #ocaml
zpe has quit [Ping timeout: 248 seconds]
_andre has joined #ocaml
oriba has joined #ocaml
cago has quit [Quit: Leaving.]
shepard` has joined #ocaml
<shepard`>
hi everyone !
<shepard`>
Does someone know if there is a standard file extension for the menhir parser generator ? (like .mly for ocamlyacc)
<shepard`>
which would be directly recognized by oasis :p
<shepard`>
or is there a way to tell oasis to use menhir and not ocamlyacc for a given file ? (for example through the _tags file, or directly through _oasis)
gnuvince has joined #ocaml
<shepard`>
I tried to add ["myparser.mly -use-menhir"] to _tags, but it does not work :( (I get an ocamlyacc error)
<f[x]>
-use-menhir is command-line option
<f[x]>
why do you add it to tags?
ollehar has quit [Ping timeout: 240 seconds]
<shepard`>
ah ok, I just need to do "ocaml setup.ml -build -use-menhir" :p
<shepard`>
sorry for such an easy question then :p
Drup has joined #ocaml
<f[x]>
hmm
<shepard`>
13:16 <f[x]> hmm
<f[x]>
does it work?
<shepard`>
yes, it works :)
<f[x]>
hmmm!
<f[x]>
ok then ;)
<shepard`>
I get compile errors, but at least it calls menhir and not ocamlyacc :-)
<shepard`>
thank you ! :-)
testcocoon has quit [Read error: Connection reset by peer]
<pippijn>
shepard`: better add it to _tags
<pippijn>
shepard`: true: use_menhir
testcocoon has joined #ocaml
breakds has joined #ocaml
redfire has joined #ocaml
csakatok_ has quit [Remote host closed the connection]
<whitequark>
pippijn: some things I want to have in merr:
<whitequark>
1) parameterized EOF token. right now, if I make it %token <Location.t> EOF, it explodes
<pippijn>
because of libmerr
<whitequark>
2) more flexible substitutions for token name... because "class name cannot be an integer", but "class name cannot be a constant"
<whitequark>
yes, libmerr
<pippijn>
2) when merr uses camlp4, that is trivial (unless I misunderstand)
<whitequark>
in fact, libmerr doesn't even need to import the EOF token
<whitequark>
since I can just name it %token EOF "end of file"
<pippijn>
right
<whitequark>
camlp4, yeah
<whitequark>
I'll probably rewrite it in camlp4, it isn't that big
<whitequark>
but not yet
<pippijn>
I'd do it, but I don't have time right now
<pippijn>
maybe in august
* whitequark
nods
<whitequark>
why do you even need libmerr?
<whitequark>
I'd just emit that single function right in the _errors.ml
demonimin has quit [Ping timeout: 260 seconds]
<whitequark>
I imagine that merr could emit default handlers for everything right in the _errors.ml, and the user could override them if desired
<whitequark>
with usual scoping rules
<whitequark>
(with camlp4 preprocessor)
<pippijn>
yep
<pippijn>
that's the idea
ttamttam1 has joined #ocaml
lopex has quit [Remote host closed the connection]
<pippijn>
whitequark: this is now "type constructor"?
<pippijn>
instead of the token value
<whitequark>
pippijn: eh? that's just your code, moved around
<whitequark>
let me look
<pippijn>
no, you killed string_of_token
<whitequark>
moved it to makeErr.ml
<pippijn>
+ | E_tokens.TK_TYCON _ -> "TK_TYCON"
<whitequark>
I'll make merr write a dedicated file for generated stuff later
<pippijn>
that's token name, not string_of_token
<whitequark>
and will import it in makeErr.ml
<whitequark>
oh
<whitequark>
yes.
<whitequark>
I killed string_of_token.
<pippijn>
desc_of_token doesn't return the token value for value tokens
<whitequark>
the generated code refers to the autogenerated definition directly.
<pippijn>
but that's ok
<whitequark>
I'll fix it later
<pippijn>
in the future, it should, though
<whitequark>
I may split the PR if you want
<pippijn>
whitequark: it's fine
<whitequark>
ok
<pippijn>
hmm
<pippijn>
levenshtein is in corelib
<pippijn>
libmerr can die
<pippijn>
or it should be renamed
<pippijn>
because: Error: Error: Files c_errors.cmo and ../../../../_install/lib/ocaml/corelib/corelib.cma(Levenshtein) make inconsistent assumptions over interface Levenshtein
<whitequark>
oh, I see
<pippijn>
or rename levenshtein
<whitequark>
Merr_levenshtein?
<pippijn>
or make libmerr a pack
introom_ has quit [Remote host closed the connection]
<whitequark>
yeah, pack will work as well
<whitequark>
I'll do it later today
<pippijn>
Merr.Levenshtein
f[x] has quit [Ping timeout: 240 seconds]
<pippijn>
ok
<pippijn>
done (for obuild)
<shepard`>
13:24 <pippijn> shepard`: better add it to _tags
<Drup>
pippijn: and this is how you quickly transform your supposedly easy to read point free code into spaghetti :D
<adrien_oww>
:D
<flux>
nah, one flip don't ruin it. I mean. you have a line that mentions Enum.fold, IntSet.add, IntSet.Empty, a range, you're going to guess what it means :-)
<kaustuv>
If I never see another flippin' IntSet.add in my life, it will be one too many
<gnuvince>
kaustuv: thank you
<flux>
a type-directed function calling convention could be nice at times
<kaustuv>
I think gasche is working on something like that
<flux>
you would just put IntSet.add there and as long as it has different types of two arguments, it will know
<Drup>
flux: labels are nice for that too
<flux>
but they have their downsides
<kaustuv>
Merlin actually makes labels very pleasant to use
<kaustuv>
Gone is the look-up-docs-to-guess-what-the-label-is-called dance
<adrien_oww>
reminds me I need to prepare a presentation to oups for lablgtk: with ocaml-ty, merlin, frp, ...
<pippijn>
flux: that's like overloading
<Drup>
adrien_oww: fuuusion !
<pippijn>
also, I feel that such a thing could make error messages extremely confusing
<pippijn>
and code, too
<adrien_oww>
Drup: fusion? :o
<pippijn>
wrong code would suddenly compile and do something unexpected
<pippijn>
I'd rather be explicit with "flip"
<Drup>
adrien_oww: "lablgtk: with ocaml-ty, merlin, frp, ..."
<adrien_oww>
yeah, and probably a lot of fun
ttamttam has joined #ocaml
ollehar has quit [Ping timeout: 264 seconds]
ttamttam1 has quit [Ping timeout: 245 seconds]
ollehar has joined #ocaml
smondet has joined #ocaml
<olvar>
I am sorry to keep bothering you guys, but could someone tell me why is this wrong? http://pastebin.com/uPyF1S6U
<olvar>
I could use the code kaustuv pasted earlier, but Id like to know in what way i am thinking this wrong
tobiasBora has joined #ocaml
introom has quit [Remote host closed the connection]
<flux>
pippijn, well, not quite, because there would still be only one possible function to call.
ttamttam has quit [Quit: ttamttam]
<flux>
ambiquities wouldn't be solved
<pippijn>
ok
<pippijn>
I'm not sure I'd like that
<kaustuv>
olvar: the add function in a map takes *three* arguments: key, value, and map
<kaustuv>
you only give it two arguments
ggole has quit []
<olvar>
kaustuv: lol, i am an idiot, there should read set
<olvar>
thank you :P
<pippijn>
and I'm not sure how that could be married to HM
<flux>
pippijn, probably partial application wouldn't be quite compatible with that..
<kaustuv>
gasche gave a talk where he had an idea that if there was a "hole" in your code of type ('a -> 'b -> 'c) -> ('b -> 'a -> 'c), then there is only function (upto usual extensional equality of functions) that can be plugged in there. So, e.g., if you said Enum.fold (? Set.add), then it would infer flip for ?
<kaustuv>
it is an interesting idea if it can be made to work, but I am a bit skeptical
mort___ has quit [Ping timeout: 246 seconds]
<pippijn>
that's interesting, but it would definitely require annot
<gasche>
note that the "please generate some code here" is made explicit in this setting by the "?" marker
<pippijn>
because you could end up with a lot of questionmarks in your code
<gasche>
as opposed to, say, Scala's implicit coercions
<pippijn>
you will want to know what function was chosen
<pippijn>
I don't think I like this..
<gasche>
(but in presence of appropriate tooling both are equivalent: you want a way to reveal anything implicit locally, be it the place and content of implicit coercion, or only the generated-term for the ?-hole)
travisbrady has joined #ocaml
<kaustuv>
it doesn't matter what function was chosen if there can be only one inhabitant of its type
<gasche>
today a colleage told me that he had needed something like this for some formal-circuits work of his a few years ago, and tried to get Coq typeclasses to do that for him (which did not work very well)
<kaustuv>
(assuming these functions are effect-free, of course)
<flux>
maybe pippijn meant if it was 'flip' that was chosen or something else
<gasche>
but in general I agree with kaustuv that the practical applications are not convincingly present yet
<flux>
I suppose the purpose was not to do a search of functions that would make it work
<flux>
that would be way too general I think
<flux>
List.iter (fun c -> Printf.printf "char: %c\n" c) (? "hello world") :-)
<Drup>
how can I ask ocamlbuild to use menhir's merge function ?
<flux>
albeit that would be pretty cool as well :-)
<gasche>
what's menhir merge function?
<kaustuv>
flux: that example doesn't fit the pattern. the type of the hole cannot involve concrete types like strings, ints, etc.
<Drup>
gasche: have multiple .mly file and "merge" them into one grammar.
<gasche>
(or one would take the convention to forget about all the constants at these types, effectively treating them like blind atomic types)
beckerb has quit [Quit: Konversation terminated!]
<gasche>
Drup: there is a .mlypack target in menhir, but I'm not sure what it does and if it's what you're looking for
beckerb has joined #ocaml
<flux>
kaustuv, would it do a general search of other functions then, say ('a * 'b * 'c) -> ('a * ('b * 'c)) ?
f[x] has joined #ocaml
<kaustuv>
flux: gasche can answer that better, but I would guess "yes"
<flux>
that would sometimes be nice, but I wonder how it works if you have types that involve resolving multiple holes to find
<flux>
and in such complicated situations type feedback would indeed be important
<Drup>
flux: doesn't Agda have something like that ?
<pippijn>
Drup: put the names of the included files into a .mlypack file
malo has quit [Quit: Leaving]
<gasche>
(I'm not sure I understood what flux's question was)
beckerb has quit [Quit: Konversation terminated!]
beckerb has joined #ocaml
Yoric has joined #ocaml
ben_zen has joined #ocaml
transfinite has joined #ocaml
eikke has quit [Ping timeout: 256 seconds]
olvar has left #ocaml []
eikke has joined #ocaml
zpe has joined #ocaml
<gasche>
hnrgrgr: you should get a review comment on #4243 in a few minutes
<Drup>
There should be an error when ocamlbuild can't find a file listed in a pack ...
<gasche>
Drup: look at the mantis and, if there is not yet, submit a bugreport?
tobiasBora has quit [Read error: No route to host]
tobiasBora has joined #ocaml
<Drup>
not sure if the mlypack is really working in fact
<gasche>
does the _log say something about it?
<whitequark>
Drup: it is
cago has left #ocaml []
mika1 has quit [Quit: Leaving.]
mort___ has joined #ocaml
ben_zen has quit [Quit: off to work]
ttamttam has joined #ocaml
travisbrady has quit [Quit: travisbrady]
travisbrady has joined #ocaml
shepard` has quit [Remote host closed the connection]
zpe has quit [Remote host closed the connection]
maurer has joined #ocaml
<maurer>
Is there a way to get something similar to haskell's "deriving Read" in ocaml, or do I need to manually write a parser for a type?
<maurer>
Anyone have any experience with ocamlbuild?
<maurer>
I'm having a hard time getting it to link against libraries
<maurer>
if I pass -lib batteries, it fails to find a module that is in batteries
<maurer>
if I pass -lib definitelynonexistent, it fails the same way, almost as though it is ignoring the option
ocp has quit [Ping timeout: 245 seconds]
<eikke>
maurer: can't you use -use-ocamlfind and -package ... ?
<eikke>
(I'm by far no ocamlbuild expert though)
<maurer>
eikke: I see neither of those in the manpage for ocamlbuild
<maurer>
ah, but it does show up in the error message
<eikke>
I don't use batteries, but something like ocamlbuild -use-ocamlfind -package batteries mymodule.byte might work
<maurer>
It seems to work
<maurer>
I'm just confused as to why neither the manpage nor the html manual mentioned these flags
<maurer>
both mention -lib instead
<maurer>
which seems to be a no-op
tobiasBora has joined #ocaml
bondar has joined #ocaml
ontologiae has quit [Ping timeout: 240 seconds]
mrvn has quit [Ping timeout: 256 seconds]
mrvn has joined #ocaml
tobiasBora has quit [Ping timeout: 246 seconds]
<samebchase>
Hello Everyone, Can someone point me to a small-ish project which makes good use of the available libraries, so that I can learn how to structure things
tobiasBora has joined #ocaml
Drup has joined #ocaml
cthuluh has quit [Ping timeout: 256 seconds]
<amiller>
having trouble building 32bit ocaml on 64bit linux: "Make sure the C compiler gcc -m32 -O is properly installed."
malo has joined #ocaml
<amiller>
it's on ubuntu 64 bit, it's following the command suggetsed by the install file:
<mrvn>
didn't utf16 have codepoints that change a mode so japan/china chars can be done?
<whitequark>
hmm
<pippijn>
mrvn: sounds horrible
<whitequark>
pippijn: hey, you implemented this :D
<pippijn>
I implemented encodings
<whitequark>
also you're right, in ucs16 codepoints = characters too
<whitequark>
argh
<whitequark>
utf16
* whitequark
. o O ( should sleep )
<whitequark>
so to summarize: utf8, utf16, utf32 all have codepoint = character. grapheme = one or more codepoints or characters; same amount of both.
<pippijn>
ok
<pippijn>
and a glyph?
<whitequark>
In displaying Unicode character data, one or more glyphs may be selected to depict a particular character. These glyphs are selected by a rendering engine during composition and layout processing. (See also character.)
<pippijn>
I read it
<pippijn>
what does it mean?
<whitequark>
in some languages (something something arabic), the look of a character can be radically changed by adjacent ones
<whitequark>
so that's different glyphs for the same character
<pippijn>
ah, I see
<pippijn>
makes sense
<pippijn>
so I named my type wrong in deliantra :)
<pippijn>
because there, a glyph is actually a grapheme
<pippijn>
I'll rename that
<whitequark>
deliantra?
<whitequark>
mmorpg?
<pippijn>
yes
<whitequark>
you wrote that?
<pippijn>
together with 2 other guys
<pippijn>
and I wrote two console clients, one in C++ and one unfinished in ocaml
<whitequark>
seems like a huge undertaking
<pippijn>
yes, years :)
<whitequark>
the graphics is painfully horrible :(
<whitequark>
common for almost all foss games
<pippijn>
but more content than every other foss game I know
<pippijn>
this module connects to the server and returns 2 functions
<pippijn>
a recv and a send function
<pippijn>
the recv function is then called with a (handler : 'a -> string -> 'a Lwt.t) and an (env : 'a)
<pippijn>
recv loops until the network connection dies
<pippijn>
send writes commands prefixed with their length (16 bit) to the socket
<pippijn>
the rest is done in the protocol handler
<pippijn>
but the protocol handler doesn't know anything about send and receive buffers
<pippijn>
the protocol handler doesn't know about a receive function, either, it just gets one message at a time, and a send function that it can use to respond
<pippijn>
the protocol parser doesn't know about the send function, either, that one just parses messages
<mrvn>
how do you know what a message is?
<pippijn>
at first, a message is a byte string with a certain length
<mrvn>
that kind of sucks for e.g. http.
<pippijn>
mrvn: this is for deliantra
<pippijn>
not http
<pippijn>
this is not a framework
<pippijn>
this is a networked game
<pippijn>
I want to use a nice framework
<pippijn>
lwt is pretty nice, so far
<mrvn>
problem is how to do the GUI with lwt.
<pippijn>
why?
mort___ has quit [Quit: Leaving.]
<mrvn>
because when you call the GUIs event loop the lwt threads block
<pippijn>
it's fine with lablgtk
<pippijn>
lwt can be integrated with the glib event loop
<pippijn>
or glib can use the lwt event loop
<mrvn>
SDL sucks there. you can't even integrate sockets
<pippijn>
and for deliantra, I want to make my own UI toolkit with ncurses
<Drup>
why does opam suddenly want to downgrade lots of my package ? O_o
<pippijn>
so that's easy, because ncurses just needs one fd: stdin
<pippijn>
I stopped working on that, because I couldn't figure out a good way to get reasonable performance with immutable widgets
<mrvn>
imho GUI elements are inheriently objects. Anything else is just painfull.
eikke has quit [Ping timeout: 240 seconds]
oriba has joined #ocaml
osnr has joined #ocaml
osnr has quit [Changing host]
osnr has joined #ocaml
<pippijn>
mrvn: yes, objects
<pippijn>
mrvn: but can't they be immutable objects?
<mrvn>
so when I press a button you create a new one with pressed=true, then a new button box, new grid, new table, ...., new window?
<pippijn>
well, that is the question
<pippijn>
how does haskell do it?
<pippijn>
monadic mutation?
<pippijn>
I was thinking that you could have the structure separated from the behaviour
<mrvn>
you can give every widget an ID and use the ID instead of the object in the parent. That way you only need to create a new button and the storage of all widgets by id.
<pippijn>
yeah, my idea was a little different
ollehar has quit [Ping timeout: 248 seconds]
<pippijn>
I was thinking I could have the widget hierarchy as structure and store the data model (including "pressed" or "checked" things) somewhere else
<pippijn>
perhaps with an ID
<mrvn>
still ends up with O(log n) for every action
<mrvn>
Or can you do a functional map that has faster replace?
<pippijn>
a very cheap O(log n)
<mrvn>
n == number of widgets
<pippijn>
no, but with a prefix trie on integers, that's pretty fast
<pippijn>
you don't need to create new widgets all the time
<pippijn>
or HAMT
<mrvn>
every widget has a size that can change
<pippijn>
actually
<pippijn>
no :)
<pippijn>
I don't need that
<pippijn>
widgets only change size when the window resizes
<mrvn>
yes. And then you recreate them all?
<pippijn>
no
<pippijn>
then I recompute the size for all
<pippijn>
the size is already stored externally
<pippijn>
by ID
<pippijn>
O(log n) to look up
<mrvn>
==> n == number of widgets
<pippijn>
yes
<pippijn>
but lookups are fast, allocations are not
<pippijn>
log_2 64 is still just 6
<mrvn>
allocations are fast in ocaml
<pippijn>
* 64 = 384
<pippijn>
mrvn: small allocations are fast
<pippijn>
recreating the whole widget tree on every change is not fast
<mrvn>
mutables.
<pippijn>
yes, maybe I really need to drop the idea of immutable widgets
<mrvn>
I just change the pressed state. Not even an allocation for a bool
<pippijn>
separating everything into maps is not pretty, either
<Drup>
pippijn: do you have a reason for wanting absolutly immutable widgets ?
<pippijn>
Drup: purely academic interest :)
<pippijn>
just for fun
<mrvn>
pippijn: yeah. It works but it is slower and ugly.
<pippijn>
mrvn: the slower part is not important to me
<pippijn>
the ugly part is
<pippijn>
I want a pretty widget toolkit
<pippijn>
nice code
<Drup>
pippijn: wouldn't you be satisfied by frp ?
<pippijn>
Summary: FRP is about handling time-varying values like they were regular values.
<pippijn>
is that true?
<pippijn>
time-varying?
<Drup>
kind of, yes
<pippijn>
what about user input?
<Drup>
it's time varying values, isn't it ? :)
<pippijn>
ok
<pippijn>
for example
<pippijn>
the frame that currently has focus must be highlighted
<mrvn>
at time t1 the q key is pressed, at t2 the q key is released
<pippijn>
ok, so React hides the mutation
<pippijn>
right?
<mrvn>
pippijn: Another idea that might work is to build a tree of the widgets and mutate it as the mouse moves so the widget under the mouse is always at the root.
<Drup>
you could see it like that but I prefer to see it as a graph of dependency between values and "clever" reexecution of values when you replace a values by another
hnrgrgr has quit [Ping timeout: 246 seconds]
hnrgrgr has joined #ocaml
<pippijn>
mrvn: that's an interesting idea
<Drup>
and in fact, there is no real mutation, the old value is still there
<ousado>
that's called a zipper, right?
<pippijn>
mrvn: but what about widgets that change without user input?
<mrvn>
pippijn: they will be slow
<pippijn>
ok
<mrvn>
pippijn: there might be ways to move them close to the top though.
<mrvn>
haven't thought about that
<pippijn>
in practice, I don't have a lot of widgets