"Monad I Love You Now Get Out Of My Type System" by Gjeta Gjyshinca (Strange Loop 2022)

Поділитися
Вставка
  • Опубліковано 11 лис 2024
  • Traditionally, libraries that support asynchronous execution invade the type system, with monad-like constructs changing function signatures, and execution concerns inevitably leaking into business logic.
    Our platform is different. Automated asynchronous execution; caching; a bitemporal data store; distribution; dependency tracking - these are just some of the core features our platform provides. And what do our users see? For the most part, five extra characters, @node, a guarantee of referential transparency for our compiler and runtime.
    Built on top of Scala and now a decade old, our platform draws on ideas from the Scala community to provide a solution for a programming framework that truly separates business logic from execution concerns. At last, it's being open-sourced, and it will run on cloud. Join this session to see live coding demos and a whole new paradigm for concurrency.
    Gjeta Gjyshinca
    Software Developer, Morgan Stanley
    Gjeta is a software developer at Morgan Stanley, working on the core of the platform she will present. Her work focuses on the cache and the scheduler, with a big focus on performance. Gjeta is involved in Morgan Stanley's volunteering efforts to teach students to code, expanding the programme in London and now involved in teaching at schools in New York. She has also worked with Global Code to teach students in Ghana, and is now involved in Talent Beyond Boundaries, a charity helping skilled refugees find work.
    ----- Sponsored by: -----
    Stream is the # 1 Chat API for custom messaging apps. Activate your free 30-day trial to explore Stream Chat. gstrm.io/tsl
  • Наука та технологія

