<CiscoKid>
Oh good, I just did that in vim to try to figure out what you were saying. :)
<simon->
hehe
<CiscoKid>
Isn't this the same thing as List.filter?
<simon->
ahh it might be. I am terrible at remembering. I just did it for the exercise though. know any good exercises?
<CiscoKid>
Oh, it's a fine exercise. :) One that seemed to be missing that I thought was interesting was List.iteri
<CiscoKid>
val iteri : (int -> 'a -> unit) -> 'a list -> unit
<simon->
what does that do?
Snark has quit [Nick collision from services.]
Boojum is now known as Snark
<CiscoKid>
Iterate a list and pass in both the value and the offset in the list.
<simon->
I like how one can generalize everything by using higher-order functinos.
<simon->
functions, rather
<CiscoKid>
It may be late, but I don't see how your grep calls f tl twice.
<simon->
first it calls it using "match f hd with" and then it calls it with "false -> grep f tl" or "true -> hd :: grep f tl"
<simon->
wait
<CiscoKid>
The only time f is called at all is in that match.
<simon->
I am silly now. you're right
<CiscoKid>
Heh, perhaps you did better than you thought. :)
<simon->
the problem I was thinking of is with "map" which I haven't made yet, I couldn't decide which one to make first.
<simon->
CiscoKid, which material have you been using to learn ocaml?
<CiscoKid>
Applications I needed to write, mostly. :)
<simon->
huh?
<simon->
that sounds recursive.
<CiscoKid>
Then it must be correct! :)
<CiscoKid>
I started with a python app that processed some logs, but took too long. Ported it to Eiffel, C, scheme (bigloo) and ocaml.
<simon->
which implementation did you like the most?
<CiscoKid>
The ocaml seemed to be the fastest and easiest to maintain, so I kept playing with different things.
<CiscoKid>
Definitely the ocaml. It was the fastest and most stable. I was using the bigloo apps for a while, but as soon as I tried to add a bit more complexity, I started getting segfaults.
<simon->
actually I'm thinking of processing some logs, but I might use regular expressions for it, and that will inevitably be slow for big logs.
<CiscoKid>
I'm not a big fan of regex. The first thing I wrote in ocaml and bigloo was a string library.
<CiscoKid>
In both cases, I got a 4x speed boost by not using regex, replacing them with just plain splits.
<simon->
aha. well, it's mostly because my current logs are in a very unoptimized format. I could rewrite them once
<CiscoKid>
I had some pretty complex stuff to deal with. One of my most valuable logs has a million or so different devices starting and stopping various transactions, but the log doesn't record the time. I have to match a stop with a previous start for the given device.
<simon->
ouch, no timestamps?
<simon->
actually my logs have HH:MM timestamps and I'd like UNIX timestamps.
<CiscoKid>
I have timestamps, just not durations in the logs. I have an event stop and have to match it to the most recent event start for the given transaction type for the given device.
<simon->
how often do you process these logs?
<CiscoKid>
I've got YYYMMDDThhmmss.ms for each record. It's readable and easy to parse.
<CiscoKid>
I do about two days worth every day from about twelve busy servers.
<CiscoKid>
It's for a report that's generated before business hours.
<simon->
I like unix timestamps because producing real timestamps from one should be fairly easy, and computing deltas is also easy (integer subtraction)
<simon->
does ocaml have an strftime library?
<CiscoKid>
I've got subseconds in my timestamp, so as long as they're floating point it'd be alright. People like to read these logs, though. I'd really prefer it. OCaml's a bit weak in date processing.
<CiscoKid>
It doesn't seem to have strftime or strptime.
<CiscoKid>
People have made libraries with them, though.
<CiscoKid>
It takes several cdb files and concatenates them into a single cdb.
<CiscoKid>
Almost the entire program is the following line: List.iter (Cdb.iter (Cdb.add destcdb)) srcs
<CiscoKid>
It takes a list of cdb filenames and an open cdb for writing, reads each key/value pair from the thing, and reindexes them into the new cdb.
<CiscoKid>
On my slow-ass dev box at work, I duplicated a ~350MB cdb in 1:14. cp duplicated it in 1:06.
<simon->
wow
<CiscoKid>
And the cp had the advantage of having the file be in cache. I ran the cdbcat cold.
<simon->
well, I'm not a big fan of "if then else" when "match with" is synonymous, and looks more 'correct', which is of course just one thing that makes it look less imperative, thus possibly harder to grasp.
<simon->
I don't know if it'll do me any good, but currently I am really "without a language"
<simon->
I do a lot of languages half-hearted
<simon->
currently sticking to perl and c. perl is just not efficient enough and c is too c-ish! (probably the typical scheme, heh)
<CiscoKid>
Heh. OCaml is just amazing performance-wise. It's also fairly pleasant to use. I've been writing more erlang lately, though.
<CiscoKid>
I avoid perl whenever possible.
<simon->
yeah well, I like how ocaml actually competes with c, yet I find it a lot more readable.
<simon->
well, perl/ruby/python/tcl. they're all the same.
<CiscoKid>
heh
<CiscoKid>
tcl is closer to sh than the rest. :)
<simon->
what I'm saying is that there's no point in arguing which of those is best, because they're all fairly slow.
<simon->
tcl is kind of fun. almost esoteric ;)
<CiscoKid>
It's not all about slow, though. We've recently replaced a C program with a python in a place with high performance requirements where we needed to add functionality we just couldn't add in the C program. Turns out the performance didn't make much of a difference there.
<CiscoKid>
erlang doesn't perform anywhere nearly as well as ocaml, but ocaml doesn't make it trivial to write a distributed application with high availability and simple cluster management.
<simon->
okay.
wordless has joined #ocaml
Hipo_ is now known as Hipo
wordless has left #ocaml []
<simon->
is there a hash table?
<CiscoKid>
Hashtbl. It's non-functional, though.
<simon->
actually I just need an array. is there one?
<Snark>
simon-: you can't because that would be a flaw
<CiscoKid>
I'm not sure why you think it'd never happen. There are empty arrays out there.
Demitar has joined #ocaml
<CiscoKid>
As a side, I've got two recommendations for this function: Swap your s and your l. More curry friendly is better. Secondly, you can replace the function with ``let join_strings String.concat'' (at least, if you swap the parameters for curry friendliness).
<CiscoKid>
er, I left a = out of there.
<simon->
CiscoKid, ah. well, yet again, this was just an exercise. I was sure the library had it. :P
<simon->
CiscoKid, but logically my hd::tl case tests the tail already. I get it though, was just wondering as it seemed trivial. :)
<simon->
ohh, if it's completely empty from the start! gotcha.
gim has joined #ocaml
<CiscoKid>
the ``function'' keyword is also handy there: let rec join_strings s = function