pattern has quit [orwell.freenode.net irc.freenode.net]
pattern has joined #ocaml
Etaoin has quit ["Client exiting"]
yangsx has quit [Read error: 110 (Connection timed out)]
Nutssh has quit ["Client exiting"]
Etaoin has joined #ocaml
bruce_ has joined #ocaml
arty has joined #ocaml
arty has left #ocaml []
bruce_ has left #ocaml []
cjohnson has quit [Read error: 104 (Connection reset by peer)]
Vincenz has quit ["Sleep, deep sleep"]
voltron has quit ["night"]
IorekByrnison has quit []
Nutssh has joined #ocaml
<async>
Nutssh: are you studying at rice?
<async>
one of my good HS friends does EE in rice
<Nutssh>
Hi. Yes.
giedi has joined #ocaml
Swynndla has joined #ocaml
giedi has quit ["Client Exiting"]
cmeme has quit [Connection reset by peer]
cmeme has joined #ocaml
cmeme has quit [Read error: 104 (Connection reset by peer)]
cmeme has joined #ocaml
cmeme has quit [Read error: 104 (Connection reset by peer)]
cmeme has joined #ocaml
Demitar has joined #ocaml
blueshoe has joined #ocaml
blueshoe has quit ["_"]
wazze has joined #ocaml
Swynndla has quit ["Leaving"]
Nutssh has quit ["Client exiting"]
mimosa has joined #ocaml
karryall has joined #ocaml
_JusSx_ has joined #ocaml
clausen has joined #ocaml
<clausen>
we are entertaining the idea of rewriting GNU Parted in ocaml
<clausen>
anyone tempted to convince us one way or the other?
<clausen>
motivation: it is getting hard to maintain in C
<clausen>
moreover, since bugs are more important for Parted than other programs
<clausen>
type safety is a bug plus
Hipo has quit [Read error: 60 (Operation timed out)]
Hipo has joined #ocaml
<karryall>
that's interesting
<karryall>
what do you want to rewrite exactly ?
<clausen>
the whole lot
<clausen>
it's in C
<karryall>
libparted or just the frontend ?
<clausen>
the former is more important
<clausen>
the frontend is only about 1000 lines of C
<clausen>
so it isn't very important
<clausen>
(it is easy to rewrite)
<karryall>
but how does libparted access the hd ?
<karryall>
isn't that very low-level ?
<clausen>
libc, and some ioctl stuff
<clausen>
low-level is a problem?
<clausen>
the "hard part" of parted is high level
<clausen>
although there are obviously some low-level OS-specific things
<karryall>
it can be
<karryall>
you'll have to write bits of C for the very low-level (ioctls)
<karryall>
but then you can write in ocaml on top of that
<clausen>
well, the low-level stuff is very clearly separated
<clausen>
(even in the C version)
<clausen>
we have libparted/linux.c and libparted/gnu.c
<clausen>
(the latter for GNU/Hurd)
<mellum>
I don't think it's a good idea. You'd need C bits anyway. Also you'd drag in Ocaml library stuff which is bad for space constraint environments.
<clausen>
mellum: the C bits would be quite small (< about 3%)
<mellum>
And you'll always have trouble with the 31-bit ints.
<clausen>
mellum: there are no 64-bit ints?
<karryall>
clausen: yes there are
<mellum>
clausen: there are, but they are clumsy to sue
<mellum>
use even
<clausen>
mellum: how clumsy?
<karryall>
not very clumsy
<clausen>
C is also very clumsy
<clausen>
we have PED_LE16_TO_CPU(...) macros everywhere
<clausen>
for filling in on-disk structs
<clausen>
this is a far more serious issue than ioctl crap
<clausen>
also, wrt libraries... how big are we talking?
<mellum>
clausen: well, you'd need the same in Ocaml, so where would be the gain?
<clausen>
mellum: the macros aren't the motivation for the rewrite
<karryall>
clausen: the runtime is around 150K
<clausen>
mellum: I'm just saying that if ocaml does it in a significantly worse way, it might not be worth a rewrite
<clausen>
karryall: that's fine :)
<clausen>
we require 2 boot disks (linux kernels are big nowadays!)
<clausen>
so, that will fit easily
<mimosa>
in ocaml you can concentrate on the program, I think partitions involve complicated data strucutres and ocaml is relly good for manipulating complicated structures
<clausen>
does ocaml compile code more/less space efficiently?
<clausen>
CPU run time is mostly irrelevant when you're waiting for the hard disk :)
<karryall>
there's a compiler switch like -Os
<clausen>
karryall: is it good?
<mellum>
I'd suppose rather less space efficient.
<clausen>
I guess it's a hard question to answer
<clausen>
since it depends on coding style, etc.
<karryall>
karryall: can't tell, never compared
<mellum>
It needs to shuffle in GC code, for example.
<clausen>
mellum: is the compiler smart at figuring out when it needs to GC?
<Banana>
?
<karryall>
clausen: it need GC all the time
<Banana>
the GC code is the same in all program.
<clausen>
well, if you inline functions, then you often know you don't need to GC
<clausen>
sure, but you need to call the GC functions ;)
<clausen>
those calls might be significant overhead
<karryall>
what calls ?
<Banana>
clausen: no the GC is very efficiant.
<karryall>
are we speaking about the same thing ?
<mellum>
Ocaml has a minor heap for object allocation. After each allocation, it checks whether it is full and triggers a minor GC then. That code (ca. 3 insns) is inlined.
<clausen>
I'm concerned about space-efficiency, not runtime
<clausen>
(as on, code space)
<clausen>
(not RAM usage)
<clausen>
*in
<mellum>
And for example every created Int64 is heap allocated.
<karryall>
like I said runtime, GC included is 150K
<clausen>
that's not very nice :/
<Banana>
clausen: yes but no matter what the gc code is attached to your programm.
<clausen>
Banana: I'm concerned about the per-function cost of GC management code
<clausen>
like, you have to call some "unref" function frequently?
<clausen>
(well, the gen'd code)
<karryall>
clausen: you shouldn't be concerned about that
<Banana>
yeap.
<Banana>
GC is smart and efficient.
<karryall>
the GC is not a reference counting GC
<clausen>
it is minimal code space?
<clausen>
ah, ok
<Banana>
clausen: plus you can tune its behavior with the Gc module in ocaml.
<clausen>
in any case, I suspect gzip would compress such ref/unref code well
<Banana>
there is no ref unref code.
<Banana>
every boxed value in caml (tuple, list....) have a 1 bit tag sayin that they are boxed or not.
<Banana>
then the gc iterate on the adress of boxed bloc and free those which are not reachable anymore.
<Banana>
(basicaly).
<clausen>
ah, ok
<Banana>
in fact there are 2 pass. a minor pass for short life values which does a mark and swepp (it is fast but leads to fragmentation of the heap).
<clausen>
it was quite amusing, that practically everyone on the bug-parted list were closet functional programmers, hehe
<Banana>
and a second pass which is the major pass which does a stop and copy (for longer life value).
<Banana>
(and which triggers a recompaction of the heap).
<karryall>
Banana: no the major is mark & sweep, the minor is stop & copy
<Banana>
ah ?
<karryall>
yes
<Banana>
yeah ...
<Banana>
you are right.
<Banana>
incremental Mark and sweep for Major Cycle.
<clausen>
karryall: I have played with haskell and mercury
<clausen>
karryall: two others have played with ocaml
<clausen>
my only exposure to ocaml has been reading "Purely Functional Data Structures" (by Okasaki)
<Banana>
clausen: i don't think it realy shrink the adress space but compact what you use so that you have more space to allocate bigger blocs.
<Banana>
(I'm not an expert on compaction though ~_~).
<clausen>
it would be nice if it did
* clausen
thinks mmap() and madvise() should be used more aggressively in userland
<karryall>
clausen: heap compaction happens very rarily I think
<mellum>
Indeed. I once had a bug in a program triggered by heap compation which occurred only after about 5h running time :)
<karryall>
btw, Okasaki's book uses SML, not OCaml :)
<clausen>
karryall: oh
<drWorm>
is there any data structure that can map arbitrary type values to arbitrary type values and have O(1) lookup time? i know there's hashtables, but they are O(log n) i suppose? and there's tables, but they can only map ints to something, right?
<clausen>
drWorm: that seems a bit hopeful!
<drWorm>
oh, i know :)
<karryall>
No hashtables are O(1)
<drWorm>
but ocaml is so cool, maybe it even breaks real scientific ground :P
<Banana>
drWorm: hashtables (the Hashtbl modules) are array of list. these are mutable structures with *mean* access time O(1).
<drWorm>
oh, cool
<Banana>
(i meant they are not like the Map module with BBT wich has access time O(log n)).
<drWorm>
i see, thanks -- is this described anywhere online? certainly not in the library reference of the manual
<Banana>
?
<Banana>
what is not described ?
<drWorm>
i mean the complexities
<Banana>
ha.
<Banana>
when you create a hashtable you have to give an initial size of table. if you give a prime number which is close to the amount of data you store, then it improves performance a bit.
<drWorm>
heh, nice trick
<clausen>
actually, good hash functions don't use primes
<Banana>
yeah but prime number size for the array reduce hash clashes and avoid some resizing.
<Banana>
(or so was I told).
<clausen>
it depends on your hashing function
<clausen>
good hashing functions don't need primes
<clausen>
and primes are bad for memory allocation
<clausen>
(not in nice power of 2 chunks)
<Banana>
yeah but it works for ocaml's standard hashing function.
<Banana>
if you have to many hash conflict then the depth of your hash table will grow and that will lead to a flatten operation which involves resize of the table and copy of elements...
<clausen>
sure... if you have a crap hash function
<clausen>
(i.e. primes will only improve the situation if you have a crap hash)
<Banana>
yes but good hash function take more time to compute.
<mellum>
It's worth it, though.
<clausen>
I doubt it
<clausen>
the crap ones usually involve divisions / remainders
<clausen>
so they are slow anyway
<Banana>
well ocaml basic function uses prime number so...
<clausen>
if it does division, you can do a lot better by bit-bashing
<Banana>
i don't know if it uses division directly.
<Banana>
it seems to be a cumulative sum of acc = acc*233+(hash of the bloc).
<Banana>
and it iterate througout a bloc traversal of the structure you give.
<Banana>
hum..
<Banana>
lunch time.
* Banana
&
cjohnson has joined #ocaml
clausen has quit ["Client exiting"]
owll has joined #ocaml
owll has left #ocaml []
Vincenz has joined #ocaml
Demitar has quit [Remote closed the connection]
Demitar has joined #ocaml
d2004xx has left #ocaml []
_JusSx_ has quit ["[BX] Tony the Tiger uses BitchX. Its Grrrrrrrrreat!"]
mw has left #ocaml []
mattam has quit [Read error: 110 (Connection timed out)]
cmeme has quit [Connection reset by peer]
cmeme has joined #ocaml
cjohnson has quit ["Drawn beyond the lines of reason"]
Etaoin has quit [Remote closed the connection]
cjohnson has joined #ocaml
Etaoin has joined #ocaml
kiff has quit ["leaving"]
pattern has quit [Read error: 110 (Connection timed out)]
pattern has joined #ocaml
_JusSx_ has joined #ocaml
cjohnson has quit [Client Quit]
palomer has joined #ocaml
<palomer>
when is ocaml going to have operator overloading, so it can be gone with *. ?
<liralen>
er, never?
<liralen>
It would have to extend its typesystem with typeclasses, anyway, to get nice overloading.
<palomer>
yes, why doesn't it?
<palomer>
instead of types, why not have the functions manipulate objects. for example: let f x = x + x;;
<liralen>
because it has a different type system. Why don't you ask the creators?
<palomer>
that would mean: f takes an object with operation +, and applies it to itself
<liralen>
palomer - that would change ocaml from a statically-typed to a dynamically-typed language, to an extent.
<liralen>
palomer - and that would create ad-hoc overloading, which sucks.
<palomer>
it would all be done during compile time
cjohnson has joined #ocaml
pattern has quit [Read error: 110 (Connection timed out)]
pattern has joined #ocaml
Iorek has joined #ocaml
<Banana>
and to add something, overloading and polymorphism make type inference impossible without anotation from the programmer.
<Banana>
or so I heard.
<Iorek>
some OO features interact poorly with type inference
<Banana>
yes.
Defcon7 has quit [Read error: 110 (Connection timed out)]
<Banana>
I discussed it with one of the cristal team and he explained me that if you had some features to the type system (like algebraic guarded type) then typecheking has a non elementary complexity.
<Iorek>
I'd imagine
<Banana>
(that is you cannot major it by a tower of exponential : 2^(2^(2^(2^...) n times.
<Banana>
impossible to use in practice.
<Iorek>
in many ways, OCaml is kind of an experimental language... it includes many features not before tested in "production" language... so there are some rough corners
Defcon7 has joined #ocaml
<Banana>
and some features have been added just recently (like recursive modules).
<Iorek>
labels
<Banana>
labels have been around since 3.00 no ?
<Banana>
but according to its designer himself there are some design issues in the compiler that make some features hard (impossible) to implement. They did not thought ocaml would be so successful ;)
<Iorek>
yes, since version 3... but it shows the language is always changing... like python
<Banana>
yes.
pattern has quit [Read error: 110 (Connection timed out)]
pattern has joined #ocaml
<Smerdyakov>
Cool. You can make Hashtbl.something overflow the stack somehow... and I'm no sure how I did it. :\
<Smerdyakov>
The stack backtrace has this over and over:
<Smerdyakov>
Called from module Hashtbl, character 3583
<Banana>
not Hashtbl.{iter,fold} with a function of your own ?
<Smerdyakov>
How can I find out more information?
<Smerdyakov>
I don't think I call either of those.
<Banana>
arf
<Banana>
that's awkward then.
<Smerdyakov>
Hm.. raised from a C function, with nothing but that same Hashtbl location on the stack.
<Banana>
what do you use as key for your hashtbl ?
<Smerdyakov>
First, I'm using a bunch of libraries that may call Hashtbl themselves; I'm not sure. I think _I_ only use it with string keys.
<Smerdyakov>
Buuuttt... some code I based my code off in fact calls it on a custom recursive data type.
<Smerdyakov>
Could that be the problem?
<Banana>
yes.
<Banana>
if this structure is used as a key... it might be a problem.
<Banana>
because Hashtbl uses structural equality to test if 2 keys are equal.
<Smerdyakov>
OK
<Smerdyakov>
Trying without that
<Banana>
I think = can loop if the data compared are recursives.
<Banana>
yep it loops.
<Smerdyakov>
I wish OCaml didn't have this special hashing stuff for all types. It just opens too many possibilities for problems. :(
<Smerdyakov>
Well, I stopped using that, but the overflow still occurred.
<Banana>
i think i have an idea.
<Banana>
character 3583 in module Hashtbl is the find_all function.
<Smerdyakov>
I am checking one hypothesis now, which might be causing the problem if a library I use is using Hashtbl.
<Smerdyakov>
Nope, that wasn't it. :(
<Banana>
more precisely a non-tail recursive function which iterate a list.
<Smerdyakov>
Which list is it?
<Banana>
Hashtbls are array of lists.
<Banana>
I mean Hashtbl.t is an array of list.
<Smerdyakov>
Ah.
<Smerdyakov>
I see a call to find_all in a library I am using.
<Banana>
i juste tried to run this function let rec f = function
<Banana>
0 -> [0] | n -> n :: (f (n-1));;
<Banana>
which stack overflow if n > 60000.
<Banana>
so if you put many many data in your hashtable this can happen...
<Smerdyakov>
Ah shucks.
<Banana>
(but it can be something else and the debugger is skrewed up... i don't use it).
<Banana>
i mean the debugger could be skrewed up and as I don't use it i can't say.
<Smerdyakov>
But this seems most likely.
<Iorek>
see ya ppl
<Smerdyakov>
I think I will know soon if that is it. :)
Iorek has quit []
<Smerdyakov>
(Running with new debug prints)
<Banana>
;)
<Banana>
I use the same debugger :)
<Banana>
good old printf between function calls :D
<Smerdyakov>
The hashtable has one entry for every line of an assembly program.
<Smerdyakov>
I bet it is overflowing because of that.
<Banana>
he he.
<Banana>
I can go further i think.
<Riastradh>
Yaagh. Why is it like that?
<Banana>
are there many similar lines ?
<Banana>
like NOP;
<Banana>
or something like that.
<Smerdyakov>
It's long enough that lots of lines will be the same.
<Smerdyakov>
But there is only a small set of possible keys.
<Banana>
then all the data you associate with identical lines will be stored in the same list...
<Smerdyakov>
And the part with one entry per line all have the same key.
<Banana>
maye be if you use (line,linenumber) instead of line for keys, you'll have a nicer distribution in the Hashtable.
<Banana>
(that's pain in the ass I know but).
<Smerdyakov>
No, the keys are all a constant string.
<Smerdyakov>
I'm using a general system for code annotations.
<Smerdyakov>
I have one annotation per line of assembly code, with the same key for each.
<gl>
yo
<Banana>
oy
<gl>
how orkut ppl are? :)
<Banana>
^_^
<Banana>
Smerdyakov: can't you use Map of maps instead of Hashtbl ?
<Smerdyakov>
I may be able to change the library that I'm using, but I'd rather not.
<Banana>
ha you are not using hashtables directly.
<Banana>
how many lines has the assembly prog you are testing on ?
<Smerdyakov>
Well, only 1342 entries for a file where it breaks, I think.
<Banana>
and how many data for each entry ?
Swynn_wk has joined #ocaml
<Smerdyakov>
Oh, 1342 is the total number of name-value pairs.
<Smerdyakov>
I think all but one have the same key.
<Smerdyakov>
I get 1022 stack traceback lines.
<Smerdyakov>
Which makes sense.
<Banana>
yeah but I don't see why it fails now that I think of it :|
<Smerdyakov>
I don't know. I haven't even found the exact call where this happens yet.
<Banana>
even if your values are big, 1342 elements in a list is nothing.
palomer has quit [Remote closed the connection]
<Smerdyakov>
Well, I'm trying to find the exact call with binary search in code now. ;)
<Banana>
yeah.
<Banana>
Who would think you're debugging a caml programme.
<Banana>
(sounds more like somthing in C to me ;) )
<Smerdyakov>
Well, the exception is raised in a C function, so that partly explains it. :)
<Banana>
yark.
HackerMaster has joined #ocaml
* Smerdyakov
laughs at HackerMaster's nick. :)
<HackerMaster>
what?
<Smerdyakov>
Hm. It is looking likely that the overflow happens in a library function that normalizes a type.
<Smerdyakov>
HackerMaster, you just have a funny handle!
<HackerMaster>
ok
<Banana>
Smerdyakov: normalize a type ?
<Smerdyakov>
Nope, that wasn't it!
<Smerdyakov>
It's a library for handling Typed Assembly Language.
<Banana>
ha I thought an Ocaml type.
<Banana>
(felt strange to have such a function...)
<Smerdyakov>
It wouldn't be, really, since OCaml has type synonyms.
<Banana>
yes but a function can't do that.
<Banana>
but don't worry i'm in my own world.
<Smerdyakov>
It can at the meta level, i.e., in the OCaml compiler.
<Banana>
yeah.
<HackerMaster>
so
<HackerMaster>
who here has heard of the mafia clan?
<teratorn>
_JusSx_: but why don't you go ahead and tell me why my nick is awful.
<_JusSx_>
tera = monster
<Banana>
hu ? isn't it going a bit off-topic ?
<_JusSx_>
Banana : lol
<teratorn>
Banana: stupid, at least.
_JusSx_ is now known as Kiwi
Kiwi is now known as apple
<teratorn>
gl: ?
<Banana>
yeah I like those to.
<Banana>
too.
<karryall>
for me, tera = 10^12
<apple>
lol
<gl>
teratorn, yes ?
<apple>
for me apple is macintosh logo
<teratorn>
gl: would you like to kick this idiot?
<pattern>
terra = earth
<Banana>
a teratorn is prehistoric bird no ?
<Banana>
hello pattern.
<teratorn>
Banana: indeed
<pattern>
hey, banana
<apple>
i saw a porn movie where i girl put a banana in her ass
<Banana>
pattern: any fun exercices ?
<gl>
apple very interesting.
<apple>
hey gl you forgot open
<pattern>
banana, i actually found something that really confuses me that i will be asking about here at some point... but i'm going to have to leave soon, so it'll have to wait
<Banana>
gl: I advert my eyes while you lay thee wrath upon this fool.(In thy merci).
<Banana>
mercy.
<Banana>
he he pattern tricky problem always welcome ^_^.
apple was kicked from #ocaml by gl [stop, *please*]
<teratorn>
gl: you are too nice! :)
<Banana>
that's how he is.
<gl>
I thought #ocaml was a cool chan, with cool people, but ...
<pattern>
it usually is
<gl>
Yeah, usually
<pattern>
maybe they're from efnet
<pattern>
:)
<Smerdyakov>
gl, wow, you are the only one to have op privs here except for anyone at opcode.org??
<gl>
yes
<gl>
I'll change access
<Smerdyakov>
Banana, I got it to work! It must have been a problem in a library I was using, but I managed to do something a different way to avoid calling the library. Thanks for all the help!! :D
mattam has joined #ocaml
<Banana>
he he.
<Banana>
what did you use instead of the library ?
<Banana>
(by the way, the best ocaml debuger is still the Printf module ^_^).
<Smerdyakov>
I was calling a theorem prover to generate a proof that was easy to generate manually.
<Banana>
hummm. sounds fun.
* Smerdyakov
runs the regression tester and awaits the results. O_o
<gl>
banana, your nick isn't registered.
<gl>
chan access is modified
<Banana>
no it isn't.
<Banana>
NickServ ?
<gl>
yes
<gl>
/msg nickserv help register
<Banana>
done.
<Smerdyakov>
Banana, now Hashtbl is looping at a different character number!! D;
<Smerdyakov>
(for a different input)
<drWorm>
wonder why they didn't just call it Hashtable -- saving two characters, big deal :)
<Banana>
but still overflow ?
<Smerdyakov>
Yes
<Banana>
rhalala.
<karryall>
Smerdyakov: are you using weird values, like cyclic values or stuff like that ?
<Smerdyakov>
I don't think it's a result of any Hashtbl calls I am making. I think it's in libraries.
keltus has joined #ocaml
keltus has quit ["Leaving"]
Hipo has quit ["leaving"]
gim has quit [orwell.freenode.net irc.freenode.net]
gim has joined #ocaml
<Smerdyakov>
Hm. It looks like I've gradually causing more and more hypotheses to be active in the theorem prover, and eventually Hashtbl.add overflows for the table that stores them. :D
<Banana>
hi hi.
<karryall>
you need to have an astronomical number of entries to cause that
<Smerdyakov>
And I did!
<Smerdyakov>
It was about 400 times the number of labels in the input assembly program. :)
<Smerdyakov>
Actually, it's number of jumps of all kinds, I think.
<Banana>
yark.
<Smerdyakov>
But I've fixed it now. :)
<Banana>
used another data structure or reduced the number of entries ?
<Smerdyakov>
The growing number of entries was unintentional. I was forgetting to retract old assumptions.
<Banana>
logical memory leak ;)
<Smerdyakov>
Yeah, and it took HUGE examples to bring it out, like this MAMMOTH 100 line Scheme program. ;)
<Smerdyakov>
Which comes out to around 3000 lines of assembly.
<Banana>
that's why we need certified compilers.
<Smerdyakov>
Woo! Regression tester returned no errors!
<Smerdyakov>
Oh, but I _am_ working with certified compilers. :)
<Smerdyakov>
Certifying Scheme->TAL compiler.
<Banana>
hi hi.
<Banana>
great.
<Banana>
I might** have to work on a certified optimising compiler from a subset of C to powerPC asm.
<Smerdyakov>
That compiler isn't what I'm working on, though. I'm using an old one from 1998. It's the general architecture for checking assembly programs from arbitrary compilers that we are working on now.
<Banana>
have you got any pointers on that ?
<Banana>
this might be my future.
<Banana>
:)
<Smerdyakov>
Sort of. There are some oldish papers from the group from before I joined that describe the precursors of this.
<gl>
even "naissance de la phisolophie a l'epoque de la tragedie grecque" :)
<Banana>
hé ben !!!
<Smerdyakov>
gl, "the birth of philosophy and the time of the Greek tragedy"?
<Banana>
yes.
<Smerdyakov>
I think English translations use "The Birth of Tragedy," or something like that.
<mattam>
Zarathoustra is pretty poetic but i guess the rest isn't, am i wrong ?
<Smerdyakov>
mattam, I think you are right!
<Smerdyakov>
Hey, I don't supposed you guys are looking for Internet hosting..? ;)
<gl>
Zarathustra isn't simply poetic, i think the reading of it and milgram's "obedience to authority" is the best protection against indoctrination
mimosa has quit ["J'ai fini."]
<gim>
mattam: great ledit have been added :)
<mattam>
hehe
<mattam>
gl: The study ? seems interesting
<drWorm>
i have a string list and want to make a string which is all the elements comma seperated (["a"; "b"; "c";] -> "a, b, c"), what's the best way? List.iter? List.fold_left?
<Banana>
drWorm: thank god you are here.
<Banana>
;)
<drWorm>
that bad? :>
<Banana>
no no.
<Banana>
I just don't understand what they are talkinga about :D
<drWorm>
ah, yeah, i'm just a simple country boy i guess :)
<Banana>
drWorm: a fold in this case.
<Banana>
but you should remove the first elem of the list and catenate it after.
<Banana>
if not you will have ", a, b, c"
<drWorm>
gah, it's the same problem basically, i wrote a naiive recursive function to do it but ended up with "a, b, c, ", which is what i wanted to avoid :)
<Smerdyakov>
drWorm, actually, you want to use String.concat. :D
<Banana>
don't tell him.
<Banana>
rahhh.
<drWorm>
interesting. :)
<Smerdyakov>
Well, I think it's probably impossible to get good speed without using that, right?
<Smerdyakov>
One ^ at a time leads to quadratic total time.
<Banana>
little scarab grow stronger by reimplementing all by it self.
<Banana>
?
<Smerdyakov>
I hope it's impossible to reimplement!
<drWorm>
"String.concat sep sl concatenates the list of strings sl, inserting the separator string sep between each." -- that's exactly what i want!
<Smerdyakov>
I would hope String.concat does this:
<Smerdyakov>
Add up the lengths of all the strings you pass, add in appropriate separator length, etc..
<Smerdyakov>
Allocate a single chunk of memory of that size.
<Smerdyakov>
Write the data into it in a single pass.
<Smerdyakov>
Linear time in input sizes.
<Smerdyakov>
Maybe there is another way to get that in OCaml, since strings are mutable.
<Smerdyakov>
But String.concat is the only way you could get linear time concatenation in SML.
<Banana>
Smerdyakov: that's what it does.
<liralen>
let sidle x l = match l with [x] -> l | (h::t) -> h::x::sidle x t;; String.concat (sidle ", " ["a";"b";"c"]) -- without matching [] and without testing, since this machine doesn't have an O'Caml yet.
<Smerdyakov>
liralen, String.concat is already all that's needed.
<Smerdyakov>
String.concat ", " ["a";"b";"c"]
<liralen>
oh, good =)
<mattam>
Smerdyakov: SML has no Buffer module ?
<Smerdyakov>
mattam, well, nothing with that name. There's probably a way to do it with arrays, since in SML type string = char vector, essentially.
<Smerdyakov>
(Where vector is immutable array)
<Smerdyakov>
Yeah, you can do it with Word8Array.vector. :)