Git Product home page Git Product logo

Comments (5)

raquo avatar raquo commented on August 20, 2024 2

Those are all good points, thanks for elaborating! At the moment I can't give a specific, compelling, example, for what impure things the users could legitimately be doing in the zoomInFn callback. If nobody will be able to come up with that by the time I get to implementing it, I say perhaps it's a good indication that the problem is not worth worrying about in practice, and the lazy owner-less behaviour is better off being the default.

I may be wrong in calling the requirement on zoomInFn "purity" – FP nomenclature isn't my strong suit. At a high level, if zoomInFn has side effects, lazy evaluation will likely be undesirable, as the execution of said side effects will be unpredictable at definition site. You're right that because we can at least get rid of redundant evaluations of zoomInFn, the range of "side effects" that could cause problems is reduced. For example, if the zoomInFn callback is merely expensive to compute, that won't be a problem. If it does some logging that doesn't affect program execution, it's probably fine too. If it creates new instances that don't have structural equality like case classes, proooobably still fine, at least if nothing stateful is involved.

Naming-wise, we already use strict to indicate strict evaluation, e.g. mapToStrict vs mapTo (the latter is accepts the argument by-name, so the argument is evaluated lazily). Perhaps the existing zoom method could be renamed to zoomStrict to make room for the new lazy zoom method, but StrictSignal's map will need some other name, mapStrict would be inconsistent with other strict names, and I'm not ready to change the contract of map.

A final, orthogonal thought on API-design is that I do enjoy a post-fix pattern for method alternatives, if only because it more naturally works with autocomplete.

I must say that IntelliJ gives me all the relevant autocompletions regardless of whether the method starts with what I typed, or just contains it somewhere in the middle, so the main advantage of that strategy is kind of diluted IMO. Still, I try to follow this when the resulting method name sounds fine (e.g. zoomStrict is fine, but other times adding a suffix just doesn't read well).

from airstream.

kitlangton avatar kitlangton commented on August 20, 2024 2

Brilliant! Sounds like a plan 😎 I'll put my lil' demo code to work and report back if any weird side-effects crop up.

🥳🥳🥳

from airstream.

kitlangton avatar kitlangton commented on August 20, 2024 1

🥳 Very exciting!

I do have some general thoughts/questions about the purity requirements.

Do users currently depend on zoomIn being called precisely as many times as the parent variable is updated? I can't easily imagine a case, even if my Var contained mutable state, in which I'd be relying on that invariant—particularly if zoomIn might be called fewer times than the parent is updated, rather than more.

Perhaps the user could perform some logging/tracking in here? Yet, if one wished to execute some logic each time the parent Var changed, wouldn't using the Var's Signal be the more natural approach?

And because the zoomIn function may be called even fewer times than before, is this so much a purity issue? I think it could be argued that it's an implementation detail.

Of course, I completely understand that it's impossible to guess how users might be relying on some particular behavior. In fact, it's nearly certain that for any library of modest user-base, someone somewhere is pinning the hopes of their entire application on each incidental bit of functionality, conceived of and maintained by the author or not.

And then, I'm sure the maintenance of such invariants is useful to you, yourself, as you develop a library with such intrinsic complication. You're clearly well versed in the multifarious gotchas of this domain, as well as the guarantees you've thus far painstakingly preserved.


So, I guess what I'm devil's advocating for here is the possibility of the wholesale replacement of zoom with this new Ownerless variant, and casting the current behavior to the wind.

The benefits would be:

  • I'd guess that for 99.9% of cases, the Ownerless implementation will be more pleasant to use. In fact, I'd imagine that some users are currently using zoom with unsafeWindowOwner or some other custom leaky Owner. I assume this because I know I've done it myself, before I fully understood the consequences, and really wanted to zoom into my Var.
  • Less code > more code. Both for users and maintainers. Users won't have to reckon with the decision between these two overrides, and maintainers won't have to reckon with question of which of the many subtypes of Var they might be dealing with.
  • I guess those are the only two points, but that wouldn't be aesthetically pleasing. So I'll reiterate that I'm a big fan of smaller, more opinionated APIs, especially when the alternatives would be so rarely (if my guessing is at all accurate) useful.

And the downside would be the relaxing of some previous behavior. But of course, the recommended alternative would be to simply observe the parent var's signal if you wanted to be notified exactly-once (and no less) per emission.


I do see the argument for StrictSignal not behaving this way. Perhaps mapStrict, with a docstring of the caveats, would make sense? Though perhaps it's still worth thinking through the worst negative consequences of just doing the Ownerless version.


My lesser, backup (imp's advocacy) argument would be that perhaps the current behavior could get demoted to zoomImpure, and the Ownerless variant could get top-billing. Only because I think it's more often what people would want (and to avoid folks jury-rigging zoom with an unsafeWindowOwner).

A final, orthogonal thought on API-design is that I do enjoy a post-fix pattern for method alternatives, if only because it more naturally works with autocomplete. The user would type zoom and see all of the variants listed out at the end zoomX, zoomY, zoomZ. Though, it's more important to be consistent with the library's existing patterns.


Okay! All done! I'm super happy either way, just thought I'd put those arguments out there in case they're helpful.

from airstream.

raquo avatar raquo commented on August 20, 2024

Sorry, I've accidentally pressed Cmd+Enter and posted the half-written issue too early. I've now updated it with the full text.

from airstream.

raquo avatar raquo commented on August 20, 2024

You can now preview this feature in Airstream v17.1.0-M1. It can be used with Laminar 17.0.0. The new method name is zoomLazy.

from airstream.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.