thrasibule has quit [Read error: 110 (Connection timed out)]
flx_ has joined #ocaml
tmaeda is now known as tmaedaZ
alp_ has joined #ocaml
Alpounet has quit [Read error: 113 (No route to host)]
flux has quit [Read error: 110 (Connection timed out)]
eldragon has joined #ocaml
_unK has quit [Remote closed the connection]
verte has joined #ocaml
willb is now known as willb-out
willb-out is now known as willb
<Camarade_Tux>
are the darcs speed issues only during merges?
<Camarade_Tux>
*darcs'
ccasin has joined #ocaml
Amorphous has quit [Read error: 110 (Connection timed out)]
Amorphous has joined #ocaml
srcerer_ has joined #ocaml
srcerer has quit [Connection timed out]
tonyIII__ has joined #ocaml
srcerer has joined #ocaml
BigJ2 has joined #ocaml
srcerer__ has joined #ocaml
struktured has joined #ocaml
<BigJ2>
I am confused as to whether or not trees and linked lists are the same....
tonyIII_ has quit [Read error: 110 (Connection timed out)]
tmaedaZ is now known as tmaeda
BigJ2 has quit [Client Quit]
srcerer_ has quit [Connection timed out]
srcerer has quit [Connection timed out]
tmaeda is now known as tmaedaZ
mjonsson has quit [Remote closed the connection]
<infoe_>
they are not
<infoe_>
bigj2: the linked list is a sequence of values, each value is accompanied by a pointer to the next value in a sequence, seems like you could build a tree like this but the connections between leaf and node would need to be inverted
valross has joined #ocaml
tmaedaZ is now known as tmaeda
jcaose has joined #ocaml
jcaose has quit [Client Quit]
ccasin has quit ["Leaving"]
BigJ2 has joined #ocaml
BigJ has joined #ocaml
caligula_ has joined #ocaml
ulfdoz has joined #ocaml
caligula__ has quit [Read error: 110 (Connection timed out)]
prince has quit [Remote closed the connection]
jeddhaberstro has quit [Client Quit]
eldragon has left #ocaml []
verte has quit ["~~~ Crash in JIT!"]
ikaros has joined #ocaml
ulfdoz has quit [Read error: 110 (Connection timed out)]
Associat0r has joined #ocaml
ikaros has quit [Read error: 54 (Connection reset by peer)]
BigJ2 has quit [sendak.freenode.net irc.freenode.net]
Ched has quit [sendak.freenode.net irc.freenode.net]
Camarade_Tux has quit [sendak.freenode.net irc.freenode.net]
mbishop has quit [sendak.freenode.net irc.freenode.net]
mbishop has joined #ocaml
Camarade_Tux has joined #ocaml
caligula_ has quit [Read error: 104 (Connection reset by peer)]
caligula_ has joined #ocaml
valross has quit [Read error: 110 (Connection timed out)]
valross has joined #ocaml
caligula__ has joined #ocaml
struktured has quit [Read error: 60 (Operation timed out)]
caligula__ has quit [Read error: 60 (Operation timed out)]
caligula_ has quit [Read error: 110 (Connection timed out)]
caligula__ has joined #ocaml
flx_ is now known as flux
BigJ2 has joined #ocaml
Ched has joined #ocaml
jonafan has quit [Read error: 54 (Connection reset by peer)]
ttamttam has joined #ocaml
_zack has joined #ocaml
Amorphous has quit [Read error: 60 (Operation timed out)]
ertai_ has joined #ocaml
mehdid_ has joined #ocaml
ertai has quit [Read error: 104 (Connection reset by peer)]
mehdid has quit [Read error: 104 (Connection reset by peer)]
reid99 has quit [Read error: 110 (Connection timed out)]
reid99 has joined #ocaml
Amorphous has joined #ocaml
mehdid_ is now known as mehdid
rwmjones-afk is now known as rwmjones
Snark has joined #ocaml
munga_ has joined #ocaml
valross has quit [Read error: 104 (Connection reset by peer)]
flx_ has joined #ocaml
valross has joined #ocaml
_andre has joined #ocaml
flux has quit [Read error: 110 (Connection timed out)]
flux has joined #ocaml
flx_ has quit [Read error: 104 (Connection reset by peer)]
flx_ has joined #ocaml
munga_ has quit [Read error: 113 (No route to host)]
flux has quit [Read error: 110 (Connection timed out)]
sgnb` is now known as sgnb
tmaeda is now known as tmaedaZ
flx_ is now known as flux
alp_ has quit [Read error: 54 (Connection reset by peer)]
alp_ has joined #ocaml
_zack has quit ["Leaving."]
rwmjones_lptp has joined #ocaml
tmaedaZ is now known as tmaeda
Yoric has joined #ocaml
<Yoric>
hi
<flux>
hello
alp_ has quit [Read error: 110 (Connection timed out)]
Yoric has quit []
jcaose has joined #ocaml
det has quit [Remote closed the connection]
Alpounet has joined #ocaml
rwmjones_lptp has quit ["This computer has gone to sleep"]
Modius has quit [Read error: 110 (Connection timed out)]
valross has quit [Remote closed the connection]
<rwmjones>
hmm gildor not around
<rwmjones>
and no zack either :-(
bzzbzz has joined #ocaml
<mehdid>
rwmjones: is it a Debian question?
<rwmjones>
mehdid, yeah, indirectly
<rwmjones>
so fedora have device that X core fonts are "teh evil"
<rwmjones>
and are trying to remove them from the whole distribution
<rwmjones>
(I think this is silly really, but anyhow)
<rwmjones>
an ocaml Graphics module uses core fonts (and basic X calls)
<flux>
fortunately the Graphics interface is really quite simple, it should be easy to provide the same semantics with whichever font API :)
<mehdid>
rwmjones: we don't intend to get rid of core fonts ... So, I don't think that one of us has already investigated the question
<flux>
but wouldn't it be cool otherwise if Graphics had all that anti-alias-coolness etc :-)
<mehdid>
like rwmjones said, Graphics is made for demos/beginners. Real/modern applications use gtk or pango
<mrvn>
The Graphics interface also needs to learn about mouse buttons.
<flux>
mrvn, what about them?
<mrvn>
That there is more than one.
<rwmjones>
I'm certainly not intending to rewrite or remove Graphics
<rwmjones>
just modify it enough so it doesn't need core fonts
<flux>
mrvn, well, I'm not sure if that's required.. although I suppose it'd be convenient.
<rwmjones>
unless I can get a pass on this .. I don't think there's any harm in using core fonts occasionally
<mrvn>
button : bool; (*true if a mouse button is pressed*)
<mrvn>
BUt is it left, right, middle, scroll up or scroll down?
<flux>
soem old code might break, if they generate their own statuses
<flux>
(I suppose the whole status-field should be private anyway)
<flux>
(to enable extension)
<mrvn>
flux: If it where private one could add items to the end.
<flux>
mrvn, however, Graphics is intended for really. simple. applications. adding another field button_idx wouldn't make it more complicated to use, though..
<flux>
mrvn, yes, my point exactly.
<mrvn>
As it is not private I would change button into an int. The number of button pressed
<mrvn>
or int option
<mrvn>
and keypressed + key into char option
<flux>
well, that would certainly break code
<mrvn>
Any change will potentially break code anyway.
<flux>
(and IMO for a particularly good reason)
_zack has joined #ocaml
<flux>
well, I think in practice it is really rare that people mess around with that record, other than deconstruct it
<mrvn>
One could alternatively define Graphics.GraphicsX11.status
<flux>
slipping away from the simplicity..
<mrvn>
flesh out the X11 modules more.
<mrvn>
What is the actual use of GraphicsX11 now? You can open subwindows. But the only thing you can do with them is close them again. Jipey.
<flux>
indeed :). I suppose Graphics-module uses the most recently created window
<flux>
maybe open_graph can use the window_id?
<mrvn>
flux: The subwindows are sub to the one open_graph opened.
<mrvn>
GraphicsX11 should have all the calls Graphics has with window_id as first parameter.
<mrvn>
By the way, there is an alternative for mouse buttons that remains compatible. DO it like java. The different buttons are signaled by also passing a key. This works also for macs that only have one button. Press button + alt for the second mouse button and so on.
<flux>
hmm, I can't do anything useful with GraphicsX11.open_window
<flux>
it appears to draw a blank area to my window, but I can't draw anything on it
<flux>
closing it makes stuff underneath reappear
<mrvn>
flux: You could pass the window_id to some C code to draw into. Or fork some app to run in it.
<mrvn>
e.g. start xflames in it.
<flux>
ah, ok
<mrvn>
But for ocaml, as said above, it is quite useless.
_unK has joined #ocaml
struktured has joined #ocaml
reid99 has quit [Read error: 110 (Connection timed out)]
reid99 has joined #ocaml
<flux>
ngh, OUnit's bracket-function's type makes no sense
<flux>
val bracket : (unit -> 'a) -> ('a -> 'b) -> ('a -> 'c) -> unit -> 'c. the second function is the function to actually run, so why doesn't the function return 'b..
<thelema_>
because it returns the result of tear_down
Yoric has joined #ocaml
<mrvn>
First function creates the input data, second runs the test and third gives the expected answere?
<thelema_>
just look at the code, it's pretty clear.
<thelema_>
let bracket set_up f tear_down () = ...
<flux>
thelema_, I can understand that, but is the return value of tear_down somehow useful?
<mrvn>
ahh, last function frees resoures
<thelema_>
yes - tear-down for unit tests does the comparison
<flux>
thelema_, in any case, it's not even returned if your function throws an exception
<mrvn>
flux: assume 'a contains a mutable field. The tear_down checks the mutable field and returns if it contains the right value.
<flux>
so the purpose woudl be to do some final checking? I thought that'd be part of the actual test function
_unK has quit [Read error: 60 (Operation timed out)]
<thelema_>
A bracket is a functional implementation of the commonly used setUp and tearDown feature in unittests. It can be used like this:
<flux>
don't tests in OUnit signal the success or lack of with a unit return value an exception in general?
<flux>
in practice the signature doesn't really matter, it could even be (unit -> 'a) -> ('a -> unit) -> ('a -> unit) for the purposes of OUnit, no?
<thelema_>
yes.
_unK has joined #ocaml
<rwmjones>
if only we could persuade harrop to open source his "smoke" vector library ...
ztfw has joined #ocaml
seanmcl has joined #ocaml
hyperboreean has quit [Read error: 60 (Operation timed out)]
hyperboreean has joined #ocaml
Yoric has quit []
Yoric has joined #ocaml
Yoric has quit [Client Quit]
struktured has quit [Read error: 110 (Connection timed out)]
rwmjones has quit [Remote closed the connection]
rwmjones has joined #ocaml
_zack has quit [Read error: 110 (Connection timed out)]
_zack has joined #ocaml
_zack has quit [Read error: 110 (Connection timed out)]
seanmcl has quit []
_zack has joined #ocaml
seanmcl has joined #ocaml
Yoric has joined #ocaml
munga_ has joined #ocaml
_zack1 has joined #ocaml
jcaose has quit [Read error: 110 (Connection timed out)]
ikaros has joined #ocaml
seanmcl has quit []
_zack has quit [Read error: 113 (No route to host)]
jcaose has joined #ocaml
seanmcl has joined #ocaml
seanmcl has quit []
Yoric has quit []
srcerer__ is now known as srcerer
seanmcl has joined #ocaml
ttamttam has quit ["Leaving."]
seanmcl_ has joined #ocaml
seanmcl has quit [Read error: 104 (Connection reset by peer)]
seanmcl_ is now known as seanmcl
_zack has joined #ocaml
_zack1 has quit [Read error: 113 (No route to host)]
jonafan has joined #ocaml
Yoric has joined #ocaml
<infoe>
thelema: you got a moment to explain the aim of aaa to me?
<infoe>
from what i've gathered on forums, it is a subset of batteries with less external dependencies?
<Camarade_Tux>
yes
<Camarade_Tux>
which should make it easier to install and more portable (if I'm not mistaken)
<infoe>
alright, so these external dependencies are projects in other languages or projects in ocaml not directly associated with batteries?
<infoe>
i used git to grab batteries and then i grabbed all the dependencies and built it as a first timer with out issues
<Camarade_Tux>
it's mostly for other platforms, windows for example
<Camarade_Tux>
it also tries to avoid camlp4 as it causes issues on some platforms
<infoe>
well i have ocaml installed on three machines now, 64-bit arch linux, a 32-bit arch linux (asus eee) and a pretty awesome workstation running windows 7
<infoe>
but seems that ocaml for windows is only 32bit
<infoe>
the GODI install was pretty good
<Camarade_Tux>
no, it can work on 64bit too
<Camarade_Tux>
anyway, you can make 32bit installs on win x64 too
seanmcl has quit [Read error: 104 (Connection reset by peer)]
<Camarade_Tux>
(and gcc or msvc on windows?)
seanmcl has joined #ocaml
caligula_ has joined #ocaml
caligula__ has quit [Connection timed out]
_zack has quit ["Leaving."]
<hcarty>
rwmjones: He talked about releasing the code for Smoke at one point.
<mrvn>
Is that vectors as in (x,y,z) or operation on larger arrays of values?
ikaros_ has joined #ocaml
ikaros has quit [Read error: 60 (Operation timed out)]
<infoe>
mrvn: would you consider the example to be naive ocaml code? is there a way to make it faster?
<infoe>
mrvn: must be the fldcw assembler instruction to get 64-bit rounding mode
<mrvn>
Your C++ code is horrible inefficient already
<infoe>
oh that is not my code
thieusoai has quit ["leaving"]
ulfdoz has joined #ocaml
seanmcl has quit []
<Camarade_Tux>
at least, set_fpu doesn't seem to change anything wrt. performance
<mrvn>
infoe: The reason why the basic ocaml code is so slow is that floats are boxed. That results in float operations allocating a box that points to an also allocated float. Two allocations for every float that the GC has to clean up again.
<mrvn>
Then iter2 creates a record of 2 floats. I think that keeps floats unboxed. Not quite sure what costs you there.
<mrvn>
I would have thought that might even be faster.
<mrvn>
And in iters3 you are creating a class object. All methods are virtual (compared to c++) and go through a hashtable.
<Camarade_Tux>
8.52s -> 6.29s by not calculating x*.x and y*.y twice in the first example in the first function
<mrvn>
By the way, your c++ iters3 code is just wrong. And it also gets 100% "optimized" away. template<> in C++ means the source gets completly duplicated for each invokation and then translated. Makes no difference to writing the type in yourself.
<Camarade_Tux>
that code wasn't really after speed...
<mrvn>
As your 3rd code you should abstract the whole class and not just the operator* and operator+.
<mrvn>
You could also try functors.
<mrvn>
What you should also compare is the difference between having all code in one compilation unit and in seperate units.
<hcarty>
mrvn: Vector as in (x,y,z) - thing SVG and PS vs PNG or GIF.
<mrvn>
That would even be only (x,y)
<hcarty>
mrvn: I think Smoke supports 3D, though I may be wrong. But yes, in the end it reduces to (x, y)
<mrvn>
infoe: I just checkd and in your code the mul z z for complex numbers does not optimize common subexpressions. It realy multiplies two complex numbers. Might be due to not giving an inlining argument though. gcc on the other hand is verry good at eliminating common subexpressions.
<mrvn>
That will also apply to the basic example. You compute x*x and y*y twice. gcc will compute it once.
ulfdoz has quit [Read error: 60 (Operation timed out)]
Yoric has joined #ocaml
ygrek has joined #ocaml
<mrvn>
Ok. I took the iters2 example but moved the complex into a seperate compilation unit: http://paste.debian.net/51312/
<mrvn>
ocaml speed is about +-1s for multiple runs. Looks to me iters1 and iters2 are actualy the same speed on amd64.
TaXules has joined #ocaml
maskd has joined #ocaml
animist has joined #ocaml
tab has joined #ocaml
reid99 has joined #ocaml
Associat0r has joined #ocaml
zhijie has joined #ocaml
mfp has joined #ocaml
svenl has joined #ocaml
Pepe_ has joined #ocaml
brendan has joined #ocaml
bind_return has joined #ocaml
noj has joined #ocaml
<mrvn>
It is interesting to note that in real life you will have much more code in seperate compilation units and a lot of the speedup of c++ will vanish. Even this simple case makes c++ slower than ocaml by splitting the complex class into a seperate unit.
<det>
C++ has templates
<mrvn>
det: what has that got to do with it?
<det>
you can abstract using templates without penalties
<mrvn>
det: templates are little more than #define. textual replacement.
<det>
sure
<mrvn>
They cost nothing in speed but they totaly blow up your binary size.
<mrvn>
and compile time.
<det>
Im not sure binary size is really an issue
<det>
MLton is a good example
<mrvn>
det: can make a huge difference on cache hits.
mrvn has quit [sendak.freenode.net irc.freenode.net]
mattiase has quit [sendak.freenode.net irc.freenode.net]
__marius__ has quit [sendak.freenode.net irc.freenode.net]
rbancroft has quit [sendak.freenode.net irc.freenode.net]
eibmozoib has quit [sendak.freenode.net irc.freenode.net]
bacam has quit [sendak.freenode.net irc.freenode.net]
srisw has quit [sendak.freenode.net irc.freenode.net]
orbitz has quit [sendak.freenode.net irc.freenode.net]
patronus has quit [sendak.freenode.net irc.freenode.net]
gim has quit [sendak.freenode.net irc.freenode.net]
<det>
but polymorphic code has many drawbacks itself
bacam_ has joined #ocaml
beibmozoi has joined #ocaml
mattiase has joined #ocaml
orbitz has joined #ocaml
patronus has joined #ocaml
gim has joined #ocaml
rbancroft has joined #ocaml
__marius__ has joined #ocaml
<det>
monomorphized code using a complex type need not any heap allocation
mrvn has joined #ocaml
<mrvn>
re
<mrvn>
det: can make a huge difference on cache hits.
<mrvn>
Bigger problem is that template<> means the code is totaly inlined. Forget putting template into a library and updating the lib without recompiling the binary too.
<det>
well, using monomorphized code can often mean inlining into a small loop
<mrvn>
Forget about writing 2 libraries with the same interface and then doing time LD_PRELOAD=lib1.so binary; time LD_PRELOAD=lib2.so binary kind of things.
<det>
that's a hack
<mrvn>
det: but a verry nice one in C
<det>
I've never needed to use it
<mrvn>
On the other hand ocaml doesn't have dynamic libs. So who are we to complain. :)
<det>
I thought it does now
<mrvn>
There are some hacks for a dynmic lib interface but I ment in general.
<det>
I have been giving a lot of thought about writing a compiler for a ML-like language
<det>
I think an approach with type classes + specialization could lead to some very fast code
<mrvn>
det: The first thing I would change is add more type information.
<det>
esp if compiled to LLVM IR
<det>
oh sure
<det>
C++ templates suck
<det>
no argument
<mrvn>
1) add exceptions to the type of functions
<mrvn>
2) add info about mutability to types
<det>
I agree with 2
<mrvn>
3) add info about side effects
<det>
#1 is maybe
<det>
agree #3
<mrvn>
det: If I write try foo () with Bar -> () | Baz -> () then I want the compiler to complain that foo () can also throw Buzz.
<mrvn>
and I want to see that in the module interface and therefor docs.
BigJ2 has quit [Connection timed out]
<det>
Ya, would be nice
<det>
I would also get rid of currying
<mrvn>
Also, with mutable flag, note where a mutable type is mutable-ed in a function.
<det>
and add a new type that is a tuple but not heap allocated
<mrvn>
det: 4) local,escaping,destructable type information
<mrvn>
let (x,y) = foo () in x
<mrvn>
(x,y) is local. no need to heep allocate
<det>
that solves just 1 case
<det>
what about a complex number type that is passes around
<det>
and you would like to pass it in registers
<det>
(if possible)
<mrvn>
By destructable I mean values that won't be used after this call.
<mrvn>
And escaping means the called function might leak the value to somehwere else. So you can't pass a copy in registers.
ttamttam has joined #ocaml
<det>
complicated and can fail
<mrvn>
Ideal "Hashtbl.add tbl x y" would also note that x and y escape into the tbl.
<det>
easier to add something like: {} == heap allocated type, () == value type
<mrvn>
det: can't fail. ight just not find all cases where something doesn't escape or remain local.
<mrvn>
+m
<det>
new type has more uses too
<det>
such as how you want to lay out in an array
<mrvn>
det: Hashtbl.add tbl x y where x,y are () == value type should give an error.
<mrvn>
det: or should it then copy them to the heap?
<det>
After specialization it should be a noop :-)
<det>
well
<det>
do you mean () == unit
<mrvn>
det: no, your value type syntax
<det>
oh ok
<mrvn>
You can't put a value type (except primitives) into a hashtbl.
<det>
I dont understand the question then
<det>
why cant you put a value type into a hashtable
<mrvn>
The hashtbl only stores a reference to the value which would then be in registers or the stack and have limited lifetime.
<det>
hashtable would be specialized
<det>
for each type
<det>
I need to go for a bit
<mrvn>
det: so (int,int) Hashtbl would use registers but ('a, 'b) Hashtbl heap?
<det>
Would like to continue this later
<mrvn>
would that be monomorphic types?
<det>
an array of (int, int)
<det>
there would be no such thing as ('a, 'b) hashtable
<det>
at runtime
thrasibule has joined #ocaml
Snark has quit ["Ex-Chat"]
<det>
Im not sure how hashtable is implemented internally in ocaml
<det>
if you tell me, then I can tell you your answer
<flux>
det, you would like this to work: let hashify els = let h = Hashtbl.create (List.length els) in List.iter (fun (k, v) -> Hashtbl.add h a b) els; h
<flux>
(well, I would anyway)
<flux>
val hashify : ('a * 'b) list -> ('a, 'b) Hashtbl.t
<flux>
hmph, bug, a b should be k v
jcaose has quit [Read error: 110 (Connection timed out)]
safire has joined #ocaml
<safire>
what does a type val * val mean?
rwmjones_lptp has joined #ocaml
<safire>
is that a tuple of vals?
<flux>
yes
bacam_ is now known as bacam
<thelema_>
det: hashtbl is implemented as an array of lists
thelema_ is now known as thelema
<det>
sorry, I am in out at atm
<thelema>
n/p
<det>
all functions would be monomorphized
<thelema>
then you'd have to build all the different possible implementations
<det>
sure
<thelema>
and use the correct one
<det>
that is the only way to retain performance
<det>
otherwise you end up monomorphizing manually when it is important
<thelema>
how many implementations of [fun x y -> x :: y] are there?
<det>
that is something that would always be inlined anyways :-)
<thelema>
function calls are quite cheap.
<det>
but allocating a new list is how many instructions ?
<det>
allocation is 1 compare + increment
<thelema>
in fast path, yes
<thelema>
very likely in-lining this is a win, yes.
<det>
I dont see why such a fear of code side with monomorphization
<det>
in C you essentially monomorphize everything by hand
<det>
by writting boilerplate loops all over the place
<thelema>
because with complex functions like List.map, there's a lot of possible monomorphizations
<det>
map is such small code though
<det>
inlined or not
<ygrek>
how will GC work?
<det>
who knows :-)
<thelema>
sure, but there's a combinatorial explosion of monomorphizations
<det>
this issue doesnt affect mlton
<det>
which monomorphizes everything
<thelema>
for int(-like), tuples (incl. array & record), floats, float tuples... What else am I missing
<thelema>
mlton gets to do whole program optimization, no?
<det>
yes
<det>
has to do
<det>
but that is irrelevant, point is monomorphization does not lead to code explosion in practice
<thelema>
libraries + separate compilation -> code explosion
<det>
what about C++ libraries that expose templates?
<det>
monomorphization only affects polymorphic functions too, of course
<det>
and only 1 specialization per type
<det>
not to mention that monomorphism exposes more opportunities for the compiler to simplify code
<thelema>
ah, ocaml's compiler is intentionally not an extreme optimizing compiler like gcc
<det>
LLVM can simply monomorphized fold_left((+), 0, [1;2;3;4;5]) to a print :-)
<thelema>
it's important to have predictable performance
<thelema>
It's better to have less innocuous changes that cause huge performance losses
<ygrek>
thelema, inpredictable faster perf is better then predictable slow which is better then inpredictable slow :)
<thelema>
ygrek: predictable slow can be improved where important.
<ygrek>
"C++ libraries that expose templates" tend to make project compile for ages
<ygrek>
so you argue it is better? really?
<thelema>
I'll try to take on the role of the ocam dev team and argue for it, yes
<thelema>
I dunno if I'll do a good job...
<det>
than crappy boxed code that cant properly convert List.fold_left(fun a b -> a + b, 0, [1;2;3;4;5]) to a nice loop? yes better
<thelema>
Another important aspect of OCaml’s performance is its predictability. OCaml
<thelema>
has a reasonably simple execution model, making it easy to look at a piece of
<thelema>
OCaml code and understand roughly how much space it is going to use and how
<thelema>
fast it is going to run. This is particularly important in building systems that react
<thelema>
to real-time data, where responsiveness and scalability really matter.
<ygrek>
thelema, I can't believe that any programmer would say that having surprisingly fast code is worse :)
ulfdoz has joined #ocaml
<det>
yes, it has a predictable worst case
<det>
and is sometimes better :-)
<thelema>
The problem isn't "surprisingly fast", the problem is "Having to tiptoe around hard-to-predict performance bombs" (still other people's words)
<det>
but what if the worst case == ocaml's best case ?
<hcarty>
det: Then that's magical
<ygrek>
thelema, these citations about unpredictable perf mean "unpredictably slower", not "unpredictably faster"
<hcarty>
det: And everyone will use it
<ygrek>
hcarty, everyone would use it if it existed :)
<thelema>
when you write code that has a certain performance, and you make a little tweak that ends up missing the optimization that makes it fast, you get unpredictably slower
<det>
optmizing compiler worst case is usually very close to stupid compiler best case
<ygrek>
det, how will gc work? how will ffi work? you abandon uniform runtime representation - that raises lots of questions
<det>
right, you get the code that the stupid compiler (like Ocaml) would produce
<mattiase>
fast code is bad news when you charge your client by the hour
<thelema>
det: yes, they are the same, but the problem isn't the worst case, it's when you think you're writing good code, but you actually aren't - your code is being "fixed" by the compiler
<thelema>
I mean optimizing compiler worst case and stupid compiler best case
<thelema>
are the same
<thelema>
stupd compiler best case = stupid compiler worst case
<thelema>
When the compiler is no longer able to fix your code, you've stepped on a performance land-mine
itewsh has joined #ocaml
julm has quit ["leaving"]
julm has joined #ocaml
julm has quit [Client Quit]
slash_ has joined #ocaml
julm has joined #ocaml
ygrek has quit [Remote closed the connection]
ikaros_ has quit ["Leave the magic to Houdini"]
<det>
thelema, then do you consider abstraction bad code ?
<thelema>
no, as it's only a constant worse than direct representation.
<thelema>
FWIW, I do want a language that allows high abstraction and high performance
seanmcl has joined #ocaml
<thelema>
but I appreciate the compiler authors respect for predictable performance
<thelema>
and defer to their judgement on how many optimization techniques are brittle
onigiri has joined #ocaml
<det>
abstraction requires an optimizing compiler
<det>
if you want performance
ulfdoz has quit [Read error: 110 (Connection timed out)]
<thelema>
ocaml optimizes a little bit, and achieves sufficient performance for many uses.
<thelema>
many optimizations that can be done by hand (common sub-expression hoisting) should be done by hand
<Camarade_Tux>
imho this isn't even optimization but readability
ztfw has quit [Remote closed the connection]
<thelema>
yes, you do usually get more readable code by hoisting sub-expressions by hand
razel has joined #ocaml
<razel>
let card = Joker | Node of card * int;; let a = Node(Joker,4) ;; a <- Node(Joker,3) ;;
<razel>
what is the correct way to go about doing that
<razel>
notably a <- Node(Joker,3);;
<Camarade_Tux>
you want to "change" a?
<razel>
yes
Yoric has quit []
<thelema>
let a = ref Node(Joker,4) in a := Node(Joker,3)
<razel>
hmm
<Camarade_Tux>
by default, things are immutable
<razel>
and reference contents are mutable ?
<thelema>
yes
<razel>
ok so now i have a type deck = { (*initial card *) cards : card ; int size }
<razel>
should it be type deck = { cards : card ref ; size : int ref };;
<razel>
going with the above card example
<thelema>
no.
<thelema>
type deck = {mutable cards: card; mutable size: int}
<razel>
so then if 'cards' = a and i want to change a ?
<thelema>
d.cards <- Joker
thieusoai has joined #ocaml
seanmcl has quit []
<razel>
hmmm but what if i wanted to pass d.cards to a function that loops through the cards and modifies a specific one. For example we have the following cards:
<thelema>
right now d.cards only holds one card
<thelema>
oh, your cards are a linked list...
<thelema>
don't do that.
<razel>
ace = Node(king,1) ; king = Node(queen,2) ; queen = Node(jack,3) ; jack = Node(Joker,4) ;
<razel>
yes exactly a linked list
<razel>
dont do what ?
<thelema>
type card = Joker | King of suit | Queen of suit | Jack of Suit | Num of int * suit
<razel>
ok but theres an unlimited number of cards
<razel>
yeah cool for simplicity, type card = Joker | Card of int * card ;;
<thelema>
let take_card d = let c = List.hd d.cards in d.cards <- List.tl d.cards; d.size <- d.size-1; c
<thelema>
Of course, if you didn't need size cached...
<thelema>
type deck = card list
<thelema>
let take_card = function [] -> failwith "Empty deck" | h::t -> (h,t)
<thelema>
returns a card and the remainder of the deck
<razel>
im not there yet :0\
<razel>
:)
<razel>
but the above wouldnt be a linked list no more it would just be a list.
itewsh has quit ["Quitte"]
ttamttam has quit ["Leaving."]
<hcarty>
razel: A "list" in OCaml is a linked list
<hcarty>
razel: As thelema pointed out, you can get the first element of the list and the remainder of the list a few different ways.
verte has joined #ocaml
<razel>
see im contemplating now if im suposed to do it like that because the instructions say that the d.cards is suposed to hold "the first node of a linked list of nodes", in other words, "the first card of a linked list of cards
<razel>
"
<razel>
d.cards in thelma's example holds a list of nodes not a node ( list of cards not a card )
<thelema>
razel: you're doing homework that's designed to be done in ocaml?
<razel>
yes
<razel>
ocaml course
<razel>
,sort of
<thelema>
the right ocaml way is to use a card list
<thelema>
but if it's forced on you to implement your own linked list, make sure that cards can follow Joker
<hcarty>
thelema: Unless they are supposed to implement their own list implementation?
<hcarty>
thelema: Sorry, wrote too soon :-)
<razel>
hmm
<thelema>
and keep doing it with your cards type
<razel>
how would i do it if i wanted to for example type card = Joker | Card of int * card ref;;
<razel>
is the above correct ? ( * card ref;; )
<thelema>
you could...
<thelema>
it's correct, but it may not be what you want
<razel>
hmm
<razel>
what would be the ideal way
<razel>
respecting the rules, of course.
<thelema>
if you can't use "list", then...
<thelema>
type card = Empty | Joker of card | Card of int * card
<razel>
Joker is the same as Empty, aka the Last card, hence it does not have a node
<thelema>
ah, Joker isn't a card, it's always the last card?
<razel>
yeah sorry
<razel>
lol
<thelema>
if so, drop empty and the * card on joker
<razel>
its to replace Null
<razel>
or empty whatever
<thelema>
yes, ok.
<razel>
yes type card = Joker | Card of int * card;;
<thelema>
good.
<razel>
first let me explain the way i have it
<razel>
for example delete card i = (* deletes the ith card, start counting at card *) match card with
<razel>
| Joker -> raise Exception
<razel>
|Card(n,c) -> etc.
<thelema>
ok
<razel>
now ocaml wont let me for example do card <- Card(9,c_card)
<thelema>
correct - you can't change your cards, you can only change your deck
<razel>
yes, but then how do i remove, i have A -> B -> C , if i remove B i need to set A -> C (A points to C)
<razel>
thats my theory
<thelema>
you need to do that?
<razel>
and B will be discarded by the garbage collector since its not used anymore
<razel>
no
<razel>
thats just the way i pictured it
<thelema>
do you need to remove cards in the middle, or just at the top?
<razel>
in the middle
<razel>
the i'th card
<thelema>
ok.
<razel>
one sec ill show you my code
<thelema>
del i c = if i = 1 then c.rest else c.first, del (i-1) c
<thelema>
where c.rest gets the following cards
<thelema>
and first gets the first card
<razel>
look for example at ln 22
<razel>
oh
* thelema
will be back in a few hours - good luck
Yoric has joined #ocaml
smimou has quit [Read error: 110 (Connection timed out)]
Yoric has quit []
<mrvn>
det: If abstraction needs a good compiler and gcc is so much better then why is mandelbrot in abstract (meaning moved complex into their own compilation unit so another person can work on that part) slower than ocaml with abstract as seperate module?
Alpounet has quit ["``Do what you think you can't do.'' -- E. Roosevelt"]
<mrvn>
razel: Normaly in functional languages you try not to use mutables. So to change a card you would create a new card with the new value. To remove a cars from the list you recursively descent into the list till you find the card to remove and then you build a new list on the way back up with the remainder of the list.
<mrvn>
You also normaly wouldn't mix data types. You wouldn't use greedy data structure (that's the name I learned for them). You write a polymorphic list and then use that with a card type to create your deck. But that might be against what the teacher specified.
Xteven has joined #ocaml
<Xteven>
hello, is there some function to print out a complex data structure in ocaml ? like Data::Dumper in perl and print_r in php ?
<hcarty>
Xteven: You would either need to write one for the data structure in question, or use one of the existing automatic printers around.
<mfp>
Xteven: type information is not kept at run time, so you can only get an approximate representation in general. See extlib's Std.dump for instance.
<Xteven>
approximate is good ennough
<Xteven>
thx
<mfp>
alternatively, there are several camlp4 extensions that generate pretty-printers from you given the type definition
<Xteven>
its a very complex type
<Xteven>
the reason why I want to print it, is because I don't knonw what it contains
<mfp>
no matter how complex it is; if you have access to the full type definition, you can use for instance sexplib to generate S-expression serializations, just by appending "with sexp" to the type definition