Hacker News new | past | comments | ask | show | jobs | submit login
SmooshGate (2021) (chrome.com)
120 points by triyambakam on Oct 10, 2022 | hide | past | favorite | 90 comments



I was a huge MooTools fan back in the day. I literally have a t-shirt in my closet[1] and an inordinate amount of MooTools left on my personal site. Even so, I think trying not to break it is beyond silly.

It made the decision to extend prototypes. In hindsight, a huge mistake. At the time, almost nothing in JavaScript had changed in over a decade, it seemed safe, an unmoving target.

Douglas Crockford really doesn't get enough credit for the work he did getting ECMAScript into a living standard again. How soon people forget, but in the mid-aughts any mention of JavaScript was followed by a scoff.

Anyway, JavaScript shouldn't be trying specifically not to break MooTools. MooTools was trying to fix JavaScript.

[1]: https://twitter.com/donatj/status/1468728094588506115


> It made the decision to extend prototypes. In hindsight, a huge mistake.

I think it was a mistake at the time, but I still believe prototypal inheritance is pretty great idea. And JS desperately needs standard library, which IMO should extend built-in prototypes, so the language would be more coherent. ES1995 [0] was a funny take on this direction, but people (mainly non-JS people) would like to seriously use it. Go figure.

[0]: https://github.com/mlajtos/es1995


> here’s the kicker — if you overwrite a non-enumerable property, e.g. Array.prototype.sort = whatever, it remains non-enumerable.

One thing I never understood about this problem: Why not change the behavior so that overriding non-enumerable properties makes them enumerable? That seems to be the behavior that library developers (e.g. MooTools) were already expecting anyway.


My guess is that they don't do that because that would change behavior for developers that are intentionally overriding existing methods-- like one might do if monkey-patching a method to work around a bug, or polyfill newer functionality, or add instrumentation.

Basically, anything they could do here is a behavior change for someone. So, if they insist on not breaking things for anyone, the only option they have available (short of moving towards Windows-style app-specific compatibility workarounds) is to not change anything here, and just use a different name for the new method.


Doesn’t that break things for the MooTools equivalent(s) that called the method `flat`?


Yes. At a certain point you stop searching and move forward. Which is what many other comments are asking for without realizing the scope of what would break at the give-up point alternatives they prefer.


That's exactly what I would like to know -- what are the trade-offs involved in going with my preferred solution of changing modified non-enumerable properties to be enumerable? Every possible solution to the problem could create breakage somewhere, so what is the breakage that would be created with this solution and why is it less favourable than the solution they ended up with?


MooTools is simply setting a value to a property that did not exist before the assignment. It isn't using Object.defineProperty() to create the property. You cannot call Object.defineProperty() twice for the same property (it throws an error).

If assigning a value to a property that was previously defined as non-enumerable were to make it enumerable, then the very act of defining a property would have no value, except in the case where you are making a read-only property (ie using the "writable: false" option for Object.defineProperty).


You can specify the value as part of the options to defineProperty, and also it is legal to call defineProperty twice on the same property but with a different value.


I get the whole “don’t break the web” thing, but surely it still has to come down to how significant the websites are that you’re breaking or how ludicrous the reason for the breakage is, right? Like surely I can’t prevent any new array methods from ever existing by making a website with a list of known array prototype properties and throwing an error if any new ones show up, right? I’d like to hear more details about how these decisions are actually made.


> surely it still has to come down to how significant the websites are that you’re breaking

As determined by whom, with what criteria and what methodology?

> or how ludicrous the reason for the breakage is

This behavior in MooTools (and Prototype.js and probably others) of monkey-patching built-ins was widely considered ludicrous at the same time as they were widely used across huge chunks of the web.

A more recent example: I consider real world use of alert to be ludicrous for nearly every usage I can imagine, and I hate when I interact with its usage even for benign things, but when Google tried to remove it from Chrome I objected along with a lot of others who have no personal love for alert itself. I opposed its removal because alert has certain guarantees, and removing it would break an untold number of sites in totally unpredictable ways. There are a bunch of “why don’t you just…?”-type suggestions in other comments, but the fact is you can’t “just” substitute anything for alert without recreating all the things people hate about it.

