<Trou>
and /usr/lib/ocaml/compiler-libs/ocamlcommon.cmxa
<Trou>
make inconsistent assumptions over implementation Location
<Trou>
what should I do ?
<Trou>
(sorry I didn't say hi and pasted 4 lines...)
<companion_cube>
start with `make clean` or equivalent
<Trou>
yes I did that, but that's from Debian files
<Trou>
I guess the maintainer should recompile stuff ?
<Trou>
(ppx_tools I guess)
<smondet[m]>
you could `opam switch` to a locally built compiler
<Trou>
I don't use opam, only debian packages
MercurialAlchemi has quit [Ping timeout: 240 seconds]
<Trou>
so, I should report a bug on the debian package ?
<smondet[m]>
that seems like the right place to ask yes
<smondet[m]>
you're on debian "stable"?
<Trou>
no, unstable
<Trou>
the compiler was updated today
<smondet[m]>
oh so maybe `ppx_tool` will be updated soon also
<smondet[m]>
*tools
<Trou>
I hope :)
MercurialAlchemi has joined #ocaml
aciniglio has joined #ocaml
MercurialAlchemi has quit [Read error: No route to host]
MercurialAlchemi has joined #ocaml
sh0t has quit [Ping timeout: 258 seconds]
frefity has quit [Ping timeout: 255 seconds]
MercurialAlchemi has quit [Ping timeout: 264 seconds]
sh0t has joined #ocaml
tane has joined #ocaml
mnemem has quit [Ping timeout: 258 seconds]
govg has quit [Ping timeout: 260 seconds]
Joost has quit [Quit: WeeChat 1.8]
Joost has joined #ocaml
thizanne_ has joined #ocaml
thizanne_ has quit [Client Quit]
mbuf has joined #ocaml
mbuf has quit [Quit: Leaving]
yawaramin has joined #ocaml
samrat has quit [Remote host closed the connection]
yawaramin_ has joined #ocaml
yawaramin has quit [Ping timeout: 258 seconds]
sh0t has quit [Ping timeout: 258 seconds]
aaronwint has joined #ocaml
<aaronwint>
Hi everyone, I'm currently learning OCaml. In order to get my hands a little bit dirty, I tried to implement a small library for bitset manipulation. I would like to know if someone experimented would be down to code review it? It's not very long and pretty self-contained
<aaronwint>
and I offer a reward of 0.01BTC !
<aaronwint>
I'd like to know if my code is "idiomatic" and if the design sucks etc.
<Armael>
just give a link to your code here, I think
<Armael>
(afaik they are kinda required when using the toplevel, but otherwise are not needed)
<aaronwint>
please don't hesitate to tell me how much it's shit
<hannes>
aantron: in line 11, there's no need for the parens around the constructor
<hannes>
err, I meant aaronwint, sorry... also lines below... 14, 16 - remove the parens
<Armael>
are you representing bitsets as strings of characters '0' or '1'? That's probably not the most compact representation
<Armael>
(memory wise)
<Armael>
I think you could also just have "type t = string"
<aaronwint>
Armael: yes exactly, my understanding was that there isn't bit-sized datastructures in OCaml? Basically, my thought process was that "the memory footprint is not going to be low anyway, so you might as well store them in a way that's human readable i.e ascii"
<hannes>
aaronwint: no need for 'raise (invalid_arg "foo")', 'invalid_arg "foo"' already raises
<aaronwint>
hannes: ty! will change that
<Armael>
ftr, you can replace matches with one case by a let ("match foo with Foo x -> bar" ~> "let Foo x = foo in bar"); just like you would do to destruct tuples ("let (x, y) = foo in bar")
<aaronwint>
Armael: the reason I wrap the string in Binstr is just to force the encourage the user to not mess with it using "unsafe" methods
<Armael>
aaronwint: I guess a more compact representation would be a list or array of machine size integers (but then the code gets more complicated)
<aaronwint>
does that make sense?
<Armael>
if you want to unforce that, then you should wrap your type definition in a module
<Armael>
along with its unsafe operations
<Armael>
and give the module a signature that hides the implementation
<aaronwint>
ok I will do that
<Armael>
(here, the "user" is yourself, the implementor of the library; for the actual user, the implementation of t is abstracted anyway in the .mli)
bitbckt has joined #ocaml
<aaronwint>
oh I see
<Armael>
from a syntactic point of view, the coding style looks mostly ok; you just have some extraneous parenthesis there and there (e.g. lines 314 and 316)
<Armael>
here and there*
<pmetzger>
I just got my first core dump out of ocaml.
<pmetzger>
I have no idea how to debug it. :)
<aaronwint>
one thing is that the lib assumes everything is given in BigEndian, is that ok?
<aaronwint>
I suspect there's a way to take advantage of the type system to have it both ways
<pmetzger>
I'm building something using the OCaml llvm bindings, so it should not be entirely surprising that something could go wrong in the C++ code, but how do I use the core dump to get a backtrace?
<pmetzger>
or should I try using the bytecode interpreter?
<yawaramin_>
aaronwint: about wrapping the type definition in a module to hide it from unsafe operations, you don't need to do anything more than you've already done, since your .mli file will already enforce that `t` is an abstract type
<aaronwint>
Armael: also I don't aggressively compact the binstrings (i.e remove leading zeros) - what do you think? should I leave it to the user? which one is the better design
<yawaramin_>
in the implementation you can `s/Binstr of//`
<aaronwint>
yawaramin_: but then, take unsafe_s for example
<aaronwint>
how do I "cast" a Binbin.t to stirng
<aaronwint>
val unsafe_s t -> string
<aaronwint>
if I do: unsafe_s b = b then the compiler is going to yell at me no?
<yawaramin_>
nope, that's the beauty of it :-)
<yawaramin_>
compile-time safety with no runtime cost!
<aaronwint>
so the compile will take the unsafe_s signature
<aaronwint>
and look at the return type of unsafe_s
<aaronwint>
and see that Binbin.t = string ?
<aaronwint>
like how does it work? where can I read more about this?
<aaronwint>
yawaramin_: then when is it useful to encapsulate your stuff in a module with the module keyword
<aaronwint>
sorry for all the qs lol :P
<yawaramin_>
no worries :-) so at compile time users won't be allowed to just pass in strings, the compiler will enforce that they need to use the functions you provide
<yawaramin_>
but at runtime the conversions etc. will be erased and everything will be just strings
sh0t has joined #ocaml
<aaronwint>
interesting
<yawaramin_>
you would encapsulate in a syntactic module (`module X = struct ... end`) when you need a submodule, i.e. a nested module
<aaronwint>
oh makes sense got it
<yawaramin_>
since every .ml file is semantically a module anyway
<aaronwint>
yeah that's why I was confused a bit
<yawaramin_>
yeah it can be a bit confusing since OCaml conflates the two
<pmetzger>
hrm. throwing eprintf's into my code doesn't seem to print anything before I dump core.
<aaronwint>
so for example, if I wanted to have good support for both LittleEndian and BigEndian
<aaronwint>
could I make two types representing each, then have only two implementations for some functions but keep the others
<aaronwint>
for example, size could stay the same
<yawaramin_>
you would probably want to encode it as a functor so the user can choose between BE & LE
<aaronwint>
but to_int would have two versions of it
<aaronwint>
functors are modules as functions, is that correct?
<aaronwint>
let the module take a parameter basically?
<pmetzger>
Joy. I've been reduced to binary search with commenting.
<yawaramin_>
so you'd provide a functor `Binbin.Make` and two modules `Binbin.BigEndian` and `Binbin.LittleEndian`, and users would create the module they wanted with e.g. `module BinbinBE = Binbin.Make(Binbin.BigEndian)`
<aaronwint>
but then you duplicate your code no? you would have one method "size" for `Binbin.BigEndian` and another one for `Binbin.LittleEndian` even though they do the same thing, no?
<yawaramin_>
no the common code would go in the functor, only the unique/distinct code would go in the input modules
<aaronwint>
fascinating
<aaronwint>
ok thanks I will read about that tonight
<aaronwint>
do you think that I should "compact" my binary strings or let the user handle it? (by compact I mean remove the trailing zeros)
<aaronwint>
for example if someone: XOR "11111111" "11111111" should the result be "0" or "00000000". I tend to think the former is better, but that makes life a little bit tedious for the user
<Drup>
aaronwint: don't compact
<Drup>
(it's completely non-sensical to compat if you consider the datastructure as isomorph to "bool array", which is a common use case of bitsets)
<Drup>
You can lookup roaring bitmaps if you want to see how to do the compaction correctly
<aaronwint>
yeah, you're right
<aaronwint>
oh will do thanks for the lead
<aaronwint>
btw, did someone take a look at my tests? Is that how you do it in OCaml? They're very rudimentary + I'm still trying to figure the best way to test map, mapi, dmap, foldr and foldl
<yawaramin_>
hmm, this is general advice but one test should have only one assertion
<Drup>
(btw, the comparison with bool array/bool list should also help you design the API, you want something quite similar, just with bool as element)
<Drup>
In particular, your iterators are not really write, the give 't' to the function, which is not what you really would like
<Drup>
s/write/right/
<yawaramin_>
also if you find yourself aesthetically displeased by the multiline `(fun ... -> ...)`, you can use `begin fun ... -> ... end`
aaronwint has quit [Ping timeout: 260 seconds]
aaronwint2 has joined #ocaml
<yawaramin_>
yeah e.g. `map` should be `val map : (bit -> bit) -> t -> t` where `bit` is also a (abstract) type in the module
<yawaramin_>
or maybe just `(bool -> bool) -> t -> t`
<Drup>
I would use bool
Soni has quit [Excess Flood]
<aaronwint2>
then I would define type t = bool * t | bool ?
<yawaramin_>
ok, i was under the impression it would be the same size as int.
<Drup>
Well, an individual bool will be the same size as an integer, yes
yawaramin_ is now known as yawaramin
<yawaramin>
but bools get boxed ... oh yeah
<yawaramin>
so int array then
<Drup>
but a bool inside a bit vector should not. You can store it in a much more compat manner
<Drup>
if you have a bool array of size 100, it will be 101 words. You can make it fit in ... 4
<Drup>
That's the point of bitvectors :p
<yawaramin>
i know, but for a learning exercise?
<yawaramin>
btw, backtracking's implementation is also basically an int array
<Drup>
Well, that's precisely the exercise, isn't it? :)
andreas__ has quit [Quit: Connection closed for inactivity]
<Drup>
Anyway, using strings is not a bad idea for a first shot
<yawaramin>
yeah. and it will be a lot of fun figuring out how to compact them into C-style bitfields
<aaronwint2>
so, just to make sure I understand, my iterators are wrong because they're dealing with Binbin.t instead of whatever makes up a Binbin.t, correct?
<Drup>
aaronwint2: yes
<octachron>
pmetzger, this is a common pitfall of eprintf: you need to flush stderr, for instance by adding "%!" to your format string
<aaronwint2>
and using a string to store my bitfield is bad because 1 char = 1B so it takes size_binstr * 8 bits to represent my stuff in memory
<Drup>
aaronwint2: you just have to fit 8B per char :3
<aaronwint2>
8bits or 8Bytes :p
<Drup>
The one that is correct :)
<aaronwint2>
haha
<aaronwint2>
Drup: can you explain that last one, no matter b or B I don't get it :p
<aaronwint2>
-> when I could use a bunch of 32bit integers bundled together (via int array), then I would have a much smaller memory footprint but at the expense of code complexity
<Drup>
Well, a char is a 8 bit integer, so you can do the same
<aaronwint2>
Drup: or where you referring to the cool roaring stuff?
<aaronwint2>
so I would map 4 chars to my 32 bit integer, for example: B_1 , B_2, B_3, B_4 and consider 32bits integer i:(i1,i2,...i32)
<aaronwint2>
I would have B1 on the first 8bits i1,..i8
<aaronwint2>
B2 on i9,...,i17
<aaronwint2>
etc.
<Drup>
You do one or the other, no need to do both
<aaronwint2>
?
<aaronwint2>
oh...... ok my bad I get it
<aaronwint2>
so if I had b = "10000000" I could just have b = [128]
<aaronwint2>
now I use 4Bytes instead of 8B
Soni has quit [Ping timeout: 240 seconds]
<Drup>
Yes
<aaronwint2>
I could keep track of the length
<aaronwint2>
okok I think I have a better idea
<aaronwint2>
exciting
<aaronwint2>
:P thanks
<aaronwint2>
I'll first functorize my stuff to learn about it, then get to that more efficient representation
<aaronwint2>
then take a serious look at roaring
<aaronwint2>
anything you suggest me to do that's interesting and could be useful to others?
<Drup>
On that topic ? Not sure. I guess people would use bitv when they want bit vectors. There are OCaml bindings to the C implem of roaring. It would be amusing to have an OCaml implementation of roaring, but I would expect it to be quite slower than the C version
<Drup>
(I'm really curious how it would fare in javascript, though)
<Drup>
(but that's more for shit&giggles than for any serious usage)
Soni has joined #ocaml
andreas__ has joined #ocaml
<pmetzger>
octachron: Oh, that's gross. I'm used to "error" printfs in other languages always flushing. (because they're writing to stderr after all...) But thank you!
<aaronwint2>
Drup: would there be any advantage to having a roaring impl in pure ocaml?
<Drup>
aaronwint2: in this case, not really. You can compile it to javascript, which is always amusing, but I doubt it's extremely useful here :)
<Drup>
It's probably a very cool exercise though
<octachron>
pmetzger, note that you can rewrite your own flushing version of eprintf with "let eprintf fmt x = Printf.eprintf (fmt ^^ "%!") x"
<Drup>
(note: closes all the current boxes and reset the indentation)
shinnya has joined #ocaml
cbot has joined #ocaml
jnavila has joined #ocaml
<pmetzger>
octachron: I might do that. :(
<pmetzger>
But I think for now just knowing I needed the %! is enough.
ayxih has joined #ocaml
tane has quit [Quit: Leaving]
_andre has quit [Read error: No route to host]
jnavila has quit [Ping timeout: 248 seconds]
Algebr has joined #ocaml
_andre has joined #ocaml
jimt_ has joined #ocaml
jnavila has joined #ocaml
jimt has quit [Ping timeout: 240 seconds]
kakadu has quit [Quit: Konversation terminated!]
mnemem has joined #ocaml
mnemem has quit [Read error: Connection reset by peer]
mnemem has joined #ocaml
mnemem_ has joined #ocaml
mnemem has quit [Ping timeout: 258 seconds]
copy_ has quit [Quit: Connection closed for inactivity]
aciniglio has quit [Ping timeout: 240 seconds]
jnavila has quit [Ping timeout: 246 seconds]
cbot has quit [Read error: Connection reset by peer]
cbot has joined #ocaml
sz0 has quit [Quit: Connection closed for inactivity]
jnavila has joined #ocaml
Soni has quit [Excess Flood]
Soni has joined #ocaml
Soni has quit [Remote host closed the connection]
aciniglio has joined #ocaml
AlexRussia has joined #ocaml
kakadu has joined #ocaml
kakadu_ has joined #ocaml
yawaramin has quit [Ping timeout: 255 seconds]
yawaramin_ has joined #ocaml
Soni has joined #ocaml
kakadu has quit [Ping timeout: 248 seconds]
Denommus has joined #ocaml
ShalokShalom_ is now known as ShalokShalom
ristos has joined #ocaml
yawaramin_ has quit [Ping timeout: 255 seconds]
yawaramin_ has joined #ocaml
mnemem_ has quit [Ping timeout: 248 seconds]
kolko has quit [Ping timeout: 240 seconds]
mnemem_ has joined #ocaml
yawaramin_ is now known as yawaramin
AltGr has left #ocaml [#ocaml]
Algebr has quit [Remote host closed the connection]
aciniglio has quit [Ping timeout: 246 seconds]
jnavila has quit [Ping timeout: 240 seconds]
enterprisey has joined #ocaml
mnemem_ has quit [Ping timeout: 240 seconds]
yawaramin has quit [Ping timeout: 258 seconds]
sepp2k has quit [Quit: Leaving.]
aciniglio has joined #ocaml
mnemem_ has joined #ocaml
sh0t has quit [Remote host closed the connection]
yawaramin has joined #ocaml
mnemem_ has quit [Ping timeout: 258 seconds]
aciniglio has quit [Ping timeout: 240 seconds]
argent_smith has quit [Quit: Leaving.]
cbot_ has joined #ocaml
cbot has quit [Ping timeout: 248 seconds]
damaja has joined #ocaml
<damaja>
Hi
damaja has quit [Ping timeout: 260 seconds]
_andre has quit [Quit: leaving]
pitastrudl has quit [Remote host closed the connection]
mnemem_ has joined #ocaml
mnemem_ has quit [Ping timeout: 240 seconds]
pitastrudl has joined #ocaml
pitastrudl has quit [Remote host closed the connection]
ayxih has quit [Quit: Leaving]
pitastrudl has joined #ocaml
al-damiri has joined #ocaml
Simn has quit [Quit: Leaving]
nicklaf has joined #ocaml
enterprisey has quit [Remote host closed the connection]
pmetzger has quit []
kakadu_ has quit [Remote host closed the connection]