New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use maybes for unsafe operations #683
Comments
we just moved all the types |
ok, after mulling this over, i think i am |
How would that work with |
the contract of tail is already null-safe, `cuz it returns a functor, an array. |
It's safe, yes, but also lossy: R.tail([1]) //=> []
R.tail([]) //=> [] Whereas with maybes these cases are distinct: R.tail([1]) //=> Just([])
R.tail([]) //=> Nothing() |
i don't see why the proposal is an improvement over simply letting the user compose for themselves: |
Having Maybe(R.head([undefined]))
Maybe(R.head([])) These are not equivalent in my mind: I expect |
You can re-implement Maybe in terms of
That is because of weird-ass JS. |
I don't see this as a JavaScript-specific issue. Take the tuple |
yes, that's the situation we are in:
Aside: A quick look at https://github.com/folktale/data.maybe/blob/master/lib/maybe.js doesn't back me up here, allowing And another thing: Why favor |
I have several thoughts here.
|
I'm missing something... My understanding is that ES6 array methods will ignore "holes". If I pass |
I avoid differentiating these values in code I write. I like to pretend there's just one nil value (which I call "null", but which others sometimes call "undefined"). I have my linter configured to allow |
i agree, but composing by passing down |
Another option would be to return |
Further, the |
But, at least in the single-argument case, the only way to distinguish them is by querying the length of the
There are definitely times when we want to conflate the two notions. But they do represent different concepts in JS. While So when we want to ask "Is it there?" it's fine to conflate the two. But for "Did we pass/define it?" I think they need to be distinguishable if we're to work with the grain of the language. |
Also, @AutoSponge:
Also, we're not particularly concerned with exactly what native implementations do nor with other languages or other libraries do. We look to them for inspiration, but not guidance. |
@CrossEye, Ramda currently treats |
@AutoSponge: and that's where I see little distinction between |
@davidchambers can this be closed, or do you wanna fight for it? |
I would like Ramda to encourage and enable clear, correct JavaScript code. With Ramda one can write more declarative code than is possible with vanilla JavaScript; Ramda undoubtedly encourages and enables clear JavaScript code. By removing the need for imperative loops and variable assignment Ramda also goes some way towards improving code correctness. I would like the library to go further in this direction. Taking another step down the path towards guaranteed correctness may violate Ramda's philosophy of being practical, though I do wonder whether practical in this case really means easy to use. One option I'm considering is testing these functions in the wild in a custom Ramda build. After a few weeks or months I could then report back on the experience. |
for the record, i'm not so concerned about the "practical" part of the slogan--I feel like that ill-defined term gets thrown out there to support anybody's hobbyhorse, and so i usually find that an unpersuasive argument. but I am concerned about adding overhead to fundamental functions that can easily be composed in if desired. (Incidentally, way back when, |
My view is that safety should be opt-out rather than opt-in. If one knows |
What this really makes me want to do is fold But I'd still rather make this a step you can compose yourself. Those who don't want to deal with a Regarding "practical", I've been working again on that Philosophy Of Ramda document, and using "a practical functional library for Javascript developers" as a framing mechanism. But I started from the back forwards, discussing what it means to be for developers, how it's focused on Javascript qua Javascript and not a poor-man's Haskell/Clojure/Scala/whatever, how it hangs together as a library, and have nearly finished the section on what it means to be functional. Now I have to write the "practical" section. I think I have some meaningful things to say there, but I agree that it's the most squishy term in our mantra. |
@CrossEye , will that article arrive before Perl 6? |
also, we could add this would mean checking on the way in, rather than the way out. |
FWIW, I found that once a user enters the world of "container programming" - that is to say, monadic/functor based types, intimate familiarity with the "container apis" is essential. var get = curry2(function(key, obj){ return Maybe(obj[key]); })
var head = get(0)
var garyBday = compose(map(add(1)), chain(get('age')), head)
var xs = [{name: "Gary", age: 30}, {name: "Lisa", age: null}]
garyBday(xs) Here we have to know about I like using these things to enforce safety and purity, but I see the learning curve skyrocket. Perhaps a safety_net.js include could just overwrite some functions: var head = compose(Maybe, _.head) Just a thought. But, yeah, i think the adoption rate would decrease if enforced. |
If you're pushing for safety of this sort, do you suggest we try to capture the sort of things @AutoSponge was mentioning too?
So should |
In @CrossEye's example, above, fault can be laid with...
Depending on who you blame for this TypeError will determine how it gets fixed. It's easy to push this to the user/coder however I seem to run into more and more APIs with unstructured data and I don't want to have to pre-process every response--but maybe that's the case for transducers being made again. |
I'm not suggesting we enforce type safety in a dynamic language. Besides, there are other projects that could work with ramda to accomplish this. I'm just thinking monadic programming should be optional and it'd be sweet to opt-in to the behavior somehow. i'd hate to see the adoption rate decrease despite my obvious bias toward the haskell way |
@DrBoolean For "you" read "@davidchambers". I agree that there is a very sweet spot for monadic programming. I just don't think Ramda's core is it. |
@AutoSponge: I was really using this as an example of the sort of thing we've chosen not to deal with so far in Ramda, mostly for comparison's sake. There are good questions to be had about sparse arrays. I just don't really want to ask or answer them, as they are not the type we are trying to model with Ramda, the list. Unfortunately, a JS array can have holes as well as arbitrary non-integer named properties; none of these really has anything to do with the only structure we care about for many of our functions. |
These list functions are available in Sanctuary, a JavaScript library for manipulating values without null checks. Sanctuary plays nicely with Ramda, and takes advantage of |
Sanctuary looks pretty nice |
Very nice! |
@austbot i intend a PR to add Then you could just:
in your example: why |
Saw that, removed it to not confuse people :)! |
i'm sorry you did, it makes my comment a non sequitur |
Github backup please!!! :) |
Certain Ramda functions are unsafe. Take this quartet, for example:
I suggest the following types:
We could also provide the unsafe versions:
We'd also provide the following function which takes a default value as its first argument:
Let's consider a simple example: taking the first element of a
[String]
of unknown length and converting it to upper-case.It's cleaner and less error-prone to map over a maybe than to rely on checking for the empty list whenever one uses a member of this quartet.
These types are used by purescript-arrays. I'd like to Ramda do the same.
The text was updated successfully, but these errors were encountered: