Hacker News new | ask | show | jobs
by nwah1 3837 days ago
The important use case is to allow people to write web applications with their language of choice, instead of horrible javascript. And get near full performance.
4 comments

I think this is important. Probably because I have the "worse is better" article from 1991 open in another tab, and if you s/Lisp/Javascript/g then many of the criticisms ring true. Some of what made Unix, Windows, and Mac OS healthy environments for development was the fact that all developers were equally well off, you didn't have to pay a tax for writing something in a language other than Lisp. You could keep your Fortran code, and mix it into a C program, run from a Bourne shell, running in terminal emulator written in C and a WM written in Lisp. You can replace any part with a part written in a different language.

JavaScript will continue to be dominant, but we desperately need to be able to write things in the language of our choice.

Hmm? You paid a huge tax in desktop development for writing in a language other than the one the OS was written in. All of the platform documentation & examples were in its "native" language. You usually had to marshall data structures yourself to fit the data formats of the native language. You had to write shims (oftentimes in assembly!) that would bridge the calling conventions of your preferred language to those that the frameworks were written in.

There's a reason that C became the dominant language during the 80s and early 90s: it's because Win32, UNIX, and MacOS >=7 were all written in it. That's a large part of what Worse is Better was about. Richard Gabriel founded a company to write software for Lisp Machines, pivoted it to run Lisp on commodity hardware, found that all of his customers would rather just write in C, pivoted it again to do a C++ dev environment, and eventually went out of business.

The renaissance for other languages was really during the web era, when everything just spit out HTML and it didn't matter what the server was written in. Once customers started demanding rich interactivity on the client, there was a strong incentive to write everything in Javascript, and then a strong incentive to write the servers in Javascript too, and then a strong incentive to use Javascript for other things like native apps and IoT devices too.

Yes, you paid a tax. But my argument here is that the tax for writing in different languages on Win32, Unix, and Mac OS was far cheaper than the tax for writing in other languages on a Lisp machine. This is because translating low-level code to high-level code is not as straightforward as the reverse operation. For example, if I compile C to JavaScript, how do I even think about writing a function like memcpy()? You end up with a monster like asm.js where interacting with the DOM is a chore.

Yes, the web brought a renaissance in different languages. But we already had a bunch of different languages lying around when the web became important. We were already using different languages to write desktop software. I didn't even learn C until the late 1990s, but I was happily writing software before then.

WebAssembly is going to make languages other than JavaScript palatable in the browser, and I can only see that as a good thing.

> Richard Gabriel founded a company to write software for Lisp Machines,

The company Gabriel founded (Lucid Inc.) was never supposed to write software for Lisp Machines. Its mission from day zero was to develop a Common Lisp implementation for stock hardware (SUNs, etc.). Symbolics, the Lisp Machine maker, refused to fund a portable Common Lisp implementation (which Gabriel and Benson, the latter then at Symbolics, proposed).

> found that all of his customers would rather just write in C, pivoted it again to do a C++ dev environment, and eventually went out of business

Actually the Lisp business of Lucid Inc. financed the C++ development.

It was a gamble. They easily could have continued to develop and sell Common Lisp (their main competitors from that time, Franz Inc. and LispWorks are still alive) and stay in a small/shrinking niche. But Lucid tried to diversify and to grow. The idea was to write a C++ environment with a similar and improved development experience as a Lisp system. They used the cash cow they had and eventually sunk the whole company when the C++ system flopped in the market. Their C++ system (Energize) was very expensive, technically complex, ...

I think that's like saying: "I prefer to use the hammer instead of the screwdriver" for something with a helical ridge.

You are better off re-inventing Java or Python, but in a container and streamed over the Internet from an URL.

I can't believe people still bash JavaScript.

I've used a lot of different languages including Java, C#, C++, AVR Assembly, Python and others but JavaScript is my favourite and I would not want to go back.

I think its a shame that some people just didn't seriously try JavaScript. It's a very powerful, expressive language.

Also, testing with JS is amazing - Especially unit testing on Node.js. It lets you do stuff like redefine entire objects, properties or methods at runtime (for stubbing).

Also, JS is great for writing asynchronous logic.

I can't believe people still bash JavaScript.

I can't believe people actually like it. It might be understandable if you're comparing it to enterprisey Java, but I'm baffled that anyone could prefer ES5 to Python or Ruby. (I will acknowledge that ES6 puts it somewhere in the area of Python 2.5).

It's an incredibly powerful, expressive language.

Not if you want super advanced features like a hashtable with non-string keys, or checking if two objects are equal.

It lets you do stuff like redefine entire objects, properties or methods at runtime (for stubbing).

