gildor changed the topic of #ocaml to: Discussions about the OCaml programming language | http://caml.inria.fr/ | OCaml 3.12.1 http://bit.ly/nNVIVH
Tobu has quit [Ping timeout: 260 seconds]
abdallah has joined #ocaml
<abdallah> I have a signature like
<abdallah> S = sig
<abdallah> type param
<abdallah> val f : param -> int -> bool
<abdallah> end
<abdallah> and a functor like
<abdallah> F (M : S) =
<abdallah> struct
<abdallah> type param0 = ...
<abdallah> let f0 p0 i = ...
<abdallah> type param = (M.param * param0)
<abdallah> let f (pM, p0) i = (M.f pM i) || (f0 p0 i)
<abdallah> end
<abdallah> this allows me to combine a base operators (M) with a higher-level one represented by F. Each has its own proper parameter and the functor application allows to chain the parameters into nested tuples.
<abdallah> For instance we have F(F(F(M))).param = (param0 * (param0 * (param0 * M.param))). This looks nice and general but in practice param0 is unit or something simple and the parameters are often shared (I have different Fs). Is there a better desing pattern for this kind of tasks?
<_habnabit> abdallah, in the future, please use a pastebin for code
<abdallah> ok sorry
<abdallah> _habnabit: would this be better:
<abdallah> "I have a signature and a functor like http://pastebin.com/mpMAN7EH
<abdallah> this allows me to combine a base operators (M) with a higher-level one represented by F. Each has its own proper parameter and the functor application allows to chain the parameters into nested tuples.
<abdallah> For instance we have F(F(F(M))).param = (param0 * (param0 * (param0 * M.param))). This looks nice and general but in practice param0 is unit or something simple and the parameters are often shared (I have different Fs). Is there a better desing pattern for this kind of tasks?"
<abdallah> ?
<_habnabit> sure
<abdallah> kk
<abdallah> why?
<_habnabit> it's much easier to look at and refer to
<abdallah> ok, I see
iago has joined #ocaml
Tobu has joined #ocaml
hypnocat has joined #ocaml
Tobu has quit [Ping timeout: 272 seconds]
<hypnocat> what's the idiomatic way to do something like: if foo then 1 elseif bar then 2 else 3
<hypnocat> do you have to use a bunch of nested if statements?
<hypnocat> or is there a better way?
<_habnabit> hypnocat, you might be able to do a match, but if/else if is fine
<hypnocat> alright, thanks
<thizanne> hypnocat: the behavior of if statement allows you to use else if as a « elseif » keyword, as stated hypnocat
<thizanne> therefore « nested » if statements behave as if they were not nested
<hypnocat> ah.. right.. of course :)
<hypnocat> how can i join two lists together?
<_habnabit> @
<hypnocat> thank you
Tobu has joined #ocaml
NihilistDandy has joined #ocaml
Juzor is now known as JuzorBNC
destrius has joined #ocaml
iago has quit [Quit: Leaving]
lihaitao has joined #ocaml
Tobu has quit [Ping timeout: 260 seconds]
emmanuelux has quit [Remote host closed the connection]
Tobu has joined #ocaml
NihilistDandy has quit []
abdallah has quit [Quit: Ex-Chat]
mjonsson has quit [Quit: Leaving]
andreypopp has joined #ocaml
foocraft has quit [Ping timeout: 245 seconds]
foocraft has joined #ocaml
ben_m has quit [Quit: Leaving]
Tobu has quit [Ping timeout: 260 seconds]
Tobu has joined #ocaml
tufisi has joined #ocaml
hto has quit [Read error: Connection reset by peer]
hto has joined #ocaml
Tobu has quit [Ping timeout: 260 seconds]
Tobu has joined #ocaml
Submarine has joined #ocaml
Submarine has quit [Changing host]
Submarine has joined #ocaml
hto has quit [Read error: Connection reset by peer]
hto has joined #ocaml
hto has quit [Read error: Connection reset by peer]
tlockney has quit [Quit: ZNC - http://znc.sourceforge.net]
andreypopp has quit [Quit: Computer has gone to sleep.]
ftrvxmtrx has quit [Quit: Leaving]
Submarine has quit [Ping timeout: 248 seconds]
Cyanure has joined #ocaml
ftrvxmtrx has joined #ocaml
munga has joined #ocaml
Tobu has quit [Ping timeout: 272 seconds]
ggherdov has quit [Remote host closed the connection]
hto has joined #ocaml
Tobu has joined #ocaml
Cyanure has quit [Remote host closed the connection]
Submarine has joined #ocaml
Submarine has quit [Changing host]
Submarine has joined #ocaml
Submarine has quit [Remote host closed the connection]
djcoin has joined #ocaml
silver has joined #ocaml
emmanuelux has joined #ocaml
rby has quit [Remote host closed the connection]
rby has joined #ocaml
Cyanure has joined #ocaml
emmanuelux has quit [Read error: Operation timed out]
silver_ has joined #ocaml
silver__ has joined #ocaml
eikke has joined #ocaml
bfgun has joined #ocaml
beckerb has joined #ocaml
beckerb has quit [Client Quit]
bfgun has quit [Quit: Leaving]
bfgun has joined #ocaml
munga has quit [Quit: Ex-Chat]
munga has joined #ocaml
albacker has joined #ocaml
albacker has quit [Changing host]
albacker has joined #ocaml
avsm has quit [Quit: Leaving.]
bigfg has joined #ocaml
eikke has quit [Ping timeout: 240 seconds]
bfgun has quit [Ping timeout: 245 seconds]
munga has quit [Ping timeout: 265 seconds]
avsm has joined #ocaml
avsm has quit [Quit: Leaving.]
thomasga has joined #ocaml
silver has quit [Remote host closed the connection]
silver_ has quit [Remote host closed the connection]
silver__ has quit [Remote host closed the connection]
silver has joined #ocaml
ulfdoz_ has joined #ocaml
ulfdoz has quit [Read error: Operation timed out]
ulfdoz_ is now known as ulfdoz
avsm has joined #ocaml
albacker has quit [Ping timeout: 248 seconds]
lihaitao has quit [Ping timeout: 245 seconds]
silver has quit [Remote host closed the connection]
destrius has quit [Quit: Leaving.]
silver has joined #ocaml
emmanuelux has joined #ocaml
_andre has joined #ocaml
Tobu has quit [Ping timeout: 260 seconds]
bitbckt has quit [Ping timeout: 245 seconds]
shachaf has quit [Ping timeout: 245 seconds]
d3z has quit [Ping timeout: 276 seconds]
bitbckt has joined #ocaml
bitbckt has quit [Ping timeout: 272 seconds]
bitbckt has joined #ocaml
shachaf has joined #ocaml
d3z has joined #ocaml
Tobu has joined #ocaml
Lor has quit [Excess Flood]
Lor has joined #ocaml
emmanuelux has quit [Ping timeout: 272 seconds]
albacker has joined #ocaml
albacker has quit [Changing host]
albacker has joined #ocaml
albacker has quit [Ping timeout: 245 seconds]
eikke has joined #ocaml
ankit9 has joined #ocaml
<Lor> Gaahh, the string limit on 32-bit, gaahh...
<djcoin> GaaaaH
<djcoin> Sorry could not resist :)
<Ptival> sad kitten
<djcoin> BraaaIiin
<Lor> Hm, and lwt's output_value is still based on a temporary string buffer.
<Lor> If worst comes to worst, I may have to reimplement it.
<pippijn> the string limit
<pippijn> where does it come from?
<Ptival> pippijn: the header for blocks has 22 bits for size
<pippijn> ah
<Ptival> two bits for the GC, 8 for the tag, the rest for the size
<thelema> Lor: why do you need to output such a large amount of data?
<Lor> Err, because there's lots of data I need to move from one machine to the other.
<thelema> in a single output_value call?
<Lor> Yeah.
<Lor> Worse, I may have some atomic custom blocks whose serialization _alone_ won't fit into a string on 32-bit.
<Lor> I may end up kludging by writing everything into a temporary file or something.
<thelema> needs to be atomic?
<Lor> Probably not, but that's the way it is currently (not my code), and I don't want to change those parts.
<thelema> I suggest you write a custom serializer that does output_string in blocks
<Lor> As I said, I may end up reimplementing Lwt_io.output_value.
<thelema> yup.
<Lor> But first I have to verify if I really really really have to support 32-bit.
<Lor> OTOH, trying to get everything working in 64-bit in windows is likely to present challenges, too...
<thelema> Lor: not too bad once you have all the needed cygwin/msvc tools installed and setup for ocaml
<Lor> Yeah, I got everything working on 32-bit (finally).
<Lor> 64-bit is to my understanding a bit less supported, so there may be additional pitfalls. Dunno.
<pippijn> 64 bit windows or in general
<pippijn> ?
<Lor> windows
<pippijn> ah
<pippijn> by the way, why isn't there an optimiser for lambda terms?
<thelema> 64-bit windows is supported, just that cygwin tries to provide a 32-bit compiler by default, so setting up the build system is tricky
<pippijn> the byte code could benefit from that
<Lor> Why oh why doesn't ocaml support custom channels?
<Lor> thelema, on the other hand, flexlink defaults to 64-bit linker.
<thelema> Lor: Batteries
<Lor> thelema, that doesn't help much since the Marshal functions don't use batteries.
<thelema> lor? Batteries provides Marshal.to_channel that marshals to a batteries channel
<Lor> At least the version I'm looking at does that by first marshalling to a string.
<thelema> ok, fair enough.
<thelema> this doesn't solve your problem.
<Lor> I'm inclined to use a temporary file.
<thelema> If you come up with a better solution, I'd be happy to include it in batteries
<thelema> The temp file solution would not be good for the common case, so that'd have to get its own name.
<thelema> (function name)
<Lor> If I reimplement it, I'm likely to do it using lwt.
<Lor> Since the problem with lwt's output_value even now is that it requires temporary storage for the entire marshalled value instead of streaming it directly to the output channel.
<thelema> One alternative would be Marshal.to_enum, that would produce an enumeration of strings
<Lor> Yes.
<Lor> Funnily enough, the marshal module internally actually allocates a bunch of strings.
<thelema> but the internals of marshal would have to be hooked, as the existing marshal interface doesn't provide a way to do this
<Lor> They just aren't exposed.
<Lor> I was thinking of reimplementing marshal directly in ocaml, using Obj.
<Lor> That still wouldn't solve custom blocks whose marshalling requires more space than fits in a string.
<thelema> That would be interesting. I assume you've seen the extlib dump code, right?
<Lor> I know BatStd.dump.
<Lor> Actually I just modified it a bit for my purposes.
<thelema> that's the one. (It comes from extlib)
<thelema> if your modifications are useful, please share.
<Lor> This is mostly for debugging purposes: I'm making it dump out information about the binary marshalling of custom blocks.
<thelema> If you were implementing marshal directly in ocaml, you can get the length of the block ... hmm, isn't it all blocks that can't be > 22-bit length in 32-bit ocaml? or do custom blocks have a different representation?
<Lor> Custom blocks have custom marshallers defined in C code.
<thelema> ah, yes.
<Lor> The custom blocks may contain pointers to C data that are inaccessible from ocaml.
<thelema> caml_serialize_block_4(large number)?
<thelema> anyway, gotta go. Good luck
ftrvxmtrx has quit [Quit: Leaving]
cyphase has quit [Ping timeout: 245 seconds]
Tobu has quit [Ping timeout: 272 seconds]
cyphase has joined #ocaml
iago has joined #ocaml
albacker has joined #ocaml
albacker has quit [Changing host]
albacker has joined #ocaml
smondet has joined #ocaml
tomprince has quit [Ping timeout: 272 seconds]
fraggle_laptop has joined #ocaml
skchrko has joined #ocaml
lihaitao has joined #ocaml
Tobu has joined #ocaml
hypnocat has quit [Quit: ZNC - http://znc.sourceforge.net]
<hcarty> diml: Is the effect of Lwt.cancel defined for processes spawned with the Lwt_process module?
<diml> hcarty: you mean for pread*, pwrite* and pmap* ?
Tobu has quit [Ping timeout: 260 seconds]
tlockney has joined #ocaml
<avsm> Lor: I noticed there is a caml_output_value_to_block defined in caml/intext.h
<avsm> which I use to go into an mmaped area
<avsm> seems to be the least-copying way of marshalling out
<Lor> If you want to output to a file, sure.
<hcarty> diml: Lwt_process.(with_process_full, exec) for example
<Lor> But then you could as well use Marshal.to_channel
<avsm> Lor: I'm going to shared memory chunks
<avsm> via an shm_open
<Lor> That's a reasonable way to do it when you want to communicate with another process on the same machine.
<Lor> That's not my situation.
<avsm> what are you trying to do? multi-host?
<Lor> Yes.
<diml> hcarty: there is nothing special, if the function passed to with_process_* fails, the process is "closed" (= opened pipes are closed)
<avsm> Lor: what's wrong with caml_output_value_to_malloc then, and passing directly to Lwt_bytes.send
<avsm> this is how I'm doing it in the UNIX version of our parallelisation framework, but I haven't finished perf testing it yet
<Lor> avsm, nothing really (except for the oversized duplicated buffer), but it requires writing a C module.
<avsm> oh yeah, can't escape that
<Lor> This is certainly a solvable problem.
<avsm> i do wish I could find out how big the value will be
<hcarty> diml: Ok. As a simple test I tried to run "sleep 50" in a thread, canceled the thread and quit the toplevel. The sleep process continued to run.
<Lor> I just want to solve it with minimal effort. :)
<avsm> indeed, same here
<Lor> I think the temporary file would be minimal effort.
<hcarty> diml: Is the proper work-around for that "don't use Lwt.cancel"?
<avsm> problem is that you can't use malloc() when going to shared memory of course. caml_output_value_with_custom_allocator, while a mouthful, would be quite useful :)
<Lor> Custom channels would be useful.
<diml> hcarty: you can always catch Lwt.Canceled and kill the process
* avsm gave up on channels a while back. the interaction of fork, threads, signals and flushing was too painful to debug
<hcarty> diml: Of course, that makes sense. Thank you!
avsm has quit [Ping timeout: 244 seconds]
<adrien> aaaaavvvvvvvssssssssmmmmmm!!!
Cyanure has quit [Remote host closed the connection]
lihaitao is now known as lht
tufisi has quit [Ping timeout: 246 seconds]
cixaxa has joined #ocaml
cixaxa has quit [Ping timeout: 246 seconds]
albacker has quit [Ping timeout: 252 seconds]
avsm has joined #ocaml
tufisi has joined #ocaml
ankit9 has quit [Ping timeout: 252 seconds]
Submarine has joined #ocaml
Submarine has quit [Changing host]
Submarine has joined #ocaml
ankit9 has joined #ocaml
albacker has joined #ocaml
albacker has quit [Changing host]
albacker has joined #ocaml
eikke has quit [Ping timeout: 260 seconds]
JuzorBNC is now known as Juzor
ankit9 has quit [Ping timeout: 246 seconds]
avsm has quit [Quit: Leaving.]
silver has quit [Remote host closed the connection]
<Lor> Errrr... is ocaml's marshalling interface _designed_ to be incompatible across architectures with different word sizes?
lht has quit [Quit: Ex-Chat]
<thelema> Lor: no, designed to be compatible
<Lor> "The user-provided serialize function must then store in its wsize_32 and wsize_64 parameters the sizes in bytes of the data part of the custom block on a 32-bit architecture and on a 64-bit architecture, respectively."
<adrien> it can't do magic
<Lor> To me this implies that it is allowed (and expected) that a structure is serialized differently depending on the host architecture.
<adrien> if there's not enough bits, it's the programmer's issue to chose int64 instead of "int"
<adrien> you can Marshal file descriptors too but...
<adrien> that might make little sense
<Lor> The documentation is wrong, though, the sizes are expected to be in words, not bytes.
<Lor> Ah, no, sorry.
ankit9 has joined #ocaml
<Lor> Ah, right, now I get it.
Tobu has joined #ocaml
<Lor> That's terribly inconvenient, though.
<Lor> We have to hard-code into the serialized form fixed assumptions about the sizes of custom blocks on different-sized architectures.
ftrvxmtrx has joined #ocaml
<Lor> Even though it is up to the C compiler to decide how to represent structs that are stored in the custom block.
<adrien> considering how much variation you get with C structs, I don't consider OCaml's way of doing to be annoying :P
<Lor> But the point of custom blocks is that you should be able to store C structs in them.
<Lor> So ocaml should have to accommodate for the representation variability that you get with C structs.
beckerb has joined #ocaml
<adrien> no
<adrien> it's not doable
beckerb has quit [Quit: Konversation terminated!]
<adrien> do you know what is "packing" in the context of C structs?
<adrien> (and then you have padding and alignment)
<pippijn> padding and alignment can be calculated
<pippijn> ocaml has the information to do that
<pippijn> and packing is not standard C
<adrien> for ocaml things
<adrien> but not for C onse
<adrien> ones*
<adrien> the C ones are handled by the C compiler, not ocaml
<pippijn> so if you want to use non-standard extensions, you're on your own
<Lor> That's why they shouldn't be preallocated.
<pippijn> ocaml has to know some things about the system C abi
<Lor> Instead, the deserialization function should manually allocate as big a block as it wants.
<adrien> the point custom blocks is not to store C data in them but to store arbitrary data in them
<pippijn> so why can't it know more?
<adrien> and ocaml won't go look any close
<adrien> I don't think it knows much
<adrien> but it gets compiled according to the ABI
<adrien> so it follows it
<adrien> but it doesn't "know" about it
<adrien> (I think)
<pippijn> it has to explicitly do so
<adrien> ocaml uses cc and ld for some things
<adrien> it doesn't do extra stuff itself
<pippijn> it has to pass arguments in certain registers or stack locations
<pippijn> this lag is interesting.. I can see you writing stuff but what I wrote is not sent
<pippijn> adrien: it compiles to native code, not via C
<Lor> It wouldn't help if ocaml knew the abi of the local architecture.
<pippijn> so it needs to know about the C calling convention
<Lor> The serialized files should be usable _everywhere_.
<pippijn> Lor: of course, but you said "accommodate for"
<adrien> pippijn: the C interface uses C stubs which are compiled by the C compiler, not ocaml
<Lor> But now the serialization format dictates that there are only two possible sizes for custom blocks.
<pippijn> if it knows its own local arch
<pippijn> then it can abstract from it
<pippijn> => accommodate for whatever you want
<adrien> Lor: also, Marshal is NOT thought by anyone to be the best serialization tool/format available
<Lor> The question here is: why is the deserialization function given a preallocated block, instead of allowing it to manually allocate an appropriately sized block
<adrien> far from it
<adrien> Lor: that sounds like parsing rather than deserializing
<pippijn> anyway
<pippijn> serialising arbitrary C data is hopeless
<pippijn> you can't serialise functions
<pippijn> if your data contains function pointers, those are lost
<pippijn> unless you look them up in the debug symbol table
<pippijn> and store symbolic references
<Lor> That's true, but I don't see how it's relevant here.
<pippijn> (no, I'm not really serious)
<pippijn> ok, I am not really in the conversation, so I don't know what it's about
emmanuelux has joined #ocaml
cdidd has quit [Remote host closed the connection]
<bigfg> is ocaml faster than c?
<adrien> sometimes
<bigfg> is it worth to learn ocaml then? i know haskell, it doesn't seem that different
<adrien> considering this channel is #ocaml, it's obviously useful (and vital) for you to learn ;-)
<adrien> it does a number of things differently
<adrien> (compared to haskell)
<adrien> even if it looks similar to you, there are differences that are taking a look at
<adrien> and it shouldn't take you long to pick the language
emmanuelux has quit [Remote host closed the connection]
emmanuelux has joined #ocaml
Tobu has quit [Ping timeout: 272 seconds]
tomprince has joined #ocaml
fraggle_laptop has quit [Remote host closed the connection]
djcoin has quit [Quit: WeeChat 0.3.2]
Tobu has joined #ocaml
albacker has quit [Ping timeout: 246 seconds]
ankit9 has quit [Ping timeout: 276 seconds]
ankit9 has joined #ocaml
ankit9 has quit [Ping timeout: 246 seconds]
<Drakken> bigfg it depends on what your goals are. OCaml is sort of like Haskell without monads and lazy evaluation.
<bigfg> why not monads?
<pippijn> that's wrong
<_habnabit> monads are only necessary if you want to pretend that mutation never happens
<_habnabit> ocaml embraces mutation
<bigfg> cool
<pippijn> ocaml has monads
<pippijn> but no type classes
<pippijn> so no generic operator >>=
<bigfg> but aren't functors similar?
<Drakken> ocaml doesn't have the restriction of pure FP in regular code.
<_habnabit> bigfg, not really
<_habnabit> bigfg, functors are more like template specialization
<pippijn> monads are not really special
<bigfg> if it is not type-independent it is not a functor in the mathematical sense right?
<pippijn> just have a structure with proper return/bind and you have a monad
<bigfg> i'm very confused about the word functor, it is abused so much
<Qrntz> ocaml also has a lazy evaluation mechanism, but it's explicit and not too common in usage
<Drakken> ocaml functors are functions from modules to modules that get evaluated at compile time.
<Drakken> The argument is used to customize the return value.
<_habnabit> bigfg, functors can be type-independent
<_habnabit> bigfg, e.g. in the ocaml stdlib, specializing a map for a particular combination of type/comparison function
<pippijn> Drakken: are ocaml functors really specialised?
ankit9 has joined #ocaml
<pippijn> so if you instantiate one with int, you get specialised int code?
<Drakken> you instantiate with something like [struct type t = int end]
<pippijn> yes
<pippijn> will it really specialise or is it just a type system thing?
<pippijn> and is it really compile time?
<pippijn> because you can put if/else around it, which depends on a runtime boolean value
<_habnabit> when else are types evaluated
<pippijn> the types are
<pippijn> ok, I understand what you mean
<thelema> _habnabit: huh? types are evaluated?
<_habnabit> how would you describe it, then
<pippijn> computed
<thelema> types are verified at compile time, that's it
<_habnabit> yeah, that's what I mean
<thelema> "typechecking"
<pippijn> not just verified
<thelema> There's a phase of the compilation (part of the inference process) where types are checked to be compatible
<pippijn> yes
err404 has joined #ocaml
<thelema> oh, I see - the question is when specialized code (such as for ints) is generated...
<pippijn> yes
<pippijn> for example
<pippijn> fun min a b = if a < b then a else b
<pippijn> er
<pippijn> let min a b = if a < b then a else b
<pippijn> is 'a -> 'a -> bool
<thelema> If you compile that function, it will generate code that does a polymorphic compare.
<pippijn> yes
<thelema> if you insist that a has type int, it will generate int-compare code
<pippijn> correct
<thelema> This happens for very few things, 1) compare/equality tests, 2) Array indexing (float vs. non-float have different layout on 32-bit) and for bigarrays
<thelema> 3) for bigarrays
<pippijn> there is special compiler support for bigarrays?
<thelema> yes, the compiler can generate specialized code for indexing into bigarrays of known layout
<pippijn> nice
<pippijn> that makes bigarrays more attractive for high performance code
<pippijn> I'll keep that in mind and investigate more when I need it
<Drakken> If you define a top-level module from a functor, when does the functor get evaluated? Is that actually deferred until runtime?
<pippijn> I'm pretty sure it is
<thelema> Drakken: what would it mean for the functor to be evaluated at compile time? How could it print_string?
<flux> drakken, are you thinking in terms of when side effects are evaluated?
<flux> you can think of ocaml programs as being evaluated from top to bottom as if you were writing them in top level
<thelema> yup, that's the semantics I'm familiar with.
testcocoon has quit [Quit: Coyote finally caught me]
testcocoon has joined #ocaml
Tobu has quit [Ping timeout: 260 seconds]
Tobu has joined #ocaml
bigfg is now known as bfig
Juzor is now known as JuzorBNC
<Lor> side effects in functor bodies are icky
<pippijn> Lor: menhir does it
<Lor> You're better off writing a function from first-class modules to first-class modules.
<pippijn> for the backend selection
<pippijn> or wait, I'm not sure it's actually performing side effects
<Lor> I tried to do some hackery with side effects in functor bodies but something went awry (I don't remember what) and switched to functions over modules.
<pippijn> maybe it just calculates something big and at the end they call a single side effect function that writes out the calculated code
<thelema> Lor: I've used them for auto-registering tests to be run on functorized variants of a piece of code.
<thelema> just a simple `let () = Something.register my_f` in the body of the functor
<Lor> Ah, now I remember why I had trouble.
<pippijn> tests
<pippijn> maybe I should start testing my code
<Lor> OCaml's functors are applicative, and in my case I specifically needed generative functors.
<Lor> functions over modules were a reasonable alternative for those.
<pippijn> but coming from C++ and java, I find that my ocaml code mostly just works
<pippijn> (my c++ and java code tends to need some iterations)
<pippijn> errors in my ocaml code are much more visible and if anything ever goes wrong, the mistake is usually very apparent
<adrien> that's only because you're very bad at ocaml
<adrien> ocaml pros manage to make the most subtle errors :P
<pippijn> yes
<pippijn> I'm young
<adrien> ;-)
<pippijn> only a few weeks of ocaml experience
* adrien might be "not funny" too, been fighting administration for the past ten days
_andre has quit [Quit: leaving]
<Ptival> administration =__=
<adrien> in particular when it doesn't say anything
thomasga has quit [Quit: Leaving.]
Tobu has quit [Ping timeout: 272 seconds]
tufisi has quit [Ping timeout: 245 seconds]
Tobu has joined #ocaml
ankit9 has quit [Quit: Leaving]
skchrko has quit [Quit: ChatZilla 0.9.88.1 [Firefox 11.0/20120314111819]]
alinrus has joined #ocaml
<Lor> Hrm, Lwt_log doesn't export any function to check if a given log message would be written anywhere?
<Lor> Sometimes producing the log message can be expensive, and it would be nice to avoid it when e.g. the debug level is not enabled.
eikke has joined #ocaml
bfgun has joined #ocaml
bfig has quit [Ping timeout: 248 seconds]
iago has quit [Ping timeout: 248 seconds]
<thelema> Lor: ocaml sadly lacks features to do this in the "right" way. One can use camlp4 to generate code to do this, but all arguments to functions will be evaluated.
<thelema> other workarounds include lazy and (fun () -> ...)
Submarine has quit [Quit: Leaving]
<thelema> IMNSHO, the "right" way for level-based logging has syntax "log `Debug "Foo%sBar" (generate_string x y z)" and works like "if !log_level >= `Debug then fprintf log_channel "Foo%sBar" ..."
<Lor> Right.
albacker has joined #ocaml
albacker has quit [Changing host]
albacker has joined #ocaml
ggherdov has joined #ocaml
albacker has quit [Ping timeout: 272 seconds]
<mfp> Lor: Lwt_log.debug[_f]-related code is removed by default
<mfp> unless you compile with -lwt-debug
<Lor> I'm not using syntax extensions.
<Lor> Anyway, I'd like to have a debug option even in production code.
albacker has joined #ocaml
albacker has quit [Changing host]
albacker has joined #ocaml
<mfp> Lor: I can think of several good reasons to avoid syntax extensions, but lwt's are _very_ tempting. The lwt_log one in particular does exactly what thelema described as the "right way" above.
<mfp> e.g. Lwt_log.info_f ~section "x = %d" x -> (if Lwt_log.Section.level section <= Lwt_log.Info then Lwt_log.info_f ~section "x = %d" x else return ())
<mfp> Lor: hmm, is Lwt_log.Section.level section what you were looking for, if you don't mind doing it manually?
Tobu has quit [Ping timeout: 272 seconds]
<Lor> Ah, right. That's sufficient for my purposes, thanks.
zorun has quit [Read error: Connection reset by peer]
zorun has joined #ocaml
eikke has quit [Ping timeout: 252 seconds]
Tobu has joined #ocaml
albacker has quit [Ping timeout: 252 seconds]
smondet has quit [Remote host closed the connection]
thomasga has joined #ocaml
thomasga has quit [Client Quit]
cdidd has joined #ocaml
err404 has quit [Remote host closed the connection]