> I’d like to hear more details about how these decisions are actually made.

They discuss some of that in the article, but if you want more detail there’s a ton of public record in the various TC39 repos on GitHub[1], including repos detailing their process as well as per-proposal repos demonstrating application of their process. If you’re particularly interested, you’re in for a lot of good reading.

1: https://github.com/tc39


At the end of the day, it comes down to whether browser vendors are willing to ship the feature even though it breaks said websites, and they do have visitor data to back those decisions. If the rule was "never break any website ever", you'd be able to block proposals you don't personally like by crafting a website that "gets broken" by that proposal.

At least in the array grouping proposal, they did evaluate amount and popularity of possibly breaking sites, before eventually renaming the method from .groupBy to .group

https://github.com/tc39/proposal-array-grouping/issues/37


> I get the whole “don’t break the web” thing

I wish Chrome devs did. They have been actively breaking the Web on multiple occasions. Just try to launch some unmaintained HTML5 game from a few years ago and watch it trip over a non-working audio context. They reverted their window.alert change after deploying it only because the resulting breakage was too big to ignore. "Don't break the Web" is a myth, it's actually "don't break the Web so much that the user will notice enough things stopping to work after browser update to blame it on the browser".


Frankly, I think the web should have stopped breaking itself years ago. The widespread adoption of JavaScript is a mistake fuelled by the trainwreck that we call modern app distribution. If the App Store/Play Store hadn't succeeded, there might still be a distinction between Apps and Websites.


Fascinating perspective. Can you elaborate?

In particular, given that Javascript predates App Stores by many years (I would hazard an unresearched guess at over a decade), and that Javascript serves myriad purposes in websites that have nothing to do with apps, this assertion requires extraordinary justification.


> Like surely I can’t prevent any new array methods from ever existing by making a website with a list of known array prototype properties and throwing an error if any new ones show up, right?

No, and that’s not what’s happening here. MooTools was very popular and is still used on many websites.

They are adding ‘flat’ even though in some obscure corner of the internet that’s going to break something.


Adding methods to primitive prototypes should probably have always been considered risky.


Hindsight is 2020. There were no major changes to the language between 1997 and 2009. As a developer at the time, JavaScript seemed locked in stone.


+1 for remembering the CamelCase of the proper name of this garbage language we all write in now ;)


Also, is this fixable downstream? I imagine they could have kept a kind of "mixin prototype" object sitting around, and they could enumerate the properties of that object instead of Array, and in doing so attach their custom properties to Array as well as Elements and whatever else.

It seems less flaky anyway, compared to relying on this subtle enumerability property.


They did fix it downstream. I remember maintaining a JS tool many years ago that was being embedded on client's websites, and before we added a bunch of hacks to make it not break with bad Mootools versions we did manage to convince some non-zero number of clients to fix their sites by updating it.


In fairness, one of the nicest things about early JS was the flexibility it offered. It was never meant to be a language for building large libraries and huge applications. Coming from strongly typed languages it was sort of liberating, at a certain point. Now... well, arguably it's okay that it's so loose because it's allowed things like TypeScript to spring up, but you can still just override Array if you feel like it. (Until one day you can't, hah).


They could of course fix it downstream any number of ways, many more straightforward than adding a layer of indirection to keep monkey patching the built-ins. But that wouldn’t fix sites still running the older code.


For context, it's worth pointing out the PR and some of the actual reactions:

https://github.com/tc39/proposal-flatMap/pull/56

https://twitter.com/bterlson/status/971210573818904576

https://twitter.com/BenLesh/status/971462667322839040

https://twitter.com/andrestaltz/status/971500672620351494

It's probably not worth engaging in these threads, since everyone now knows it was a joke, but Twitter doesn't put old things into read-only model unfortunately.


That broken version was 8 years old at the time of the bug? Screw that. I’d you’re running an 8 year old unmaintained script you have different issues.


