Despite all that, and me being very familiar with both Rust and JS, it was a big pain. WASM will remain a niche technology for those who really need it, as it should be. No one is going to write their business CRUD in it, it would be a terrible idea.
I find the crossing in and out of JavaScript to be less than ideal. However, I don't see why WASM couldn't evolve to require less of that, ie. expose more of what you need JavaScript for today.
It can, and it is. Designers are already doing all they can to make it an appealing target for a variety of languages on multiple platforms.
Its also despite a couple decades of hard work by some very good compiler/JIT engineers at a considerable disadvantage perf wise to a lot of other languages.
Third its most common runtime environment, is a poorly thought out collection DP and UI paradigms that don't scale to even late 1980's levels, leading to lots of crutches. (AKA, just how far down your average infinite scrolling web page can you go before your browser either takes 10s of seconds to update, or crashes?).
Regarding performance, modern JS is plenty fast, but it's not in the 'terrible' category. It's memory usage, perhaps ;) https://benchmarksgame-team.pages.debian.net/benchmarksgame/.... For performance critical code JS is not the answer, but good enough for most uses, including UIs.
Regarding UI paradigms, I'm not sure what the problem is, or what significantly better alternatives are. I did MFC/C++ in '90s and C++/Qt in the '00s, and both were vastly inferior to modern browser development. React+StyledComponents is a wonderful way to build UIs. There are some warts on the CSS side, but mostly because Stackoverflow is full of outdated advice.
* Apps eventually degenerate in a mess of interconnected components triggering events on each other. Building UIs felt more like writing Verilog than writing functions. Nothing like chasing event ordering bugs through library components. With React I never saw 'enqueue a new event for component X' anti-pattern. All callbacks flow from children to parents in a fairly regular manner.
* Related, there is no need to manually manage repaint events in React. Visual updates happen automagically. See, for example, https://stackoverflow.com/questions/952906/how-do-i-call-pai... for a hair pulling session related to manual repainting.
* On the ergonomics side, having a markup language allows for terse but readable definitions of component trees. I see 2020 Qt has introduced a markup language, this was not the case circa 2005.
* Hooks give an extra layer of niceness. Declaring a component is as easy as declaring a function. Local state becomes almost as simple as declaring a local variable.
* The inspector capabilities of modern browsers are very handy when debugging layout and styling issues.
I've since moved on to other development areas, but have done a bit of both JS (on and off from about 2005->2015), and a bit of QT here and there too. The latter seems to have gotten better in the past few releases AFAIK. C# is at least ok too.
So in the case of MFC and early QT its not surprising that you prefer react+JS as neither of those were exactly the pinnacle of UI development in the late 1990's early 2000s.
What you describe in a later posting about MFC was never really a problem with the VCL, pretty much no one dealt with repaint messages unless you were writing a custom component. I remember showing a number of MFC programmers BC++ builder (which is also still a thing) when they were singing the MFC tune. They tended to get really quite after that.
PS/edit: Crazy, I just went and looked at the latest visual studio documentation and MFC is still an option, and at first glance seems basically the same as it was 25 years ago. Although the section on creating win32 applications is in front in the manual. I guess i'm not surprised that MFC is still a thing, but I am surprised that it doesn't have a giant depreciation warning. I frankly can't imagine creating a new MFC application in 2020.
But when it comes to JS and even other dynamic languages, people for some reason absolutely lose their minds, like a teenager whose parents are going out of town and are leaving them home by themselves overnight for the first time. I've seen horrendous JS from Java programmers, for example, that has made me think "Just... why? Why didn't you write the program you would have written (or already did write!) were you writing it in Java?" Like, "Yes, there are working JS programmers who do these kinds of zany things and make a real mess like this, but you don't have to, you know?"
It's as if people are dead set on proving that they need the gutter bumpers and need to be sentenced to only playing rail shooters instead of the open world game, because they can't be trusted to behave responsibly otherwise.
Javascript requires some self-discipline, where other languages discipline you if you try to fuck things up yourself. It's kind of like a drunken sailor on leave going on a bender on-shore - the minute they leave the ship all bets are off. Some people just can't wrap their head around using weak/dynamic typing, because it loosens the rules. But that doesn't mean there aren't any rules.
I code in a dozen other languages and Javascript is still my favorite because it's so easy to use, no boilerplate, and it doesn't give me any "gotchas" because javascript actually does follow some very basic easy to understand rules. The people that don't bother to learn those rules invariably shit on javascript. It's not fair, it's not real criticism.
And practically all of the "examples" of bad javascript is almost always code that nobody should ever write, in any language, because it's just stupid to write code in those ways. But people think "aHa, aNoThEr 'gOtChA'" and the myth of javascript being somehow inferior continues. And to anyone who actually knows how easy javascript is to use, it just looks silly, pathetic, and obnoxious.
Object = Object.prototype
Function = Function.prototype
That's how most dynamic languages work, no need for explanations, obvious assertions: Object.__proto__ === null
Function.__proto__ === Object
object = new Object.constructor
object.__proto__ === Object
object.constructor === Object.constructor
object.toString === Object.toString
object.private = function () { return 'hello' }
Object.shared = function () { return 'world' }
Object.constructor.static = function () { return '!' }
It shows hidden complexity — what does instanceof mean? // Object instanceof Function
Object.constructor.__proto__.constructor === Function.constructor
// Object instanceof Object
Object.constructor.__proto__.__proto__.constructor === Object.constructor
// Function instanceof Function
Function.constructor.__proto__.constructor === Function.constructor
// Function instanceof Object
Function.constructor.__proto__.__proto__.constructor === Object.constructor
Why would anyone want this? Lets get rid of .constructor on both sides: Object.constructor.__proto__ === Function
Object.constructor.__proto__.__proto__ === Object
Function.constructor.__proto__ === Function
Function.constructor.__proto__.__proto__ === Object
Now it is obvious — constructor is a Function, Functions __proto__ is Object. JavaScript programmers jump through ".prototype" hoops which should not be exposed.None of this crazy reflective, meta-level programming belongs in the LOB application logic of any program. Save it for your programmer workspace/REPL environment--which is something that 90+% of JS programmers aren't using anyway. They're all editing "dead" files in Visual Studio Code and SublimeText.
> Object.constructor.__proto__.constructor === Function.constructor // Object instanceof Object
... and that's not even what instanceof means.
I've thought that's caused by prototype inheritance, but no io language [1] prototype based yet easy to understand. The only difference — it does not hide [[Prototype]]. I've redefined Object and Function to show how it works. You would get same result in "dead" files. REPL to make it easy to reproduce.
Imagine it is another language
object.private = function () { return 'hello' }
Object.shared = function () { return 'world' }
Object.constructor.static = function () { return '!' }
vs object.private = function() { return 'hello' }
Object.prototype.shared = function () { return 'world' }
Object.static = function () { return '!' }
Can you see the difference? Or straight from io tutorial Contact = (class {
constructor(name, address, city) {
this.name = name
this.address = address
this.city = city
}
}).prototype
holmes = new Contact.constructor("Holmes", "221B Baker St", "London")
Contact.fullAddress = function() {
return [this.name, this.address, this.city].join('\n')
}
holmes.fullAddress()
No "prototype" (except from class but it can be redefined).> ... and that's not even what instanceof means.
Thank you, it should check [[Prototype]] not constructor
// Object instanceof Object
Object.constructor.__proto__ === Function
// Object instanceof Object
Object.constructor.__proto__.__proto__ === Object
// Function instanceof Function
Function.constructor.__proto__ === Function
// Function instanceof Object
Function.constructor.__proto__.__proto__ === Object
[1] https://iolanguage.org/> Do you ever type "prototype"?
Not every day or even once in an average week, unless you're doing something wrong.
> You would get same result in "dead" files.
You don't understand. You shouldn't even be futzing with these things in _any_ file in the first place. Keep this sort of thing inside your REPL, and keep it out of anything checked into source control or anything distributed to other other people. 99% of ordinary LOB logic simply does not require (or justify) the use of these kinds of meta-programming facilities. Don't start using clever code reflection tricks unless you're writing a reflection framework.
Dropping this highly relevant link here for the second time:
https://users.dcc.uchile.cl/~rrobbes/p/EMSE-features.pdf
> straight from io tutorial `Contact = [...]`
Er... okay. In JS:
class Contact {
constructor(name, address, city) {
this.name = name;
this.address = address;
this.city = city;
}
getFullAddress() {
return this.name + "\n" + this.address + "\n" + this.city;
}
}
let holmes = new Contact("Holmes", "221B Baker St", "London");
console.log(holmes.getFullAddress());
Prints: Holmes
221B Baker St
LondonDo you have to understand it or not? There is a ton of information on the web (viewed 191k times) [1], [2], etc. Acting like it is intuitive is disingenuous.
No, that's you who don't understand. I've shown particular code that is error prone in JS but is ok in other languages. That is the issue. It is not solved. Every novice gets it. It is simple to solve. Instead you claim "you should not need this", tell it 191k viewers. Yes, you know what's going on, still you claim "you don't need this".
class Foo
end
foo = Foo.new
foo.class == Foo // metaprogramming! *You shouldn't even be futzing with these things in _any_ file*
Sure I know about method definition in class. Extend it (same class). It is useful technique.And please don't post twice same if you can't read response.
[1] https://stackoverflow.com/questions/9959727/proto-vs-prototy...
Because your comments are incomprehensible.
> I've shown particular code that is error prone in JS but is ok in other languages.
It's not OK in Java. It's not OK in C. It's not OK in C++. Because you can't even do that in any of those languages.
> still you claim "you don't need this"
Look at the languages I listed above. Think about the program you're trying to write. Do you think it's impossible to write the program you want to write in those languages, where you are not even allowed to to do your clever tricks?
Look at the underscores in the name __proto__. That's a huge, massive sign in your face that means, "If you find yourself touching this a lot, it's because you're doing something wrong." How could it be clearer? Imagine it were called __proto$do_not_use$__ instead. But you use it anyway. And then you ask, "why is this so difficult?". Where's the surprise?
Think about this whole thread. You're doing something, experiencing pain, and then complaining about the pain that you feel. Yes, of course you feel the pain. Every time you mention the pain, you are actually giving an argument against yourself: it's not the right thing. So stop doing it. The fact that you got instanceof wrong is further evidence that you're not the best person to tell us which road to take to get to the party--you don't know the city.
(As for the code snippet you wrote in this comment, it's not clear at all what you're even trying to say. Once again: incomprehensible.)
class Foo {}
typeof Foo
//"function"
Foo instanceof Function
//true
Is there underscore here? How about typeof Object
//"function"
typeof Function
//"function"
Object instanceof Function
Object instanceof Object
Function instanceof Function
Function instanceof Object
How many underscores there? And looks like you don't know about Object.getPrototypeOf
Object.setPrototypeOf
Reflect.getPrototypeOf
Reflect.setPrototypeOf
without underscore and you blame I don't know this land.You've got burned by Java and C++, bad for you. There are other languages — Python and Ruby (last example). JS [[Prototype]] is equivalent of class hierarchy. You shown many times that you can't comprehend, normal reaction should be investigate and understand first, not your case. It shows you in a bad light.
No, you haven't ever defined _any_ problem, only abstract things that bother you.
There is only one problem that matters: writing a (correct) program. If you can do it without meta-programming, then you should.
If you start meta-programming when you don't have to, then you have already lost. If you are doing this when you shouldn't, and then you experience pain and say, "This system needs to be fixed", then make sure you fix the correct part of the system: yourself.
> JS [[Prototype]] is equivalent of class hierarchy.
Which nobody is futzing around with (because they can't, and they shouldn't futz with it anyway) on the level that you're insisting we do, in the ordinary course of writing programs. (The level where you are seeing "problems".) Once again: keep that stuff in your REPL. If you are editing a regular source file that will be committed to the repo and you are typing out "prototype" or "__proto__" or "setPrototypeOf" more than once or twice every 10k lines, then you're almost definitely doing something wrong.
> You've got burned by Java and C++, bad for you.
No, it's that the world is burning because of thousands of programmers who can't behave responsibly because they pick up a dynamic language and say, "There are no adults around to discipline me, so now is the time to go nuts."
(And the irony is that this thread exists because of your complaints about JS and how it burns you, where I started out arguing that JS is fine at the beginning. But now you're the champion for JS?)