racket / rhombus

Rhombus programming language
Other
333 stars 59 forks source link

Monads as part of standard language or library #82

Open arvyy opened 5 years ago

arvyy commented 5 years ago

Both scheme and racket are inclined into functional programming. Monads is a useful (albeit not a required) tool for functional programming. Monads don't need to be so syntax sugared or have imposed usage like in Haskell; but having an official option for the most common ones would be nice.

At least one technical challenge I'm aware of, is that generic interfaces on structs in typed racket do not work, which could've been useful for succinct api.

jackfirth commented 5 years ago

Monads seem somewhat less useful in a functional programming language that allows side effects, such as scheme, racket, or ocaml. I'd expect a standard monad interface to be a part of something like Hackett, not Racket.

arvyy commented 5 years ago

I'd argue eg. option / either / list monads are useful regardless of language's ability to have direct mutability or side effects. FWIW, I barely know haskell; my inspiration for monad inclusion actually comes from working with Java (vavr library)

dedbox commented 5 years ago

Racket already has monads lurking in every corner of its API. Did you know Racket's flavor of truthiness is a somewhat confused monad? Having a dedicated Fail or Nothing value has saved my ass more than once. I think a focused set of abstractions for expressing algebraic properties and a library that exploits those properties for base Racket types is a great idea.

rocketnia commented 5 years ago

Having recently refactored the implementation of my language to use a more fully monadic style, I can attest that Racket's parameters are really annoying to reconcile with monads. I was trying to use a parameter and somehow keep it in scope for the entire time my deterministic concurrency monad was operating, but in the end I ended up preferring to do a reader transformation on my monad instead of using a parameter.

Why do I have a deterministic concurrency monad in the first place? Because the first implementation strategy I can think of has nothing to do with using channels and semaphores, just writing a manual arbiter looping over a list of blocked computations. Maybe at some point I'll find it's more performant if I refactor it to use threads or futures, but this is good enough for now.

jackfirth commented 5 years ago

I agree monads can still be useful in untyped code. With regards to how they could fit into racket2, I'm imagining one of two options:

  1. There's a standard monad interface and some utilities for working with them in a generic way.
  2. Same as 1, and also various other core libraries expose monads in their API somehow (e.g. the standard list type implementing a hypothetical gen:monad interface).

These seem like two very different ideas, with the second being significantly more invasive than the first since we'd have to make sure to design all the other standard APIs in a monadic way. I'm not necessarily opposed to either option, but I think it's important to treat them as different choices.

LiberalArtist commented 5 years ago

@lexi-lambda has a package that provides, among other things, gen:monad, including an implementation for lists: https://docs.racket-lang.org/functional/index.html