In which @error solicits recommendations and feedback


  • I survived the hour long Uno hand

    @error said in In which @error solicits recommendations and feedback:

    I'd rather have input parameters accept interfaces only,

    I'd rather have interfaces at all wistful sigh


  • ♿ (Parody)

    @error said in In which @error solicits recommendations and feedback:

    I'd love to call it finally but that's a reserved word.

    finale


  • FoxDev

    @Yamikuronue said in In which @error solicits recommendations and feedback:

    Accalia and I have this discussion every code review, so you're in good company wanting more future-proofing and less readability

    yeah, yami usually wins that discussion too (correctly even!)



  • @accalia said in In which @error solicits recommendations and feedback:

    :do_not_want.png:

    ... why?

    It's 100% backwards-compatible, already highly-compatible with ES7 (if not 100%), and adds optional strong typing and typing hints to JS.

    Do you have a reason other than "new and different" knee-jerking? ... but in this case even that doesn't matter since normal JavaScript is quickly turning into TypeScript.


  • FoxDev

    @blakeyrat said in In which @error solicits recommendations and feedback:

    Do you have a reason other than "new and different" knee-jerking? ...

    read the rest of the thread, you'll get the answer, then you can call me an idiot knowing my answer.



  • @accalia Meh you have kind of a point, but it seems minor compared to the benefits.


  • FoxDev

    @blakeyrat said in In which @error solicits recommendations and feedback:

    @accalia Meh you have kind of a point, but it seems minor compared to the benefits.

    it's enough of a point to keep me from migrating. when es7 comes out and typescript merges with JS and browsers support it, and i can native debug. then i'll switch.



  • @accalia You're fighting the tide. Get a head-start now.


  • FoxDev

    @blakeyrat said in In which @error solicits recommendations and feedback:

    @accalia You're fighting the tide. Get a head-start now.

    nah. i'll let the tide polish the sharp edges off the rocks, and turn the cutting edge into a well supported beach ecosystem teaming with life. then i'll just dock my boat and enjoy the beach.

    I enjoy javascript development, but i'm not so stupid as to think that just because something is the absolute bleeding edge it's the best thing out there and i must jump on the band wagon straight away.

    i did the same thing with HD-DVD versus BluRay I let them fight it out and bought the winner after the fight was over. worked out well for me. would have done the same thing with betamax vs vhs too, but that fight happened long before i had any sort of discretionary income, and that would have worked out well too. Now i'll do the same thing with typescript versus plain JS, and i'm sure that will work out well for me too.



  • @accalia said in In which @error solicits recommendations and feedback:

    i'll let the tide polish the sharp edges off the rocks,

    You're using open source technologies, I can guarantee that will never happen.

    Look at how old Python is. It has all the same sharp edges it did from day one. Heck, they've added a couple more.


  • Considered Harmful

    @blakeyrat I use TypeScript religiously and am very involved in the Github issue/feature tracker.

    I love the language, my main issue is the type definition ecosystem. That's not Microsoft's fault, really, because they don't provide those (or maybe it's their fault for not providing an official channel for those). The community stepped in with things like Typings (which sucked but is getting better), and DefinitelyTyped (which is a massive cluster of :wtf:).

    The other issue I have is that the language is evolving faster than the documentation for the language. There's clearly out-of-date information in the manual, and of course all the Stack Overflow answers are basically obsolete already. Fuck Stack Overflow anyway.


  • Notification Spam Recipient

    @error said in In which @error solicits recommendations and feedback:

    DefinitelyTyped

    NFC what that is, but from the name alone...


  • Considered Harmful

    @Tsaukpaetra said in In which @error solicits recommendations and feedback:

    @error said in In which @error solicits recommendations and feedback:

    DefinitelyTyped

    NFC what that is, but from the name alone...

    TypeScript requires (or strongly recommends) that you provide "type definition" files for any external code you interface with. This gives it information about e.g. what functions and classes are available, what types the parameters and return values are, etc.

    DefinitelyTyped is a git repository of definitions for thousands of third-party modules, of widely varying quality and accuracy. Basically a big dumping ground for type definition files. Many of them pollute the global scope (e.g, they declare global variables, which may or may not actually exist depending on which module system you use), or are missing large chunks of the API.

    In theory, the type definition file format is expressive enough to support most libraries nearly perfectly. In practice, you never really know what you'll get when you reference a DefinitelyTyped type definition file.


  • Notification Spam Recipient

    @error said in In which @error solicits recommendations and feedback:

    you never really know

    That's almost enough to convince me not to even look...


  • Considered Harmful

    @sockdevs in particular. A few design concerns and just general thoughts about @error_bot. (@error_bot can be an unstable sandbox where we [I] vet experimental techniques and architectures.)

    I've been trying to come up with a way for @error_bot modules to extend different kinds of functionality. At first I had the very late-90s onFoo onBar methods, but those feel clunky. I peeked at SockBot and saw you guys using EventEmitter (I'm good with ES6 but a little n00b about Node API), and that looked much better.

    Problem: It does not allow you to capture the return value of an event handler: I'd like for them to be able to cancel out of events, or return a Promise that delays further processing.

    • I considered possibly passing in a mutable event object, but I'm trying to avoid statebags.
    • Maybe the event object has cancel and wait methods? Thinking of e.g. preventDefault and stopPropagation

    I was thinking of also linear pipelines of processors, where each step decorates/processes the command more. This is problematic, though. First off, TypeScript (INB4 accalia 🔥) wouldn't know which augmentations have occured where in the pipeline. At first, I was annoyed about that, but then I realized that it was just illustrating a weakness in the design - maybe it's not such a great idea to have a temporal dependency chain where it's hard to know what state a given object is in at a given time!

    Instead I'm thinking of passing my modules more-or-less opaque raw command objects, and exposing a number of APIs to them to parse them in whatever way is most appropriate. (So Mafia could use a different, more complex command parser than echo, which really doesn't need much parsing at all.)


    I know I need to encapsulate and abstract away the NodeBB APIs from the rest of the bot, it's hard to figure out what kind of abstractions make sense. I know SockBot uses providers, and my first thought was that that was over-engineered, YAGNI; but we've switched platforms twice already and people are talking about a third time, so maybe I didn't give you guys enough credit there. I guess my problem is that there's not even a universal standard on the underlying primitives (categories, threads/topics, replies, chats?, tags?).

    I think I just need to ruminate on this one.


    Passing state around is probably the biggest conceptual problem I'm facing right now. (Not made any better that I'm dealing with socket.io's stateful nature and jellypotato.)

    I'm trying to go on the principles of breaking things apart into small pieces that focus on single things, and having objects be mostly stateless and injecting into them. But then it seems to place a burden on the consumer to gather and pass in the necessary dependencies.

    I also keep wavering on the classes / constructors / objects / functions as the primitive of choice, as well. Classes are just groups of functions, by my stateless principle, so maybe objects... but if I'm just dealing with groups of functions, do I need the objects... Well, now all my functions need you to pass in 5 things... Maybe I just pass the dependencies into the constructor! But now my objects are stateful... Round and round it goes.


    It's interesting how our designs converge in some ways. I've made a conscious effort to keep @error_bot fully independent, but some ideas just make sense.

    Any feedback or suggestions on any of these things would be welcome.


  • FoxDev

    @error said in In which @error solicits recommendations and feedback:

    Problem: It does not allow you to capture the return value of an event handler: I'd like for them to be able to cancel out of events, or return a Promise that delays further processing.

    hmm... i'm tempted to say YAGNI to that feature, unless you have a compelling reason to include it.

    if you really want that sort of functionality you may wish to implement your own system.

    EventEmitter is all well and good but when you fire an event it fires all the handlers, you may want to chain the handlers in a manner similar to DOM event bubbling, EventEmitter's not designed for that, i'd look for an implementation that is, or build your own if you need the functionality, but again without a pressing need for this i'm tempted to say YAGNI to the feature.

    Designing for the future is one thing, but this sort of feature can be a huge hassle to build and maintain for relatively few benefits (in a lot of situations)

    @error said in In which @error solicits recommendations and feedback:

    I was thinking of also linear pipelines of processors, where each step decorates/processes the command more.

    @error said in In which @error solicits recommendations and feedback:

    Passing state around is probably the biggest conceptual problem I'm facing right now.

    hmm..... sounds like you do want some sort of event bubbling model then.

    Events bubble up a tree of event handlers from the most specific event type to the least, with multiple event handlers at each node supported and the event is cancellable...

    yeah that's totally doable. and actually a kinda cool model. nice and flexible without relying too heavily on preconceptions so easy to extend.

    @error said in In which @error solicits recommendations and feedback:

    . I know SockBot uses providers, and my first thought was that that was over-engineered, YAGNI

    yeah, that gave me trouble, but i eventually decided that i needed to abstract what forum is underlying the bot from the bot. that way when we change forums again only the provider needs to change, not the plugins. because from 1.0 to 2.0 and 2.0 to 3.0 needed the plugins to change, but we've done 3.0 to 4.0 since and plugins needed 0 changes. :-D

    @error said in In which @error solicits recommendations and feedback:

    Any feedback or suggestions on any of these things would be welcome.

    and the reverse is true as well. it's always good to get a different persoective.


  • I survived the hour long Uno hand

    @error said in In which @error solicits recommendations and feedback:

    that was over-engineered, YAGNI;

    I'm building a Slack provider, and I plan to migrate my IRC bot to the same platform so i only have to maintain one. So... 🤷


  • Considered Harmful

    @Yamikuronue said in In which @error solicits recommendations and feedback:

    @error said in In which @error solicits recommendations and feedback:

    that was over-engineered, YAGNI;

    I'm building a Slack provider, and I plan to migrate my IRC bot to the same platform so i only have to maintain one. So... 🤷

    I did add in the same sentence:

    @error said in In which @error solicits recommendations and feedback:

    but we've switched platforms twice already and people are talking about a third time, so maybe I didn't give you guys enough credit there.


  • Considered Harmful

    @error said in In which @error solicits recommendations and feedback:

    Problem: It does not allow you to capture the return value of an event handler: I'd like for them to be able to cancel out of events, or return a Promise that delays further processing.

    Here's an idea:

    • There's a list of active module objects that execute sequentially, possibly with multiple instances of the module running concurrently: say, trivia modules running on three different topics.
    • Modules just expose a method that accepts Event objects (they can be stateful or stateless, as needed - encapsulated away)
    • Event object passed to handlers has resolve and reject methods on it.
    • resolve with a PromiseLike<Event> for async handling, or Event for sync event decoration
    • module in the chain can replace the event with a different event if necessary (maybe to resolve ambiguity or provide aliasing, context sensitivity?)
    • resolve with null kills the event propagation. The event is handled. Done. Success.
    • resolve with a value means another module should keep processing the event.
    • reject cancels the event. The event failed. Pass an Error with why. Bail out of the chain early.
    • neither resolve nor reject just indicates the module wasn't interested in that event
    • if the event makes it through the whole module list without some module handling it with resolve( null ), then maybe an "unhandled" module at the end of the list responds with a warning to the user?

    Feedback anyone (@sockdevs especially)? Very rough sketch of my thought processes here.

    Edit: Group mentions seem borked. CC @accalia @Yamikuronue


  • Considered Harmful

    Extending my thoughts there... The Event at the start of the chain might be super generic just-the-command-text and then several parser modules attempt to match it with regexes, and call resolve with more specific parsed events that later modules can respond to...

    CC @accalia @Yamikuronue


  • FoxDev

    @error said in In which @error solicits recommendations and feedback:

    neither resolve nor reject just indicates the module wasn't interested in that event

    E_NOT_PROMISELIKE

    you must resolve or reject a promise. this case needs to be handled as part of one of either resolve() or reject()

    otherwise that seems to be an interesting and possibly very powerful design.


  • Considered Harmful

    @accalia said in In which @error solicits recommendations and feedback:

    @error said in In which @error solicits recommendations and feedback:

    neither resolve nor reject just indicates the module wasn't interested in that event

    E_NOT_PROMISELIKE

    Events aren't promiselike. Well, really, they expose the resolve and reject callbacks of a real bona fide Promise, but the promise itself is an implementation detail hidden from the module. After the module handler fires, the caller resolves the promise. Since only the first call matters, this won't affect the result.

    There's a promise involved, but the modules never see it. They can only interact indirectly. This is intentional behavior. WONTFIX BYDESIGN


  • FoxDev

    @error said in In which @error solicits recommendations and feedback:

    WONTFIX BYDESIGN

    -_-

    :doing_it_wrong:

    :-P


  • Considered Harmful


  • Considered Harmful

    @accalia Maybe I'll just double down on those sweet, sweet async functions. It's a shame SockBot can't use those, they make everything so much easier (and use real Promises). 🚎

    (Really I'm silly, because I got caught on the idea that event handlers couldn't have return values... but if I have to reinvent them anyway, then of course they can. I don't need methods on the event objects.)


  • Considered Harmful

    @accalia I thought of a slightly less linear approach where modules subscribe to less specific events and fire more specific events.

    I feel like this runs the risk of feedback loops, reduces my capacity to do lifecycle management, and could lead to two modules racing to handle the same event. Basically trusting modules more to behave themselves. The tradeoff is greater levels of parallelism and I can get by with the standard EventEmitter. Thoughts?

    Edit: I really want stronger guarantees of state at a given time and against races. Linear chains seem to be the way to go.


  • FoxDev

    @error said in In which @error solicits recommendations and feedback:

    @accalia I thought of a slightly less linear approach where modules subscribe to less specific events and fire more specific events.

    I feel like this runs the risk of feedback loops, reduces my capacity to do lifecycle management, and could lead to two modules racing to handle the same event. Basically trusting modules more to behave themselves. The tradeoff is greater levels of parallelism and I can get by with the standard EventEmitter. Thoughts?

    i'll be honest. seems a bit over engineered to me.

    I mean the system is pretty cool, and i like the amount of thought you're putting into this, it just seems a bit much for a forum bot, you know?

    still i like the idea and totally plan on looting your code for clever ideas once you write it.


  • Considered Harmful

    Sorry for the bombardment. I'm at the gym and my mind is racing. What if instead of a command queue there was a command pool? I get the parallelism I want, but also can manage the lifecycle (I can track and possibly interrupt a processing chain).

    Basically want to avoid a callback hell where things are happening all over in a chaotic fashion without me. I want to be able to pull the plug on and hotswap modules.


  • FoxDev

    @error said in In which @error solicits recommendations and feedback:

    Sorry for the bombardment.

    bombardment?

    i mean i expected this sort of thing in slack, but here's fine too.

    i like to talk.

    @error said in In which @error solicits recommendations and feedback:

    I'm at the gym and my mind is racing.

    must be a cardio day then. you wouldn't have a hand free if you were doing a strength day properly. ;-)

    @error said in In which @error solicits recommendations and feedback:

    What if instead of a command queue there was a command pool?

    An interesting idea. i'd like to see an sketch of how that would be laid out.


  • Considered Harmful

    I may be crazy, but I'm thinking of it like a little OS where modules are programs. It's a core design goal that everything be in a well-defined, discrete state at every point in time. Exposing an event subscription API really seems to open the door to "zombie" modules that can't be killed off. That's why I like the idea of spoonfeeding the events (pushing instead of letting them pull). Also want to introduce a kind of hypervisor that is watching the health of every module (this one has been stuck a while doing stuff, raise a warning, maybe kill it with fire).

    Am I crazy @SockDevs?


  • FoxDev

    @error said in In which @error solicits recommendations and feedback:

    Am I crazy @SockDevs?

    crazy? i dunno. show me someone who is sane so i can compare.

    i'd say ambitious. if you succeed you could have a hell of a system. ;-)


  • I survived the hour long Uno hand

    @error I mean, Sockbot started with an Observer pattern, that modules would register for the events they cared about, and later added a "simpilified" Command interface over top. And for 90% of use cases, Command is more than sufficient.


  • FoxDev

    @Yamikuronue said in In which @error solicits recommendations and feedback:

    @error I mean, Sockbot started with an Observer pattern, that modules would register for the events they cared about, and later added a "simpilified" Command interface over top. And for 90% of use cases, Command is more than sufficient.

    basically this.

    this pattern has proven to be more than sufficient for most purposes.

    :-D

    still it's nice to see the more ambitous approaches tried.


  • BINNED

    @accalia Well, whole of Qt is designed around it and I find it easy to work with and it seems to work fine.

    @error, you might want to take a look at http://doc.qt.io/qt-5/signalsandslots.html, it might give you some inspiration.


Log in to reply