TRWTF is the entire JS ecosystem



  • @Zerosquare said in When the reviewer doesn't understand my Javascript it's his fault:

    A textbook case of Javascript Syndrome: the patient think (s)he's more clever than everyone else, while (s)he's in fact creating substandard equivalents of existing stuff (at best) or straight antipatterns (at worst).

    (yeah, yeah, I know you can find people like this for any language. But the JS community seems to encourage this behaviour.)

    @Gribnit said in When the reviewer doesn't understand my Javascript it's his fault:

    @Zerosquare said in When the reviewer doesn't understand my Javascript it's his fault:

    the JS community seems to encourage this behaviour.

    Arguably:trollface: the JS community is based on this behavior, starting from the language itself.

    23d6513b-3c4a-409b-bb11-4d98874de60f-image.png

    JS is actually a unique and fun language to play with, just like Python and Ruby. I played with those languages a lot, does C# and Java in my day job, and occasionally touches Haskell for the type-level drugs. However often what is not mentioned is that the average language proficiency in JS ecosystem is so abysmal and outrageous that even JS memes of all things are consistently of the lowest quality among all programming language memes. I guess it's because people don't want to admit that they don't actually know shit about JS, or modern programming languages in general.

    Let's give out some examples about JS, along with the things I learnt about JS itself after playing with it for a long time:

    Oh, let me give a warning first: this is a long post.

    Prototype, or how to do OO in JS the right way

    Let's look at Ruby. Ruby has instance methods and singleton methods (which are defined on a singleton class, an anonymous class that is defined for one and only one particular instance). Class methods are just singleton methods on the class itself. This allows you to simultaneously have all instances share a method, but also replace the same method in some of the instances, which the old class-based OOP language (read: Java and C#) lacks.

    JS is a prototype-based language, which means while OO in JS is just as same as class-based OO, it's done differently. The so-called "constructors" in JS is no different from any other functions, and they can have any properties attached to them, which automatically becomes "class properties/methods". Then there are prototype methods, which is the same as instance methods, but defined on the constructor's .prototype object; and finally, there are instance methods that are defined for one particular instance, just like Ruby's singleton methods:

    // constructor method
    console.log(Object.toString()); // "function Object() { [native code] }"
    
    // prototype method
    var obj = {truth: 'FileNotFound'}; // obj is an instance of Object
    console.log(obj.toString()); // "[object Object]"
    // this is because obj.toString === Object.prototype.toString,
    // which return, roughly speaking, `[Object ${obj[Symbol.toStringTag]}]`
    
    // instance method
    var obj = {truth: 'FileNotFound', toString: function() {return JSON.stringify(this);}}
    console.log(obj.toString()); // '{"truth":"FileNotFound"}'
    

    The order of precedence for the lookup is: instance > prototype > parent's prototype > ...

    Inheritance is done by setting up the prototype chain:

    function Animal(name) {this.name = name;}
    Animal.prototype = {
      greet() {return `${this.name} is an animal.`;},
      growl() {return `${this.name}: Grrrr!`;},
    }
    
    function Cat(name) {Animal.call(this, name);}
    Cat.prototype = Object.assign(
      Object.create(Animal.prototype), // this inherits all the prototype methods from Animal
      {
        greet() {return `${this.name} is a cat.`;},
        meow() {return `${this.name}: Meow!`;},
        catGrowl() {return super.growl.call(this) + " *Cat Noises*";},
      }
    );
    

    The ES6 class syntax is just sugar for doing the same thing, but finally looks like can be grasped by the cough Java monkeys.

    Now about polymorphism, we've already done the overriding:

    var animal = new Animal('A'), cat = new Cat('C');
    
    // overriding
    console.log(animal.greet()); // "A is an animal."
    console.log(cat.greet()); // "C is a cat."
    

    We can even override just one specific instance:

    var myCat = new Cat('FileNotFound');
    Object.assign(myCat, {
      __proto__: Cat.prototype, // this makes super === Cat.prototype in this object literal
      greet() {return super.greet.call(this) + " TRWTF is PHP.";}
      // Or super.__proto__.greet.call(this) if you want Animal.prototype.greet.call(this)
    });
    
    console.log(myCat.greet()); // "FileNotFound is a cat. TRWTF is PHP."
    

    You can do method hiding too, but not in the usual Java/C# up/down-casting way, as it's even better: you get to choose which method you're using on the instance! In fact, you can even make up one on the fly and it'll work just as fine:

    console.log(myCat.greet()); // "FileNotFound is a cat. TRWTF is PHP."
    console.log(Cat.prototype.greet.call(myCat)); // "FileNotFound is a cat."
    console.log(Animal.prototype.greet.call(myCat)); // "FileNotFound is an animal."
    
    console.log(function() {
      return `${this.name} is a mole.`;
    }.call(myCat)); // "FileNotFound is a mole."
    
    // Function.prototype.bind is also helpful if you want to lock the context, e.g Object.is.bind(null, -0)
    

    Hence JS actually achieves the ultimate form of OOP paradigm: an actual OO system that completely detaches state and behaviour, and is also fully flexible and configurable. (Not to mention JS does FP very well too. It's multi-paradigm.)

    In Ruby you can (sort of) do the same:

    class A
      def initialize
        @id = 'A'
      end
    end
    class B
      def initialize
        @id = 'B'
      end
    end
    
    def wTF(suff) "#{@id}.#{suff}" end
    
    p A.new.instance_exec {method(:wTF).call 'WTF'} # "A.WTF"
    p B.new.instance_exec {method(:wTF).call 'ABC'} # "B.ABC"
    
    # to add an existing method to a instance you have to either wrap it yourself in the singleton class,
    # or put the method into a module and then do obj.extend(Module)
    

    And Python too, which turns out to be a bit easier than Ruby:

    class A:
        def __init__(self): self.id = 'A'
    class B:
        def __init__(self): self.id = 'B'
    
    def wTF(self, suff): return f'{self.id}.{suff}'
    
    print(wTF.__get__(A())('WTF')) # "A.WTF"
    print(wTF.__get__(B())('ABC')) # "B.ABC"
    
    # to make it an actual "method" of the instance, dump the method to the instance's dict
    # after binding it to that instance. It's roughly what Python's class syntax sugar does anyway
    a = A()
    a.__dict__['wTF'] = wTF.__get__(a)
    print(a.wTF('WTF')) # "A.WTF"
    

    But, no, you're not gonna convince enterprise programmers and software engineers that anything that does not look like Java (classical OO) will work, especially since this language is called JavaScript, and since they're too virgin to configure things in code at runtime (just like Ruby rewriting classes), while they're okay to configure configuration XML files at runtime. :doing_it_wrong:

    Why is this important? In any not brain dead OO language (e.g Kotlin) this is not much of a problem, but in C# and Java there's a huge issue fundamental to themselves: the minimal unit in Java and C# is interface/class, and hence to define a simple function you have to make a class to contain it, to make a method configurable you have to add another layer of abstraction that provides the method as a service for your wrapper method to call it (using private field to emulate flexible method), and to make different such instances you have to add another layer of interface/abstract class to summarize them. We all know what that looks like. It's taught everywhere, for decades.

    The result is that solving problems in C# and Java is often not about "taking the shortest path", but "making more layers of abstractions to smooth out the language restriction". If you look at most "design patterns" perpetuated in software engineering courses, they are all "workarounds that are essentially in Java because of how criminally rigid it is". (Protip: GoF is also widely criticized for being a book about C++ workarounds more than actual "design pattern" books.) This includes factory, builder, service, repository, visitor, observer, strategy... After touching and trying many languages I like languages like JS much more than others because I can focus on taking the shortest path when solving problems instead, with none of these redirection nonsense.

    (Of course, this would also mean you can't restrict your fellow :wtf: monkeys enough to write qualitatively minimally conformant code, but it's not like a restrictive language like Java has stopped them from doing so, right? :trollface: )

    Fortunately, the Ruby folks know that Ruby is not Java, and you need to do things the Ruby way. In Ruby, it's a common wisdom that polymorphism is done by aliasing the method and then define a new method with the original name. JS? People are crappy for the most part, and still keeps talking shit (maybe it's exactly because they don't know they're crap). So much that never add prototype methods to built-in objects is withheld as a very vocal "best practice". Typical JS opinions are like this:

    • JS has this feature
    • But some donkeys have abused it and made unmaintainable (subjectively speaking) code!
    • Therefore we should discourage everyone from using this feature!

    The irony here is that JS, for what it's worth, copiestakes new features from other languages more often than anything since ES6; while the ecosystem, is full of dummies who are more ignorant about other languages than any other ecosystem. In fact their opinion don't even hold inside the ecosystem, since the likes of JQuery and modernizr rely on adding prototype methods, which means their opinion is clearly not followed by the biggest libraries.

    Duck-typing, or how to handle JS objects the right way

    Quick quiz: What is considered an array in JS?

    Objects that come from Array.from? Wrong.
    Objects that come from [] syntax? Wrong.
    Array as a type? Wrong. (There are no types further than objects in JS anyway)
    Anything that Array.isArray returns true for? Nope, still wrong.

    In JS, everything is either one of the primitive data types or objects, and things are evaluated at runtime; if you write a.then(b), as long as a is declared and can be propertied (aka it's not something like null), has a then which is callable, and b has been declared, this statement will run.

    What this means is that as long as your object quacks like an array, it effectively is an array. An object quacks like an array if it has a length property that is an positive integer of [0, 2**32), and the respective prototype methods (which, as we established above, is separate from the object itself, so strictly speaking this isn't even needed). This makes for very interesting usages of the language:

    1. The simplest array-like object is {length: 0}. In fact new Array(n) basically returns an Array instance with nothing but length: n and the prototype methods set.
    2. What Array.from does is just converting quack-like-an-arrays to Array arrays.
    3. Array.isArray is merely obj instanceof Array that also checks for all Array objects in all globals.
    4. Array holes makes perfect sense, because arrays are just objects, and objects can have arbitrary properties. Meanwhile, type arrays can't have holes because they're actually backed by binary data buffers, which also makes perfect sense.
    5. You can directly apply most array prototypes to strings and other objects. Examples include: Array.prototype.slice.call(arguments) to get argument Array, Array.prototype.concat.apply([], arrayOfArrays) to flatten array by one layer, Array.prototype.filter.call('thedailywtf', e => e === 't').length to count occurrences of characters instead of the ugly 'thedailywtf'.split('t').length - 1 suggested by the typical StackOverflow JS "coder"s.
    6. You can chain anything with Promises as long as the thing has a callable then property, also called "thenable". No need for transient interfaces at all!

    (To the pedantic: Array is actually an exotic object, and some operations in JS uses abstract operations to create arrays so you can't override them with any amount of JS code. However usually it doesn't matter, and it can be emulated with Proxys or very closely in pre-ES6 with tons of Object.defineProperty.)

    In fact, JQuery has been doing duck-typing all the time: JQuery objects are just objects with a heavily dosed prototype that quacks like an ever-extending chimera. When you add stuff to $.fn, you're adding functionality to the duck as $.fn === $.prototype === $(whatever).__proto__. I've never seen this actually explained by anybody in the JS ecosystem. The people there only know to treat JQuery like a magic wand, and just wave it randomly when they need to use it. Like monkeys fiddling with sticks.

    Automatic Semicolon Insertion (ASI), why is this still controversial in 2k19?

    ASI is a language feature that has well-defined behaviour, and it's not even hard.

    Instead, your typical JS coder loves to shoot themselves in the foot by not reading what the code's grammar is at the spot as they stop writing semicolons, and then yell at others to tell them stop omitting semicolons because "it might introduce bugs in your code". They never mention what causes "bugs in your code", just that "there will be nasty bugs!!!!!11!!1" which is "very bad", and so you should "stay safe" and avoid The Bad (TM). The FUD is super strong.

    WAT do you mean it's an overused, completely exaggerated meme?

    2cc3ddd9-61ba-4cdd-809d-95dfe56de877-image.png

    People love to compare JS to PHP and say "JS has implicit type conversion, hence it's as bad as PHP!" despite that they barely know anything about JS in depth.

    Said people are also idiots who can't distinguish between Java and C# and lots of other things:

    • JS's implicit type conversion is well-defined according to ECMAScript standards. There are some quirks, yes, and PHP has much more due to backwards compatibility and a worse initial design. But so does other languages: Did you know that true.ToString() in C# returns "True"? And you really can't be bothered to RTFM? Oh wait, they indeed can't. It's why JSPerf is so popular. (See next point for JSPerf.)
    • Have you heard of === in PHP? Yes, PHP has it too! You know, the real, actual, scientific equality operator that tests for identity! These idiots not only are oblivious of said operator, but are also oblivious of its function or semantic meaning, results in them asking idiotic questions like "why is === faster than ==", in both JS and PHP. There are really no reasons to use == except when you're being lazy (which then you deserve being punished for mistakes introduced this way) or when you're code-golfing (which, again, is your fault if you broke your code this way).
    • Who the hell still references that WAT talk unironically? It's a parody that exaggerates these "quirks" for comedic value. Only actual idiots would ignore everything else about Ruby in the talk, then repost the same JS snippet (like {} + []) everywhere to mock JS even when said cases can be reasoned reasonably easily. /r/ProgrammerHumor is full of them.

    Oh, and did I mention Ruby? In Ruby, String's [] is overloaded with indexing, slicing and sub-string matching:

    s = '1357924680'
    p s[2] # "5"
    p s['2'] # "2"
    p s[(1..5)] # "35792"
    p s[1,5] # "35792"
    p s[7.2] # "6"
    p s[/7.2/] "792"
    p s[/7(.)2/, 1] "9"
    

    Similarly, JQuery does overloading too, and similarly, nobody bothers to mention the good JS things like this. See the pattern?

    JSPerf, the epitome of nobody knows what they're doing

    What's the popular method of resolving language-lawyer inquiries in C++ ecosystem? Refer to the C++ language draft.
    What's the popular method of resolving language-lawyer inquiries in JS ecosystem? JSPerf!

    Because most JS users are incompetent monkeys who do not have the capability to read the language specs/docs, reason about language behaviour or determine code quality, you need to feed them with simple results that is also not "just do this" to withhold the illusion of "making my own judgement" for them. JSPerf produces nice numbers and graphs for them to nibble on, not unlike what the management guys would love to gobble up. The response of "how to do X in JS" is usually:

    1. People piling in to provide 100 ways of doing the thing because it's JS (which is a good thing, but that's due to JS itself, and not the users)
    2. People are too crappy to have any ideas which one is cleaner (because they're not Python programmers), how applicable/correct each one is and which one is less of a :wtf: in general
    3. Instead they'll put every snippet in JSPerf with a broken/poorly set up test code that does a completely unrealistic tests, like empty loop, and announce that "results are in!"
    4. But hey, results are out, 🍌s are dispensed, the monkeys nibble on the bananas and go home happily thinking they learned something mind-blowing today

    Oh, and did I mention most JSPerf tests are broken and poorly set up? Because it's worth mentioning again. Bad benchmarks are worse than no benchmarks. You should take JSPerf tests with a grain of salt in general. Even if the benchmark's not broken, usually they're measuring completely idiotic and irrelevant thing anyway; and lots of these "absolute truths!!!11!" are from 10 years ago where JS engines are basically Ruby before YARV, largely unoptimized and hardly representative of engine performance nowadays, which involves very, very heavy JITing.

    Some big examples of idiotic JSPerf tests include:

    It's idiotic in the sense of every schizophrenic crank/noob programmer around: thinking that compiler should be smart enough to optimize their code like reading their minds, while also believing that micro-optimizing every tiniest thing should make the code even faster because compiler should not be smart enough to outsmart their attempts to outsmart the compiler! It makes one wonder whether they're coding in JS or in C, where micro-optimization is directly visible for the most part. Well, I guess their syntax are kind of similar (JS == C?), so... 🚎

    (But hey, at least JS doesn't emit IL bytecodes, hence completely disallows any monkey's attempt to try to outsmart the JIT process since you cannot observe what's being done down below. This is a very chad thing, compared to JITs like JVM: we all know how desperate some people go just to optimize the hell out of JVM's JIT process. Also it allows for some very crazy things.)

    And, in the end, even if Ruby is much slower than JS, the Rubyists are better than the JS monkeys because they actually document their benchmark findings. JS monkeys never document their benchmarks (they instead ask benchmark questions on StackOverflow), and JSPerf is a shitty site with very bad content discovery. You can ensure everyone to repeat the same mistakes if you never aggregate any of the collective knowledge around!

    p.s Official ECMAScript specs is completely free. You should take a read at it whenever necessary.

    But I don't want to learn async!

    JS is fundamentally async, period. This is one of the biggest difference between JS and other languages. We've also since evolved from callback hell (pre-ES6) to Promises (ES6) and then async/await(ES8), which all aims to make writing async code easier. In Node event streams are also used very frequently.

    It doesn't stop people from wanting to make async code synchronized, or wanting to write sleep that is not busy. One example is with them adding async: false in their ajax calls because they never learnt how to write async code properly. They also never knew about the event loop either apparently, as anything async will not run until the next tick, which is almost always after the current block of code has finished execution. And async code/stream error handling? Lots of people never does them or does them right (they think try/catch will handle everything), which causes Node to crash without any stack traces whenever their crappy app has rejections and errors from a Promise/event stream.

    And if you think JS tutorials are already bad, JS async tutorials are even worse! I've almost never seen actually good explanations of how to do these properly in JS. Meanwhile, if you're in C# (which has the same async/await syntax that JS presumably takes from), you sort of learn how to write async code very quickly because the resources for learning how to do it is much better IMO.

    JS on StackOverflow, more like RepWhoreOverflow

    JS on StackOverflow is one of the most massive sources of rep whores. Enough said.

    Not convinced? Just look at this:
    Can (a== 1 && a ==2 && a==3) ever evaluate to true?

    An actually useful answer would be listing all 3 typical ways of doing so (valueOf, Proxy and Unicode variable names). Instead everyone is just posting the same, easy way (valueOf) as their answers.
    (There were even more of them back when the question became popular but the mods have purged lots of them. I've also seen at least 5 people decided that it'd be something they'd plagiarize directly to make their own coding puzzles in competitive programming sites. There people are so original.)
    The other deeds these rep whores have done include:

    • Posting snippets of other languages showing the same idea. WTF? This is a JS question! One answerer even sayd There are enough good JS answers already. I just thought it would be interesting to show how it can be done in other languages, and possibly give JS developers some ideas. I for once thought I was browsing Reddit and not SO.
    • Posting more questions asking the same thing in *other languages. WTF? You can't figure out your language's features to see if something's possible, and has to open a question to farm more rep?
    • Making yet another analogy of one of the popular beginner JS topics, like closures and async code. Because apparently "monad tutorials" are not rep whore enough, and people actually think analogies === helpful explanations?

    (At least there's an actually interesting answer, based on race conditions in SharedArrayBuffers.)

    The typical comments on StackOverflow JS questions/answers are just about as idiotic. It really shows the average quality of the monkeys are the JS ecosystem. Oh, also did I mention that lots of the most voted JS questions are about how to do simple things in the language, and they're also often locked for some reasons, unlike similar questions in other languages? My first guess is the same rep whore monkeys keep adding in useless noise to these questions, which leads to the mods being fed up and just lock the entire question instead.

    npm, the snowflake repository

    Have you heard of the left-pad incident?
    Or the flatmap-stream incident?
    Or the monstrosity known as node_modules folder because every snippet deserves to be a module, and everyone is too lazy to write the snippet themselves and uses yet another such module to their projects?

    npm ecosystem is a massive conglomerate of snowflakes that seems to lack the basic common senses: they don't take any responsibilities, their security and management is the definition of chaos (pretty much the opposite of Nuget), any major incident requires the official npm team to get it resolved, and whenever disaster happens, they blame the innocent users instead for "not doing everything to ensure they're not fucked by npm's disasters". Wow, thank you for telling us you're the most untrustworthy repository in the entire solar system! It's a pity that there are no alternatives, or I'd have migrated on the spot!

    Hmm, not unlike the JS rep whores on StackOverflow. Maybe cancer is infectious after all...

    Why does Codecademy even exist?

    Enough said. They're powered by venture capital, relies on heavily deceptive, manipulative and sugar-coated marketing practices, to create the entitlement that "everyone can learn how to code easily" in order to net wishful and unsuspecting users. Their courses and tutorials are useless and underwhelming, that doesn't really teach you anything beyond "learn Java in X minutes" level. They also created lots of crappy "JS front-end programmers". They've really contributed a lot into making the JS ecosystem the global WTF as it is right now.


    To end the WTF in some good news, there are still good JS resources: MDN, and https://javascript.info, but unfortunately the latter is originally in Russian, and is quite oudated in the english translation. Reading them is more helpful than the nest of chaos and random noise for learning JS.

    (Yes, I know PHP resources are even worse. But usually you don't have to touch PHP compared to JS that is everywhere, unless you're working with Wordpress for some reasons, which is a WTF of its own. :trollface:)


  • Discourse touched me in a no-no place

    @_P_ said in TRWTF is the entire JS ecosystem:

    JS is actually a unique and fun language to play with, just like Python and Ruby.

    FWIW, my experience with Python and Ruby is that they're good at getting you started on a project quickly, but become rather more horrible once you get into maintaining some code for the long term, as that's when you end up paying for whatever non-portable hackery you've ended up using (and which isn't immediately obviously a problem due to the flexibility of the languages). I suspect that JS is the same, but I've not delved in deep enough to say for sure; my exposure has just been hacking together stuff to deploy as part of a website or SPA.


  • BINNED

    Well, I, uh… mostly read it. You haven't left much room to say anything extra, really.



  • @_P_ I hate prototyping so much. I know classes are just sugar, but here's the thing: I spent a lot of time playing with prototypes, and I still prefer ES6 classes. It's just less notation to do the same thing without having to instantiate something now rather than when it makes sense to do so.


  • BINNED

    Actually, I think I can distil a key point here:

    However bad JavaScript might be, a large amount of its (more vocal) developers are responsible for most of the problems.


  • Banned

    @_P_ said in TRWTF is the entire JS ecosystem:

    Let's look at Ruby.



  • @Shoreline said in TRWTF is the entire JS ecosystem:

    @_P_ I hate prototyping so much. I know classes are just sugar, but here's the thing: I spent a lot of time playing with prototypes, and I still prefer ES6 classes. It's just less notation to do the same thing without having to instantiate something now rather than when it makes sense to do so.

    Yes, hence I didn't say the class syntax is bad. In fact as sugar they're definitely convenient and useful.

    The fact that they reinforce the idea that JS is doing OO just like Java is more of a problem of the majority of the users that they really don't know how to use JS like JS. Remember those "Java turned to Python" professors who write getter/setter to every class in Python? Yeah, it's like them.

    If you're using JS like JS and Ruby like Ruby (with its versatile class-rewriting and metaprogramming features), you're good to go. Otherwise it's always gonna be a bunch of :wtf:s, which, unfortunately, is what's happening around the ecosystem for the most part.



  • @dkf said in TRWTF is the entire JS ecosystem:

    @_P_ said in TRWTF is the entire JS ecosystem:

    JS is actually a unique and fun language to play with, just like Python and Ruby.

    FWIW, my experience with Python and Ruby is that they're good at getting you started on a project quickly, but become rather more horrible once you get into maintaining some code for the long term, as that's when you end up paying for whatever non-portable hackery you've ended up using (and which isn't immediately obviously a problem due to the flexibility of the languages). I suspect that JS is the same, but I've not delved in deep enough to say for sure; my exposure has just been hacking together stuff to deploy as part of a website or SPA.

    Node is pretty portable and is one of the most multi-platform runtime ever nowadays. See electron/nw.js? They can even run on Switch.

    As with most things, hackery is unavoidable. However I find C#/Java requiring much more hackery than usual, in the form of needless abstraction as workarounds to the fact that I can't just mock an object directly as is. Writing a small web app in modern C# stack (ASP.NET MVC + OWIN + Entity Framework) is easy, but once you want to unit-test it, suddenly everything breaks down and you're spending all the time abstracting your architecture for no reasons just so you can actually run the site without hosting it instead. It's baffling.


  • Banned

    @_P_ said in TRWTF is the entire JS ecosystem:

    Hence JS actually achieves the ultimate form of OOP paradigm: an actual OO system that completely detaches state and behaviour

    Which is funny because the main design goal, the defining characteristic, the raison d'être of OOP is to entangle data with behavior and treat it as atomic unit.



  • @_P_ said in TRWTF is the entire JS ecosystem:

    As with most things, hackery is unavoidable. However I find C#/Java requiring much more hackery than usual, in the form of needless abstraction as workarounds to the fact that I can't just mock an object directly as is. Writing a small web app in modern C# stack (ASP.NET MVC + OWIN + Entity Framework) is easy, but once you want to unit-test it, suddenly everything breaks down and you're spending all the time abstracting your architecture for no reasons just so you can actually run the site without hosting it instead. It's baffling.

    You probably do not mean it, but his bit of text reads to me like "I really hate designing stuff. Churning out code without any though to structure is what I want to do. Languages that wont let me do that is bad!"


  • ♿ (Parody)

    @_P_ said in TRWTF is the entire JS ecosystem:

    Automatic Semicolon Insertion (ASI), why is this still controversial in 2k19?

    ASI is a language feature that has well-defined behaviour, and it's not even hard.
    Instead, your typical JS coder loves to shoot themselves in the foot by not reading what the code's grammar is at the spot as they stop writing semicolons, and then yell at others to tell them stop omitting semicolons because "it might introduce bugs in your code". They never mention what causes "bugs in your code", just that "there will be nasty bugs!!!!!11!!1" which is "very bad", and so you should "stay safe" and avoid The Bad (TM). The FUD is super strong.

    You made some good points. And you also talked about ASI. The problem here is that sometimes you forget. And then something weird happens. And then it takes you forever to notice that weird thing is because a semi-colon is missing somewhere. Now, if it's your habit to always put them in then it should be easier to spot, because it will look funny to your brain.

    It's all well and good to talk shit about how you know the formal spec and that sort of bullshit but that can fuck right off. You don't keep the entire spec in your head when you're looking for a bug. You don't always even have a clue what you're looking for. You like to be the nerd who knows the spec inside and out? Great. The rest of us have goddamned work to do.

    This is no better than making meaningless variable or function names that you have to memorize without any clue as to what they're for. Sure, the spec and the language handle it fine but the people don't.



  • @Carnage said in TRWTF is the entire JS ecosystem:

    @_P_ said in TRWTF is the entire JS ecosystem:

    As with most things, hackery is unavoidable. However I find C#/Java requiring much more hackery than usual, in the form of needless abstraction as workarounds to the fact that I can't just mock an object directly as is. Writing a small web app in modern C# stack (ASP.NET MVC + OWIN + Entity Framework) is easy, but once you want to unit-test it, suddenly everything breaks down and you're spending all the time abstracting your architecture for no reasons just so you can actually run the site without hosting it instead. It's baffling.

    You probably do not mean it, but this bit of text reads to me like "I really hate designing stuff. Churning out code without any thougth to structure is what I want to do. Languages that wont let me do that is bad!"

    A few things:

    1. I'm writing tests for an application because I want a more stable product, not because I want to write tests. Automated tests is a secondary objective there (the app is not that big so manual tests are very feasible), so it should leave as tiny of a footprint in the codebase as possible. However my current impression is that a typical C#/Java codebase has to change (read: add layers of abstraction) a lot just to accommodate for unit/functional testing, when everything is working properly and codebase is simple. It's more of an anti-pattern more than a pattern IMO.

    2. I'm more of a person that only refactor things and abstract things if something's starting to get out of hand. I know software engineers have the tendency to overly worry about extending things (not unlike computer scientist overly worrying about performance and optimization), but aiming for an overly engineered architecture for the task at hand just to ensure "the design must be right the first time around" is akin to the waterfall model, which kinda doesn't work, and, in addition, violates the "make the code maintainable" principle. If the code is maintainable, the design should be robust and you can refactor it in a reasonable amount of time; an architecture with the sweet spot of minimally required abstraction is also easiest to maintain.

    3. Are you sure C#/Java doesn't allow you to churn out code without any thought to structure? If that's true the amount of article in TDWTF would be reduced by like 90%. :trollface: Not to mention that you can design badly, and it happens often, and a bad design is arguably worse than no design because changing the architecture requires you to pull out the usable blocks first, which is an extra step with a cost proportional to how deep your current design is.


  • 🚽 Regular

    @boomzilla said in TRWTF is the entire JS ecosystem:

    The problem here is that sometimes you forget.

    My goto example of this is when I was bit by something like:

        var sql = 'UPDATE ATable' +
            'SET Field1 = ' + _escapeSQL(field1) + ',' +
            'SET Field2 = ' + _escapeSQL(field2) + ',' +
    +       'SET Field3 = ' + _escapeSQL(field3)   // I did not forget to delete the comma!
            'WHERE ID = ' + _escapeSQL(id);
    
        _executeUpdate_HopeYouHaveAWHEREClauseInYourStatement(sql);
    


  • @boomzilla I think you're assuming a bit too much. For the record, I do add semicolons in my JS code out of habit.

    The point is (if you have opened that link that talks about ASI in detail), ASI is well-defined so it's not some arcane magic, and you do get bitten if you omit them in a few specific cases, but you need to be aware of the rule before you can say adding semicolons to the code is meaningful; otherwise it's just a pointless ritual. You can add all the semicolons and still write

    return 
      { success: false,
        reason: 'FileNotFound' };
    

    and then wonder why the semicolon did not save you.


  • ♿ (Parody)

    @_P_ yes. That's just another ASI :wtf: of its own.



  • @boomzilla What do you want it to do then? Read your mind and choose the one interpretation you wanted based on big data, neural network and deep learning?

    My point is that

    @boomzilla said in TRWTF is the entire JS ecosystem:

    Now, if it's your habit to always put them in then it should be easier to spot, because it will look funny to your brain.

    is completely false, because unless you actually know how ASI works, you wouldn't even know what to look for. And the example I gave (taken from that article) is exactly that: the semicolon is added but it's not helping. You don't teach newbies "hard rules" without explaining why; that'd be the exact what we hate the JS ecosystem for.


  • ♿ (Parody)

    @_P_ said in TRWTF is the entire JS ecosystem:

    What do you want it to do then?

    I want nuke ASI from orbit, like any sensible person.

    My point is that

    @boomzilla said in TRWTF is the entire JS ecosystem:

    Now, if it's your habit to always put them in then it should be easier to spot, because it will look funny to your brain.

    is completely false, because unless you actually know how ASI works, you wouldn't even know what to look for. And the example I gave (taken from that article) is exactly that. You don't teach newbies "hard rules" without explaining why; that'd be the exact what we hate the JS ecosystem for.

    If you think that point contradicts my point then you're missing it.



  • @boomzilla said in TRWTF is the entire JS ecosystem:

    I want nuke ASI from orbit, like any sensible person.

    I can agree to that.

    @boomzilla said in TRWTF is the entire JS ecosystem:

    If you think that point contradicts my point then you're missing it.

    I also know it's not gonna happen, because it belongs to the box named "backwards compatibility", where things such as typeof null === 'object' sits in.

    So if you know for certain it'll never be changed, what do you do? You put cones and warnings around it so others do not step into the pothole to a cruel fate. You don't say "don't ever walk on the road because you might step into a pothole".


  • ♿ (Parody)

    @_P_ said in TRWTF is the entire JS ecosystem:

    So if you know for certain it'll never be changed, what do you do? You put cones and warnings around it so others do not step into the pothole to a cruel fate. You don't say "don't ever walk on the road because you might step into a pothole".

    In my mind that's what I'm doing. "Put semicolons in" is like "look both ways before you step off the curb."



  • @boomzilla said in TRWTF is the entire JS ecosystem:

    "Put semicolons in" is like "look both ways before you step off the curb."

    This analogy would be true if we all know what is coming: we all know that if you step off the curb without looking, you might get hit by a car, which results in injury. Telling people to put semicolons in blindly is like saying, "if you step the curb without looking, you might get hurt". Okay, but why? You didn't explain this part. Is it because you'll get tripped by the height difference of the curb? Or is it an alien will come out and abduct you? For one thing some people will actually believe the latter, and since this is not your typical C/C++ undefined behaviour, aliens can't exist.


  • Banned

    @_P_ the best part is that putting semicolons DOESN'T HELP ANYTHING. The implicit semicolons are still there.


  • ♿ (Parody)

    @_P_ said in TRWTF is the entire JS ecosystem:

    @boomzilla said in TRWTF is the entire JS ecosystem:

    "Put semicolons in" is like "look both ways before you step off the curb."

    This analogy would be true if we all know what is coming: we all know that if you step off the curb without looking, you might get hit by a car, which results in injury. Telling people to put semicolons in blindly is like saying, "if you step the curb without looking, you might get hurt". Okay, but why? You didn't explain this part. Is it because you'll get tripped by the height difference of the curb? Or is it an alien will come out and abduct you? For one thing some people will actually believe the latter, and since this is not your typical C/C++ undefined behaviour, aliens can't exist.

    :wtf: are you talking about? "Telling people to put semicolons in blindly is like saying..."

    Also, correct, I didn't explain everything in my post. I'm assuming a bit of knowledge in this thread, but of course didn't fully protect myself from pendantic dickweedism.



  • @boomzilla You don't tell people to "put in semicolons blindly to avoid ASI pitfalls" does not mean everyone else don't do it either. And in the wild the people who does this to newbies are immense. (I speak from my own experience.)



  • I don't understand the aversion to semicolons. Were those people VB developers in a past life or something?


  • ♿ (Parody)

    @Zenith I've always suspected it came from the nature of the way js was being used back then. In particular, putting a function call in an html tag. onclick="doTheNeedful()"



  • @Gąska said in TRWTF is the entire JS ecosystem:

    @_P_ the best part is that putting semicolons DOESN'T HELP ANYTHING. The implicit semicolons are still there.

    Putting semicolons in helps in some situations. There are two ways to get fucked over by ASI:

    1. ASI inserts a semicolon you didn't want, e.g. the implicit semicolon after the return keyword here:

      return 
        { success: false,
          reason: 'FileNotFound' };
      
    2. ASI doesn't insert a semicolon where you intuitively expected it to, e.g. (from the blog post):

      a = b + c
      (d + e).print()
      

      gets interpreted as

      a = b + c(d+e).print();
      

    @boomzilla is saying that sprinkling semicolons into your code everywhere that you correctly can protects you from the second kind of error. This is true. You and @_P_ are saying that this isn't sufficient to protect you from needing to understand ASI, because you can still get fucked by the first kind of error. This is also true. These observations don't actually contradict each other.


  • Considered Harmful

    @_P_ said in TRWTF is the entire JS ecosystem:

    JQuery objects are just objects with a heavily dosed prototype that quacks like an ever-extending chimera.

    I am a large fan of your writing style.


  • Considered Harmful

    I have three principal problems with this rant.

    1. "Why does it fuck up!" "RTFM".
      JS doesn't suck just because you can do really strange things with it. You can do really strange things in a lot of languages, Gradle being a good example. JS's suckage is a function of how easy it is to do, in operations that you think should make sense not because they exist in other languages but because they are simply logical. For example, semicolon insertion fucks up very often when you rely on it; a great example is the return @boomzilla mentioned. The complaint is not that it has it; the complaint is that its implementation is garbage. See Kotlin for an example of how to correctly do it. Same goes for ===. Why is the obvious equality operator the operator you almost never actually want? A much better design would be == for basic equality and =? for type converting equality.
    2. "dynamic or gtfo"
      You haven't actually illustrated how great prototyping is. To me you have simply described why I continue to rejoice the existence of wasm. You can do a great number of things that are wildly strange but work beautifully. You can also do a great number of things that are wildly strange and have subtle bugs in them. The key difference between non wildly strange things and wildly strange things is that when there's a subtle bug in the wildly strange thing it's very very difficult to figure out where in the hell it is. C++ for example allows you to do all manner of silliness in seemingly innocuous lines; copy constructors, regular constructors, operator overloading, and so forth. Whereas in Rust every single line is completely unambiguous despite borrowing many of the same features like operator overloading. That's how to design a language well. In C++ a = b could invoke absolutely anything and I would have no way of knowing, and then bugs creep up and I discover 'hey there's a copy constructor doing something bizarre, this whole time I thought it was just doing a bitwise copy'. You make the analogue of how you can also fuck up your Java code horribly, but it's not about what you're capable of doing but what you're capable of hiding.
    3. 'how have you not learned anything'
      You say that it's the morons who add async: false because they didn't know how to write async code properly. But most people just want to develop what they've been developing. Yes I'm sure everything will be better if you just learn how to use these five different systems that have been released a year ago but that doesn't make them less of a pain in the ass. As you tell it, learning to write async code properly was hell before ES6. Great, so people developing code before ES6 got a free pass. Except a ton of people are still developing before ES6 because that's how the software industry works, and this magical async/await system you're saying to RTFM on was only just released a year and a half ago. Adoption takes time. The only difference between JS and other languages in this regard is that your target platform, compiler, and stdlib is 'latest Chrome'. And this is also why things like async: false are so subtly evil: in Rust 'breaking change' is just a phrase because you've already laid down what compiler version you're using and your libraries have already been compiled, but in JS you only ever execute on latest so stuff that you didn't have to worry about suddenly requiring you to worry about it makes it one hell of a pain to maintain. 'Java developer' on a résumé means you've used it for long enough that you know how to use the battle-tested libraries and can adapt to new ones with ease; to hear you tell it, 'JavaScript developer' means that you know the features they've added in the last three months and can write code that won't break because of them.

  • Banned

    @pie_flavor said in TRWTF is the entire JS ecosystem:

    See Kotlin for an example of how to correctly do it.

    A quick google suggests otherwise:

    The rule is: Don't worry about this and don't use semicolons at all

    I know it might be just noobs posing as experts since it's SO, but equally likely is that the actual rules are so complicated that you absolutely have to not worry about it, or you'll go insane. Like the whole canBuildFrom business in Scala.



  • @_P_ said in TRWTF is the entire JS ecosystem:

    Prototype, or how to do OO in JS the right way
    [...]
    We can even override just one specific instance.

    Who want's a lot of Ducks where you (as the programmer) aren't sure how and why some specific Ducks quack different then the others? Specially if they quack in different datatypes.


  • Considered Harmful

    @Gąska I don't understand what you're saying. I'm saying that JS's semicolon inference works very badly and is not something you can use to forget about semicolons entirely, and Kotlin's is.


  • Banned

    @pie_flavor sooner or later, you'll encounter a case when Kotlin inserts a semicolon when you don't want it to. And the error message won't be a simple "hey, the compiler put a semicolon there, and that broke your otherwise fine code". It will be something much more cryptic, like "I couldn't find the right implementation of ++ to use for your list here", or some other red herring. And then you'll wonder WTF is going on. And then you'll fiddle a bit with your code, and find out that you cannot break list1 ++ list2 into two lines of code such that ++ ends up at the beginning of line, because Scala sees a complete expression and puts a semicolon there, and suddenly ++ becomes unary. Even though you've done it earlier many times all over the code and it was always fine. Then, one of two things can happen:

    1. You look up the rules. They are simple enough to wrap your head around them with ease. You learned something about your language and are ready to write good, clean code and you never get taken by surprise again.
    2. You try too look up the rules. You either find out that "you shouldn't worry about it, just remember these few special cases", or find an extremely complicated ruleset that you can't make sense of. Either way, you end up with not knowing what is and isn't allowed in your language, and you make up some cargo cult rules like "Thou Shalt Never Put Binary Operator At The Beginning Of Line". You know these rules are wrong, but you stick to them because it's the best you have. You hope that your cargo cult's commandments are accurate enough, and try to live on, always being wary that there's an important part of language that you don't fully understand and that can bite you in the ass at any moment.

    Whoever says that you can completely forget about some of your language's syntax rules, is lying.


  • BINNED

    I'm on par with the people you complain about, since I have zero real experience with JS (save for maybe a small userscript or one liner) so take what I say with a grain of salt, but I did know most of the things you said from just what I picked up randomly.

    @_P_ said in TRWTF is the entire JS ecosystem:

    Have you heard of === in PHP? Yes, PHP has it too! You know, the real, actual, scientific equality operator that tests for identity! These idiots not only are oblivious of said operator, but are also oblivious of its function or semantic meaning, results in them asking idiotic questions like "why is === faster than ==", in both JS and PHP. There are really no reasons to use == except when you're being lazy (which then you deserve being punished for mistakes introduced this way) or when you're code-golfing (which, again, is your fault if you broke your code this way).

    I feel this is in direct contradiction with your previous paragraph about duck typing. Arguably, == is just the duck typed version of ===, and you said duck typing is awesome.

    Dynamic typing has its advantages and disadvantages. Personally, I use Python to hack together quick proof of concepts because it's fast and simple to do, but I wouldn't want to do a large project in it. Once that stage is reached, I prefer the compile time guarantees static typing gives me over things breaking at runtime.
    You mention unit tests, and it seems they are indeed easier to write with dynamic typing. But then I wonder how many unit tests are written just to make up for the lack of compile time checks.

    Also, I can't see the advantage of overriding just one instance's method. Effectively, this just seems to be an instance of an ad-hoc class. Unless you're going to generate an unbounded number of different methods dynamically (eval?), you'll have a limited number of those ad-hoc definitions in your code and could have just made a normal class for them.


  • BINNED

    @pie_flavor said in TRWTF is the entire JS ecosystem:

    C++ for example allows you to do all manner of silliness in seemingly innocuous lines; copy constructors, regular constructors, operator overloading, and so forth. Whereas in Rust every single line is completely unambiguous despite borrowing many of the same features like operator overloading. That's how to design a language well. In C++ a = b could invoke absolutely anything and I would have no way of knowing, and then bugs creep up and I discover 'hey there's a copy constructor doing something bizarre, this whole time I thought it was just doing a bitwise copy'. You make the analogue of how you can also fuck up your Java code horribly, but it's not about what you're capable of doing but what you're capable of hiding.

    I've seen that argument before, and I don't think it makes sense.
    Either you have operator overloading or you don't. If the operator can be overloaded, you can overload it with something that semantically makes sense or with something stupid. If you do the latter, you've fucked up.
    But the same happens without operator overloading. In Java you can't overload == but you can provide an implementation of equals or hashCode that does something stupid. Operators are just fancy function names. If you write a matrix class in Java you can't overload operator + (only String can do that, apparently) and instead will do the ugly prefix variant of defining a function add. And of course that function could in theory do something stupid, just as an overloaded operator could.
    In C++ you're not hiding anything, either. a + b calls operator +. If you're surprised by what it does, you'd be surprised by the analogous add method too.
    There's many valid complaints about C++. I don't think this is one of them.

    could invoke absolutely anything and I would have no way of knowing

    Of course you have, just look up the class definition or read the docs.

    How does Rust allow operator overloading but prevent the overloaded operator from being counter-intuitive?


  • ♿ (Parody)

    @topspin said in TRWTF is the entire JS ecosystem:

    There's many valid complaints about C++. I don't think this is one of them.

    The "best" operator overload I've seen seems to be ++ and its potential effect in loops.

    Next someone will say that C++54 has fixed that or whatever but out here in the real world people are still using g++ 4.4.7.



  • @boomzilla said in TRWTF is the entire JS ecosystem:

    still using g++ 4.4.7.

    :eek:


  • BINNED

    @boomzilla said in TRWTF is the entire JS ecosystem:

    @topspin said in TRWTF is the entire JS ecosystem:

    There's many valid complaints about C++. I don't think this is one of them.

    The "best" operator overload I've seen seems to be ++ and its potential effect in loops.

    Next someone will say that C++54 has fixed that or whatever but out here in the real world people are still using g++ 4.4.7.

    I assume that's scare quotes around "best", but I'm not sure what you mean.
    ++it on an iterator is more or less analogous to it.next() (it only advances but doesn't dereference, I'm not sure if there's an actual analogue), with the advantage of working the same way for an iterator and a raw pointer. It's not surprising, what else would incrementing the iterator do?

    And sorry about gcc 4.4.7, at least gcc 4.8 on my RedHat v.ancient does C++11.


  • ♿ (Parody)

    @topspin said in TRWTF is the entire JS ecosystem:

    I assume that's scare quotes around "best", but I'm not sure what you mean.

    Yes, best as in, the biggest potential problem, which means it's bad. I dunno...people have talked about foo++ potentially being really expensive. Not sure if it was in loops or just in general or what.


  • BINNED

    @boomzilla said in TRWTF is the entire JS ecosystem:

    @topspin said in TRWTF is the entire JS ecosystem:

    I assume that's scare quotes around "best", but I'm not sure what you mean.

    Yes, best as in, the biggest potential problem, which means it's bad. I dunno...people have talked about foo++ potentially being really expensive. Not sure if it was in loops or just in general or what.

    Oh, I got what you mean now.
    foo++ will have to create a copy of the original before advancing, as that's what it evaluates to, so ++foo is potentially cheaper. It's easy to avoid, but I don't think it's anywhere as close of a problem as it's made to be. And modern compilers are really good at optimizing inlined code.


  • 🚽 Regular

    @Cabbage said in TRWTF is the entire JS ecosystem:

    1. ASI doesn't insert a semicolon where you intuitively expected it to, e.g. (from the blog post):

      a = b + c
      (d + e).print()
      

      gets interpreted as

      a = b + c(d+e).print();
      

    I would totally have fallen for this.



  • @_P_ said in TRWTF is the entire JS ecosystem:

    I'm writing tests for an application because I want a more stable product, not because I want to write tests. Automated tests is a secondary objective there (the app is not that big so manual tests are very feasible), so it should leave as tiny of a footprint in the codebase as possible. However my current impression is that a typical C#/Java codebase has to change (read: add layers of abstraction) a lot just to accommodate for unit/functional testing, when everything is working properly and codebase is simple. It's more of an anti-pattern more than a pattern IMO.

    I'm happy to tell you that no, you do not have to add layers of abstraction to at least Java to do unit tests. It is good if you're doing CDI, preferably through constructor parameters. But that is just plain good design.
    I do know that a lot of Java is being subjected to layers upon layers of unnecessary shit, but there is no need of it.

    @_P_ said in TRWTF is the entire JS ecosystem:

    I'm more of a person that only refactor things and abstract things if something's starting to get out of hand. I know software engineers have the tendency to overly worry about extending things (not unlike computer scientist overly worrying about performance and optimization), but aiming for an overly engineered architecture for the task at hand just to ensure "the design must be right the first time around" is akin to the waterfall model, which kinda doesn't work, and, in addition, violates the "make the code maintainable" principle. If the code is maintainable, the design should be robust and you can refactor it in a reasonable amount of time; an architecture with the sweet spot of minimally required abstraction is also easiest to maintain.

    The golden rule is KISS. Everywhere, all the time.
    And don't design for possible futures, design for whats known now. Overengineering is always bad, I agree wholly. Every software in use for long enough will eventually grow outside of it's original design so badly that it is no longer fit for purpose, that is when you redesign from the ground up for whatever it's gonna be done in. I've been spending the better part of this past decade replacing ancient relics that have grown into unwieldy amorphous blobs. This time tends to come sooner if there is too much "intelligent" and "smart" design in my experience. So, I think I agree with you completely here. :D

    @_P_ said in TRWTF is the entire JS ecosystem:

    Are you sure C#/Java doesn't allow you to churn out code without any thought to structure? If that's true the amount of article in TDWTF would be reduced by like 90%. Not to mention that you can design badly, and it happens often, and a bad design is arguably worse than no design because changing the architecture requires you to pull out the usable blocks first, which is an extra step with a cost proportional to how deep your current design is.

    Oh gods no. Hachiman knows it's perfectly possible to write undesigned shitpiles in Java, just as in every language ever. The culture around the language is one of designing stuff though. Often even too much. I've even fairly recently shared some exquisitely horrible java code as proof of no design (or even basic skill or knowledge in general) being necessary.

    I have not written a line of C# in a very long time so I won't say anything about that language... And then it was a horribly, ugly hack just for the hell of writing a horrible, ugly hack and still passing the challenge requirements.


  • Banned

    @topspin said in TRWTF is the entire JS ecosystem:

    How does Rust allow operator overloading but prevent the overloaded operator from being counter-intuitive?

    Gentleman's agreement, basically. Though it does have separate traits for PartialEq ("I just want ==, don't expect anything more") and Eq ("the true equivalence relation, that's symmetric, reflexive and transitive, and you can rely on it to always work, really, I promise, scout's honor"), and counterpart PartialOrd and Ord traits for </<=/>/>=.

    But the most important difference that makes Rust's equality so much better than in PHP, JavaScript, Java, C# and other languages is that no object has equality comparison by default. You don't have to wonder whether the library author has remembered about proper overloads for equals() and hash() and whatnot, because if they didn't, it's simply not there and you cannot use it.

    There's an interesting gotcha: because of NaN, primitive float types implement PartialEq but not Eq. This means you can't (easily) have a map container keyed by a float.


  • Banned

    @boomzilla said in TRWTF is the entire JS ecosystem:

    @topspin said in TRWTF is the entire JS ecosystem:

    There's many valid complaints about C++. I don't think this is one of them.

    The "best" operator overload I've seen seems to be ++ and its potential effect in loops.

    I see your ++ and raise you &&, which you can overload just fine, but then your ifs lose the short-circuit property.


  • Banned

    @boomzilla said in TRWTF is the entire JS ecosystem:

    I dunno...people have talked about foo++ potentially being really expensive.

    You have to remember those were C++ people talking. When they said "really expensive", what they meant is "eight bytes get copied over".



  • @Gąska Don't forget operator,. You also lose the sequencing properties with that one.


  • Considered Harmful

    @Gąska It could be a lot more, if the type is a wrapper and ++ is overloaded to produce a new immutable instance each time.



  • @Gąska said in TRWTF is the entire JS ecosystem:

    When they said "really expensive", what they meant is "eight bytes get copied over".

    That's why you build for the x32 ABI. 🚎

    Filed under: Or you do pointer compression, JVM style


  • Considered Harmful

    @topspin said in TRWTF is the entire JS ecosystem:

    How does Rust allow operator overloading but prevent the overloaded operator from being counter-intuitive?

    Because overloading is a misnomer. If I see a + b for types A and B, that always means A implements std::ops::Add<B> and it's calling Add's add function. Numbers are no exception; they implement the trait too. The same goes for other operators which in some languages exist by default - there simply is no default in Rust. For example, == is not usable on any type that does not implement PartialEq. So when you see ==, it always refers to a trait function. Compare to C++ where you can override what the fucking comma means.


  • Considered Harmful

    @topspin said in TRWTF is the entire JS ecosystem:

    And of course that function could in theory do something stupid, just as an overloaded operator could.

    My point is that if you do something stupid in an add() method, it is plainly obvious that you are calling an add() method. Like I said: it's about what you can hide. C++ is a language where what looks like ordinary variable assignment or field lookup can actually be a function call.


  • Discourse touched me in a no-no place

    I think this thread’s title is wrong.

    It should be “TRWTF is JS”.

    I’m convinced that satan created JS while on a kilo of crack, a kilo of meth, and a metric shit ton of heroin laced with fentonyl, used motor oil, and ether.