КОМЕНТАРІ • 57

  • @MeNowDealWIthIt
    @MeNowDealWIthIt 2 роки тому +127

    Her: "As you all presumably know, a monad is"
    Me: "A monoid in the category of endofunctors!"
    Her: "A container or wrapper that abstracts away execution concerns"
    Me: "That makes a bit more sense than the thing I learned to parrot, but no I actually don't know what a monad is."

    • @DF-ss5ep
      @DF-ss5ep 2 роки тому +5

      It's a wrapper and you can merge a bunch of wrappers in any order.

    • @gabedamien
      @gabedamien 2 роки тому +5

      @@DF-ss5ep mmmm, it depends on exactly what you mean. For example that description arguably is more specific to semigroups and monoids than for monads. There is an associative operation for monads, namely, kleisli composition, but it's not how we always think about monads practically speaking.

  • @danchatka8613
    @danchatka8613 2 роки тому +38

    Excellent presenter.
    Would love to hear this same presenter discussing the topic next year, to find out if it worked as well as planned.
    Elaborate optimization frameworks can take on a life of their own, have unexpected side-effects, and become unmaintainable. Ideally, if the framework is successful long-term, it would become the basis of an open source library with a wider support base.

  • @batlin
    @batlin 2 роки тому +12

    Drowning in clever Scala cats/cats-effect/akka/etc code was one reason I left my old job. I like learning and languages, but our velocity sucked because only one extremely nerdy genius on our team was comfortable and productive working with that codebase.

  • @ernesto8738
    @ernesto8738 2 роки тому +27

    feels very erlang BEAM

    • @udadog
      @udadog 2 роки тому +4

      Been enjoying using Elixir since it runs on the beam. It was all because I was really interested in concurrency when my professor had me make a multi tcp chat server. Went from Python as the start, to Go, then finally to Elixir.

    • @theteachr
      @theteachr 2 роки тому +10

      Seems like we keep forgetting the great ideas and keep reinventing them.

  • @gdargdar91
    @gdargdar91 2 роки тому +35

    If you want parallelism, use applicatives not monads. Monads are sequential by nature. Haskell automatically switches to applicatives when it sees you don’t use the binding. So monads are not the problem here, Scala is.

    • @rikamayhem
      @rikamayhem 2 роки тому +1

      Isn't applicative-do a language option disabled by default, though? How many people really use it?

    • @flight_risk
      @flight_risk 2 роки тому +8

      so let me get this straight
      we should adopt category theoretic abstractions as a clearer and more concise way to express our applications because… nobody except GHC contributors knows how to use them ’correctly.’ if they did, they would simply implement their compiler to branch on how they are invoked, and therefore ‘monads in production have never been tried.’
      on a completely unrelated note, have you ever wondered why there are not a great many haskell developers?

  • @codeasone
    @codeasone 2 роки тому +13

    Looks like it will make developer's lives a lot nicer. Great talk, so many good talks at Strange Loop this year.

  • @vsams14
    @vsams14 2 роки тому +4

    This is extremely pertinent to my work and I greatly appreciate this presentation!

  • @exl5eq28
    @exl5eq28 2 роки тому +20

    22:00 "no developer write code like this"
    it's daily life for c++ devs lol.
    `std::shared_ptr`

    • @garorobe
      @garorobe 2 роки тому

      No. We use aliases and type tagging/wrapping/subclasses.

  • @mikhailfranco
    @mikhailfranco Рік тому +2

    Virding's First Rule of Programming:
    _Any sufficiently complicated concurrent program in another language_
    _contains an ad hoc informally-specified bug-ridden slow implementation of half of Erlang._

  • @virkony
    @virkony 2 роки тому +7

    Thank you for a great talk. I like topics brought in here.
    And it is interesting idea to sort of auto-lifting normal types to hide more complex ones behind pre-processor triggered by @node. If I understood correctly, difference from various async keywords of languages is that it fuses deeply with types rather than simply wrapping in Future[T].
    But isn't it basically adding yet another axis of types?
    E.g. Mercury language having "insts" alongside with types that bascially allows both split types further (e.g. non-empty list) and to model some stuff that is not covered by types.
    BTW, Haskell code by itself also parallelizable and cachable without invading types, which allows parallel library to have "using :: a -> Strategy a -> a". And promise given when marking something with @node probably can be compared to unsafeInterleaveIO.
    But downside is that this might easily push development to practice "tweak and check actual code/behavior it produces" due to sometimes unexpected behavior for devs. I had impression that this is something that no longer considered as a feature and that's why libraries like conduit/iteratee/pipes gain more control over resources use.
    Curious about how it is being balanced between being too generic with low control and a lot of places to tune (e.g. caches) to get it right. Are there any interesting auto-tuning and/or auto-learning work cost that keeps decisions about batching vs latency and competing caches?

  • @7th_CAV_Trooper
    @7th_CAV_Trooper 2 роки тому

    Glad I stayed to the end. Very cool solution.

  • @capability-snob
    @capability-snob Рік тому

    I really like this. Few people seem to understand that in order to safely ignore concurrency boundaries, you need to verify RT. I honestly watched this expecting to see another bad coroutine library, rife with "stale stack frame" bugs, but this is well thought out.

  • @a_external_ways.fully_arrays
    @a_external_ways.fully_arrays 2 роки тому +4

    In general an interesting talk - thanks. I had some comments underway:
    * The monad is not _in_ your type system - the type system is able to _express_ the monad
    * The fact that Scala doesn't have a way to express concurrent threads in their for-comprehensions doesn't say anything about FP languages in general. In fact the example you made isn't relevant for OCaml where we have a monadic 'and' operator. E.g. "let* v = some_thread1 and* v' = some_thread2 in ..."
    * I worked with Scala for 4 years - it's one of the most messy languages compared to other statically typed FP languages, in terms of libraries, culture, language syntax, language semantics etc.
    * In OCaml I have positive experiences with the concurrency monad - though I agree that rearranging/mapping stacks of monadic values is cumbersome - but it doesn't happen that often.
    * SQL handles concurrency, yes, but debugging bad performance in SQL is horrible. You can't just write anything you like - i.e. if you want performant - you need to know what the query planner will do. In the end this means that real-world SQL is not fully declarative.

  • @paulpinecone2464
    @paulpinecone2464 2 роки тому +4

    Have you in fact invented macros where it wraps your code with the necessary machinery for concurrency without us having to see it?
    Also since we are teaching people to favor transparency would it be preferable to assume @node and instead mark anything nontransparent with @unsafe?

  • @zyansheep
    @zyansheep 2 роки тому +7

    How does this compare to algebraic effects?

  • @monad_tcp
    @monad_tcp 2 роки тому

    21:45 transpose and/or traverse to reorder the layers of stacked monads . I did that on F#

  • @U1F984
    @U1F984 2 роки тому +4

    Great talk. I wonder about the example with the cached author though; what happens if the business logic writes something to the data store? Will it see its own writes?

    • @EvincarOfAutumn
      @EvincarOfAutumn 2 роки тому +2

      I’ve worked on a similar system (Haxl) in Haskell. We allowed writes, but by default, the effect of the write would not be visible to subsequent reads within the same transaction. In order to _entirely_ prevent observable side effects, you would need to either ban writes or ensure that your read queries don’t overlap-for example: “load XY, store Y, load YZ” could observe that Y has changed, because YZ is distinct from XY, so it’s not cached. In practice, however, this wasn’t a problem: users wanted to avoid this cache-busting behaviour anyway, since it means you’re redundantly fetching the same record multiple times. In principle it could also be mitigated by rewriting queries and results, if you know more structure about the data store.

  • @Milan_Openfeint
    @Milan_Openfeint Рік тому

    I'm a bit late to the party, but at 28:05 the function iCanCodeRT is pretty clearly not "referentially transparent" as defined by Gjeta, since it can return different results with the same parameters - it depends on the state of anotherRTNode.
    If this is allowed, how is it different from standard stateful procedural programming?

    • @jeberle1
      @jeberle1 Рік тому

      She states that referential transparency means that a series of calls can be reordered w/o changing expected results. The calls are indepenedent of one another. Pure functions have the property you describe. Same args in means same results out.

  • @yasinyaqoobi
    @yasinyaqoobi 2 роки тому +1

    Wonderful talk.

  • @sidneymonteiro3670
    @sidneymonteiro3670 Рік тому

    Where is the link to github with the implementation?

  • @dobotube
    @dobotube 2 роки тому +15

    The type intrusive garbage collected language is... Rust!

    • @SimonBuchanNz
      @SimonBuchanNz 2 роки тому +7

      Rust is exactly as garbage collected as C++, that is, it is not (without libraries at least)

    • @jonaskoelker
      @jonaskoelker Рік тому

      I believe OP's point was that information about memory handling (mutability and lifetimes) seeps into your type declarations, similarly to what was shown on the slides.
      Or maybe I was missing the point. Maybe it was really "intruding information about GC generations into your types is just as bad as introducing execution concerns into your code" and not "intruding information about memory handling (in some form or another) into your types is just as bad as introducing execution concerns into your code". I think something else, though.

  • @KeremyJato
    @KeremyJato 2 роки тому +4

    Well presented talk!

  • @monad_tcp
    @monad_tcp 2 роки тому +1

    17:27 Its Erlang, isn't ?

  • @jhorneman
    @jhorneman 2 роки тому

    Really nice talk!

  • @slowpnir
    @slowpnir Рік тому

    5:52 Wild guess: `Applicative` functor

  • @holykoolala
    @holykoolala 2 роки тому

    Could Scala implement this as an official part of the language?

  • @adambickford8720
    @adambickford8720 2 роки тому

    So async/await as a product for scala?

  • @twin9408
    @twin9408 2 роки тому +1

    cool, good talk

  • @fabracht
    @fabracht 2 роки тому +1

    Very interesting topic. Bravo!

  • @ThinklikeTesla
    @ThinklikeTesla 2 роки тому +6

    Great talk! I can't figure why the annotation is called @node. I know everything's getting taken over by NodeJS, but I don't think that's it. :) @referentially-transparent is too long. @pure?

    • @lawrencedanna
      @lawrencedanna 2 роки тому +3

      I'm guessing it refers to there being a directional acyclic graph in which the nodes are invocations of @node functions and the edges are data dependencies between them.

  • @xremming
    @xremming 2 роки тому +1

    All I am hearing is "problems that Go does not have" when I am listening to this talk. Sometimes complexity just is not a solution.

  • @jackgenewtf
    @jackgenewtf 2 роки тому +2

    I wanted to clarify something. You had mentioned the "colored function" problem. But isn't that what you are introducing here? Just that instead of the "async" keyword, you introduced the "@node" annotation?

    • @pas.
      @pas. 2 роки тому +1

      not really. the problem with colored functions is that they then in turn color other functions. here all that is hidden. @node function can return primitive types. you can write functions without thinking about what kind of functions might call it. (or without thinking about what kind of functions you can call.)

  • @klasus2344
    @klasus2344 2 роки тому

    This is like an effect system, but not builtin to the language

  • @XArticSpartanX
    @XArticSpartanX 2 роки тому +7

    not really a fan of how she frames the issue at the beginning. Futures offer failure states, Future.failed. You can map over these and even catch them. They also nest throwables, so you can specify what type of exception is (was) thrown. In addition, Future.sequece and Future.traverse solve her last problem of not handling a future of sequence, or a sequence of futures. I do agree this mental gymnastics is not beginner friendly, but the power it gives the developer is well worth the energy required to get up to speed with these concepts.
    I am kinda surprised she brough up such beginner issues.

    • @yawaramin4771
      @yawaramin4771 2 роки тому +1

      Because the vast majority of developers will be at that level. It's really only a tiny minority of devs who actually ever dive deep into the category theory rabbit hole.

    • @jackgenewtf
      @jackgenewtf 2 роки тому +4

      Understanding how to use futures correctly, and "diving deep into the category theory rabbit hole" are not the same thing. I understand everything @XArticSpartanX said about the Scala Futures API, I had those concerns too, watching the talk, but I couldn't tell you the first thing about category theory.

    • @duncanw9901
      @duncanw9901 2 роки тому +1

      @@yawaramin4771 The category theory rabbit hole is ankle-deep. It's simpler than almost anything else in mathematics.

    • @sigmundwong2489
      @sigmundwong2489 Рік тому

      @@duncanw9901 That's just plain false. The very fundamentals of CT are ankle-deep, but the reason that CT is useful is because it gives you an ankle deep wading pool from which you are able to extract killer-whale-sized mathematics (and in a highly principled way). Consider the fact that, for example, all of formal logic can be phrased in terms of CT, as can much of quantum mechanics. There is a lovely paper wherein a handful of axioms are used to form a category; the authors then prove that such a category _must_ be a category of Hilbert spaces and bounded linear operators (the basic language of QM/QIC). To claim that the basic definition of a category is easy is one thing; to claim that the whole of category theory is trivially understood is disingenuous, and frankly oozes of hubris.

  • @TaranovskiAlex
    @TaranovskiAlex 2 роки тому +6

    so you "invented" coroutines in scala. interesting. will this all be basically obsolete once the loom project is delivered?

    • @NoNameAtAll2
      @NoNameAtAll2 2 роки тому

      what's loom?

    • @piraka_mistika
      @piraka_mistika 2 роки тому +2

      if you watch the questions section at the end, Gjeta mentions Loom a couple times

    • @PeerReynders
      @PeerReynders 2 роки тому +2

      @@NoNameAtAll2 “Project Loom, Fibers an Continuations, is to intended to explore, incubate and deliver Java VM features and APIs built on top of them for the purpose of supporting easy-to-use, high-throughput lightweight concurrency and new programming models on the Java platform.”

    •  2 роки тому +1

      loom doesn't do batching or caching, so no. Don't think she explained how the batching works, maybe there are other annotations.

    • @virkony
      @virkony 2 роки тому +1

      I think talk was started about having solutions, but they are clunky.
      If I understand correctly, Loom supposed to breake away from OS threads and from mandatory stack traces allowing tail-call elimination. You still need to incorporate that in languages and run-time that do those multiplexing IO implementation (that "interpretation" mention).
      Just spawinging bunch of fibers is not going to bring you batching and caching. I suspect only thing that Loom might make obsolete is how those async nodes of execution represented and wired.
      P.S. coroutines - is a bit messy term in my opinion. Sometimes it refers to tearing/re-wiring apart linear code (e.g. Python generators), and sometimes it referred to continuations (e.g. async in Python/C#).