As does any other dynamic language.

Also, JS is great for writing asynchronous logic.

As is any other language with first-class functions. And with others you don't have to do silly contortions to work around JavaScript's broken "this".

I think its a shame that some people just didn't seriously try JavaScript.

Tried it, have written it professionally for many years, and as a result am very much looking forward to WebAssembly.

An interesting aspect which JS has and other languages don't is the "objects are hashes" notion. Combined with TypeScript / Elm / PureScript's ability to write and check the types of these (especially Elm before the refactor that removed the add/delete field features), this is very powerful. I often wish Haskell's built in records were as powerful as Elm's / PureScript's, but wonder if thats doable in an efficient way without the JIT logic in engines like V8.

Also, there is something to the whole "modules are records/hashes" idea which is quite elegant, IMO. I'm not sure why we still put up with the idea that the module system needs to be a whole different language with different rules. But I'm not sure if there is a type system capable of modelling this very well.

Are there any dynamic languages in which objects are not hashes?
Ruby -- object data is all private, and the reader/writer/attr things just make the getters and setters for you.
Python is another example. You can assign dynamic properties, but there is no object literal syntax
> I can't believe people still bash JavaScript.

Can you believe you can satisfy every programmer out there with a single language? of course not. Why did you have to use all the languages you listed? Because some made sense in a specific context, other didn't.

> Also, testing with JS is amazing - Especially unit testing on Node.js. It lets you do stuff like redefine entire objects, properties or methods at runtime (for stubbing). Also, JS is great for writing asynchronous logic.

Testing with Python is also amazing. It doesn't matter how amazing it is if I hate writing Python code.

No, the reality is that, in 5/10 years, javascript skills wont matter, only a good knowledge of the DOM and WebAPIs. In fact I'm pretty sure you'll see more opening for C++ developers on the front-end than Javascript ones.

> In fact I'm pretty sure you'll see more opening for C++ developers on the front-end than Javascript ones.

I would be happy to take a bet that this will not be the case.

The fact is that JS is much easier to learn than C++, has a broader ecosystem in the browser, is faster to write than C++ due to memory safety among other considerations, and is fast enough for app logic.

Think about it. C++ code has been supported for years on mobile. Yet Java/Dalvik is king on Android, and Objective-C is king on iOS. JS is faster than both (in the case of Objective-C, JS property access is faster than Obj-C virtual method dispatch due to ICs). So I see no reason why this will not be true on the Web as well. Web Assembly is very needed and important, but JS won't be going away.

If you're dissatisfied with objc_msgSend performance, you can write C or C++ seamlessly - or use that other language that's partially designed to address the dynamic dispatch nightmare.

If you're dissatisfied with JavaScript call performance, you have no choice.

> If you're dissatisfied with JavaScript call performance, you have no choice.

Other than the topic of this article?

Right - but this subthread is saying that JavaScript is enough and everyone should write JavaScript and not complain.
I have no idea what you mean by JavaScript being "easier" to learn than C++. My experience has been the exact opposite.

C++ is a giant beast, but most of it was relatively easy to learn after I internalized the general principles that guide the language's design. These principles were the first coherent account I ever found of how programs manipulating ephemeral resources should be written. [I am aware that Rust improves on C++, but it builds on, rather than replace, the general principles established by C++.]

On the other hand, in JavaScript I have never found anything even remotely close to methodological guidance for writing programs. JavaScript seems to make sense of anything as long as it is syntactically valid - a very low bar. As a result, I felt like I had to navigate a really huge space, hoping to eventually find a correct program somewhere.

JavaScript's ability to run in the browser is, as far as I can tell, its only advantage over C++.

> I have no idea what you mean by JavaScript being "easier" to learn than C++. My experience has been the exact opposite.

You are a tiny minority in this. I've taught C++ and JS and have never once seen JS be harder to pick up.

> On the other hand, in JavaScript I have never found anything even remotely close to methodological guidance for writing programs.

The #1 selling JS book is (was) literally called "JavaScript: The Good Parts". It teaches "methodological guidance" for writing JavaScript programs. Just as modern C++ books teach the "good parts" of C++.

> JavaScript seems to make sense of anything as long as it is syntactically valid - a very low bar.

That's (a) not true, with the static resolution semantics in modules; (b) to the extent that it is true is mostly a criticism of dynamic typing, which has a lot of advantages and is not a criticism of JavaScript.

> JavaScript's ability to run in the browser is, as !far as I can tell, its only advantage over C++.

Memory safety? GC? A module system (as compared to #include)? Dynamic typing? This is silly.

(NB: I also think C++ has a lot of advantages over JS for certain domains. I'm a language pluralist.)

> The #1 selling JS book is (was) literally called "JavaScript: The Good Parts". It teaches "methodological guidance" for writing JavaScript programs. Just as modern C++ books teach the "good parts" of C++.

I'm talking about guidance from the language itself, not external parties. For instance, C++ templates don't provide such guidance - it's very difficult for C++ compilers to tell you where and how exactly you're using templates wrong. On the other hand, C++ destructors do provide such guidance - just put all your finalization logic in destructors and you're done.

> That's (a) not true, with the static resolution semantics in modules

Even with strict mode and statically resolved imports, JavaScript requires extremely defensive programming to get useful diagnostics when anything goes wrong beyond using identifiers not in scope.

> (b) to the extent that it is true is mostly a criticism of dynamic typing

Python (not to mention Scheme, which JavaScript is allegedly inspired by) is dynamically typed, but does a much better job of treating nonsensical code as an error.

> Memory safety? GC?

It's true that garbage collection makes memory management a non-problem in the vast majority of situations, but it doesn't even begin to address managing other resources. Unfortunately, a program whose only avilable resource is memory (and perhaps the standard streams) is nothing but a fancy calculator.

RAII is a comprehensive solution to a wide class of problems that includes memory management as a special case, so I think C++ wins this one.

> A module system (as compared to #include)?

Of course, you're completely right about this.

> Dynamic typing?

I can get exactly as much dynamic typing as I need in C++ programs, without affecting the parts that are meant to be statically typed.

I've tried JavaScript, and I decided I preferred type safety. This kind of thing:

> It lets you do stuff like redefine entire objects, properties or methods at runtime

Sounds horrifying to me, because, as in Ruby[1], library authors will decide that's a good idea. Typeclasses/protocols solve this problem perfectly, while maintaining type safety.

[1]: for some reason, this seems to be less of an issue in Python and Obj-C, even though it's totally doable?

If type safety is what you miss, why not to use some transpiler like TypeScript?

http://www.typescriptlang.org/Tutorial

Then you're not writing JavaScript, which was OP's concern. TypeScript is fine (although Elm, Swift, and Haskell are more interesting, IMO).
TypeScript is very close to normal JavaScript. It's basically just JavaScript + type annotations which a compiler can check.

Compilation phase removes the annotations, after that point it is pure JavaScript.

How are Swift and Haskell relevant for client side web development?

Edit: Removed Elm

Are you aware of GHCJS, Haskell-to-JS, compiler? In the new and rather popular "build/dependency manager"[1] for Haskell, named Stack, you can now quite easily install this compiler.

And I think it is only a matter of time till someone writes a Swift-to-JS compiler (Apple might already have it on it's radar).

[1]: I know it is not a "build/dependency manager", but I don't know how to call better in for sake of this discussion.

Elm's only target is the browser/JS.
Look at purescript. In order to install this madness you need to install not less than 5 package managers, but you might like it.
The situation has improved since cabal install was required.

npm install -g pulp purescript

should be enough now.

> I can't believe people still bash JavaScript.

== vs ===

!==

hasOwnProperty

> Also, testing with JS is amazing - Especially unit testing on Node.js. It lets you do stuff like redefine entire objects, properties or methods at runtime (for stubbing).

Doable in Common Lisp for 21 years…

> Also, JS is great for writing asynchronous logic.

ITYM JavaScript has first-class functions. So does Lisp, so does Python, so does Go…

Now try to take a look at some real languages. At the languages with well-defined, simple, orthogonal semantics.

And, no, JavaScript is nowhere near any "powerfull, expressive language". It is embarrasingly low level for a supposedly scripting language and it does not provide any powerful productivity features whatsoever.

JS is also a nightmare for the implementers, it does not have a sane specification, therefore most of the tooling is not comprehensive.

It's not a bad language, but it's not good either. But who is it powerfull? It's a very poor man's scheme, and scheme is not powerfull either. If javascript has anything to over it's IMO simplity and not power.

But I'll never understand who thought this asynchronous API was a good idea.

I just wanted to draw pictures in a canvas _in order_, because they should overlap. A common task you could mean. I ended up building a monadic builder for callback chains, that creates a javascript string that is evaled. I felt like this language and the api was incredibly cumbersome, minimalistic and limited. It lacks a blocking api, monad support, dsl support, macros and lazy evalution.

But mayme there is a simple solution to that, that I'm not aware of.

> scheme is not powerfull either

In what sense is Scheme not powerful? It has TCO, syntax-rules, call/cc, etc.

Of course, all of those are things scheme has that JavaScript doesn't.

No types, a very minimal syntax, a standard library so slim that everything interesting is a implementation-detail. And, as I a said, javascript has less. Javascript even lacks integer variables, while scheme has the numeric tower. (Although that is not required by rsr4/rsr5 and that what most implementations care about)
> No types, a very minimal syntax

I don't see how these make the language less powerful. Especially the syntax part, which plays a big part in Scheme's power, as an enabler for macros.

> a standard library so slim

I agree with this though.

Sorry to say, but the web isn't about writing apps in the language of your choice. If it's beyond plain, passive HTML, it's about running applications on foreign hosts/resources without a well specified license to do so. Scripting languages provide both audible code and a small load as compared to binary object code (which is, why we had them on servers and clients in the first place).

If we turn the web into an anything-goes bonanza using binary code without any keys, credentials, or permissions, WebAssembly (and Turing complete CSS as well) may be well the beginning of end of the web as we know it, giving raise to a new, leaner and more restricted platform (for which some are already on the lookout, BTW).

[Edit] A small real world example: Client asks me to implement a third party plugin to allow them direct communications with their users via their website. A quick scan of the source code tells in a minute that the script isn't just doing that, but is also tracking user behavior and is phoning home related data. Now I can ask the client, if they really want to expose their users to this. With WebAssembly, there's no chance to do so.

Try looking at the source of Google.com and saying all it's doing in under a minute.

You could look at the APIs it's using - why is it calling XMLHttpRequest or looking at the user's cookies? - but you can do the same with binaries, you just have to use a tool, e.g. 'nm -D <binary>' shows you the external functions the program calls.

I held the same position until circa 2008 (?), when JS minifying became truly widespread; nowadays, I think that battle is already lost.

So, just give up?

(Please mind that there has to be a strict relation between a minified code and a plain source code provided at some repository. This is not true, at least in terms of the resources needed to verify this and the probability of this being covered by average budgets, for binary codes. – Recommended reading: "Reflections on Trusting Trust" by Ken Thompson)

Edit: At best you're winning a year's worth of Moore's law in performance and are paying for it in terms of page load. On the down-side, binary code is just as bad an idea as e-voting: You're putting the interests of your users against literary trillions of dollars of interest in exploiting the system (yes, the leverage would be enorme) – and if the worst has become true, it's already too late to revert.

Probably solve it the way we do with the rest of shared libs and open computing:

Require the source. Download compiled code from trusted sources.

Download a nuget package; dll's. Download an apt package; binaries and so's. This won't blow up web.

Not your everyday real-life story. Client: "Integrate this (see attachment)". You, "No, they have first to hand over the source code in order to allow me auditing their software." Client: (gone).

As for the real-life example given above: The third party is billing the client only a few bucks, since the real business is in profile building and exchanging profiles. So, are they expected to hand out the source code for 5 bucks or so? Probably not. Who is to lose? Everyone visiting the website.

Why are you under the impression there won't be disassemblers and decompilers for WebAssembly?

It's not like a bunch of minified JS is going to be "quick" to go through.

Even, if there would be a suitable disassembler, this would just account to an exponential curve in terms of auditing any software. (We're not speaking of minutes here anymore, but rather of months or even years – who will be willing to pay for it?) BTW, with minified JS, you've just to recode variable names (while anything adequate to system calls has to be in plain text somewhere by definition), with WebAssembly, this becomes an entirely different story. – No comparison.
This is basically the same case for traditional binaries. I'm no RE expert, but when I've done such work it consists of "renaming variables" including functions and looking for calls to imported functions. Intentionally obfuscated code is harder.

But nothing stops JS from loading a bunch of encrypted strings, self-modifying at runtime, using eval+substring (at various offsets) on loaded and renamed functions to make it hard to know if there are calls to other functions, let alone what they are.

It can still be done, and obfuscated JS is probably easier than obfuscated x86 but saying it makes an audit only take minutes means it's not really being obfuscated.

>But nothing stops JS from loading a bunch of encrypted strings, self-modifying at runtime, using eval+substring (at various offsets) on loaded and renamed functions to make it hard to know if there are calls to other functions, let alone what they are.

There is a solution to that. Control the platforms. You have like what, 4? major vendors of browsers. Convince them to make eval disabled by default and you warp the entire usable market. The percentage of people who would bother to go hunting the setting to turn it on would be minuscule.

Use the power of the default to affect the whole space.

I really don't get the down voting: While we've come globally to the conclusion that we require signed software, curated app stores and kill switches for traditional applications, because sh#t happens, we're going to distribute binary software in the browser without any such limitations? With the average user not even knowing that she is running some software from untrusted sources? (Yes, I know, it will be sandboxed, and there will never be a zero-day anymore in any browser ...)