companion_cube changed the topic of #ocaml to: Discussion about the OCaml programming language | http://www.ocaml.org | OCaml 5.0 released(!!1!): https://ocaml.org/releases/5.0.0.html | Try OCaml in your browser: https://try.ocamlpro.com | Public channel logs at https://libera.irclog.whitequark.org/ocaml/
dnh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<discocaml> <elliottcable> a large complicated record from a library
bibi_ has quit [Quit: Konversation terminated!]
waleee has quit [Ping timeout: 260 seconds]
waleee has joined #ocaml
<discocaml> <darrenldl> the library doesnt give any accessor or whatever to manipulate the data at all?
<companion_cube> (alcotest always sounds so annoying)
<discocaml> <elliottcable> it definitely does; but then i'm reduced to a painful deconstruction and manual pretty-printing. bleh.
Hammdist has joined #ocaml
<discocaml> <darrenldl> i think im just confused about what the matcher should do by your description
<discocaml> <elliottcable> ideally i'd love a way to just completely ignore some subset of a construction, but there's just … no way to type that.
<discocaml> <elliottcable> again, simplest example is "one might want to match `Some blah`, desiring pretty error-messages about the `Some`-ness, without having to _also_ have tons of details and pretty-printing magic for the `blah`-ness"
<discocaml> <elliottcable> anyway, not that important, can just use a `bool` matcher and `Option.is_some`; just gives less clear messages when it fails. meh nbd.
<companion_cube> Maybe one day I should make an ezounit2 or something
<companion_cube> Or fork it to clean it up
TrillionEuroNote has quit [Ping timeout: 260 seconds]
TrillionEuroNote has joined #ocaml
Hammdist has quit [Quit: Client closed]
Hammdist has joined #ocaml
caasih has quit [Ping timeout: 248 seconds]
caasih has joined #ocaml
waleee has quit [Ping timeout: 240 seconds]
<discocaml> <jumpnbrownweasel> it's hard to come up with a general purpose function signature that would do that. the check is custom, the error message is custom, and the pp is custom
<discocaml> <jumpnbrownweasel>
<discocaml> <jumpnbrownweasel> wouldn't it be simpler to make the check directly and `fail` the test with the message you want?
chrisz has quit [Ping timeout: 240 seconds]
chrisz has joined #ocaml
ursa-major has quit [Quit: WeeChat 4.0.4]
<discocaml> <elliottcable> eh probably. the bool approach worked for me
ec has quit [*.net *.split]
ec has joined #ocaml
ansiwen has quit [Quit: ZNC 1.7.1 - https://znc.in]
ansiwen has joined #ocaml
bartholin has joined #ocaml
Serpent7776 has joined #ocaml
bartholin has quit [Quit: Leaving]
azimut has joined #ocaml
rgrinberg has joined #ocaml
TrillionEuroNote has quit [Ping timeout: 244 seconds]
TrillionEuroNote has joined #ocaml
mro has joined #ocaml
chrisz has quit [Ping timeout: 260 seconds]
chrisz has joined #ocaml
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
peony has quit [Read error: Connection reset by peer]
mro has quit [Quit: Leaving]
dnh has joined #ocaml
dnh has quit [Ping timeout: 246 seconds]
bibi_ has joined #ocaml
dnh has joined #ocaml
wingsorc has quit [Quit: Leaving]
bibi_ has quit [Ping timeout: 258 seconds]
bibi_ has joined #ocaml
peony has joined #ocaml
Guest63 has joined #ocaml
Tuplanolla has joined #ocaml
<Guest63> hi! was thinking about this method inspired by some papers I read for type safe matrix operations. Basically the idea (which is well known) is to encode invariants in parametric types ( the 'a of 'a t). So the idea is to define a ('a, 'row, 'col) matrix = { data  : 'a array ; n_rows : 'row; n_cols : 'col) with the constraint that 'row and
<Guest63> 'col are Peano integers type 'a s = Zero -> () s | Succ : 'a s -> 'a s s
<Guest63> but it's a bit inefficient in terms of memory to encode numbers like that
<octachron> That can work, but it is a bit painful, and you will also hit the fact that it gives you huge type.
<Guest63> wondering if doing so is worth it just to check the dimensions of matrices in common matrix ops
<octachron> https://github.com/Octachron/tensority uses a binary type-level encoding
<octachron> with a ppx.
<Guest63> ah nice!
<octachron> You can also generate dimension with a generative functor.
<Guest63> cool
<Guest63> you can create a custom syntax with a ppx it seems
Guest63 has quit [Quit: Ping timeout (120 seconds)]
Guest63 has joined #ocaml
<discocaml> <sienhopist> I have a list of filepaths and pipe each of them with `|>` to a function that calls an external command on the filepath and returns the command's stdout. I noticed that when I do this with 100 filepaths in a list, I get 100 external processes created almost simultaneously and the overall speed of the program is considerably slower than I expect it to be. How can I make it execute the external commands one by one to see if that will improve
Guest63 has quit [Quit: Ping timeout (120 seconds)]
<discocaml> <sienhopist> I have a list of filepaths and pipe each of them with `|>` to a function that calls an external command on the filepath and returns the command's stdout. I noticed that when I do this with 100 filepaths in a list, I get about 100 external processes created almost simultaneously and the overall speed of the program is considerably slower than I expect it to be. How can I make it execute the external commands one by one to see if that will im
<discocaml> <._null._> `|>` is just reverse application, so you have to look into the function you're applying your list to
<discocaml> <_terence_> @octachron
<discocaml> <_terence_>
<discocaml> <_terence_> Does using a `constraint` compulsory for what you want to define here ? https://github.com/Octachron/tensority/blob/master/lib/tensor.mli#L22
<discocaml> <_terence_>
<discocaml> <_terence_> Also, while I get what constraint does, do you have some resources about when to use it and its power ?
<discocaml> <octachron> The constraint is really a constraint here: it mostly here to ensure that the phantom type parameters always have the right shape.
<discocaml> <_terence_> You could not have use a GADT with a single constructor ?
<discocaml> <_terence_> You could not have used a GADT with a single constructor ?
<discocaml> <sienhopist> This is the function in question. I believe `Unix.open_process_args_in` is responsible for this but idk how to process the files sequentially
<discocaml> <._null._> There's no list of files here
<discocaml> <sienhopist> That's just the function
<discocaml> <sienhopist> I use it like this for example `["file 1.mp4"; ... etc] |> List.filter_map ~f:get_duration`
<discocaml> <sienhopist> So imagine the list has 100 files and when I execute that ⬆️ I notice almost 100 `ffprobe` commands running the background, most of them zombies, but eventually they do finish and I get their results as expected. However the whole thing is a lot slower than I expected, about 9 times than the equivalent Go version. I'm thinking the problem is that it tries to execute `ffprobe` for almost every list element simultaneously
<discocaml> <sienhopist> So imagine the list has 100 files and when I execute that ⬆️ I notice almost 100 `ffprobe` commands running the background, most of them zombies, but eventually they do finish and I get their results as expected. However the whole thing is a lot slower than I expected, about 9 times slower than the equivalent Go version. I'm thinking the problem is that it tries to execute `ffprobe` for almost every list element simultaneously
<discocaml> <._null._> I don't see why your code would be concurrent, you're not using anything to
<discocaml> <._null._> I don't see why your code would be concurrent, you're not using anything to make it so
<discocaml> <sienhopist> Maybe it's got something to do with this in the `Unix` documentation page
<discocaml> <sienhopist>
<discocaml> <sienhopist> `create_process prog args stdin stdout stderr` creates a new process that executes the program in file prog, with arguments args. The pid of the new process is returned immediately; **the new process executes concurrently with the current process**
<discocaml> <octachron> @_terence_ , a GADT would have been heavier here: with the constraint, the type-level constraint is only reflected at the type-level and never affect values.
<discocaml> <sienhopist> It mentions that the new process is concurrent
<discocaml> <._null._> Sure, but `In_channel.input_line` should be blocking
<discocaml> <darrenldl> are you sure a single input line exhausts the output?
<discocaml> <sienhopist> There might be one empty line that I don't read from stdout
<discocaml> <darrenldl> then the process doesnt exit fully
<discocaml> <sienhopist> Same problem even with `In_channel.input_all`
<discocaml> <._null._> `Unix.close_process_in`
<companion_cube> I hate this API so much
<companion_cube> (tbh I really dislike most of what's related to the standard channels)
<discocaml> <sienhopist> Thanks, that's precisely what I was missing. That fixed all the background processes, but the execution time is the same, meaning this wasn't causing the slowness apparently
<discocaml> <sienhopist> In that case idk why it's so slow
<Leonidas> companion_cube: the API is also extremely weird, because the process is somehow encoded in the channels you get out of the tuple
<discocaml> <darrenldl> whats your go version like?
<Leonidas> What if you construct a second process and pass (ch_proc1, ch_proc2) to `close_process_in`? It probably throws
<companion_cube> it's terrible in so many respects
<discocaml> <darrenldl> it is an absolute hassle to use
<companion_cube> forces channels to have (more) hidden global state; no wait to get the PID while it's running
<Leonidas> I was also wondering why it didn't close the process, but turns out it fails if you don't read the output with SIGPIPE or something
<discocaml> <_terence_> gadt affects value because of the constructors ?
<companion_cube> omg, fuck SIGPIPE
waleee has joined #ocaml
rgrinberg has joined #ocaml
<discocaml> <functionalprogramming> companion_cube: would you say having Xyz.Make() and passing in PARTIAL_ORD and TOTAL_ORD is a good idiom to follow, as you have done for your containers library? https://github.com/c-cube/ocaml-containers/blob/master/src/core/CCHeap.ml I am writing my own data structure and would like to know the best way to do it (crosspost from #beginners but i don't know if you're in that IRC channel)
rgrinberg has quit [Client Quit]
<discocaml> <._null._> (there's only one ocaml IRC channel AFAIK and it's linked here)
<discocaml> <functionalprogramming> ah gotcha, good to know
<companion_cube> I'm mostly imitating Map.Make/Set.Make :)
<companion_cube> so yeah, it's a good idiom for these kinds of data structures with requirements on the tyype
<companion_cube> type
<discocaml> <functionalprogramming> i see, thanks!
waleee has quit [Ping timeout: 260 seconds]
masterbuilder has quit [Remote host closed the connection]
<discocaml> <sienhopist> My apologies, I was misremembering that the Go version was multi-threaded. That's why the Go version finished in about 1 second vs Ocaml's 8 seconds in one of my tests. If I make the Go version single-threaded it goes up to 8 seconds too and Ocaml is around 200-300ms slower on average. I guess now the next objective is figuring out how to parallelize the Ocaml version
<companion_cube> if you use the threads to run subprocesses, the `Thread` module can be enough
<companion_cube> otherwise there's a handful of thread pools existing these days (esp. on OCaml 5)
dhil has joined #ocaml
Serpent7776 has quit [Quit: leaving]
Hammdist has quit [Quit: Client closed]
yziquel has joined #ocaml
rgrinberg has joined #ocaml
bibi_ has quit [Ping timeout: 258 seconds]
bartholin has joined #ocaml
Hammdist has joined #ocaml
<discocaml> <sienhopist> Can ocaml be compiled statically against musl?
<discocaml> <darrenldl> yep, i regularly do that
bibi_ has joined #ocaml
ns12 has quit [Quit: bye]
ns12 has joined #ocaml
azimut has quit [Ping timeout: 252 seconds]
azimut has joined #ocaml
yziquel has quit [Quit: Client closed]
yziquel has joined #ocaml
yziquel has quit [Client Quit]
<discocaml> <sienhopist> Speaking of which what's the easiest way to create a thread pool and have it map a function or two to a list? Or perhaps map every element in a different thread instead of using a pool
<companion_cube> <disclavimer> I'm the dev </disclaimer> there's https://github.com/c-cube/moonpool/
<companion_cube> stuff like `List.map (fun x -> Moonpool.Fut.spawn ~on:my_pool (fun () -> compute_with x)) l`
yziquel has joined #ocaml
Anarchos has joined #ocaml
masterbuilder has joined #ocaml
Anarchos has quit [Ping timeout: 245 seconds]
<discocaml> <ironside2396> what kinds of ffi exist for OCaml ? only C ?
<companion_cube> basically
<companion_cube> and C++ via the C ABI
<discocaml> <Kali> isn't there also fortran ffi?
<discocaml> <Kali> oh, nevermind; it's still C, just for fortran object files
dnh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<discocaml> <sienhopist> Thanks I'll take a look when I get to ti
<discocaml> <sienhopist> Thanks I'll take a look when I get to it
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
rgrinberg has joined #ocaml
bartholin has quit [Quit: Leaving]
<Ankhers> If I am just getting started with ocaml, should I worry myself with something like Core? Or should I stick with the standard lib that is shipped with ocaml?
<discocaml> <Kali> standard lib
<discocaml> <Kali> generally, you only use Core if you are:
<discocaml> <Kali> - Jane Street
<discocaml> <Kali> - using a package that depends on it
<Ankhers> So Core is not a package most ocaml developers will use outside of Jane Street? What is the reason more people do not use it? I was under the impression it was widely used.
<discocaml> <Kali> you probably got that impression from Real World OCaml, yes?
dhil has quit [Ping timeout: 240 seconds]
<discocaml> <Kali> it was at least partially written by someone from Jane Street
<discocaml> <Kali> in the second edition
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
<discocaml> <Kali> so they used core/base
<Ankhers> I believe so. It has been a while since I have read the book.
<Ankhers> Thank you for the information.
<discocaml> <Kali> if you want an extended Stdlib that does not make the radical changes that Base/Core does sometimes, check out Containers: https://github.com/c-cube/ocaml-containers
dnh has joined #ocaml
<Ankhers> I think I will just stick with the default stdlib for now and find my way around.
<discocaml> <Kali> this is reasonable
yziquel has quit [Quit: Client closed]
rgrinberg has joined #ocaml
ec has quit [Remote host closed the connection]
ec has joined #ocaml
Tuplanolla has quit [Ping timeout: 255 seconds]
dnh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
noddy has quit [Quit: WeeChat 4.0.4]
noddy has joined #ocaml
TrillionEuroNote has quit [Ping timeout: 260 seconds]
TrillionEuroNote has joined #ocaml
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
reynir has quit [Ping timeout: 245 seconds]
reynir has joined #ocaml