companion_cube changed the topic of #ocaml to: Discussion about the OCaml programming language | http://www.ocaml.org | OCaml 4.12 released: https://ocaml.org/releases/4.12.0.html | Try OCaml in your browser: https://try.ocamlpro.com | Public channel logs at https://libera.irclog.whitequark.org/ocaml/
Tuplanolla has quit [Quit: Leaving.]
gzj has joined #ocaml
Corbin has joined #ocaml
waleee has quit [Ping timeout: 250 seconds]
elf_fortrez has quit [Quit: Client closed]
rgrinberg has joined #ocaml
gzj has quit [Remote host closed the connection]
gzj has joined #ocaml
rgrinberg has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
gzj has quit [Ping timeout: 255 seconds]
elf_fortrez has joined #ocaml
rgrinberg has joined #ocaml
gzj has joined #ocaml
zebrag has quit [Quit: Konversation terminated!]
rgrinberg has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
mbuf has joined #ocaml
rgrinberg has joined #ocaml
gravicappa has joined #ocaml
elf_fortrez has quit [Ping timeout: 246 seconds]
Serpent7776 has joined #ocaml
<d_bot> <octachron> @bikal , no the `[@@immediate]` is here to signal the fact that your type is an immediate to user beyond the abstraction barrier.
elf_fortrez has joined #ocaml
elf_fortrez has quit [Client Quit]
<d_bot> <octachron> @TheBloodlessMan : the `type_expr` is built in `Typetexp` which translates `Rtag` to `RPresent` and `REither` (type expressions are mutable digraphs, I would rather avoid to draw them). But what are you trying to do exactly? Because accessing the fields themselves should be done using the accessor functions in `Btypes` .
rgrinberg has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
rgrinberg has joined #ocaml
rgrinberg has quit [Client Quit]
gzj has quit [Remote host closed the connection]
gzj has joined #ocaml
mro has joined #ocaml
Haudegen has joined #ocaml
rgrinberg has joined #ocaml
rwmjones|hols is now known as rwmjones
rgrinberg has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
gzj has quit [Remote host closed the connection]
gzj has joined #ocaml
shawn has quit [Read error: Connection reset by peer]
shawnw has joined #ocaml
rwmjones has quit [Ping timeout: 252 seconds]
rwmjones has joined #ocaml
glassofethanol has joined #ocaml
gareppa has joined #ocaml
gareppa has quit [Remote host closed the connection]
elf_fortrez has joined #ocaml
bartholin has joined #ocaml
<d_bot> <Cyclomatic Complexity> hey
<d_bot> <Cyclomatic Complexity> ocaml values are immutable
<d_bot> <Cyclomatic Complexity> so when I do `[ a ; b ]`, or `(a , b)`, it's the same pointer to `a` in both cases
<d_bot> <Cyclomatic Complexity> that's great, because i can write `[ a ; a ; a ; a ; a ; a ; a ]`, and the memory doesn't store `a` 7 times
<d_bot> <Cyclomatic Complexity> now, let's say i want to actually print it, or persist it
<d_bot> <Cyclomatic Complexity> i find myself in a very sad situation: i don't know how to get the actual pointer to `a` (or rather, the `| Boxed of pointer | Unboxed of 'type_of_a`), so that I could build the associative map `pointer -> value` that I actually want to display/save
<d_bot> <Cyclomatic Complexity> (For the other way around, from an associative map, rebuilding the OCaml values, I find myself in another sad situation. let's say that i have access to a `pointer -> value` map, and from it i want to recreate my ocaml values. I'll need an auxiliary `value` data-structure, that is basically my `value` data-structure, but with `pointer` instead of `value` in its type definitionl)
<d_bot> <octachron> In general, with the GC the notion of "actual pointer" is ill-defined.
<d_bot> <Cyclomatic Complexity> ouch. how so / why so / is there a way to recover it?
<d_bot> <octachron> Well, the memory location are all owned by the GCs, and the GC move around values during the promotion to the major heap or during compactions.
<d_bot> <Cyclomatic Complexity> Yeah, but it still has a way to uniquely identify the address of each value, else, you wouldn't be able to have sharing and physical equality?
<d_bot> <octachron> Physical equality is a primitive (and it is one of primitive with the less specified behaviors)
<d_bot> <Cyclomatic Complexity> ouch
<d_bot> <Cyclomatic Complexity> can you compare `ref`s?
<d_bot> <octachron> And with physical equality you have can compare directly the current location of two values.
<d_bot> <Cyclomatic Complexity> emphasis on "current", right?
<d_bot> <Cyclomatic Complexity> as in, it might yield a different result after a GC pass?
<d_bot> <octachron> More precisely, you need to compare the two values at the same GC time.
<d_bot> <octachron> And you can compare in term of equality refs but not in term of orders.
<d_bot> <Cyclomatic Complexity> hmmmmmmmm
<d_bot> <Cyclomatic Complexity> so i couldn't have the associate map, and would need to have an associative list instead?
<d_bot> <octachron> Two values physically (in)equals at time `t` will keep the same relationship.
<d_bot> <octachron> Yes, if you only have physical equality, the `q` version of the associative list functions willl work.
<d_bot> <Cyclomatic Complexity> then I guess, to avoid the performance hit, I'd have to use hash-consing / maintain a mapping myself
<d_bot> <Cyclomatic Complexity> it does make sense, just sad
<d_bot> <Cyclomatic Complexity> thx
<d_bot> <octachron> It might be worthwhile to look at what the various hash-consing are doing.
<d_bot> <Cyclomatic Complexity> i didn't expect them to do more than hashconsing + persisting an in-memory map/dict
<d_bot> <Cyclomatic Complexity> i'll check out justincase
Tuplanolla has joined #ocaml
<d_bot> <Cyclomatic Complexity> the reason this is sad to me is that it's a big pain doing metadata in ocaml. instead of a nice recursive `type t`, now i need to have `type t = { value = t' ; metadata = ... }`, all my deep pattern-matches have to match on `{ value = Pattern ; _ }` instead of just `Pattern`, I need to use an applicative/monad to map the values without changing the metadata (including in folds), etc.
<d_bot> <Cyclomatic Complexity> (i don't know if other langs have it better, but my fav one is OCaml, 😄 )
gzj has quit [Remote host closed the connection]
gzj has joined #ocaml
<d_bot> <Cyclomatic Complexity> @octachron I looked at some hashconsing library
<d_bot> <Cyclomatic Complexity> namely https://github.com/backtracking/ocaml-hashcons/
<d_bot> <Cyclomatic Complexity> and i realize, there is no GC / automatic memory management
<d_bot> <Cyclomatic Complexity> so yeah, an advantage that I would have had by using actual pointers is to also benefit from GC
<d_bot> <Cyclomatic Complexity> ~~there is no way to have the GC preserve order, even at the cost of some performance? ~~
<d_bot> <octachron> Isn't that the use case of ephemerons?
<d_bot> <Cyclomatic Complexity> I have literally never heard of ephemerons, googling it now rn
<d_bot> <Cyclomatic Complexity> wow
<d_bot> <Cyclomatic Complexity> https://ocaml.org/api/Ephemeron.html looks awesome
<d_bot> <Cyclomatic Complexity> > Ephemerons can also be used for "adding" a field to an arbitrary boxed ocaml value: you can attach an information to a value created by an external library without memory leaks.
<d_bot> <Cyclomatic Complexity> what i've been wanting for all my life
<d_bot> <octachron> (Note that the API is uncommonly used, if you end up successively using it, people might be interested by a non-CEA use case of ephemerons).
<d_bot> <Cyclomatic Complexity> ~~I'm not big into maintenance and packaging but~~ I can always link to a github repo / write a short-post about it if it ends up working
elf_fortrez has quit [Quit: Client closed]
gzj has quit [Remote host closed the connection]
gzj has joined #ocaml
gzj has quit [Remote host closed the connection]
gzj has joined #ocaml
elf_fortrez has joined #ocaml
<d_bot> <Alistair> I'm writing my ppx_open library https://github.com/johnyob/ppx-open, one of it's functions is "open" types, e.g. `[%%open Option.([%type] t [@open] [@as option_renamed])]` which would expand into ```ocaml
<d_bot> <Alistair> open (struct
<d_bot> <Alistair> type 'a option_renamed = 'a Option.t = None | Some of 'a
<d_bot> <Alistair> end)```
<d_bot> <Alistair> I've grabbed the type using `Env.find_type`, and am in the process of writing functions to convert a `Typing` `type_decl` to a `Parsetree` `type_decl` (which requires converting the `type_expr` to a `core_type`)
<d_bot> <octachron> Note that this kind of code will break at every compiler version.
<d_bot> <Alistair> I know
mro has quit [Remote host closed the connection]
elf_fortrez has quit [Ping timeout: 246 seconds]
mro has joined #ocaml
mro has quit [Ping timeout: 255 seconds]
<d_bot> <mimoo> is there an unwrap_or in ocaml?
mro has joined #ocaml
mro has quit [Ping timeout: 255 seconds]
<d_bot> <mimoo> thx!
elf_fortrez has joined #ocaml
Haudegen has quit [Quit: Bin weg.]
<d_bot> <mimoo> is there a good altenrative to cconv? it looks like cconv is dead
mbuf has quit [Quit: Leaving]
gzj has quit [Remote host closed the connection]
gzj has joined #ocaml
<d_bot> <EduardoRFS> Unless you version the typer https://github.com/EduardoRFS/typedppxlib and
<d_bot> <EduardoRFS> REALLY WIP tho
<d_bot> <EduardoRFS> Great there is no way to remove preview on discord mobile
mbuf has joined #ocaml
mro has joined #ocaml
mro has quit [Ping timeout: 272 seconds]
GZJ0X_ has joined #ocaml
GZJ0X_ has quit [Remote host closed the connection]
GZJ0X_ has joined #ocaml
ebb_ has joined #ocaml
GZJ0X_ has quit [Read error: Connection reset by peer]
GZJ0X_ has joined #ocaml
Nahra` has joined #ocaml
lobo_ has joined #ocaml
GZJ0X_ has quit [Remote host closed the connection]
theblatte has joined #ocaml
hannes_ has joined #ocaml
GZJ0X_ has joined #ocaml
ebb has quit [Killed (NickServ (GHOST command used by ebb_))]
ebb_ is now known as ebb
dmbaturin_ has joined #ocaml
nullheroes has joined #ocaml
GZJ0X_ has quit [Remote host closed the connection]
mosterdt_ has joined #ocaml
sadiq_ has joined #ocaml
GZJ0X_ has joined #ocaml
johnel_ has joined #ocaml
terrorjack2 has joined #ocaml
adrien__ has joined #ocaml
GZJ0X_ has quit [Remote host closed the connection]
GZJ0X_ has joined #ocaml
gzj has quit [*.net *.split]
Corbin has quit [*.net *.split]
ccx has quit [*.net *.split]
theblatt1 has quit [*.net *.split]
dvu has quit [*.net *.split]
terrorjack has quit [*.net *.split]
hannes has quit [*.net *.split]
johnel has quit [*.net *.split]
lobo has quit [*.net *.split]
kvik has quit [*.net *.split]
mosterdt has quit [*.net *.split]
Johann has quit [*.net *.split]
adrien has quit [*.net *.split]
sadiq has quit [*.net *.split]
Nahra has quit [*.net *.split]
dmbaturin has quit [*.net *.split]
terrorjack2 is now known as terrorjack
lobo_ is now known as lobo
GZJ0X_ has quit [Read error: Connection reset by peer]
GZJ0X_ has joined #ocaml
ccx_ has joined #ocaml
dmbaturin_ is now known as dmbaturin
Johann has joined #ocaml
GZJ0X_ has quit [Read error: Connection reset by peer]
GZJ0X_ has joined #ocaml
Corbin has joined #ocaml
GZJ0X_ has quit [Remote host closed the connection]
elf_fortrez has quit [Quit: Client closed]
GZJ0X_ has joined #ocaml
mosterdt_ is now known as mosterdt
GZJ0X_ has quit [Remote host closed the connection]
GZJ0X_ has joined #ocaml
mro has joined #ocaml
mro has quit [Ping timeout: 255 seconds]
Haudegen has joined #ocaml
mro has joined #ocaml
scoobybejesus has left #ocaml [#ocaml]
neiluj has joined #ocaml
<neiluj> Hello! Meeting some concurrence issues: basically I wait for a value with an Lwt.wait but sometimes the broadcast happens before the wait is executed
mro has quit [Remote host closed the connection]
<neiluj> Is there a way to handle this case?
mro has joined #ocaml
mro has quit [Remote host closed the connection]
mro has joined #ocaml
GZJ0X_ has quit [Remote host closed the connection]
GZJ0X_ has joined #ocaml
mro has quit [Remote host closed the connection]
mro has joined #ocaml
zebrag has joined #ocaml
zebrag has quit [Quit: Konversation terminated!]
zebrag has joined #ocaml
Haudegen has quit [Quit: Bin weg.]
GZJ0X_ has quit [Remote host closed the connection]
GZJ0X_ has joined #ocaml
mro has quit [Remote host closed the connection]
mro has joined #ocaml
glassofethanol has quit [Quit: leaving]
<d_bot> <mimoo> is there an equivalent to the `matches!` macro of rust?
<d_bot> <Alistair> You could write: ```ocaml
<d_bot> <Alistair> (match expr with
<d_bot> <Alistair> | pat -> true
<d_bot> <Alistair> | _ -> false)```. Wouldn't be too hard to write as a ppx as well if you wanted something shorter I guess
mro has quit [Remote host closed the connection]
mro has joined #ocaml
<d_bot> <Christophe> But why? What's the use case?
<d_bot> <Alistair> I've often seen it used w/ `assert`, but it's a bit of a code smell in my opinion
<d_bot> <Christophe> I cannot imagine when it couldn't be better replaced with a regular `match` or structural equality
<dmbaturin> Definitely looks like a code smell to me. I'd never use that.
mro has quit [Remote host closed the connection]
mbuf has quit [Quit: Leaving]
<d_bot> <mimoo> I feel like it gets tedious to write match expression
<d_bot> <mimoo> when I just want to check if something is equal to a specific variant
<d_bot> <mimoo> if Sys.file_exists path = `Yes then ...
<d_bot> <mimoo> or if matches (Sys.file_exists path) `Yes then
<d_bot> <mimoo> basically, a one-liner
<d_bot> <mimoo> in my case, I want to do something that returns unit only in one case
<d_bot> <mimoo> it's pretty common
<d_bot> <Christophe> but if it returns unit in one case, then it returns unit in all cases, or else it won't type
<d_bot> <Christophe> `if Sys.file_exists path = `Yes then ...` sounds good to me
bartholin has quit [Quit: Leaving]
rgrinberg has joined #ocaml
cedric has joined #ocaml
<d_bot> <mimoo> except it doesn't work because `=` excepts int
<d_bot> <mimoo> expects*
<d_bot> <Alistair> Why doesn't `Sys.file_exists` return a `bool`?
<d_bot> <mimoo> good question :p the core_kernel one returns a bool IIRC
<d_bot> <mimoo> I tried writing
<d_bot> <mimoo>
<d_bot> <mimoo> ```
<d_bot> <mimoo> let matches var expected : bool =
<d_bot> <mimoo> match var with
<d_bot> <mimoo> | expected -> true
<d_bot> <mimoo> | _ -> false
<d_bot> <mimoo> ```
<d_bot> <mimoo>
<d_bot> <mimoo> but it doesn't want to take the false case
<companion_cube> @Alistair it does return a bool?
<companion_cube> val file_exists : string -> bool
<d_bot> <Alistair> Yeah, but evidently @mimoo's implementation doesn't?
<companion_cube> 🤷
<d_bot> <Alistair> Otherwise a simple `if-then-else` would suffice
<companion_cube> idk who hides Sys beyond Base
<d_bot> <mimoo> all related functions do this thing where they return a triple yes/no/unknown
<d_bot> <mimoo> oh I'm shadowing expected here...
<d_bot> <anmonteiro> You’re just renaming var to expected in this match branch
<d_bot> <mimoo> I guess I need a guard
<d_bot> <mimoo> well I guess I can't write a matches! macro without using macros
<d_bot> <mimoo> ppx sorry
<neiluj> Wow, I've been implementing a protocol by following a spec and the pattern matching suggested a lot of corner case that were not made explicit in the specs
<neiluj> that's cool. If I implemented it in C I sure would have skipped these cases
elf_fortrez has joined #ocaml
elf_fortrez has quit [Client Quit]
<sim642> I once read that the OCaml compiler caught a redundant case in the unicode spec similarly thanks to the pattern match checker
<d_bot> <Alistair> Alternatively you could write you `if Sys.file_exists path = Yes then ...` as ```ocaml
<d_bot> <Alistair> match Sys.file_exists path with
<d_bot> <Alistair> | `Yes -> (then branch)
<d_bot> <Alistair> | `No | `Unknown -> (else branch)
<d_bot> <Alistair> ```
rgrinberg has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<d_bot> <mimoo> that's what I do, but it's three line instead of one
<d_bot> <Cyclomatic Complexity> @octachron
<d_bot> <Cyclomatic Complexity> hey, reading more about ephemerons
<d_bot> <Cyclomatic Complexity> small problem: ephemerons take a hash function
<d_bot> <Cyclomatic Complexity> but the hash function is not parametric
<d_bot> <Cyclomatic Complexity> so, if you need to hash nil, then x :: nil, then x :: x :: nil, etc. it will have a quadratic cost
<d_bot> <Cyclomatic Complexity> am i missing something here?
<d_bot> <octachron> I am not sure I follow? The width of the hash traversal is generally bounded?
<d_bot> <Cyclomatic Complexity> what i mean is that i want to annotate AST pieces
<d_bot> <Cyclomatic Complexity> if my ast has depth 100, and i need to annotate all of its sub-ASTs
<d_bot> <Cyclomatic Complexity> each will be hashed independently, and it will require traversing the entire AST
<d_bot> <octachron> Yes, but hashes don't traverse the whole structure? So this is still linear in the number of nodes?
<d_bot> <Cyclomatic Complexity> why don't hashes traverse the whole structure?
<d_bot> <Cyclomatic Complexity> https://pastebin.com/YRkfLgXF
<d_bot> <Cyclomatic Complexity> with physical equality I still get a quadratic profile: https://pastebin.com/CJ8uHMa5
<d_bot> <Cyclomatic Complexity> hmmm
<d_bot> <Cyclomatic Complexity> @octachron is your point that there is a direct trade-off between hashing and iterating over a list, that hashtbls don't remove it, it merely gives you control over it?
<d_bot> <andreypopp> Can someone recommend an open source project which uses js_of_ocaml to implement some part of the logic which is then used by JS app. I'm a bit confused how to make a library with js_of_ocaml.
<d_bot> <octachron> @Cyclomatic Complexity , it looks like your trees might all fall in the same bucket of the hashtbl once you go beyond the maximum number of scanned nodes. You should try the same test with random values on the node.
<d_bot> <Cyclomatic Complexity> the quadratic profile starts before 256 depth, but i'll do this and see what happens
<d_bot> <Cyclomatic Complexity> oh, you mean that it has to go through the whole tree before finding a difference, and that in real life, that won't be the case?
<d_bot> <octachron> But yes, hash tables only escapes the `ln n` complexity of maps by assuming that there is an easy way to partition values into as many classes as desired.
<d_bot> <Cyclomatic Complexity> yup, more linear profile with non-autosimilar ADT
<d_bot> <octachron> And the jump between 10 and 100 might be quasilinear
<d_bot> <Christophe> ah but the problem here is with Base, but you could use the polymorphic equality for polymorphic variants I think (`Poly.(=)`) and define your own equality for new types
<d_bot> <Cyclomatic Complexity> that's still sad though. given that ephemeron keep track of GC, i'd have expected it to update the pointers so that it could use `(==)` internally
<d_bot> <Cyclomatic Complexity> still better than what i had before tho
rgrinberg has joined #ocaml
<d_bot> <tsnobip> for some reason I cannot make ocaml-platform work with esy, every time I choose the sandbox from my project, the following error occurs:
<d_bot> <tsnobip> ```
<d_bot> <tsnobip> Error starting server: Sandbox initialisation failed: ocaml-lsp-server is not installed
<d_bot> <tsnobip> ```
<d_bot> <tsnobip> any idea?
<d_bot> <tsnobip> it used to work quite well, I have no idea what changed, I use ocaml-lsp-server 1.4.1 because I can't upgrade to ocaml 4.12 yet in my project
zebrag has quit [Remote host closed the connection]
zebrag has joined #ocaml
neiluj has quit [Remote host closed the connection]
neiluj has joined #ocaml
<neiluj> Got two functions that are essentially the same except for an inner function that returns a sum type instead of a set
<d_bot> <rgrinberg> @tsnobip how do you confirm that the server is installed in your sandbox?
<neiluj> Are there abstractions that allow to merge them into one function?
<d_bot> <tsnobip> yes when launching a terminal within the sandbox I can run `ocamllsp --help` for example
<d_bot> <rgrinberg> What's the exit code when you run `ocamllsp --version`?
<octachron_> neiluj, this is rather vague. An equally vague answer might be "add enough function arguments". For instance, how is the result of the inner function consumed by the outer function?
<neiluj> yeah.. my bad. Let's show a small sample
<neiluj> here it is: https://bpa.st/Q3OA (based on old and ineficient code)
<neiluj> Also interested in any critique about this piece of obsolete code written in a rush, in order to improve
<neiluj> locate_node and locate_value are exactly the same, except for the return of the inner loop that is a sum type
<neiluj> or maybe that's overthinking it
<octachron_> It feels like the root issue might be that the node_closest functions have different protocols for sucess/delayed/failure returns. Maybe it could work better if you started by unifying this query answer?
<neiluj> oh indeed that's a good perspective
<neiluj> thanks
<d_bot> <tsnobip> it exits normally:
<d_bot> <tsnobip> ```
<d_bot> <tsnobip> ocamllsp --version
<d_bot> <tsnobip> 1.4.1
<d_bot> <tsnobip> ```
gravicappa has quit [Ping timeout: 252 seconds]
<neiluj> hmm it seems that the general search (skeleton) in these two functions could take the inner loop as an argument, with some tweaks
mro has joined #ocaml
mro has quit [Read error: Connection reset by peer]
mro has joined #ocaml
<d_bot> <mimoo> what's the spec for ocaml versions?
<d_bot> <mimoo> I've been trying to parse them with semver, but it looks like opam packages don't follow semver (4.07.1 and v0.14.1 are not valid semver strings)
<d_bot> <mimoo> and is there a package to parse these versions?
<d_bot> <mimoo> looks like ocaml-version doesn't expect a `v` in the start (https://github.com/ocurrent/ocaml-version/blob/master/ocaml_version.ml#L63)
Serpent7776 has quit [Quit: leaving]
mro has quit [Remote host closed the connection]
mro has joined #ocaml
neiluj has quit [Quit: Leaving]
<d_bot> <octachron> The specs for Ocaml versions are the one parsed by ocaml-versions. `v0.14.1` is not a valid version for the compiler. Opam packages are just expected to follow debian convention for version strings.
mro has quit [Quit: Leaving...]
waleee has joined #ocaml
rgrinberg has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
rgrinberg has joined #ocaml
rgrinberg has quit [Client Quit]
rgrinberg has joined #ocaml
cedric has quit [Quit: Konversation terminated!]
<d_bot> <mimoo> so let's say that I have a bunch of dependencies and their versions, some are from opam, some are pinned (to a repo or a path)
<d_bot> <mimoo> how would I go about figuring out a dependency DAG that would work?
<d_bot> <mimoo> actually, how does it work with dune/opam to make sure that all dependencies work out?
rgrinberg has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Tuplanolla has quit [Quit: Leaving.]
GZJ0X_ has quit [Ping timeout: 255 seconds]
rgrinberg has joined #ocaml