Yeah, the issue of everything working perfectly exactly as it was 8 years ago. Such a bothersome issue. (/s)


This is a really great summary with a lot of amusing little details. A couple comments:

1. It sounds like there was confusion for a period of time because the developer made a joke. I think there really should be a specification for how to annotate humorous comments made on the web.

2. I loved the section spelling out the principle of "don't break the web." This is important, and as we get more and more legacy web the more valuable this principle becomes. That said, I wonder if a day is coming where the browser is disrupted because browser devs are moving too slowly on account of this.

Please note: #1 is a joke


i ThInK tHeRe ReAlLy ShOuLd Be A sPeCiFiCaTiOn FoR hOw To AnNoTaTe HuMoRoUs CoMmEnTs MaDe On ThE wEb.

The specification exists, it's just not enforced. If Google and Meta aren't going to step up, I think we should prosecute non-compliance with the full weight of the legal system. This is an existential threat to our society.


That's really less of a humor tag and more of a condescending sarcasm tag though. I don't see it used as a joke so much as to do an imitation of someone else speaking, repeating something they said (or might allegedly say) in such a way as to make it appear stupid.


HANDSHAKE FAILED: Missing token validating receipt of humor. Acceptable responses are: ["haha", "lol", "lmao", "lulz"]

User "aerovistae" has been flagged for non-compliance.


usER "AEROvistAE" hAs beEN fLagGEd fOR non-coMpliaNCE.


["I'm a Teapot"]


People use it all the time to mock themselves and signal their humor intent.


peOPle usE it ALl thE timE tO MoCK tHEMSELvES And SignaL tHeIr hUMoR InTeNT.


I HaD A gooD cHucKle, gAvE YOu aN UpvOTE, AnD WiSHEd I’d dEMoNSTRAtEd THE poiNt IN THe FIRSt PLaCE.


Hand me a pitchfork I'm ready to do my part


(Alt: spongebob.gif has entered the room)


> I think there really should be a specification for how to annotate humorous comments made on the web.

