Closed rikutiira closed 6 years ago
I think that having lifted Ramda functions return lifted functions when used with placeholders would be the better option.
Since all Ramda functions (I think?) are curried and have no optional arguments, it would probably be possible to simply define their arity in karet.util and have them return lifted functions until all arguments are given?
I think this would also solve the issue of having to use placeholder variables in cases like:
Before: U.find(U.propEq('foo', 'bar', U.__), array)
After: U.find(U.propEq('foo', 'bar'), array)
I know those situations have caused some confusion with a few people using karet.
I can make a PR about this if this solution sounds good to you.
Yes, I think it is likely possible to lift Ramda functions more intelligently.
I'm going to look into this soon. I think it is time to introduce separate modules/libraries for lifted Partial.Lenses functions and Ramda functions.
I started a repo: kefir.ramda
. It is very experimental at this point. Please try it out and open issues there or ask on Gitter.
Thanks! I will take the library into use in our project and report if everything seems to work nicely.
Currently, in Karet Util, a lifted function is a curried function that returns a function when applied to one or more observables (but not enough parameters to saturate full arity). In Kefir Ramda, however, a lifted function is a curried function that returns an observable (instead of a function) when applied to one or more observables.
For example, with U
as Karet Util and K
as Kefir Ramda,
U.map(U.add(Kefir.constant(1)), [1, 2, 3])
returns an array of observables, but
K.map(K.add(Kefir.constant(1), [1, 2, 3])
returns an observable array, which is what you usually want. The key difference is that K.add(Kefir.constant(1))
returns an observable that produces the function R.add(1)
.
So, Kefir Ramda functions probably work better in Ramda style point-free expressions. However, with current U.seq
they don't work, because U.seq
expects functions rather than observables. So, a lifted version of U.seq
might be useful after all.
There is now also Kefir Partial Lenses. Also U.view
in Karet Util now lifts the lens as a template and Karet Util now has U.thru
and U.thruPartial
that are lifted versions of U.seq
and U.seqPartial
.
One thing I notice is that there are still cases where one has to specifically perform e.g. a non-lifted R.compose
or R.pipe
. So, just importing
import * as L from 'kefir.partial.lenses'
import * as R from 'kefir.ramda'
everywhere does unfortunately not "just work". I'll have to go through various code sample and see if there is a simple set of advice that can be given.
We have used both R and U in our codebase, because often we have used synchronous versions of R functions in our callbacks, for example. I'm not sure if it has been the best approach because you have to have pretty good understanding of when to use synchronous R or asynchronous U.
If I recall right, there were some special cases of lifted Ramda functions where they returned observables despite not having observable arguments. Maybe I remember wrong though, it could just be that we decided it's simpler to treat U functions as something which can be potentially asynchronous due to it also having always-observable versions of Kefir methods.
you have to have pretty good understanding of when to use synchronous R or asynchronous U
Yes, I agree. I'm kind of hoping that it might be possible to make it so that one could use lifted R
and L
except in a few special cases that could be documented, but I'll have to see how it turns out.
lifted Ramda functions where they returned observables despite not having observable arguments
That shouldn't happen.
FYI, I've been converting samples at CodeSandbox to use the new lifted libraries (Ramda, Lenses, Validation) and I'm cautiously optimistic. Most of the samples have become slightly less noisy, because having the lifted libraries at hand one can eliminate some uses of U.lift
or K
.
The new liftRec
(lift "recursive") function in Kefir Combines has the nice property that it preserves the currying / optional parameter behaviour of the original function. For example, currently Karet Util exports a stringify
function, which is U.lift(JSON.stringify)
, but it has the nasty gotcha that U.lift
curries the function, so one has to call it with all three arguments unlike the original JSON.stringify
. If it were liftRec(JSON.stringify)
, the behaviour of the original JSON.stringify
would preserved and you could call it with just one argument.
My current plan is to add libraries or separately imported modules for the lifted Math
and JSON
objects (and other lifted standard functions I'm forgetting right now) currently in Karet Util and deprecate the existing lifted functions in Karet Util (including the lifted Ramda functions).
Resolved in latest version.
Would it make sense for U.seq to lift functions automatically like U.pipe?
Right now this fails:
While this works:
Alternatively if it's possible, maybe lifted Ramda functions could return lifted functions when used with placeholder values.