Thanks to visit codestin.com
Credit goes to github.com

Skip to content

assign sentinel object to R.__#746

Merged
CrossEye merged 1 commit intoramda:masterfrom
davidchambers:placeholder
Jan 24, 2015
Merged

assign sentinel object to R.__#746
CrossEye merged 1 commit intoramda:masterfrom
davidchambers:placeholder

Conversation

@davidchambers
Copy link
Member

I've never been comfortable with the value of R.__ being undefined. Why "define" it at all, in this case? I like defining a true sentinel and requiring users to reference it directly or define a convenient 👽:

var _ = R.__;
var lessThanTen = R.lt(_, 10);

@buzzdecafe
Copy link
Member

🍰

@CrossEye
Copy link
Member

What are the advantages? Right now a user can use any undefined value she has lying around. What would a true sentinel gain the user? What would it gain our codebase?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These fixes look worth doing regardless. What were we smoking?

@buzzdecafe
Copy link
Member

i think a unique placeholder object is clearer than using undefined. always felt a little queasy about using undefined as a "magic" value like that. I don't think we need any properties on the object, though.

@davidchambers
Copy link
Member Author

What are the advantages? Right now a user can use any undefined value she has lying around. What would a true sentinel gain the user? What would it gain our codebase?

Clarity. Right now our message to users is along these lines:

You may use R.__ as a placeholder. Since the value of R.__ is undefined, you could just as well use R._ or R.___ or R.placeholder or any other nonexistent property of R (or any other object). You may prefer to use undefined directly, though in some environments it's safer to use void 0. Possibly the best option is to include var _; at the top of the file then to use _ wherever a placeholder is required.

This is what I would like to say instead:

You may use R.__ as a placeholder.

I find the alternative acceptable too, though it's not as succinct:

You may use undefined as a placeholder. It's a good idea to include var _; at the top of the file to create a conveniently named variable whose value is undefined.

Let's pick R.__ or undefined. If we pick the former, let's make it a true sentinel. If we pick the latter, let's remove all the references to R.__.

@CrossEye
Copy link
Member

@davidchambers:

As ususal, you make a good argument. I still can't say I like it. I would rather go with undefined, but I believe that had unpleasant side-effects for our example code, each block of which would really need to then declare its own undefined value.

My objection to the sentinel is that R.__ is ugly and over-verbose for what it does, and requiring users who want the nicer _ to then assign a Ramda-specific alias in order to use it seems a little demanding. That they could use whatever alias to undefined they chose, even if they also wanted to use it for non-Ramda purposes, is a nicer experience.

But I don't think I can have my 🍰 and eat it too.

So here's a very reluctant 👍

@davidchambers
Copy link
Member Author

My objection to the sentinel is that R.__ is ugly and over-verbose for what it does, and requiring users who want the nicer _ to then assign a Ramda-specific alias in order to use it seems a little demanding. That they could use whatever alias to undefined they chose, even if they also wanted to use it for non-Ramda purposes, is a nicer experience.

I'm fine with closing this pull request and opening a new one to remove R.__. My main concern is that we have two ways to do something trivial, which complicates our explanations of placeholders.

@CrossEye
Copy link
Member

My main concern is that we have two ways to do something trivial, which complicates our explanations of placeholders.

I think the explanation could be significantly simpler:

You may supply an undefined value as a placeholder. We offer the undefined R.__ as one such value.

@davidchambers
Copy link
Member Author

I don't think we need any properties on the object, though.

True, but I don't see any harm in "labelling" the object to aid debugging.

@CrossEye
Copy link
Member

I don't see any harm in "labelling" the object to aid debugging.

I suppose I agree.

But I think placeholder is more explicit than sentinel:

{ramda: 'placeholder'}

or

{ramdaPlaceholder: 'sentinel'}

One other thought. I'm assuming that we'll stick with our caveat emptor, or with Peter Parker's "with great power comes great cliches" (sorry, some translation glitch), for the possibility of someone reassigning the value of R.__. I think that to make it immutable would involve adding exception logic for that file in the build script, something I'd rather avoid. If we can think of another way, it might be worth doing, though.

@buzzdecafe
Copy link
Member

If we can think of another way, it might be worth doing, though.

make R.__ a reference to R? then if it gets reassigned you can always put it back

@CrossEye
Copy link
Member

If we can think of another way, it might be worth doing, though.

make R.__ a reference to R? then if it gets reassigned you can always put it back

I'm just not sure how we would do that. R is not defined until the distribution is created and the return from the revealing module pattern is constructed. So it's not available inside the op function for such a reference.

@davidchambers
Copy link
Member Author

I think placeholder is more explicit than sentinel

I agree. I've updated the label to {ramda: 'placeholder'}.

As for the possibility of a user assigning another value to R.__:

  • we could make R immutable in environments which provide Object.freeze, but this would prevent users from adding their own functions to the object;
  • the current approach is equally "vulnerable", since one could assign 42 to R.__ while elsewhere assuming R.__ to be undefined; and
  • I'm not in the slightest bit worried as users should not mess with R.__.

CrossEye added a commit that referenced this pull request Jan 24, 2015
@CrossEye CrossEye merged commit 9ccfdc6 into ramda:master Jan 24, 2015
@davidchambers davidchambers deleted the placeholder branch January 24, 2015 20:12
@CrossEye
Copy link
Member

  • we could make R immutable in environments which provide Object.freeze, but this would prevent users from adding their own functions to the object;

Oh no, I would not consider that. I was merely thinking along the lines of

Object.defineProperty(R, '__', {
    enumerable: true,
    configurable: false,
    writable: false,
    value: {ramda: 'placeholder'}
});

which would then have to be wrapped in some not-ES3 check... not worth it.

  • the current approach is equally "vulnerable", since one could assign 42 to R.__ while elsewhere assuming R.__ to be undefined

Yes, but as that is likely to be the only reference to the sentinel, it will now be fatal, whereas when we used undefined, it was easy to reset, or to work around if you simply used another undefined reference. Again, I don't think this is a big deal.

  • I'm not in the slightest bit worried as users should not mess with R.__.

Right, and unless we grow to have jQuery-sized concerns, I don't think we ever really need to worry about how one user deals with another's abuse of our library inside the same scope. If we ever get to the point of having such worries, this will probably be among the more minor ones.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants