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/
Tuplanolla has quit [Quit: Leaving.]
John_Ivan_ has quit [Ping timeout: 246 seconds]
chrisz has quit [Ping timeout: 246 seconds]
chrisz has joined #ocaml
xd1le has quit [Quit: xd1le]
spip has quit [Quit: Konversation terminated!]
<discocaml> <darrenldl> how easy it is to implement recursion scheme in ocaml?
<discocaml> <darrenldl> how easy is it to implement recursion scheme in ocaml?
<dh`> what do you mean by a recursion scheme?
<discocaml> <darrenldl> casually reading this atm: <https://blog.sumtypeofway.com/posts/introduction-to-recursion-schemes.html>
<greenbagels> This insight is so important that I’ll repeat it: recursion schemes are just as essential to idiomatic functional programming as for and while are to idiomatic imperative programming.
<greenbagels> I feel like this is such a strong claim to make
<discocaml> <darrenldl> probably
bgs has joined #ocaml
<discocaml> <darrenldl> reads like basic map and folds are straightforward enough, ill just settle on those
Serpent7776 has joined #ocaml
bgs has quit [Remote host closed the connection]
azimut has quit [Ping timeout: 240 seconds]
mima has joined #ocaml
MarvelousWololo has quit [Read error: Connection reset by peer]
spip has joined #ocaml
kakadu has joined #ocaml
kakadu has quit [Client Quit]
<toastal> Newb question: how to handle big, nested stacks of match … with Nothing -> () Some -> …?
<toastal> I believe I need something ala `bind`, but I don’t know the words to search for in the OCaml context.
<toastal> This is largely mutable code (Lambda Soup) where everything is returning unit.
<discocaml> <bnguyenv> toastal: Option.iter ?
<discocaml> <darrenldl> or define your let binding operators to Option.map and Option.bind
<discocaml> <darrenldl> (with some extra magic possibly)
<discocaml> <kakadu18> https://gitlab.com/Kakadu/fp2020course-materials/-/tree/master/code/origami but with higher kinded types it would be easier
<discocaml> <darrenldl> ooo thanks!
<toastal> Cool to see the course on GitLab
<toastal> darrenldl: what is “define your let binding operator”?
<dh`> ah, that notion of recursion schemes
<toastal> This _sounds_ like the right topic. I think it has something to do with `let*`, no?
<dh`> I would kinda recommend avoiding that, it's a gret way to write incomprehensible code
<discocaml> <darrenldl> toastal: correct, let* for bind and let+ for map usually
<discocaml> <darrenldl> dh`: oh huh, id be interested in learning more - it feels tedious doing ast rewrites constantly, but i havent spent time looking into lifting the core complexity up until now
<discocaml> <octachron> @dar456 , there is a bit of mismatch between OCaml and Haskell here. Defining a fixed-point over type constructors requires a functor in OCaml, whereas recursion scheme can be implemented directly in OCaml without the fixed-point constructor wrapping by using recursive types and polymorphic variants.
<discocaml> <darrenldl> @octachron i think i saw your response to a forum post on the matter
<dh`> darrenldl: I just finished a few months ago ripping a bunch of scrap-your-boilerplate out of a haskell project
<dh`> it doesn't work effectively
<discocaml> <darrenldl> (though the reasoning escapes me - i suspect it'll only make much sense after learning some type theory)
<dh`> in this case the scrap-your-boilerplate library included a code generator... that produced something like 50000 lines of code
<dh`> wasn't entirely clear if that's because it was being misused or if it just sucked :-| but it wasn't the right answer
<discocaml> <darrenldl> dh`: huh. do you personally stick with explicit recursions for ast rewrites (or similar tasks)?
<dh`> at this point, yes
<dh`> it's annoying but you can bang them out fast with editor tricks
<dh`> and because they're type-safe if you change your representation the compiler will alert you to all the changes you need to make
<discocaml> <darrenldl> that is a good point
<discocaml> <darrenldl> maybe i shouldnt lose sleep over it too much
<dh`> and the other thing is, if you write it out explicitly it's clear exactly what it's doing
<dh`> whereas if you try to magick it up there's actually a bajillion slightly different possible variants
<dh`> do you recurse before or after updating the current element?
<dh`> are you actually updating, or just extracting data, or are you doing both?
<dh`> what happens when you need to update the context you're slinging around in this pass?
<discocaml> <darrenldl> gotcha. yeah that makes perfect sense - i thought i was being silly when i wasnt sure how myriad transition rules should look like in recursion schemes, and tho tedious to write, at least its obvious in explicit recursion
<discocaml> <darrenldl> awesome, thanks for the answers dh` and @octachron !
<dh`> in principle there's a bunch of names for the different kinds taken (or possibly cargo-culted) from category theory
<dh`> but
<dh`> it's difficult to keep them straight because the names have little immediate salience
<dh`> also, that only covers the simple forms, and in real code sometimes you need mixtures
<dh`> like recurse first for some constructors and after for others
<dh`> another problem (though it's specific to using haskell typeclasses for this sort of thing) is that because stuff like fmap is very generic, it does _something_ on almost any term you feed it, which means it's easy to accidentally feed it the wrong term and have the wrong thing happen
<dh`> e.g. if you define fmap on your AST fmap on AST elements will do one thing but fmap on lists you might have _in_ the AST will do something else entirely, and that's basically borrowing trouble
bartholin has joined #ocaml
<dh`> but, this isn't #haskell so I'll hush :-)
norris72 has joined #ocaml
norris72 has quit [Quit: Client closed]
<discocaml> <froyo> functors in ocaml don't strictly have the shape `'a t` right? like your functor could be made to be at module level like with `Set`.. this should work with ocaml-flavor recursion schemes, right?
waleee has joined #ocaml
Anarchos has joined #ocaml
gareppa has joined #ocaml
Anarchos has quit [Quit: Vision[]: i've been blurred!]
waleee has quit [Ping timeout: 260 seconds]
alexherbo2 has joined #ocaml
alexherbo2 has quit [Remote host closed the connection]
alexherbo2 has joined #ocaml
alexherbo2 has quit [Remote host closed the connection]
MarvelousWololo has joined #ocaml
bgs has joined #ocaml
John_Ivan_ has joined #ocaml
norris11 has joined #ocaml
MarvelousWololo_ has joined #ocaml
<chrisz> Is it possible to construct a record of type { x : 'a. ((unit -> 'a) * ('a -> unit)) list; } where x is not [].
<chrisz> I intend to run something like this function on such a list: let process { x } = List.iter (fun (a, b) -> b (a ())) x
MarvelousWololo has quit [Ping timeout: 245 seconds]
norris11 has quit [Quit: Client closed]
norris61 has joined #ocaml
<discocaml> <froyo> `type 'a nonempty = 'a * 'a list`
<discocaml> <froyo> `let to_list (x, xs) = x::xs`
<chrisz> hmm, no. Let me try to simplify my problem. For the following type:
<chrisz> type poly = { x : 'a. ('a -> unit) * 'a; }
<chrisz> I can define a function applying 'a to ('a -> unit):
<chrisz> let apply { x = a,b } = a b;;
<chrisz> Now I would like to construct a value:
<chrisz> { x = ignore, 5 };;
<chrisz> but this is not allowed:
<octachron> This is the wrong quantification.
<chrisz> Error: This field value has type (int -> unit) * int which is less general than 'a. ('a -> unit) * 'a
<discocaml> <Et7f3 (@me on reply)> let v = (ignore, 5)
<discocaml> <Et7f3 (@me on reply)> { x = v; }
<octachron> If you have a value of type `'a. 'a * _ `, you have a value of type `'a`, and thus you have proved false.
<discocaml> <Et7f3 (@me on reply)> Ah 🤦🏻
<octachron> You meant `type creation_annihilation= X: (unit -> 'a) * ('a -> unit) -> creation_annihilation`
<chrisz> octachron: so I need to use a GADT?
<octachron> (aka an existential quantification)
norris61 has quit [Ping timeout: 246 seconds]
<octachron> Indeed, you need to use GADT (or first-class module) to get an existential quantification.
<discocaml> <froyo> ohhhh right
<chrisz> thanks :)
<discocaml> <froyo> nonempty def would be useless with forall o\\
azimut has joined #ocaml
waleee has joined #ocaml
mima has quit [Ping timeout: 245 seconds]
mima has joined #ocaml
tom1212 has joined #ocaml
<tom1212> hey :)
<tom1212> the ocaml typechecker is stuck on my program
John_Ivan_ has quit [Quit: Disrupting the dragon's slumber one time too often shall eventually bestow upon all an empirical and indiscriminate conflagration that will last for all goddamn eternity.]
<discocaml> <._null._> Are you sure ? What is it stuck on ?
<tom1212> if I give a name to the third parameter of the functor the error is warning 67 [unused-functor-parameter]): unused functor parameter _
<tom1212> but if I don't provide a name, dune build @check -j 6 is stuck
<tom1212> but ocamllsp reports an error
<discocaml> <lecondorduplateau> lmao
John_Ivan has joined #ocaml
<discocaml> <xavierm02_> This probably has nothing to do with the warning. Warnings stop the compilation by default, so all you can deduce from the behavior you observed is that whatever makes dune stuck is after this functor
<tom1212> oh UnivariatePolynomial_sig is a recursive signature
<tom1212> module rec Univariate_polynomial_sig : sig module type Sig = sig type t type coeff val convert : (coeff -> 't) -> (module Univariate_polynomial_sig.Sig with type coeff = 't and type t = 'p and type C.t = 't) -> t -> 'p
<tom1212> end end
<tom1212> that might be the culprit
<tom1212> perhaps some missing constraints in the functor?
MarvelousWololo_ has quit [Ping timeout: 245 seconds]
waleee has quit [Ping timeout: 244 seconds]
waleee has joined #ocaml
Wojciech_K has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
<tom1212> ocaml type checker semiprone today
<octachron> tom1212, note that in general, you really don't want to store or include functor argument in signature. This is an easy way to end up with unusable module due to missing type equality.
tom1212 has quit [Remote host closed the connection]
tom1212 has joined #ocaml
tom1212 has quit [Ping timeout: 246 seconds]
tom1212 has joined #ocaml
gareppa has quit [Quit: WeeChat 3.8]
<tom1212> I see, thanks
Serpent7776 has quit [Quit: leaving]
<discocaml> <xavierm02_> Let's call "module extension" any unary functor that extend its argument, e.g. `functor (M : S) = struct include M ... end`. Is allowing such functor to include all of `M` and not just `(M : S)` (in the particular case of "module extensions", not for general functors) known to be incompatible with something else in the OCaml typing system?
bartholin has quit [Quit: Leaving]
<discocaml> <xavierm02_> Let's call "module extension" any unary functor that extends its argument, e.g. `functor (M : S) = struct include M ... end`. Is allowing such functor to include all of `M` and not just `(M : S)` known to be incompatible with something else in the OCaml typing system (in the particular case of "module extensions", not for general functors)?
<discocaml> <xavierm02_> (A priori one would want to represent these as a combination of signatures and modules, e.g. `functor (M : sig val f : int -> int end) = struct include M let g x = f (f x) end` could be `partialstruct val f : int -> int let g x = f (f x) end`, but this is most likely isomorphic, so I framed the question in the existing syntax)
bgs has quit [Remote host closed the connection]
mima has quit [Ping timeout: 245 seconds]
tom1212 has quit [Remote host closed the connection]
Tuplanolla has joined #ocaml
Tuplanolla has quit [Quit: Leaving.]
szkl has joined #ocaml