Skip to content
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

restrict $.Boolean, $.Number, and $.String to primitive values #100

Closed
davidchambers opened this issue Nov 20, 2016 · 1 comment
Closed

Comments

@davidchambers
Copy link
Member

Until recently I hadn't given this matter much thought. $.Boolean having four members is messy, but it's a reality of JavaScript. While working on sanctuary-js/sanctuary#279 I realized how error-prone Boolean objects are. Here's the implementation of and :: Boolean -> Boolean -> Boolean from that pull request:

function and(x, y) {
  return x.valueOf() && y.valueOf();
}

Without invoking valueOf, and(new Boolean(false), new Boolean(true)) would evaluate to new Boolean(true) rather than new Boolean(false) (or simply false).

I'd like to restrict $.Boolean to {false, true}, and similarly restrict $.Number and $.String. The reasons for doing so are as follows:

  • 5–10% of the JavaScript language is very nice. Sanctuary allows one to program entirely in this pleasant corner of the language. No type coercion. No visible mutation. No implicit arguments. No optional arguments. No arguments objects. No symbols. No null. No undefined. No imperative control flow. No identity-based equality.

    Adding three more items to this list would be quite natural.

    It would not even prevent users from using these values. Users are free to define their own types, and could, for example, define a type equivalent to the current $.String if the new $.String is too restrictive.

  • In several years of writing JavaScript I have never needed to pass around Boolean, Number, or String objects. I have occasionally written expressions such as Object(x) === Object(y) which promote primitives, but this is not much different from the promotion which occurs when evaluating s.trim().

  • Implementations of functions such as S.and, S.or, and S.not would be simpler were the functions only applicable to Boolean primitives. The corresponding tests would be simpler too, as there would be fewer input combinations to test. With four Boolean values there are 4² combinations; with two Boolean values there would be just 2² combinations (a 75% reduction).

  • The formal definitions of the types would be elegant. The definition of $.Number, for example, would be the type comprising every value x for which typeof x evaluates to 'number'.

If you're in favour of this change, react with 👍. If you're against this change, react with 👎 and post a comment explaining why you believe it's important to continue to include objects in these types.

@safareli
Copy link
Member

from related article The Secret Life of JavaScript Primitives

The ability to assign properties is just about the only advantage of objects over their primitive counterparts, but in practice even this is a dubious quality. Strings, booleans and numbers have specific and well defined purposes and redefining them as state holders is likely just going to confuse people. Moreover, since primitives are immutable you cannot modify them by tweaking the properties of the object wrapper

var me = new String("Angus");
me.length = 2; //(error in strict mode)
me.length; //5 (not 2 - thanks @joseanpg)
me.valueOf(); "Angus"

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

No branches or pull requests

2 participants