(I know you're joking but...)

Humor relies fundamentally on shared context, and the Internet destroys that shared context.

https://en.wikipedia.org/wiki/Context_collapse

I guess the problem is when an in-joke is unexpectedly leaked to an out-group.


Meh, so many things have broken on the web over the years, the "Don't break the web" is kind of bs AFAICT.

I've had to re-do so many things that were working when I shipped them but stopped because Chrome or Firefox or Safari changed something and broke it.

Heck, you can find probably 100s of examples of pages that no longer work because browsers changed things right here

https://experiments.withgoogle.com/collection/chrome

At the same time, the reason Safari doesn't report MacOS 11 is because too many sites had poorly written detectors that threw exceptions if they didn't see Mac OS 10_???? in the UA string. Here's the userAgent on Safari

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15

Even though I'm on MacOS 12.6 on an M1 MacBookPro.

So there's at least one more example of "don't break the web'


You're right in that it's pretty unevenly enforced, but I don't want to penalize the times it is enforced even though it would be convenient.


Yup, and it's the exact same reason that "Mozilla/5.0" and "KHTML, like Gecko" are both still in that user agent string.


#2 isn’t a going concern, if anything people now complain that it moves too quickly. IMO that’s a silly complaint but a steady stream of years-long processes being completed is always gonna upset someone.


> I think there really should be a specification for how to annotate humorous comments made on the web.

Scott Fahlman is way ahead of you - in 1982 he proposed [1] an annotation for "attempted humor" - colon-hyphen-right bracket

[1] https://en.wikipedia.org/w/index.php?title=Emoticon&oldid=11...


Delaying the punchline until after 2. made your joke much funnier. When we write the spec for joke syntax we'll have to include this sort of... what is it, lazy-evaluation?


You joke, but it is sorely needed, because people simply don’t understand sarcasm very well on the web these days. Personally I think it should be considered a sort of disability, and having these kind of annotations should be a requirement if a website wants to be ADA compliant.

In addition, having non-joke annotations helps people identify when a person is being dead serious. Even here on hackernews, Poe’s Law reigns supreme as people struggle to differentiate parody from genuine opinions.


> Please note: #1 is a joke

Semantic web with an ontologically complete markup is not a joke and don’t confuse “Web 3.0” with “Web3”

https://en.wikipedia.org/wiki/Semantic_Web


I'm kinda just reiterating what other people have said here, but I don't really get the "don't break the web" thing.

Apparently it was just fine to break the web when it meant shutting off Flash and breaking millions of existing games and movies - but a few old sites that could trivially be wrapped that use Mootools are somehow good enough to change "flatten" to "flat"?


Flash was never a web standard, there weren't enough independent implementations, it was proprietary only, and it had mountains of security issues. I agree with trying to not break the web, but the death of Flash on the web was great, and the only tragedy is that there's still not a great, reasonable FOSS solution for running arbitrary swf files offline.


I’m not sure I understand your logic. MooTools isn’t a web standard either. How is breaking all the websites relying on flash acceptable while breaking all the websites relying on MooTools not?


It was built on web standards.


I'll add to that that the breaking of stuff when people finally abandonned flash is exactly the sort of thing we want to avoid!


I hear you and I am nostalgic for old flash content, but replacing a method name that hasn’t shipped in a production build is an easier thing to do than maintaining an interactive multimedia plugin that was never designed to be a web standard.


Wow, what a shitty language.

Lets code dynamically change things that other code depends on. Including behavior in built-in object prototypes.

Has weird properties like "enumerable" on members of those prototypes, so that changing a property doesn't do the same thing as adding one... but the API for both is the same.

It's like the language is built to cause breaking changes. "Don't break the Web" indeed.

The root cause here is writing millions of lines of code in something that was originally just supposed to validate forms.


> Lets code dynamically change things that other code depends on. Including behavior in built-in object prototypes.

Not exactly uncommon for languages that feature reflection.

Heck the win32 api allows you to hook and intercept function calls. So do plenty of other native C and C++ APIs.

It is a powerful feature that allows for a lot of functionality, including extending out libraries and fixing bugs in SDKs that you'd otherwise have to wait an entire release cycle for, or that may never get fixed. (And release cycles used to be years long!)


The internet is a series of bad decisions its too late to undo.


Also, undoing those decisions would likely just be replacing them with new and different bad decisions.


I for one am quite ready to replace the bad decision of Javascript with the differently-bad decision of WASM. I would cherish never having to touch Javascript Object oddities again.

Can we have WASI DOM access etc soon please?


Probably true of most large codebases.


How is that any different than any language introducing a new keyword that existing code previously used as variable names? Normally this wouldn't break anything since the developer has to opt in to update the compiler/runtime. The problem is the runtime (browser) autoupdates and the developer has no way to opt out of their code running on the new runtime.


API changes are way more common than adding keywords. That’s one difference.


Doesn't matter which is more common. All actively developed languages eventually get new keywords and breaking changes. However, most of them will not interfere with existing code running under previously defined behaviors.

Even node 10 applications that use MooTools (i.e. JavaScript executing in a different runtime) will continue to work just fine if `flatten` is added as proposed in node 11+. The developers will eventually need to patch it but it's not like this bug where one day users autoupdate their browser and half the websites they visit are broken.


Can we please do “stricter mode” for some of this? “strict mode” was a great hack, and we are long overdue for fixing stuff

My white whale: make “let” mean what “const” means, and “var” mean what “let” currently means. But there are definitely better things to get done

I’m for keeping things working generally of course. People being against “don’t break the web” is a bit odd to me. But we are long overdue for versioning so we can actually fix stuff, especially given how much modern code goes through transpilers and the like


> But we are long overdue for versioning

The trend seemed to be in the opposite direction. In the early days, you could use the language attribute of the script tag to specify a version, e.g. language="JavaScript1.2". But that failed to become a standard.

HTML used to be versioned by the DOCTYPE, but that fell out of favor with HTML5.


Apparently it was fine to rename "flatten" to "flat," because that's what they did, but it wasn't okay to rename "flatten" to "smoosh." What's the difference?


Probably that flatten has a near-universal meaning across many programming languages, and flat is so close to flatten as to have its meaning be almost implicitly clear, whereas smoosh has absolutely zero precedent and its behavior would be completely uninferrable without looking up documentation.


I don't agree.


Me neither.


I'm staying out of it.


It actually wasn’t fine to rename flatten() to flat() - flat isn’t a verb, flatten() seems natural, and now you have to explain to everyone that yes it’s called flat() because someone on a standards committee really likes unmaintained web sites that probably have expired domains, expired certs, non paid for hosting but might run mootools.


Yah, flat() is a kind of poor name. toFlat() would be better IMO.


If I’m looking for flatten and have autocomplete, I’ll find flat but not smoosh.


Those are words. What is smoosh? Are we children?



I beg your pardon?


It seems like there could be a sort of quirks mode for old JS libraries, in which browsers recognise either key functions or specific hashes and could then apply library-specific mitigations. It wouldn't solve every instance of this problem, but it would solve the mootools-using majority without needing the awkward name change.


Maybe we should just make it common practice to do: Array.prototype.flatten = Array.prototype.flat

Similar to "* { box-sizing: border-box; }" has become standard.

If they can't add an official .flatten for backwards compatibility now, we can assume they never will, right?


Is it possible to poison future web API implementations by making a really popular library that would fall apart if any new Array/Object methods were added, or something like that?


Yes. Some folks who variously:

a) didn't know how to recognize a cheeky straw man proposal

