-
Notifications
You must be signed in to change notification settings - Fork 303
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
Proactively unwrap chainables when return value is a boolean. #554
Comments
Good idea. |
Give it a thumbs up if you like it! I'm going to be looking at these. |
After considering this, one thing I really don't like about the idea is the potential for confusion about which methods are unwrapped. If all methods were prefixed with var d = new Sugar.Array([1,2,3]);
d.every(1); I think it would be very confusing for this method to be unwrapped and return a boolean as it isn't following the naming pattern that would indicate this. However, if we don't unwrap it selectively for methods that don't follow the Any thoughts? |
I think never auto-unwrapping is the more consistent solution. Let's not create Yet Another List Of Special Methods that everyone has to remember... |
I think that I agree with this. I want subsequent versions of Sugar to have a lower hurdle to their use, not higher. That said, the core issue I would like to address here (if it's even possible) is also a hurdle of sorts: var d = new Sugar.Date('today');
if (d.isValid()) {
// ...
} If someone was introduced to Sugar and saw just this code, when compared to other date libs like moment.js it is unfortunate that you need a timeout to address why I wonder if this can't somehow be handled without creating more overhead for everyone else. I'm beginning to think that it can't, but I at least wanted to state the root of the problem here first... |
I agree. There is also the implicit performance costs associated with wrapping everything, e.g. a memory allocation, a method call to get the actual value, etc. It might also mean that the optimiser has a harder time doing the right thing. |
Sorry, but I'm not quite sure which part you're agreeing with? |
Everything here is very reasonable and well thought out. I agree with all of it. However, I still think the original issue should be solved in a way which doesn't violate the principle of least surprise. |
If you wanted a rule, perhaps this is it: For methods that return "composite" objects, e.g. arrays, dictionaries, dates, objects, the object can be chained. But for simple values, e.g. numbers, booleans, strings, the value is not chained by default. |
Ah ok I see... Well, the problem with that rule is that Sugar provides many useful number and string methods. Unwrapping these would inevitably lead to people needing to rewrap the result, which would lead to chaos. Even booleans could potentially have other methods on them, although it's hard to imagine what they would be. However, for example even |
I'm pretty sure 99% of use cases of |
Well I agree with that part for sure. Just to throw it out there, here are the current methods that begin with "is":
Also language methods like:
...and type methods like:
Edit: also date methods like
|
So you propose to make all |
I think that if this were to get implemented, this rule ("begins with is") is the only way to do it without introducing major confusion. As mentioned though, I don't love this idea because it's still one arbitrary rule to remember. It's just a question of where we introduce it. It's either:
or
|
Yeah, the fact that .every and others do not unwrap is :( |
I'm starting to think it's the chainability that needs to be made explicit ;-) |
@vendethiel This is the stance that I'm tending to lean toward as well. It's worthwhile noting that the complaints that I have had come in came before I created the Date page was created. I'm feeling now that it would be better to have better pointers to that page and tighten it down even further to really solidify the concept as a first step to working with Sugar. Keep in mind that static methods return booleans so there is still a way to code around this for people who really don't like it, and it doesn't even have to be long: _d = Sugar.Date; // This could be a project wide shortcut.
if (_d.isValid(date)) {
// this will still work as expected
} Also, extended mode is still available which, if allowed, solves the issue and works as expected here. Even people with an aversion to modifying the global state may be willing to make an exception with the Lastly, one note is that a quick audit of the Sugar shows that the only methods that do not start with either
|
@vendethiel To clarify, were you referring to documentation or something else? |
Oh, I already know i'm going to keep using it ;-).
Well, the non-documentation part is already "explicit", insofar as extended doesn't need this behavior. Though I guess you could argue for a |
@vendethiel Well, it's true that something like Sugar.Date.format(d); rather than: Sugar.Date(d).format(); |
ah, that's true. Then it's just a documentation issue, explained like you do here. |
I would appreciate an easier api. E.g. I got the following dates.
Then I want to compare them like this:
But instead I have to write:
Am I missing something? Is there already an easier way? |
@Catscratch I agree. This is something that I will look into very soon. To refresh since this issue has been open so long though, how do you think it would be best to handle the expectation of whether or not the chainable will be unwrapped? In other words, I realize that you expect |
@andrewplummer Hm, good question. I think the Java time api is a good example of how it should look like. I would only use the chainable api on functions that change the object itself but not on any comparision. Isn't it possible to directly return a boolean for every "is" function? Also it is a really strange behaviour that e.g. addDays(1) not only gives me a modified object with one day added, but also changes the original object. E.g. in Java you can use addDays(...) and get a copy of the original object as return value. To avoid this in Sugar I have to do something like |
Well it is possible but again As for immutability I personally see the value of it but the #1 tennet of Sugar is to coexist with the native Javascript API, which is, for better or worse, mutable. So if As for the last one, all Sugar chainables have a clone method, so you could do |
via Twitter from @ioquatix
Version 2.0.0 added chainable behavior, however one note I immediately got is that the behavior of having to unwrap boolean values, either explicitly using the
raw
value, or implicitly using==
is counter-intuitive. For example:As Sugar's date module is often seen on it's own, users who are only interested in dates (such as this user) may not (should not have to?) understand the chainable behavior.
This could potentially be improved by separating methods that return booleans and defining different behavior on them (i.e. always returning an unwrapped boolean). Note particularly that this would make Sugar more intuitive when compared to moment.js, which doesn't have to deal with this issue as it is only concerned with dates.
However this has a few possible issues:
_.chain
method do essentially the same thing as Sugar does now by wrapping a raw value, and do not unwrap boolean types either. I'm not against this but it would need a decent justification.isArray
etc available to it. If the return type is unknown for whatever reason, these methods may still be useful.undefined
(if any?). As a tangential issue, what about methods that returnundefined
ornull
? Should these be unwrapped too?The text was updated successfully, but these errors were encountered: