Comments (5)
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.
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.
🥳 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
withunsafeWindowOwner
or some other custom leakyOwner
. I assume this because I know I've done it myself, before I fully understood the consequences, and really wanted tozoom
into myVar
. - 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.
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.
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)
- .split operator is hard to use without Laminar
- Killing subscriptions from observers (?)
- splitByType / splitByEnum HOT 6
- Can `DerivedVar` support `map/update` semantics in addition to `map/contramap` semantics? HOT 2
- Add an AjaxStream upload progress observer
- FetchStream does not emit events if it's initialized outside of a transaction HOT 1
- [Question] Simulate DomEventStream click on page load HOT 5
- idiomatic usage of foreach for EventStream HOT 4
- RFC: Should we import-gate flatMap? HOT 7
- Streams should emit in a shared transaction when starting HOT 2
- Vars should be splittable HOT 4
- Error: code length overflow HOT 2
- Transaction stack overflow caused by sibling transactions HOT 4
- split doesn't memoize on Signal[LazyList[A]] HOT 2
- SplitChildSignal does not re-sync when restarted HOT 6
- `composeEither`: fixed-scope `flatten` without transcations HOT 4
- StreamFromSignal with onlyChanges = False may filter out initial value
- Streams with 'EventStream.fromFuture' drops result of futures if timing overlaps. HOT 7
- contrib: can't find dep com.dwijnand:sbt-dynver HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from airstream.