Open erights opened 7 years ago
loose?
Sloppy seems fine.
"loose", "legacy", "sloppy" - all have an appropriate judgmental connotation; one echoed by the committee's choice of auto-strict for class
and Module code anyways.
Since "sloppy" is the widest known conventional (and precise) term for it, must we still avoid the term?
@ljharb FWIW I disagree that loose and sloppy are equally judgemental. There's no reasonable situation where calling something sloppy is anything but an insult or criticism. Loose, however, is kind of definitionally opposite of strict, and can mean "more freedom", which is IMO the more appropriate connotation.
Anyway, when I teach JS I use "loose mode" to contrast with "strict mode", but I would never use "sloppy" under any circumstances, just like I don't call code bases "bloated" or "fat".
I like sloppy. Also I thought being judgmental was the point, since we don't want people to use sloppy features for new code.
I am quite pleased at the positive reaction to "sloppy". My qualifications in the first comment are because I thought it would be a non-starter. Given these other reactions, I favor "sloppy".
If we can't get agreement on "sloppy" I think "loose" is fine.
"permissive" is perhaps a more precise antonym to "strict" in the sense we're using it. ("sloppy" connotes carelessness, and "loose" is itself a loose term.)
"permissive" imo makes it sound too good - strict mode should be encouraged, even if we don't want to actively discourage sloppy mode (more than we already are, of course, both in the spec and in the best practices of the majority of the JS community).
There's "lax". Or "lenient". But "sloppy" has the convenient property of being as long as "strict" in terms of character count.
On 7 April 2017 at 08:24, Lars T Hansen notifications@github.com wrote:
"permissive" is perhaps a more precise antonym to "strict" in the sense we're using it. ("sloppy" connotes carelessness, and "loose" is itself a loose term.)
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/tc39/ecma262/issues/875#issuecomment-292452136, or mute the thread https://github.com/notifications/unsubscribe-auth/AEDOO1Pd1mZvt5DaQnIRgInTQjbiivTHks5rtdapgaJpZM4M2SaI .
I like "sloppy", but how about "legacy"?
I don't think that Mark's original premise and classification of functions is really correct.
The terms "strict function" and "non-strict function" are defined in 9.2 as concepts that are only applicable to functions objects that when called evaluate ECMAScript.
The specification also allows for the possibility of an implementation exposing exotic function objects that when called do something other than evaluating ECMAScript code. Such exotic functions are neither strict or non-strict because they don't have any ECMAScript code that the strict-mode code rules could be applied to.
9.3 allows built-in functions to implemented as either strict ECMAScript function objects or as implementation provided kind(s) of exotic function object. A built-in function may never be a non-strict ECMAScript function.
So, "strict function", "non-strict function", and "built-in function" do not describe disjoint sets.
I don't really understand the source of confusion as while a built-in might be implemented as a strict function it can never be a non-strict function. I don't see how replacing "non-strict" with some other term would be any more or less confusing or misleading.
Allen, I think the fact that a built-in function may be "implemented as" an ECMAScript function should be completely irrelevant as far as the language specification goes. AFAICT it is not observable. That makes it an implementation detail, nothing more, and need not affect any classification made in the description of semantics.
That is to say, I agree with Mark's premise.
On 7 April 2017 at 09:06, Allen Wirfs-Brock notifications@github.com wrote:
I don't think that Mark's original premise and classification of functions is really correct.
The terms "strict function" and "non-strict function" are defined in 9.2 https://tc39.github.io/ecma262/#sec-ecmascript-function-objects as concepts that are only applicable to functions objects that when called evaluate ECMAScript.
The specification also allows for the possibility of an implementation exposing exotic function objects that when called do something other than evaluating ECMAScript code. Such exotic functions are neither strict or non-strict because they don't have any ECMAScript code that the strict-mode code rules could be applied to.
9.3 https://tc39.github.io/ecma262/#sec-built-in-function-objects allows built-in functions to implemented as either strict ECMAScript function objects or as implementation provided kind(s) of exotic function object. A built-in function may never be a non-strict ECMAScript function.
So, "strict function", "non-strict function", and "built-in function" do not describe disjoint sets.
I don't really understand the source of confusion as while a built-in might be implemented as a strict function it can never be a non-strict function. I don't see how replacing "non-strict" with some other term would be any more or less confusing or misleading.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/tc39/ecma262/issues/875#issuecomment-292458884, or mute the thread https://github.com/notifications/unsubscribe-auth/AEDOO5BYwikoh-jfgiyx5gEXJsXHHntjks5rteB7gaJpZM4M2SaI .
That is to say, I agree with Mark's premise.
Mark said:
But "non-strict" is too misleading because built-in functions are "not strict" but not "non-strict".
But as Allen explained above, the 'not "non-strict"' part is incorrect per https://tc39.github.io/ecma262/#sec-ecmascript-function-objects:
An ECMAScript function object whose code is strict mode code is called a strict function. One whose code is not strict mode code is called a non-strict function.
If a built-in function is implemented as an ECMAScript function object, it must be a "strict function" (https://tc39.github.io/ecma262/#sec-built-in-function-objects). If it's not implemented as an ECMAScript function object, it's still not a "non-strict function", because that classification only applies to ECMAScript function object. So a built-in function can be a "strict function", but it's never a "non-strict function".
I agree that the current spec wording does not match with that. My point was that the current spec conflates semantics with implementation details. It would make more sense to define three disjoint categories of functions, as Mark suggests. That of course would imply removing any (otherwise irrelevant) wording about built-in functions possibly being implemented as ECMAScript functions.
On 7 April 2017 at 09:49, André Bargull notifications@github.com wrote:
That is to say, I agree with Mark's premise.
Mark said:
But "non-strict" is too misleading because built-in functions are "not strict" but not "non-strict".
But as Allen explained above, the 'not "non-strict"' part is incorrect per https://tc39.github.io/ecma262/#sec-ecmascript-function-objects:
An ECMAScript function object whose code is strict mode code is called a strict function. One whose code is not strict mode code is called a non-strict function.
If a built-in function is implemented as an ECMAScript function object, it must be a "strict function" (https://tc39.github.io/ecma262/#sec-built-in- function-objects). If it's not implemented as an ECMAScript function object, it's still not a "non-strict" function, because that classification only applies to ECMAScript function object. So a built-in function can be a "strict function", but it's never a "non-strict function".
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/tc39/ecma262/issues/875#issuecomment-292466860, or mute the thread https://github.com/notifications/unsubscribe-auth/AEDOO6fSzD4NRPw8s4WQlZqUnDTcfAPGks5rtep2gaJpZM4M2SaI .
I very much want to agree with @rossberg-chromium 's conclusion --- that there is no observable difference, and therefore it has no place in the normative spec language.
Unfortunately I see one possible exception: What would Function.prototype.toString.call(aBuiltinImplementedAsStrictJS)
print? As the spec currently reads, it could print either way. Instead I would like to require all built-ins to print the way built-ins in general print, in which case built-ins would observably be neither strict nor sloppy.
+1 to "sloppy"
Tangent, but FWIW, I think it'd be great if the ECMAScript spec made it clear (even in a note) that it exposes functions that could be exposed as strict mode JS code. This seems to have been a design goal of the spec that it's currently adhering to, and the more consistency, the easier it is to reason about, both for users and implementers.
Since the notion of strictness applies specifically to so-called ECMAScript Function Objects, we could say “strict ECMAScript function” and “non-strict ECMAScript function”.
Or we could ban the “(non-)strict function” terminology, and refer instead to the [[Strict]] internal slot of ECMAScript Function Objects instead.
I don't see how replacing "non-strict" with some other term would be any more or less confusing or misleading.
The term "non-strict function" suggests the complement of "strict function". While this is correct within the domain of 'ECMAScript function objects', it is not correct within the domain of (all) function objects. So a different term, that does not make this suggestion, would be less misleading. (Is the point of this issue.)
:+1: sloppy
@erights says:
that there is no observable difference, and therefore it has no place in the normative spec language. Unfortunately I see one possible exception: What would ...
The possible observable differences currently only relate to the set of own properties that a built-in property exposes. There is nothing currently in the spec. (except for the forbidden extensions) that restrict an implementation from defining additional properties on exotic built-ins. And it's not clear that there should be.
What is the utility of defining "sloppy" (or any other term) as meaning "any function object that is not a strict mode ECMAScript function". Where is does that concept useful and exactly how does it characterize the set of function it applies to?
For example, it would be unhelpful for it to mean that "strict mode" restrictions and alternative semantics do not apply to such functions. All of those restrictions relate to the validity and semantics of actual ECMAScript code. Most of those restrictions (can't use with
, no legacy octal constants, etc.) are simply irrelevant to exotic functions that are not defined in terms of ECMAScript code. Others, such as the binding of this
when undefined is passed are also relate to the interpretation of ECMAScript code, but similar effects are explicitly specified for each built-in function (that might not be implemented as an ECMAScript function).
The terms "strict function", "non-strict function", and "built-in function" are all precisely defined and (I believe) consistently used within the actual specification. Any confusion about the meaning of spec. text using those terms probably comes from readers making incorrect assumptions about the meaning of the term. But any alternative terms (such as "sloppy") would also be subject to similar misinterpretation. So, what is the specification benefit to changing the terminology.
Outside the specification, in the real world, where would "sloppy" be used with any mean other than exactly the one currently defined in 9.2? BTW, this isn't a rhetorical question. I'm really interested in knowing if there are any real-world situations where is it useful to talk about the set consisting of all functions (including non-ECMAScript functions) that are not defined using strict mode ECMAScript code?
BTW-2, I'm moderately ok with the colloquial meaning of "sloppy function" and occasionally use it myself. I just don't see how introducing it into the actual specification adds any value.
I'm ok with sloppy as we already use it conventionally.
Getting feedback from coworkers we also agreed "relaxed" would be a nice naming that is not judgemental and probably accurate to the spec.
What is the utility of defining "sloppy" (or any other term) as meaning "any function object that is not a strict mode ECMAScript function"?
I don't think anyone is proposing to do that. Rather, I believe people are suggesting a replacement for "non-strict" in the phrase "non-strict function", with no change in meaning.
(For consistency, we might also want to make the same change, if any, in the phrase "non-strict code".)
@allenwb, being precisely specified doesn't imply not being confusing or conflating concerns. ;)
The suggestion is to tweak the definitions such that:
This way they are cleanly disjoint and any confusion (and implementation dependency!) about what built-ins the strict-vs-non-strict labels include is avoided.
That implementations may choose to implement some exotic functions with the same internal(!) representation as ECMAScript functions is fine, but nothing that the normative text has any business being concerned about.
@jmdyck but any replacement for "non-strict function" that does not explicitly include some negation of the word "strict" is masking the essential difference between those two kinds of ECMAScript functions.
If the concern is that it isn't obvious that the strict/non-strict distinction is only applicable to ECMAScript functions then to remediate that I suggest replacing in the spec. all occurrences of "strict function" with "strict ECMAScript function" and "non-strict function" with "non-strict ECMAScript function". It's wordier but more explicit.
@rossberg-chromium You are suggesting that 1) built-ins must appear to be exotic and 2) if an implementation wants to uses an ECMAScript function to implement a built-in then it must come up with someway to mask that fact. The ability to self-host builtin using ECMAScript was one of the explicit ES6 goals. The current specification language allows that without additionally requiring that an implementation make the extra effort to do such masking.
In my ideal word most built-ins would be directly implemented as ECMAScript functions. Why do we want to make it harder for implementations to do that?
Why does "may be exotic" obligate implementations to make them exotic?
any replacement for "non-strict function" that does not explicitly include some negation of the word "strict" is masking the essential difference between those two kinds of ECMAScript functions.
Whenever I see terminology "ADJ NP" for some adjective and noun, and "non-ADJ NP" I assume this is a complete disjoint partitioning of the set under discussion. In this case, we have three leaf categories:
For my purposes, the distinction I most often need to refer to is between sloppy functions and non-sloppy functions. IOW, I often find the need for the two-way distinction that does not distinguish between strict and sloppy. Speaking in terms of today's terminology, I am left with "non-strict" and "not non-strict". Yuck!
If the concern is that it isn't obvious that the strict/non-strict distinction is only applicable to ECMAScript functions then to remediate that I suggest replacing in the spec. all occurrences of "strict function" with "strict ECMAScript function" and "non-strict function" with "non-strict ECMAScript function". It's wordier but more explicit.
That is a valid way to put the concern. Your suggestion for fixing it is logically fine but is indeed much too verbose. In fact it is so verbose that people will inevitably shorten it in conversation and in non-spec documents about the spec back to "strict function" and "non-strict function". I have already been in many conversations with experienced tc39 committee members where I used "non-strict functions" to mean sloppy functions and they thought I was talking about all functions other than strict functions.
Another possible way to slice this is by making the two distinctions that are already in our vocabulary, but redefining them so they are cross cutting:
Where we include built-in functions in the strict category. This would shift our terminology as follows:
built-in | ECMAScript | |
---|---|---|
not non-strict | built-in | strict |
non-strict | prohibited | non-strict |
built-in | ECMAScript | |
---|---|---|
non-sloppy | built-in | strict |
non-strict | prohibited | sloppy |
built-in | ECMAScript | |
---|---|---|
strict | built-in | strict ECMAScript |
non-strict | prohibited | non-strict ECMAScript |
After laying this out, I still prefer "Simple Proposal" to "Cross-Cutting Proposal". In fact I prefer it even more. This is a case where orthogonality would subtract value.
Much of this boils down to a factual question we should be able to derive from the spec: Other than the behavior of Function.prototype.toString
, are there any other observable differences between strict ECMAScript functions and built-in non-ECMAScript functions?
permissive relaxed
Say that the opening line of a novel were "Alice is permissive. Bob is strict. Carol is relaxed. Dave is sloppy." Nevermind that it would probably be a terrible novel I should put down immediately. If I did read on, the rank order of who I would expect to like would be
There is nothing objective about my reactions. Introspectively, ask yourself the same question.
If I could come up with a short clear acceptable word with worse connotations than "strict" I would. Of the short clear acceptable words, the one with the worst connotations so far is "sloppy". Many people, including myself, on first hearing even the "strict" vs "sloppy" distinction may still misunderstand that "sloppy" is likely to be the one they will be happier using. At least "sloppy" produces less bias in that direction than any of the alternatives so far.
(I wish that we could, at the same time, rename "strict" to "neat". But we cannot.)
From the spec., I believe the only observable differences is the behavior of Function.prototype.toString behavior. However, the non-standard legacy addition to caller
and arguments
potentially make the distinction between strict ECMAScript functions and non-strict ECMAScript functions.
I'm still puzzled about when anybody other than Mark (who has specific security concerns he needs to talk about) needs to talk about "strict"/"sloppy" distinction for anything other than ECMAScript functions. I appreciate the important distinction in the forbidden extensions spec. text, but does any real JS dev ever need to think about how a built-in is implemented. Does a JS dev ever need to think about the "strict"/"sloppy" distinction other than when they are talking looking at the source of an actual ECMAScript function.
However, the non-standard legacy addition to caller and arguments potentially make the distinction between strict ECMAScript functions and non-strict ECMAScript functions.
That is indeed the issue under current debate at #867 . As I read that thread, my impression is that we're in agreement that all strict and built-in functions, with the possible exception of Function.prototype
, must be born in an initial state in which these are absent. If that is indeed the conclusion, then we would not find any observable difference there. IOW, I expect us to agree that an implementation is only able to endow sloppy functions with these horrible magic properties.
Wouldn't borrowing a builtin prototype method and .call(null)
make its behavior potentially different for strict-like and sloppy-like builtin functions? (Let's say I did window.length = 0;
first)
@ljharb no, because all standard built-ins are specified such that they handle the this argument similarly to a strict ECMAScript function. (note that as of ES5, the replacement of null/undefined with the global object happens on the callee side rather than the caller side.)
@allenwb asks
I'm still puzzled about when anybody other than Mark ... needs to talk about "strict"/"sloppy" distinction for anything other than ECMAScript functions.
And then, without irony, immediately afterwards @allenwb states:
note that as of ES5, the replacement of null/undefined with the global object happens on the callee side rather than the caller side
That replacement, magically revealing the global, is only done by sloppy functions. It is never done by either strict or built-in functions. All built-ins, called with a null
value for their this
-argument, either:
Mark, I guess I miss why my second statement could be seen as ironic? The fact that the algorithmic specifications of the built-ins handle null this
values in an manner that enable their implementation using a strict function is certainly not an accident. What's important is what they actually do with those null values similarly to what you just enumerated. But those behaviors aren't a strict/sloppy distinction.
But those behaviors aren't a strict/sloppy distinction.
You asked about what users need to talk about and think about. To a user trying to reason about what the language does, it is an oddball fact that sloppy functions might magically produce the global object. Likewise, only sloppy functions retain the oddball legacy caller/arguments behaviors. The simplest user model for understanding the implications of the three different kinds of functions is to group built-in and strict together, distinguishing these from the oddball: sloppy functions. Sloppy functions have magical oddball behaviors inviting trouble. Better to avoid them and program only with built-ins and strict. (With difficulty, I restrain myself from suggesting "oddball" as an alternative to "sloppy".)
If you want to expand the "strict" category to include built-ins, I would be sympathetic, as in the cross-cutting proposal above. Then "sloppy" could be called "non-strict" without confusion. But I still prefer the Simple Proposal.
@allenwb
1) built-ins must appear to be exotic and 2) if an implementation wants to uses an ECMAScript function to implement a built-in then it must come up with someway to mask that fact. The ability to self-host builtin using ECMAScript was one of the explicit ES6 goals. The current specification language allows that without additionally requiring that an implementation make the extra effort to do such masking.
Can you explain what masking would be required? What observable consequences would them being exotic include?
@erights the title of the issue seems to be answered; but it seems like https://github.com/tc39/ecma262/issues/875#issuecomment-292660502 is still a change you'd like to make. If so, would you be able to put together a PR?
I still object to https://github.com/tc39/ecma262/issues/875#issuecomment-292660502 as I believe it muddling the fact that strictness/non-strictness is only defined as a characteristic of ECMAScript functions.
The ES spec does not place any requirements upon what implementation language may be used for built-in functions other than that if an ECMAScript function is used to implement a built-in then it must be strict-mode ECMAScript function. This requirement exists because strict ECMAScript functions have a number of specific characteristics and a few of them (such an the interpretation of undefined passed the this value) are also requirements for built-ins.
But most of the characteristics of strict-mode ECMAScript functions, such as whether a with
statement may used are irrelevant to built-ins and in particular are meaningless if the built-in's implementation language is not ECMAScript.
If the consensus is that the meaning of strict/non-strict still needs further clarification then I suggest following my suggestion from https://github.com/tc39/ecma262/issues/875#issuecomment-292639687 :
If the concern is that it isn't obvious that the strict/non-strict distinction is only applicable to ECMAScript functions then to remediate that I suggest replacing in the spec. all occurrences of "strict function" with "strict ECMAScript function" and "non-strict function" with "non-strict ECMAScript function". It's wordier but more explicit.
@allenwb:
I still object to #875 (comment)
That's your own comment (the same one you quote from later), so I'm doubtful that it's the one you object to.
@jmdyck corrected, now reverences https://github.com/tc39/ecma262/issues/875#issuecomment-292660502
I don't understand what you're objecting to or proposing. Is it just a renaming? Why use the confusing term "non-strict ECMAScript function" instead of "sloppy ECMAScript function"? Only an ECMAScript function can be sloppy, so non-sloppy would unambiguously include both "strict ECMAScript function" and "builtin function".
Alternatively, if we just include builtin functions in the "strict" category, then we have
Since the distinction I usually need is between sloppy and non-sloppy, by including builtins in the strict category, we could indeed use "strict function" vs "non-strict function" to label the same difference. But we need to do this clearly and immediately, because today "non-strict function" would seem to include builtin functions, which is a fatal mistake.
See https://github.com/Jack-Works/proposal-strict-built-in-functions Attn @Jack-Works
@erights I have two objections.
The ECMAScript specifications uses various categorization to help in specifying the semantics of the language. But value judgements are irrelevant to those semantics. In addition, the categorization strict ECMAScript function/non-strict ECMAScript function is more precise than the categorization strict ECMAScript function/sloppy ECMAScript function. It seems clear that the first categorization covers all ECMAScript functions while the second categorization leaves open the possibility that there may be ECMAScript functions that are neither strict or sloppy.
From its inception, "strict mode" has been about the interpretation of the source code of ECMAScript functions and scripts. Different subsets of the possible grammar productions and semantics rules are applied to the processing of ECMAScript code depending upon whether that code is "strict" or "non-strict". Annex C enumerates (but it isn't clear whether it has been kept update to date) these rules and it is easy to see that they are meaningful for ECMAScript functions but few, if any, could be applicable to functions that are not implemented using ECMAScript.
Turing the question around, what would be the list of requirements that a "strict" non-ECMAScript functions needs to meet? This list will undoubtably be different from Annex C. If that is the case what is the value in applying the term "strict" to both? Is there a need for a term that refers to the intersection of those two lists?
I agree that there have been a few cases that came later where we were sloppy and applied a more expansive (and unspecified) meaning to "strict". @Jack-Works' proposal addresses one of these situations:
If an implementation extends any function object with an own property named "caller" the value of that property, as observed using [[Get]] or [[GetOwnProperty]], must not be a strict function object. If it is an accessor property, the function that is the value of the property's [[Get]] attribute must never return a strict function when called.
He proposes changing the definition of "strict function" so that the phrase "must not be a strict function" can be read as meaning "must not be a strict ECMAScript function or a built-in function".
My suggestion is to leave the definition of "strict function" alone and simply substitute the phrasing I used in the preceding paragraph to explain its meaning. Similar phrasing could be using an any similar occurrences, if there are any.
Finally, it is apparent that some readers have missed the intention that "strict function"/"non-strict function" always is in reference to an ECMAScript function. To remediate this, in https://github.com/tc39/ecma262/issues/875#issuecomment-292639687 I suggest systematically replacing all occurrences of those phrases with "strict ECMAScript function" and "non-strict ECMAScript function".
Follow-up to https://github.com/tc39/ecma262/issues/875#issuecomment-570678363
I forgot to include that it isn't clear that either the @Jack-Works change to Forbidden Extensions or my alternative is web compatible as they both expand the specified set of functions that must censor what they return from their caller
method, if they have one.
It is web compat. Old browsers generally already censor this.
"sloppy" implies a value judgement that is not appropriate or necessary to include in an international standard.
Fine. Then choose a term other than "sloppy" or "non-X" for any X. It is the "non-X" phrasing than makes it impossible to speak clearly.
@erights I'm perfectly happy for you to speak the term "sloppy" as long as the listener understands that it means the same things as "non-strict". I just don't think that term belongs in the specification (which generally isn't recited).
The other issue is that with phrases like "a foo bar" and "a non-foo bar" it is clear that the set of bars is fully covered. Such coverage is not at all obvious with "a foo bar" and "a baz bar".
The other issue is that with phrases like "a foo bar" and "a non-foo bar" it is clear that the set of bars is fully covered. Such coverage is not at all obvious with "a foo bar" and "a baz bar".
This makes no sense to me when we need to speak about three categories.
Come up with a normative term other than "sloppy" or "non-strict". Otherwise, I suggest we proceed with "sloppy". A "non-X" for a label in a three way taxonomy is unacceptable.
This makes no sense to me when we need to speak about three categories.
But with regard to "strict mode" we are not talking about three categories. As I said:
From its inception, "strict mode" has been about the interpretation of the source code of ECMAScript functions and scripts.
From that perspective, "strict" defines two categories that covers the set of all ECMAScript functions. What you seem to be trying to do is to repurpose (or reinterpret) the "strict" category to define a subset of the set of all functions (probably more precisely the set of call callable objects). That destroys the simple utility of "strict" as a binary categorization of ECMAScript functions.
To further quote myself:
what would be the list of requirements that a "strict" non-ECMAScript functions needs to meet?
and what name would you give to that subset of the callables? It presumably is a superset of the category "strict ECMAScript functions as ECMAScript function is a subset of all callables.
At https://github.com/tc39/ecma262/issues/867#issuecomment-292358747 I wrote:
Precisely speaking, there are three kinds of functions: strict, sloppy, and built-in. I know we are trying to avoid the term "sloppy" in spec language, and I do not argue for it. I agree it sounds too judgemental and informal. But "non-strict" is too misleading because built-in functions are "not strict" but not "non-strict". This is too confusing.