JavaScript never ceases to disappoint. Although it was launched with great expectations and has found reasonable penetration, both JavaScript authors and their (sometimes unwilling) users find something to dislike about most every deployment. This is most certainly due to either the clash of titans that surrounded its birth or the wallowing of low-lifes that turn everything into spam. This page contains mostly bickering about the extent of this tragedy. A future refactoring will draw some lessons from the experience and maybe even point toward alternate futures. -- WardCunningham -------- ''Counterpart topic to JavaScriptRocks'' ---- JavaScript may suck. Many people do tremendously awful things with it. JavaScript is used in web pages. Usually it sucks there. It is painful to write there, and people do annoying things with it, like popup ads, security breaches, etc. JavaScript is also a system ScriptingLanguage on windows. JavaScript is also embedded into Discreet's Combustion video wonderbox software. JavaScript is used in places that perhaps it was not intended to be used, such as SystemsSoftware. JavaScript has awkward OOP, perhaps a conspiracy to make FunctionalProgramming look good in comparison? * ''Awkward its OOP may be, but instance-based (aka prototype-based) OOP is less awkward than OOP based on static classes, in which EverythingIsa object except for all the things that aren't objects. Now '''that''' is awkward.'' * Let me at least say that JS's OOP syntax is awkward for common/typical coder usage patterns of OOP. Why can't we get syntax like: object foo { // or "class foo" perhaps function method01{...} function method02{...} attrib01 = 7; } * [We can, in CoffeeScript, but why bother? JavaScript's own object syntax is already as capable and more concise, as shown below. -DavidMcLean] var foo = { method01: function() {...}, method02: function() {...}, attrib01: 7 }; * But it's quite different if you use a constructor. * [True, it looks like this.] function Foo() { this.method01 = function() {...}; this.method02 = function() {...}; this.attrib01 = 7; } * [The SelfDotSyndrome is a little more verbose, I suppose. Still, hardly a showstopper, and you can always write a function that returns an object instead of using a constructor if you want the literal syntax. -DavidMcLean] JavaScript uses "type-tags" instead of value-based typing, and has '''too many "special values"''', such as NaN and Null. See ColdFusionLanguageTypeSystem to contrast. I like dynamic languages, but JS used the wrong kind of typing system in my opinion. * ''If you have useful illustrations of Javascript's flaws, or logical arguments to present in favour of alternatives, that would be great. But that you think it "has too many 'special values' [...] in [your] opinion" is like the worst sort of social network commentary: pointless, irritating, a waste of space, and rife with that peculiar selfish arrogance that assumes someone actually cares about your personal opinion. You'd deliver an equally informative edit by telling us you don't like broccoli, or that you prefer blue cars to red ones.'' * The fuller explanation is in the referenced topic, ColdFusionLanguageTypeSystem. The paragraph here was merely an introduction, and thus didn't need to stand entirely on it's own. It's a common and accepted practice such that I don't understand your style gripe and am tempted to use retaliatory insults. I sinned not. * Particularly of interest is the bottom examples at the linked topic where I point out that one cannot know if the eventual "shorter version" of the JS function truly works correctly without extensive testing or knowing the various intricacies of "complex" types. Someone argues that it's because I don't know JS's type system well enough, while I argue I wouldn't ''have to know it'' well if it had a simpler type system to begin with. Tag-free and special-value-free "types" are a LiberatingConstraint. (PowerOfPlainText) Sure, it ramps up complexity elsewhere sometimes (WaterbedTheory), but has a net benefit, in my experience, largely because of it's WYSIWYG nature. * ''I think you're just upset because the individual who responded to you on ColdFusionLanguageTypeSystem was clearly a better programmer than you. Stop blaming your tools for your own inadequacies.'' * I suspect PersonalChoiceElevatedToMoralImperative. Should we all switch to BrainFsck also? Potentially great JobSecurity if you have a knack for it. JS's type system is complexity without a sufficient payoff. If complexity gives us sufficient power and productivity, it justifies itself. Complex types don't. I don't like WriteOnlyLanguage''''''s. GoTo master programmers from the pre-block days used to use a similar-sounding justification: "You block-heads just don't "get" hopping. You are too stupid to program. Blocks are for babies." * ''I'm not promoting Javascript at all. I don't care. I simply think you're just upset because the individual who responded to you on ColdFusionLanguageTypeSystem was clearly a better programmer than you. Stop blaming your tools for your own inadequacies.'' * People who think they can read minds are usually idiots. Extra idiocy points when they read wrong. Yes, they ARE better at JavaScript than me. I will admit it and I'm not ashamed to admit it. But, that's not point. The point is '''unnecessary complexity'''. If additional complexity gives us something wonderful in return, then it's worth it. If it mostly just makes more headaches and '''arcane trivia''' to learn, it's not. The industry wants a practical level of language simplicity; for we may be using several languages in our work world and have to switch among them without requiring a photographic memory of silly rules. ThreeValuedLogic is usually more difficult to grok than 2-valued logic (classic Boolean logic), and 4-valued logic is likewise more difficult than ThreeValuedLogic. With NaN's etc., we are ramping up combo complexity in which comprehending the interaction of all these special types and special values is nearly impossible except for a handful of experts. The rest of us have to use trial-and-error, especially since the documentation for such tags and special value interaction usually sucks. Thus, if we toss (detectable[1]) tags and toss special values like NaN, there are fewer rules to master, and typing is more WYSIWYG. -t {''Please explain what value based typing is, and why tagging down a type is not basing something on a value. All type systems determine something from a value at some point, as the value has to be of some type. Is the goal of value based typing to reparse the value each time, instead of storing the type information in some structure or tag for future use? What do you gain from this?''} I believe most of these are answered in ColdFusionLanguageTypeSystem. ''Unless you've actually personally read the cold fusion source code yourself, I'm afraid you haven't a clue what you're on about. Without deep knowledge of cold fusion compiler/interpreter internals, you don't know what they use to store type information at different points in time while parsing/interpreting/compiling. Whether or not a compiler/interpreter stores type information in structs, records, databases, tags (whatever the hell they are), shouldn't even be of concern to the typical person. That's a fucking implementation detail - I've never ONCE concerned myself with whether a language uses tags or not - in fact I'm not even sure if TAG has any meaning whatsoever. If a compiler uses a C struct to store some type information while parsing/compiling, do you consider this struct a tag? Please describe what a tag is, what value based is.. using more formal precise language.'' ''Since most languages are implemented in C, I'd bet you good money that some sort of C struct is used at some point to store information about types. Is this C struct the tag you are speaking of? I don't even know what a tag is. If it's just one of these illusions you have going on in your head, or an abstract concept, I'm afraid there is no way of confirming which languages use tags and which ones don't, because an illusion or abstract concept that exists only in Topmind's head, cannot be found in reality. In reality, you'd have to look for something more concrete, something that actually exists.. like a C struct that stores information in the compiler/parser about types. Maybe the Perl source code would be a good place to start, to see how perl stores type information (I'd guess it is some kind of C data structure). Do you consider Perl to be tag-free, value based? Or is it tag based? Since I'm a smart guy, and I can't figure out whether perl is tag based, value based, or Moose-Shit-Fecal based, and since I don't care or give a damn and never have - I'm wondering why anyone else would care, and why you would choose a language based on this one fact (or lack of fact)? Even if I found out exactly how type info is stored in some particular dynamic language, why would this implementation detail be of concern to me as a layman choosing a language? I would not choose a language based on whether it does or does not use C structs for some things.'' The "side tag" model is a model. It's not necessarily meant to mirror a particular compiler/interpreter implementation. (All ColdFusion interpreters from different vendors/makers hopefully produce the same results.) And we can study the behavior of the compiler/interpreter (output) to see if the tag model is a good fit or not. When people "reason" about types, it's nice the have a model about how they work (or don't work) to reduce the need to run gazillion tests or write overly-defensive code. The model doesn't have to reflect the actual c/i implementation, it only has to have '''prediction value''' about expression and/or program output to serve our purposes. '''If it happens to mirror implementation, that's just a nice bonus, not a prerequisite'''. Related: EmpiricalTypeBehaviorAnalysis and ApplyingTheSideTagTypingModel. JavaScript "acts" like it has side type flags while CF acts like it doesn't. Put another way, JavaScript results fit a model having side flags (separate from "value" by associated with) while CF doesn't. {At best, the "side tag" 'model' refers to an implementation strategy sometimes called a "type tag" employed by a number of programming languages. Unless it's documented elsewhere, I've never seen any set of rules that describes how the "side tag model" may be used to predict behaviour. The pages cited (EmpiricalTypeBehaviorAnalysis and ApplyingTheSideTagTypingModel) seem to employ rules that appear to exist in the "side tag" author's mind (or somewhere else unspecified) or merely reiterate common understanding of dynamic and static typing implementations, with the term "side tag" arbitrarily injected in place of "associated with a type" (or other familiar phrases commonly used to indicate a concept associated with a type.)} A specific example of why it might matter? A language with a side tag may be have a zero length variable if a length() function is used to test, yet ALSO be null, or something else "funny". In a language without side tags, we know that one variable that results a zero length is going to act like another variable with zero length. There are less variations and hidden surprises. Tag-based languages allow situations where a variable can be "two things" at the same time. This complicates programming because we have to consider more cases. I can explain to somebody why this is happening using the tag model, but the other models either cannot, or take too many steps to do it. {It matters because "side tag" complicates a simple idea, that " is of type ", with a complex one that " has a side tag that indicates it is of type ". See how the phrase "has a side tag that indicates it" is not needed?} No, it's conceptually simpler because the "type" has a representation that we can describe and draw. It's no longer ethereal. How do you illustrate "is of" or "associated with a type"? (Perhaps linguistic thinkers like it that way for some reason that escapes me, but I am not a linguistic thinker and neither is the entire population.) {If necessary, draw a diagram and draw an arrow to indicate an association. However, such explanatory illustrations do not a model make! Note (in particular) the distinct lack of any stated rules for how these "side tags" are applied.} Yes, but that tends to get messy and confusing: pasta-like. As far as stated rules, they are generally language-dependent. Plus, tags are closer to the actual implementation. All else being equal, the model that's a closer fit to implementation is generally better. And it better matches program output. It's difficult to print references as arrows without adding graphics libraries. {My objections to the "side tag" notion are well-documented in the TypesAndSideFlagsDiscussion. No need to repeat them here.} -------- Example Debra: print(x); // result is "123" print(x + 3); // result is "126" // Alternative run: print(x); // result is "123" print(x + 3); // result is "1233" It's possible to get two different answers because one has a "tag" of "string" and the other a tag of "number". This kind of thing never happens in a tag-free language. If it prints/displays a given way it behaves a given way. There's no hidden ghost-like behavior. One can output/analyze the tag in tag langs, but it's '''double the work''' and code because you have to inspect/print '''both''' the value and tag (type name) to know its full nature. If there was a clear benefit of a compound system, I might live with this extra complexity. But nobody has shown the benefits are common and strong for a majority of domains and situations. You can get one output result that looks a given way (assuming no spaces), yet behaves different depending on different operations done after in tag langs. But there is no way to get this in CF or Perl that I am aware of. It's WYSIWYG because it's tag-free (at the scalar level). This makes life easier in my opinion because I don't have to worry if it looks like a string but is really a number under the hood (different tag). There is only the value to reason about and worry about, not a hidden tag. ------ throw(undefined) Will return true. If you're using liberal throws to step through confusing jasmine tests, this line will cause your tests to pass. ------- I just got done pulling my hair out over this kind of thing: window.open(misspelledVariableName, ...); It simply did ''nothing''. No error message or warning of any kind in both IE and FireFox. A normal language would say, "Variable Foo is not defined". I had to get a pencil out and compare the variable name character for character by crossing each letter out before I finally found the subtle misspelling, something like an "l" instead of "1" ("ell" versus one). (In hindsight I should have pasted in the good copy of the name.) JavaScriptSucks! Geeeez! '''JS is the HollerithPunchCard of the internet age''' (which made me want to both holler and punch 'em.) [I was surprised to find that this is a fairly recent edit, because these days all you need to do is pop open your browser's JS console. Any undefined variables will show a Reference''''''Error in there, plus the Debugger panel in Firefox (or the Sources panel in Chrome) lets you throw down breakpoints, jump around in the callstack, and inspect locals from any level of lexical scope. JS errors in browsers are silenced by default probably due to backwards compatibility, since there're so many old sites out there with bad scripts; if your code isn't working, there're sophisticated debugging tools you should be turning to immediately. -DavidMcLean] ---------- "10 Things We Hate About JavaScript" http://www.infoworld.com/slideshow/146732/10-things-we-hate-about-javascript-239535?source=more_slideshows#slide1 ------- Footnotes [1] It's possible to use "internal" tags to make processing more efficient, but we don't have to make their existence visible to the programmer such that a clone interpreter without them would produce the same results (IoProfile). See HiddenTypeTags for more on this. ------ Rest of discussion moved to JavaScriptSucksInBrowsers. ---- CategorySucks