<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>
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]
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.
<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]