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.]
<d_bot> <Splingush> I don't know the specifics, but it's done internally by mutating that *block*. So it only computes it once, and stores the result. You could make something similar yourself with a record that has mutable fields, or a ref, and passing a closure that will be called on the first forcing.
<d_bot> <Splingush> Something like this: <https://sketch.sh/s/fjAeH0CTHHoucrIK3FPwxj/>
<d_bot> <monk> that's super illuminating, thank you 🙂
<d_bot> <Splingush> Ocaml does it more low-level, though: <https://github.com/ocaml/ocaml/blob/trunk/stdlib/camlinternalLazy.ml#L64-L65>
<d_bot> <Splingush> But I think the gist is the same 🙂
<d_bot> <monk> i found these notes to be very illuminating
<d_bot> <monk> it's that cs3110 class, but older notes rather than the current text. it's roughly the same material but it's much more step by step than the current textbook which i found a tad more illuminating
<d_bot> <monk> been really trying to get into the habit of grepping through ocaml's stdlib source to get a feel for things but i will hit that lower level stuff that just bounces right off of me
<d_bot> <monk> interesting that it's done using OCaml objects
<d_bot> <Splingush> There is a newer series with videos too, let me find it.
<d_bot> <Splingush> <https://cs3110.github.io/textbook/cover.html> this. But I think it's not complete yet.
<d_bot> <Splingush> Yeah, some of the github-code is easy to read, and reading interface-files is often the go-to way for libraries as well. But others not so much, yeah 😄
<d_bot> <monk> i actually looked for the video first which is when i realized he's slowly releasing them/they're not all done 😅
<d_bot> <monk> oh wow but this is news to me
<d_bot> <monk> didn't know he was porting it from gitbook
<d_bot> <Splingush> It's pretty amazing. You can evaluate the code inline.
<d_bot> <monk> yeah wow
<d_bot> <monk> this is really cool as a format
<d_bot> <monk> inlined snippet videos with the inlined code
<d_bot> <monk> that you can also eval and experiment with
<d_bot> <monk> that's so cool
<d_bot> <Splingush> Like jupyter-notebooks.
<d_bot> <monk> huge fan of this, wow
hackinghorn has quit [Ping timeout: 272 seconds]
favonia has quit [Ping timeout: 268 seconds]
favonia has joined #ocaml
<d_bot> <arcollector> i used cs3110 as my first ocaml tutorial
<d_bot> <arcollector> incredible how popular is this course
<d_bot> <monk> speaking of which, think im experiencing one of my first real "ah ha!" moments thanks to his notes while reading this small parser combinator library lol
<d_bot> <arcollector> you at Interpreters chapters? i skip that chapter along proof one completly 😛
<companion_cube> I think "crafting interpreters" has been released
<companion_cube> Maybe I should buy it
<d_bot> <monk> i'm currently just using it ad-hoc for when i want to understand something better
<d_bot> <monk> i started with real world ocaml, which is very good, but i'm realizing i want to know more about ocaml's idea of fp etc and cs3100 seems much more attuned to that
<d_bot> <monk> so i think i'll be switching over to cs3100 very soon and working out of that
<d_bot> <monk> and maybe coming back to real world ocaml later for stuff like menhir, sexp/ppx etc
<d_bot> <monk> so i'm reading through the opal parser combinator library since it's very short and succinct and i'm wondering why the author defined a `monad` type when it seemingly never gets used explicitly
<d_bot> <monk> but its type signature clearly is used in another type
<d_bot> <monk> does this make it some kind of type alias?
<d_bot> <monk> see here:
<d_bot> <monk> ```ocaml
<d_bot> <monk> type 'token input = 'token LazyStream.t
<d_bot> <monk> type ('token, 'result) monad = ('result * 'token input) option
<d_bot> <monk> type ('token, 'result) parser = 'token input -> ('result * 'token input) option
<d_bot> <monk> ```
<d_bot> <monk> the returned type of `parser` is clearly a monad as defined right above it so i'm confused as to why `monad` is not used then
<d_bot> <monk> ie why not just
<d_bot> <monk> ```ocaml
<d_bot> <monk> type ('token, 'result) parser = 'token input -> monad
<d_bot> <monk> ```
<d_bot> <monk> ?
wilfred has quit [Quit: Connection closed for inactivity]
<d_bot> <theangryepicbanana> I'd say it's because anyone who uses monads like that tends to over complicate everything related to them for no good reason
<d_bot> <monk> not sure i agree in this case, the library is rather nice and to the point!
<d_bot> <monk> i think it may have been something they wrote but never ended up using
<d_bot> <monk> because it doesn't even appear in the .mli file
<d_bot> <theangryepicbanana> also happens occasionally
<d_bot> <theangryepicbanana> would be funny if it ocaml had warnings for unused types
<d_bot> <monk> esp since the readme makes it sound that this is sort-of a translation of the haskell parsec library
<d_bot> <theangryepicbanana> well then the monad thing makes more sense
<d_bot> <monk> i think... i think rust does this, actually
<d_bot> <theangryepicbanana> yeah it does
<d_bot> <monk> the usage of monads here makes a lot of sense because it's a parser combinator library, and to my knowledge the vast majority of parser combinators are described in terms of monads
<d_bot> <monk> the only time i haven't seen the word explicitly invoked is actually with Nom
<d_bot> <theangryepicbanana> but like haskell is basically monads: the language, so I'm sure parsec uses them a lot and they had to compensate for that while writing the ocaml lib
<d_bot> <theangryepicbanana> maybe they had started refactoring and never finished? dunno
<d_bot> <monk> i think that's partly the case
<d_bot> <monk> i think i learned a lot tonight by reading and figuring out what this parser library is doing
<d_bot> <monk> actually happy about it
<d_bot> <monk> rare
<d_bot> <monk> mparser is another good parser combinator lib for ocaml
<d_bot> <monk> but it looks more in the nature of how angstrom is implemented
<d_bot> <monk> which is to say, it's more OCaml-y by embracing strictness afaict and using byte buffers to move over input i think
<d_bot> <monk> which is going to be a lot more performant if i had to guess compared to the lazy equivalent in OCaml
<d_bot> <monk> /i'd guess/
<d_bot> <monk> by that fact, however, i'm not sure you'd be able to write a byte buffer parser combinator library that's similarly succinct as the ~150LoC that Opal achieves
<d_bot> <monk> enough talking to myself though, this was fun and i learned a lot
zebrag has quit [Remote host closed the connection]
gravicappa has joined #ocaml
hackinghorn has joined #ocaml
bartholin has joined #ocaml
mro has joined #ocaml
Tuplanolla has joined #ocaml
dhil has joined #ocaml
Serpent7776 has joined #ocaml
<d_bot> <Competitive Complications> oof. quite a bother.
<d_bot> <Competitive Complications> is there a ppx that does it for you then? typing `ppx stack trace` yields `ppx let loc`, but i want it for non-monadic cases
mro has quit [Remote host closed the connection]
andreypopp_ has joined #ocaml
andreypopp has quit [Ping timeout: 252 seconds]
mro has joined #ocaml
mro has quit [Remote host closed the connection]
mro has joined #ocaml
yoctocell has joined #ocaml
<d_bot> <Competitive Complications> I'm using printf debugging instead, but the result of `ppx show` are pretty messed up in their indentation
mro has quit [Remote host closed the connection]
mro has joined #ocaml
favonia has quit [Ping timeout: 272 seconds]
olle has joined #ocaml
vicfred has quit [Quit: Leaving]
oriba has joined #ocaml
mro has quit [Remote host closed the connection]
mro has joined #ocaml
mro has quit [Remote host closed the connection]
mro has joined #ocaml
oriba has quit [Quit: https://quassel-irc.org - Chat comfortably. Anywhere.]
mro has quit [Remote host closed the connection]
mro has joined #ocaml
mro has quit [Remote host closed the connection]
<d_bot> <Competitive Complications> How does dune utop print recursive values? How can it know when there is a cycle?
<d_bot> <Competitive Complications> Alternatively, do I have the guarantee that there will never be a GC pass during a given function call that never polls/stops/does-await-thing?
<d_bot> <ggole> Keeps a table of addresses seen, and prints `<cycle>` if it finds something in the table
<d_bot> <ggole> GC can happen at any allocation, so you have to be very careful and know a fair amount about how the compiler works to write code that will not GC
<d_bot> <Competitive Complications> @ggole I see. And that's how dune utop does it? With a lot of care in their printing code?
<d_bot> <ggole> No, that's written in C
<d_bot> <octachron> No? The printing code of the toplevel is in pure OCaml.
<d_bot> <ggole> Oh yeah, I just looked at it
<d_bot> <octachron> However, the REPL is not printing its own data, but the data of the evaluated code. The supplementary interpretation layer helps here.
<d_bot> <Competitive Complications> But isn't the evaluated data regular OCaml data? Or do you mean that utop replicates GC?
<d_bot> <octachron> It is more than the REPL has a full view of the interpreted world. Thus it can select printers according to the types or have a table of live data for instance. But looking at the code, the printer is just using a hash table of visited objects. That doesn't require any special interaction with the GC.
<d_bot> <Competitive Complications> But if during the printing, there is a GC pass, doesn't the hash table of visited objects become unsynchronised with addresses becoming obsolete?
<d_bot> <octachron> The hash is structural, and only the equality is physical equality.
<d_bot> <octachron> Since GC passes preserve both the structural contents, and physical equality between pair of objects in the buckets, this works without breaking the value abstraction.
mro has joined #ocaml
favonia has joined #ocaml
<companion_cube> Isn't there an ellipsis, too? Making the printing finite no matter what
mro has quit [Ping timeout: 272 seconds]
waleee has joined #ocaml
<d_bot> <ggole> Yeah, although you can `#print_depth max_int`
<d_bot> <ggole> (Or at least paste the equivalent value.)
berberman_ has joined #ocaml
berberman has quit [Ping timeout: 256 seconds]
<d_bot> <Competitive Complications> I see, I thought that for performance reasons the hash might not be structural
<d_bot> <Competitive Complications> hmmmm
average has joined #ocaml
<companion_cube> it's structural but there's also a depth limit
<d_bot> <Competitive Complications> Just checking, because one never knows, but OCaml doesn't enable manual memory management for select pieces of code, right?
<companion_cube> nope
<d_bot> <Competitive Complications> how does ocaml compare recursive polymorphic variant types internally? it looks like one could reduce graph isomorphism into it
<companion_cube> hmm unification with row polymorphism I think?
<d_bot> <Competitive Complications> i see
<d_bot> <Competitive Complications> (i'm trying to compare cyclic data structures produced with rectypes)
<d_bot> <octachron> Unification with aliases to encode cycles and the restriction that recursive types are regular.
<d_bot> <Competitive Complications> What does `regular` mean in the context of rectypes?
<d_bot> <octachron> A finite number of subexpressions up to isomorphism.
<d_bot> <ggole> ```ocaml
<d_bot> <ggole> # type 'a t = 'a t t list;;
<d_bot> <ggole> Line 1, characters 0-23:
<d_bot> <ggole> 1 | type 'a t = 'a t t list;;
<d_bot> <ggole> ^^^^^^^^^^^^^^^^^^^^^^^
<d_bot> <ggole> Error: This recursive type is not regular.
<d_bot> <ggole> The type constructor t is defined as
<d_bot> <ggole> type 'a t
<d_bot> <ggole> but it is used as
<d_bot> <ggole> 'a t t.
<d_bot> <ggole> All uses need to match the definition for the recursive type to be regular.
<d_bot> <ggole> ```
<d_bot> <octachron> ^ This is not-regular because every expansion of the abbreviation creates new expressions
<d_bot> <ggole> Although perhaps `type 'a t = int t list` is a less confusing example... I don't think I've ever actually run into this error while programming.
<d_bot> <octachron> They can appear if you try to translate a non-regular variant `type 'a btree = Leaf of 'a | Node of ('a * 'a) btree` into a polymorphic variant.
<d_bot> <Competitive Complications> Oh wow. I did not know that would fail.
<d_bot> <Competitive Complications> Are there monomorphic non-regular rectypes?
<d_bot> <Competitive Complications> There might be a similar restriction at the value-level that I don't get: `let rec x = (3 , x)` works, but not `let f x = (3 , x) in let rec x = f x`
<d_bot> <Competitive Complications> It says that "this kind of expression is not allowed", but I have no idea what that kind of expression is.
<d_bot> <octachron> No, since a type constructor without arguments always count for one subexpression.
<d_bot> <octachron> The rules for recursive values are briefly explained here https://ocaml.org/manual/letrecvalues.html . In your case, the issue is that the function `f` might peek at the value under construction.
<d_bot> <octachron> I find the explanation in https://arxiv.org/abs/1811.08134 a clearer than the one in the manual.
<d_bot> <Competitive Complications> I want to peek at the value under construction, but the restriction does make sense.
dhil has quit [Remote host closed the connection]
<d_bot> <Competitive Complications> I was trying to avoid it, but I guess in the end, I do have to add an indirection layer in my ASTs.
<d_bot> <ggole> What are you actually trying to do?
Anarchos has joined #ocaml
<companion_cube> OCaml tries hard to never show you an incomplete value
mro has joined #ocaml
mro has quit [Remote host closed the connection]
mro has joined #ocaml
mro has quit [Remote host closed the connection]
<d_bot> <Competitive Complications> To add recursive values to a big-step interpreter
mro has joined #ocaml
<companion_cube> Mutability is useful for cycles
<companion_cube> And/or lazy
mro has quit [Remote host closed the connection]
<d_bot> <Competitive Complications> i'm ok with mutability, less ok with mutability + none
mro has joined #ocaml
<d_bot> <Competitive Complications> but yeah, that's what i meant by "a layer of indirection" in the ast, as in, no way around making the ast aware of it
<d_bot> <Competitive Complications> that's a bit sad to me, given that OCaml already deals with this under the hood
mro has quit [Remote host closed the connection]
<companion_cube> Well OCaml isn't the best language for writing a fast interpreter
mro has joined #ocaml
mro has quit [Remote host closed the connection]
mro has joined #ocaml
<d_bot> <Competitive Complications> the goal of avoiding the indirection is not for it to be fast, but rather for it to be simple (like, the way it's easier to use the host language's higher order functions / exceptions / state for the interpreted one)
<d_bot> <Competitive Complications> also, to learn a bit more about ocaml stuff that i don't usually do 😄
rsd has quit [Quit: Connection closed for inactivity]
mro has quit [Remote host closed the connection]
<Anarchos> i need to add a system library to compile wait3_stubs.c from dune. I added (c_library_flags -lbsd) in otherlibs/stdune-unstable/dune, but it seems not enough, i don't know what else i am missing
olle has quit [Remote host closed the connection]
terrorjack has quit [Remote host closed the connection]
terrorjack has joined #ocaml
gravicappa has quit [Ping timeout: 250 seconds]
<Corbin> Ah, by refining a previous question, I finally found something that helped: https://stackoverflow.com/questions/7261248/how-can-ocaml-values-be-printed-outside-the-toplevel
<Corbin> It seems that, unlike in many other languages, even debug-level pretty-printing is not compiled in by default. That makes a sort of sense.
average has quit [Quit: Connection closed for inactivity]
<Corbin> companion_cube: Okay, I wrote code to use ocamlc's deprecated -annot flag to spit out a textual version of an incomplete module's type. Then I wrote some Python to complete the type, and bam: https://bpa.st/DG3A
<Corbin> Clearly there are some new design issues to work out~
haesbaert has quit [Remote host closed the connection]
wilfred has joined #ocaml
bartholin has quit [Quit: Leaving]
<companion_cube> Corbin: you could also read .cmt files
<Corbin> companion_cube: I looked into that a little, but I couldn't find a way to do it. I found some stale suggestions on Stack Overflow, but the compiler libs have changed since then.
<companion_cube> It's all unstable
<Corbin> Yeah. The paradox of language is that "Z.t -> bool" is unlikely to change much!
Melantha has quit [Quit: WeeChat 3.2]
haesbaert has joined #ocaml
<companion_cube> Well sure, that part of the typed tree might not change much
<d_bot> <andreypopp> So I've found out about e-graphs and their application to term rewriting... now does anyone know if there's an OCaml implementation?
<companion_cube> Heh, Corbin was talking about them
<companion_cube> Did you read the Egg paper @andreypopp?
<d_bot> <andreypopp> Was watching talks from JuliaCon, they had a talk about Metatheory.jl which is egg ported to Julia. So yeah, in the middle of the egg paper now (not a fast paper reader).
<companion_cube> There are some congruence closures in OCaml, but not exactly like Egg, afaik
<companion_cube> (I plan to modify mine to do it though)
<companion_cube> (it's part of a bigger project)
Tuplanolla has quit [Quit: Leaving.]
Anarchos has quit [Quit: Vision[0.10.3]: i've been blurred!]
yoctocell has quit [Ping timeout: 258 seconds]
<Corbin> You can try porting the Rust. They mix structs and mutability a fair amount, though. So far, wrapping the Rust hasn't been a disaster, either; OCaml-flavored sexps are relatively close to Egg's builtin SymbolLang.
<companion_cube> I personally need a lot more than what the rust does
<companion_cube> Backtracking, and explanations