-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Need terminology other than "non-strict" for sloppy functions #875
Comments
loose? |
Sloppy seems fine. |
"loose", "legacy", "sloppy" - all have an appropriate judgmental connotation; one echoed by the committee's choice of auto-strict for 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 ***@***.***> 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
<#875 (comment)>, 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 ***@***.***> 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
<#875 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AEDOO5BYwikoh-jfgiyx5gEXJsXHHntjks5rteB7gaJpZM4M2SaI>
.
|
Mark said:
But as Allen explained above, the 'not "non-strict"' part is incorrect per https://tc39.github.io/ecma262/#sec-ecmascript-function-objects:
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. |
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 ***@***.***> 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
<#875 (comment)>, 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 |
+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. |
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.) |
👍 sloppy |
@erights says:
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 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. |
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? |
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!
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: Today
Simple Proposal
Cross-Cutting Proposal
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 |
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 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. |
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 |
Wouldn't borrowing a builtin prototype method and |
@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
And then, without irony, immediately afterwards @allenwb states:
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 |
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 |
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. |
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 #875 (comment) is still a change you'd like to make. If so, would you be able to put together a PR? |
I still object to #875 (comment) 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 If the consensus is that the meaning of strict/non-strict still needs further clarification then I suggest following my suggestion from #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 |
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 |
@erights
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
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:
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 #875 (comment) I suggest systematically replacing all occurrences of those phrases with "strict ECMAScript function" and "non-strict ECMAScript function". |
Follow-up to #875 (comment) 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 |
It is web compat. Old browsers generally already censor this. |
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 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. |
But with regard to "strict mode" we are not talking about three categories. As I said:
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:
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. |
For a non-ECMAScript function, is there anything you can observe that would make it non-strict? If not, what's wrong with saying "everything is strict except sloppy ecmascript functions"? (or "non-strict") |
I'm pretty sure the only visible item in annex C for built-ins would be the |
The If builtin functions expose Thus, the reasoning depends on a further abstract grouping: strict ECMAScript functions and builtin functions follow ocap principles. They have no spooky action-at-a-distance. Sloppy ECMAScript functions behave in spooky ways that threaten security, and so must be quarantined. Hence https://github.com/Jack-Works/proposal-strict-built-in-functions |
Regarding your desire for binary X vs non-X terminology, notice that if we had a simple name for "sloppy", then we wouldn't need a name for "strict". The two remaining categories would be "builtins" and "non-sloppy ECMAScript functions". The term "non-sloppy functions" would, without ambiguity, refer to both of those other categories together. |
As I thought. So, if you say built-ins (including non-ECMAScript built-ins) must be "strict" that means you are really talking about only one out of the seventeen listed requirements of strict-mode functions in Annex C and doing so without explicitly identifying the requirement that concerns you. That requirement is:
It is far from clear what "extend, beyond that defined in this specification, the meanings ... of properties named I think you will be better-off being explicit about what you really meaning rather than depending upon the poorly stated last item in Annex C. For example, building upon your "es legacy function proposal" we might call functions that are restricted in the manner you care about "non-leakable functions" (or perhaps OCAP functions if you prefer). The prose definition of non-leakable function might be: A callable object that does not expose any properties whose access directly or indirectly exposes a non-leakable caller of the the object. Then we could say that built-in functions must be non-leakable functions and that strict ECMAScript function are also non-leakable functions. You might even go as far as saying that all callable objects, with the exception of non-strict ECMAScript functions, must be non-leakable functions. This would cover a concern about the meaning of "built-in function" that I will address in a separate message. |
About built-ins 4.3.9 defines "built-in object" as:
and 4.3.32 says that a "built-in function" is a built-in object that a built-in function. 9.3 further clarifies this as:
Does the set of all functions consist exclusively of built-in functions and ECMAScript functions (and callable Proxy objects)? What about functions that are not specified and supplied by an ECMAScript implementation —for example, C functions invoked via an implementation specific foreign-function interface or an imported module containing functions defined using WASM? It seems to me that these definitions are just not precise or inclusive enough to base any OCAP guarantees upon. |
Ideally, it should not be detectable from outside whether a function is implemented in strict ES, sloppy ES, C++, or TeX. AFAICS, the only occasion where we’ve needed such an externally observable distinction, is for limiting the power of Function#caller and Function#arguments (currently via the “Forbidden extensions” clause), because it wasn’t reasonable to outright disable them for existing code. I think that, if the neutering of those legacy features is made correctly, we won’t ever need to make any further observable distinction, and therefore to give names. (Even, the operation “IsLeakableFunction” used in https://github.com/claudepache/es-legacy-function-reflection is intended to be used only in the scope of that proposal; therefore I’m considering to give it a less generic name, like “IsAllowedTargetForThoseTwoLegacyBlunders”. BTW, the proposal contains a second – unnamed – dichotomy distinct from IsLeakableFunction, namely: whether a function may be returned by .caller.) |
At #867 (comment) 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.
The text was updated successfully, but these errors were encountered: