I accidentally made a reactive programming library for Python

แชร์
ฝัง
  • เผยแพร่เมื่อ 1 ก.พ. 2025

ความคิดเห็น • 48

  • @dougmercer
    @dougmercer  3 หลายเดือนก่อน +1

    To try everything Brilliant has to offer-free-for a full 30 days, visit brilliant.org/DougMercer
    You’ll also get 20% off an annual premium subscription.

  • @Reeg3x
    @Reeg3x 3 หลายเดือนก่อน +26

    Oh snap. More awesome information that I am too busy to learn.

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน +14

      Hah! Add it to your "Watch Later" playlist so you can eventually delete it in 2030

    • @Reeg3x
      @Reeg3x 3 หลายเดือนก่อน +6

      @@dougmercer you get me lmao

    • @itsrobelschwarz7248
      @itsrobelschwarz7248 3 หลายเดือนก่อน +4

      @@dougmercerI literally have a folder called ‘coding stuff I’m never gonna watch’, pretty sure someone could become a senior engineer just by going through it

  • @bradentoone895
    @bradentoone895 3 หลายเดือนก่อน +4

    This is incredibly well written - I read through your src code and am super impressed! I don't have much use for it at the moment but I will definitely consider it in the future! Would be interested to see more of how reactive_method could be used to do variable function declarations and calls, and how shared use of a Signal could be used for passing messages between threaded apps.

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน +1

      Thanks! =]
      I am definitely curious what people will try to do with this. I haven't tried anything multithreaded yet, so I'm not even sure it would work (my animation library is inherently single threaded/processed), but if it does work that would be very neat to see!

    • @bradentoone895
      @bradentoone895 3 หลายเดือนก่อน

      @@dougmercer It could be useful for sharing reactive app state across websocket connections - would need to have threading locks or mutexes around the unrefs though. Could be hairy if there is recursive or deep nested Signals.

    • @permik
      @permik 3 หลายเดือนก่อน

      Using atomic numbers for cross-thread signaling will fortunately go really really far without even touching locks and mutexes, those will inherently make the architecture more complex as you have to start thinking about object/value lifetimes.

  • @CossuttaDario
    @CossuttaDario 3 หลายเดือนก่อน +1

    Nice!
    I hadn't found a real killer use for decorators(aside for showing off and making the flow of the project less readable), callbacks are often fine..,but this makes sense! Ty!

  • @noahgeller392
    @noahgeller392 3 หลายเดือนก่อน +3

    This video is crazy good. Also nice sweater :)

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน

      Thanks =]

  • @remiheneault8208
    @remiheneault8208 3 หลายเดือนก่อน +1

    You can create type variables as classes in 3.13, with attributes to control covariance, defaults etc.
    Maybe it can be used to generate types dynamically?
    Having tried that myself, working on something so meta is very frustrating because you don't produce much in the end, and Python's typing is often the limit. Great for learning though!

  • @zskater1234
    @zskater1234 2 หลายเดือนก่อน

    Will you open-source your animation library at some point?

    • @dougmercer
      @dougmercer  2 หลายเดือนก่อน +1

      Yup! Plan is early next year.
      I've refactored about 90% of it to be reactive, but there is still quite a bit to do in terms of documentation, testing, etc.

    • @zskater1234
      @zskater1234 2 หลายเดือนก่อน

      @ Amazing! Looking forward to trying it out!

  • @hampuseden9402
    @hampuseden9402 3 หลายเดือนก่อน +2

    Scala has a nice type system. Hint hint :D

    • @ramsey-b5f
      @ramsey-b5f 2 หลายเดือนก่อน

      scala >> python

  • @lame_lexem
    @lame_lexem 3 หลายเดือนก่อน

    13:10 why your type hunts won't work in mypy ?

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน +1

      I think if I didn't try to support nested signals then mypy would work, but so far I haven't figured out how to make everything work. ¯\_(ツ)_/¯

  • @jhawar-ji
    @jhawar-ji 3 หลายเดือนก่อน +5

    Who write the entire source code in __init__.py file?

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน +7

      Brother... there isn't much to this library. It's like 350 lines of code (the rest is whitespace and docstrings)

  • @laundmo
    @laundmo 3 หลายเดือนก่อน +1

    As someone who's attempted to typehint some very complex patterns, i feel your pain on mypy vs pyright incompatibilities. I'd love to know when and why your solution will break, as you didn't mention that in the vid.
    i see your comments in the source about "Dumb thing to make pyright happy" and "insane recursive type..." but i question why you judge these things like this?
    mypy supports recursive types nowadays, and thats the only place i'd guess there to be an issue.
    Besides: how are you supposed to typehint something like JSON if not recursive? thats perfectly fine.
    I suppose i'll have to try it myself once i get back on a device bigger than a phone.

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน

      Its hard to say what the tipping point is for this API that makes it so unwieldy to type hint. I think it's because it's a
      1. Recursive...
      2. Involving a TypeVar...
      3. And we somehow want to use pattern matching to extract the type of the innermost thing inside the recursive type that only satisfies the base case of the recursion (and then use that type elsewhere)
      You're totally right about JSON/recursive types.
      I'd love to find a simpler solution and would definitely welcome your input if you have any ideas =]

    • @laundmo
      @laundmo 3 หลายเดือนก่อน +1

      @@dougmercer I've submitted a unrelated PR and put what i figured out about the recursive thing int an issue. feel free to ask me stuff there, i probably wont spend more time from my side on actually implementing any more changes.

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน +1

      @laundmo the approach you suggested in the issue seems very interesting. It simplifies things a lot. I'll try to run it to ground and prepare a PR later in the week. When I do, if you'd like to reauthor it so you can get credit for the PR you'll be welcome to. Otherwise, thanks for the suggestion =]

    • @laundmo
      @laundmo 3 หลายเดือนก่อน +1

      @@dougmercer No problem. if you're willing to have me be part of the PR that way i'd be happy to. As i said in the issue, i honestly don't see where my approach is inherently different to the current one - i just wanted to see what happens with the 2 generic classes without any unrelated code.
      if you have any other questions etc, i'll probably respond to a comment on the issye far faster, TH-cam notifications tend to not show up properly for me

  • @yorailevi6747
    @yorailevi6747 3 หลายเดือนก่อน

    why not use traitlets library?

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน

      I might be wrong, but I don't believe traitlets has any support for computed/derived objects? I think it could be used to replace a Signal though...

    • @yorailevi6747
      @yorailevi6747 3 หลายเดือนก่อน

      @@dougmercer you can wrap a property with observe i think and it would work

  • @jimratliff
    @jimratliff 3 หลายเดือนก่อน +1

    Curious why you’re using a list to store subscribers rather than using a set. If the number of subscribers is large, seems like checking for membership in a set scales better than checking for membership in a list.

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน +9

      Good question! Using a set would require that whatever I put in it to be hashable, but a list doesn't. Since an observer is just something that implements `.update()`, I can't necessarily assume that it's hashable.
      I think I've went to refactor it into a set twice only to get burned by that... hah ¯\_(ツ)_/¯

    • @iez
      @iez 3 หลายเดือนก่อน

      @@dougmercerif there is no need for meaningful equivalence of the subscriber, can’t you just assign them a unique ID, override __hash__() to just has the ID, and __eq__ can be based on the ids being equal.

    • @personinousapraham3082
      @personinousapraham3082 3 หลายเดือนก่อน +1

      You should be able to use a set if you wrap the elements in a container class with a custom __hash__ function that just defers the hashing to the self.update.__hash__, as the update function should always have a stable hash. Then similarly defer the equality checkers to the wrapped instance

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน

      @@personinousapraham3082 true. I may do something like that eventually if it becomes a performance problem

    • @personinousapraham3082
      @personinousapraham3082 3 หลายเดือนก่อน +1

      @@dougmercer At the same time, with Python's overhead for classes it might just end up being even slower 😂

  • @Finnnicus
    @Finnnicus 3 หลายเดือนก่อน

    These python generic types are cursed compared to a typed language

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน

      Agreed

  • @Shenepoy
    @Shenepoy 3 หลายเดือนก่อน

    Isn't this just state management??????

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน +1

      Isn't everything just zeros and ones?

  • @g45h96
    @g45h96 3 หลายเดือนก่อน +1

    Why wouldn't this be called parametric? Like everything else that has a dependant heirachy of parameters? Not your fault, I know this is the term for it, I've just never paid attention to what it meant, and now I'm angry. Words mean things, damnit

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน +1

      I agree! Hahaha. I went with the term everyone is using, but parameter or variable make way more sense to me intuitively. Oh well ¯\_(ツ)_/¯

  • @alimuhareb8170
    @alimuhareb8170 3 หลายเดือนก่อน

    ow my brain

    • @dougmercer
      @dougmercer  3 หลายเดือนก่อน

      Sorry, maybe I should have had a trigger warning for the "function, inside of a function, inside of a function" =P