b) didn't know how to take a joke

c) didn't agree with (or understand the importance of) the never-break-the-web imperative that TC39 operates under (turns out this is a lot of people)

tried to do exactly this to "prevent smoosh":

- https://github.com/staltz/prevent-smoosh

- https://twitter.com/andrestaltz/status/971500672620351494

Mostly, though, they just taught TC39 to have less fun and to ignore the "just break the web it's okay!" crowd.

Why TC39 operates under this never-break-the-web imperative: because if they didn't, every proposal they consider might devolve into an unresolvable discussion of "well is THIS thing important enough to break the web over? how much usage would this change break? how valuable do we think this is?". The easiest, and only, way to resolve all possible such discussions is to just not have them.


Seems weird to jump through hoops to keep an outdated JavaScript library with a custom prototype working. When you create custom prototypes this is the risk you take. Name your prototypes accordingly, so they are unlikely to clash anything. As an example mtflatten, or _flatten (like underscore.js and other libraries).


The problem with prototypical inheritance is that people will use it. And now you can’t add anything ever again without this risk.

I absolutely love the ability to monkey patch in upcoming features. But I avoid adding my own array functions. Unfortunate, IMO, because it’s a really neat trick.


If the prototype extensions were scoped to modules, that would be really nice.

```js

// moduleA.js

Object.defineProperty(Array, "flatten", ...)

export Array

// moduleB.js

import { Array } from "moduleA"

console.log([[1],[2]].flatten())

```


You can kind of do that by creating your own subclass, right?


Well, you can subclass it, but you would have to convert regular array to your subtype every type you would want to use some extra property. With proposed way, you can still enjoy the terseness of the language.


(2018)


smoosh is a better name than flat; verbs are better for callables: they do something. Flat is an adjective; seeing Array.prototype.flat I'd assume its a boolean attribute indicating whether the array was "flat"


But the word is spelled "Smush" isn't it? </smirk>


From the article: “As it turns out, “don’t break the Web” is the number one design principle for HTML, CSS, JavaScript…”. So window.alert() is safe for all time? More breathtaking hypocrisy from Google.


I’m in favor of Array.smoosh


Root cause seems to be JavasScript itself. Not only is it possible for any random piece of code to add/replace implementations of bulit-in functions, but it's widely practiced and encouraged somehow.


Dang, this sucks but web standards shouldn't care about the malpractice of a single library which is used by like 0.01% of the web at most.

What's really going on is that the MooTools dev is prob. friends with someone with influence on the committee.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: