companion_cube changed the topic of #ocaml to: Discussion about the OCaml programming language | http://www.ocaml.org | OCaml 5.2.0 released: https://ocaml.org/releases/5.2.0 | Try OCaml in your browser: https://try.ocamlpro.com | Public channel logs at https://libera.irclog.whitequark.org/ocaml/
Tuplanolla has quit [Quit: Leaving.]
raskol has quit [Ping timeout: 265 seconds]
f[x] has joined #ocaml
spew has joined #ocaml
YuGiOhJCJ has joined #ocaml
myrkraverk has quit [Read error: Connection reset by peer]
myrkraverk has joined #ocaml
spew has quit [Read error: Connection reset by peer]
raskol has joined #ocaml
bartholin has joined #ocaml
bartholin has quit [Client Quit]
f[x] has quit [Remote host closed the connection]
<dh`> contificate: sorry, didn't mean to drop a bomb and disappear, got yoinked away and then forgot about it
<dh`> so sure, if you have a bunch of threads you can think of them as continuations and implement it that way, and at some level that's what every thread library is, but:
<dh`> (a) _writing_ in continuation-passing style is horrible; if you want cps code you should have a compiler cps-convert it for you
<dh`> (b) you _can_ stuff the whole thing in a monad because it's all turing-complete, but it's gross
<dh`> what you _could_ have is effectively one monad per task (because your tasks are sequential, that's the point of this kind of library) that join and split again at coordination/interaction points
<dh`> that is, that's how you would like to write the code
<dh`> (and that's _not_ a monad)
<dh`> anything else starts imposing pieces of the implementation structure on the client code, and that's always going to be ugly
<dh`> but I guess my core point was: asynchronous operations are inherently not sequential and monads are inherently sequential
raskol has quit [Ping timeout: 252 seconds]
bartholin has joined #ocaml
toastal has joined #ocaml
<discocaml> <contificate> nobody is saying it's a convenient way to program - the "function colouring" problem pervades implementations, monads in OCaml 4 and `async` prefixes in other languages
<discocaml> <contificate> you were attacking the monadic interface as if you think there's something special about monads
<discocaml> <contificate> when in reality, monads are just a design pattern around CPS
<discocaml> <contificate> which is being used solely to expose a `k` that the scheduler can use
<discocaml> <contificate> like "it's not a monad" means absolutely nothing if you only view monadic style as a kind of operational construct
<discocaml> <contificate> which I do, I would violate the monad laws in a heartbeat if it was convenient for me
<discocaml> <contificate> all this to say it's like probably one of the best ways to program and have async as a library without actually having language support
<discocaml> <contificate> what would be the alternative? there's papers that lower delimited control for async programming into the delimited control monad and work that way, is that not a monad?
<discocaml> <contificate> but, still, I still kind of disagree - almost every async programming library treats async programming as synonymous with the concept of "non-blocking", so you write code that would appear to block but things actually return immediately
<discocaml> <contificate> so it's sequential at the source level, but may not happen in that order, as the event loop/scheduler will progress concurrently
Anarchos has joined #ocaml
toastal has left #ocaml [Disconnected: Hibernating too long]
Serpent7776 has joined #ocaml
<discocaml> <gooby_clown> I think the core thing is that eventually you'll have to await your async thingy, and that's just bind
<discocaml> <contificate> yes, but the whole reason you can introduce arbitrary - scheduled - delay into this is because your have an explicit notion of "the rest of the computation" (the continuation)
<discocaml> <contificate> without actually needing much runtime language support for it
<discocaml> <contificate> the use of monads here are purely as an operational construct, to introduce functional sequence points into your program, so that an external event loop can call you back when results become available
Tuplanolla has joined #ocaml
<discocaml> <gooby_clown> I think Koka for example even compiles all the effects to monads somewhere down the line, at least for non-linear effects, but I don't know much about it
<discocaml> <contificate> yeah it does, but my understanding is that direct implementation is usually better - Koka probably has to do a fair amount of inlining
<discocaml> <gooby_clown> Whereas delimited continuations (as opposed to monads) already have good performance? Though then I assume the monadic translation was just easier to implement
<discocaml> <contificate> direct implementation tends to imply runtime support, OCaml 5 uses a segmented stack representation to split off computation contexts (caml_alloc_stack and caml_runstack)
<discocaml> <contificate> whereas I believe js_of_ocaml does a CPS translation
<discocaml> <contificate> Asai et al have papers about lowering shift/reset, which is arguably more general than the one-shot continuations of OCaml 5 (ignoring any extension work), which describe the stack copying idea explicitly - but one-shot implies you don't really need to copy the frames, you can just relink the parent pointer
<discocaml> <gooby_clown> Tbf I can't think of any non-parlour trick situations where multishot is necessary
toastal has joined #ocaml
<discocaml> <contificate> think oni linked an Oleg blog that had a more motivating example than non-determinism
gareppa has joined #ocaml
<discocaml> <qrpnxz> nondet is a pretty motivating example. Good enough for me
Anarchos has quit [Quit: Vision[]: i've been blurred!]
deadmarshal_ has quit [Quit: IRCNow and Forever!]
Anarchos has joined #ocaml
gareppa has quit [Quit: WeeChat 4.1.1]
Serpent7776 has quit [Ping timeout: 252 seconds]
deadmarshal_ has joined #ocaml
masterbuilder has quit [Quit: https://quassel-irc.org - Chat comfortably. Anywhere.]
YuGiOhJCJ has quit [Quit: YuGiOhJCJ]
masterbuilder has joined #ocaml
pi3ce has quit [Read error: Connection reset by peer]
pi3ce has joined #ocaml
raskol has joined #ocaml
raskol has quit [Ping timeout: 272 seconds]
<companion_cube> I'd love to hear a motivating example tbh
<companion_cube> Nondet isn't one in my book
raskol has joined #ocaml
<dh`> speculation?
<dh`> anyway I wasn't _attacking_ the monad interface, I was saying it isn't desirable
<dh`> and it isn't natural
Serpent7776 has joined #ocaml
<dh`> if you're going to be implementing (uniprocessor, cooperative) threads as a library, you can have whatever user-facing interface you want; all you need from the language runtime is a way to manage contexts and callcc under the covers is perfectly adequate
<dh`> (ideally you also _want_ the language runtime to give you yield callbacks at strategic points, but it's perfectly possible to do without that and you can even still have preemptive scheduling)
<dh`> in haskell you would be forced to stuff your state into a monad, but this isn't haskell
<dh`> and in the user-facing interface all you _need_ is a type H to refer to thread handles and two operations fork: (unit -> 'a) -> 'a H and wait: 'a H -> 'a
<dh`> though in practice you also want an explicit way to disable and re-enable context switches (both of which operations have type unit -> unit)
<dh`> everything higher-level you can build on top of that
<dh`> well, that and yield
<dh`> there is nowhere in here that stuffing in monad ops helps
<dh`> (and note that H is not a monad)
<companion_cube> wdym "speculation"?
<dh`> speculative execution
<dh`> which does not need to be only a hardware thing
<companion_cube> sounds like you can only make that work for purely functional code, and I don't really see the relation to effect
<companion_cube> s
<dh`> you need a rollback system, but that's possible
<dh`> (not even all that costly)
<companion_cube> yeah I wouldn't use effects
<dh`> but as far as effects, probably not
<companion_cube> if you look at kcas, it's a transactional data structure library and it doesn't use effects
<dh`> I was just thinking about multishot continuations
<companion_cube> (I mean it uses one shot effects rather)
chiselfuse has quit [Ping timeout: 260 seconds]
chiselfuse has joined #ocaml
raskol has quit [Ping timeout: 260 seconds]
<discocaml> <contificate> well, originally it started out as you criticising the usage of a monadic interface for Lwt and Async
<discocaml> <contificate> then I tried to explain why they did it like that w.r.t not modifying the OCaml 4 runtime - purely writing in a source language using monads for their CPS structure, to benefit the library
<discocaml> <contificate> nobody thinks it's the greatest thing ever; if they did, there would be absolutely zero push for effects
germ has quit [Read error: Connection reset by peer]
germ has joined #ocaml
<dh`> well right
<dh`> anyway I gather you mean it seemed like the best way to get at continuations in order to use them as threads
<dh`> i'm not convinced that (was) true but it's also not worth raking up
<discocaml> <contificate> it's not bad if you don't have runtime support
<discocaml> <contificate> like look at the simplest scheduler examples in effects papers
<discocaml> <contificate> not going to make any formal claim here, but:
<discocaml> <contificate> to some extent, such schedulers are isomorphic to if you had CPS converted your program at source and trampolined it
<discocaml> <contificate> pulling of a queue of continuations and evaluating consecutive thunks are very similar modes of operation
<dh`> that is true but ultimately it's about how one can extract a continuation context from the preexisting language and runtime support
<dh`> which is a quite different question from how one would design it for real
<dh`> what I reacted to was "it's quite suitable for these kinds of things" ("it" being monadic style), which in the general case it's definitely not
<dh`> and because I'd wandered in and out I didn't share the specific context of what can and can't be done natively in ocaml 4
<dh`> iow, I doubt we're actually disagreeing on anything
<dh`> unless you _do_ want to argue that a monadic interface is an appropriate way to design a new threading/concurrency library, and in that case I'm happy to disagree at length :-)
<adrien> I'm trying to use merlin in vim with jsoo's ppx; dune is configured properly so I was expecting things to be working automatically but omnicompletion seems to have troubles on ## and ##. ; am I missing something?
<adrien> I finally found "dune ocaml dump-dot-merlin bin" and this doesn't show anything for EXT or PKG
raskol has joined #ocaml
<adrien> it seems to work better overall (but not completely) if I don't do that in an executable
<discocaml> <contificate> > monadic interface is an appropriate way to design a new threading/concurrency library
<discocaml> <contificate> definitely not, so we don't disagree
<dh`> thought so :-)
Anarchos has quit [Quit: Vision[]: i've been blurred!]
raskol has quit [Ping timeout: 260 seconds]
bartholin has quit [Quit: Leaving]
Serpent7776 has quit [Ping timeout: 276 seconds]
raskol has joined #ocaml
raskol has quit [Ping timeout: 255 seconds]
raskol has joined #ocaml