I discovered E years ago and always lament it never had a resurgence. Coming from Scala/Akka, I adore message-based/actor systems and saw the promise of E to that end. Maybe some day we will get a first class actor language. Swift is kind of trying right now but it still feels bolted on.
There's Spritely Goblins, which takes a lot of inspiration from E. It's a library so it may feel bolted on to you, but in true lisp fashion it feels like it's part of the language when you're using it: https://docs.racket-lang.org/goblins/
I'm guessing you are not considering Erlang/Elixir "first class" then. Is it because they are hosted on the BEAM?
If the hosted VM part is what it comes down to you also have Pony. Haven't looked at it in quite a while but it always surprised me it didn't end up more popular.
My best guess is that a lot of people looked at its capability system and thought "wait, it's like Rust's borrow checker except even more of a hassle than the borrow checker?" and noped out. Which is unfair to Pony, but if you think of how Rust already scares some people off then that first impression of Pony might end up doing even worse.
Another interesting thing that came out of the object-capability ferment around E and EROS was Darius Bacon's Idel secure virtual machine: https://github.com/darius/idel
Though no other software is as influential as JS, other currently influential ocap systems include Genode, most of the current implementations of L4 (including seL4), and CHERI.
I'm not sure why nobody is talking about TypeScript? If browsers were to natively support it, that would be a game changer. We could phase out quirky features of JS and mark them as obsolete in IDEs. More use of the Map class for example would avoid some quirks of using objects.
TypeScript is designed in such a way that type annotations can't influence the runtime behavior. This is unlike e.g. Haskell, where types can drive code generation. Happy to elaborate more if necessary.
This means that transpiling TypeScript to JavaScript consists merely of stripping the type annotations + transpiling some of the syntactic features that might not be supported by the target JS version.
The "Type Annotations" proposal (https://github.com/tc39/proposal-type-annotations), IIRC championed partly by the TS team, will allow type annotations with almost-TS-like-syntax in plain JavaScript, which will make the "stripping type annotations" step unnecessary. You would still use the TS tooling to actually type-check the code, though.
Which exact part of TS do you want to be built into browsers?
There's still non-const enums generating runtime code
I think it would be huge if some future nodejs/web browser can parse native TS so we no longer need to deal with the mess of dev tools like ts-node and babel and wonder why some folder structure or sourcemap is not working
I'm surprised that Microsoft haven't already done this with their Edge browser. At least offer a 'developer' mode which enables TypeScript support only during development
We can't phase out features of JS in browsers, quirky or otherwise, because that would prevent us from running existing, fully debugged, standards-compliant web pages. It would mean that programming for the web was like depositing rare books in a library that was already on fire.
WASM does not interact with the DOM AFAIK. Of course one might (and probably somebody did) create a JavaScript programs interfacing a WASM web worker that sends user input in the JS -> WASM direction and executes DOM manipulation commands in the other one. All masked as a DOM library of the language that was compiled to WASM. Efficient? Probably no. Fast enough? Probably yes.
Thanks. In the early 90s there was "the law of Internet": if you can think about something somebody already made it and put it online. And it was a really tiny net compared to today.
No because most languages don't just compile to WASM... You need to compile and distribute a runtime or, in the case of dynamic languages, full interpreter with the web page. JS is way less code to ship depending on how much interactivity you want...
> You need to compile and distribute a runtime or, in the case of dynamic languages,
But for all other languages there are easy compilers. Which is why WASM, apparently, is used with such languages mostly[1]
I'd expect that these runtimes can be both distributed with browsers when they become really popular, and can be reduced in size. E.g. Python's runtime is relatively large and ships with a large stdlib. Most of which won't be needed in your code, so I'd expect it to be possible to compile a runtime that only includes what your code really needs, for example.
JavaScript is still the language that owns the platform, because WASM doesn't have any capabilities beyond compute, it up to the host to provide callbacks so that WASM code can call into the host, those callbacks are written in JavaScript.
That presumes that most of what JS does it "manipulating DOMs". At least in my frontend-code, this isn't the case. There is nearly always a much larger part that communicates with backends, sockets, HTTP, manages state, business logic and -validation etc.
The "writing it to screen" is often a rather thin layer. At least in my projects.
You probably wouldn't want to have to code in multiple languages even for a thin layer. Somebody could build that thin JS layer once for your language. Sounds like that's happening.
This function creates a closure with a private variable, "n". When invoked the closure will increase n by the specified amount, but there is no way to decrease it.
const incfac = () => { let n = 0; return m => (m > 0 ? n += m : n) };
A more extensive example due to Norm Hardy, presuming a multiuser Scheme interpreter that supports ocap security, is this Scheme program for voting on where to have lunch: http://cap-lore.com/CapTheory/Language/Lunch.html
You can translate this into current versions of ES straightforwardly but it doesn't get much more readable.
Norm explains:
> An invocation of mocntr is made each day for each restaurant. It returns a source of options, one of which will be offered to each of the lunch crowd. The second lambda in the definition produces such an option. The variable yet in that proc remembers if the option has been taken. The third lambda produces the getter for the count.
> bb is created each day for lunch and constitutes the ballot box. It is a list of pairs <restuarant name, <option source, count getter>>. This list is iterated over first to send each vote solicitation, and then later to count the votes.
Unfortunately he's vitrified now, so if you send him questions he will answer after a long delay, if ever.
I'm unclear about what kind of threat "freeze" protects against. Is it just protecting against your own mistakes, or against malicious code somehow running in the same JavaScript process?
Malicious code running in the same JS process, specifically malicious code that modifies an object you give it (that you retain references to) or that gives you an object and then changes it later. Running multiple mutually untrusting pieces of code in the same process was the main point of E, and that's what the modifications to JS being discussed here are aimed at.
Interesting! But I have a hard time understanding the use case in the context of a web page. If you import malicious code in a web app, wouldn't it be able to wreck all kinds of havoc anyway?
The objective of Jessie and the other capability-secure dialects of JS is precisely to allow you to import malicious code in a web app without allowing it to either wreak or wreck any havoc. You can imagine lots of ways this could be useful. One of the most boring but profitable was Crockford's original application for one such dialect at Yahoo — interactive banner ads: https://www.crockford.com/adsafe/
More generally, what if you want to drop a poll into a chat channel, upload a trading bot to a cryptocurrency exchange, run an image-filtering plugin for your paint program without giving its author access to your imagery, etc.? There are lots of scenarios where fine-grained security permits useful kinds of collaboration.
I guess I have a hard time seeing how Object.freeze() protects against malicious code, when any malicious script can still access the global object? I can understand something like the "Shadow realms" proposal, where a modules access to global objects can be constrained.
So am I correct in the understanding that Object.freeze in JavaScript does not provide any useful protection against malicious code? But in a different language, or a hypothetical future version of JavaScript, it might play a role in such a protection?
I think it provides, at best, very limited useful protection against malicious code that has access to the whole JS language, but it means that Jessie can include enormously more of JS than ADsafe did.
So first of all the article is a bit confusing: Object.freeze does make an object immutable:
const t = Object.freeze({foo: "bar"});
// throws an error in strict mode,
// silently does nothing otherwise
t.foo = "baz";
// prints "bar"
console.log(t.foo);
The tricky part is that it does not do so recursively:
const t2 = Object.freeze({foo: {bar: "baz"}});
// bar is still mutable
t2.foo.bar = "oh no!";
// prints "oh no!"
console.log(t2.foo.bar);
Still, one can easily write a function to recursively do a depth-first walk on an object and make everything immutable, so this is not really a concern in practice (if anything it gives you more flexibility).
Anyway, what I think Miller meant is that immutability is not the main reason why they introduced Object.freeze.
If I understand correctly, the main idea is to prevent people from inserting malicious code in the prototype chain (or anywhere else they might be able to).
Because JavaScript is prototype based I could in theory create a new Array class that uses the original Array class as its own prototype, then replace the Array class with itself. If you then create a new array it would still work like a regular one - it just goes up the prototype chain after all.
The malicious part is that this custom array class could then also override all Array methods to secretly watch your data and send stuff to the web without you noticing, or do anything else really. Because, again, it can just call the original method of its prototype to also behave as normal without anyone noticing.
Object.freeze would let you make sure none of the fundamental JavaScript objects can be tampered with.
The other thing is that you can ensure that any the library you create cannot be tampered with by third-party libraries.
Well yeah, it's closing over a variable that is not actually part of the properties of the function objects that are returned.
Object.freeze makes the shape (and therefore the properties) of an object immutable. It makes no guarantees about variables being closed over by a function. Those are different semantics altogether.
That feels similar to my earlier example of properties of nested objects not being affected by Object.freeze. And in this case, being able to freeze closed variables would in a sense mean exposing those variables. Which is not how closed variables work in JS (in fact it's one of the best ways to mimic "private properties" - except they're not really properties).
There are two types of immutability in JS: one is rebinding a variable (forbidden by the const keyword) and the other is modifying an object (forbidden by freeze)
In javascript these are similar as environment closures behave sort of similar to prototype chains.
One way to work around this is to serialize the argument to harden back to source, eval() it and then harden, which will prevent the captures from working.
That whole E "security model" is a really annoyingly academic endeavour. It's pretty absurd that they managed to push something into the standard only for the gain of their own obscure consulting company.
Nobody else uses it and no library utilizes it, most people haven't even heard of it. Yet it has expensive ramifications for the rest of the language.
Proxies for example are super cripled, and extremely hard to use, e.g. to build seamless database integrations (OOM), and super slow, with an added equality checks and whatnot on every access,
because they are supposed to also serve as an API gateways within that security framework.
Internal encapsulation is essential to be able to import and run (partially) untrusted code, to limit its potential side effects, and it has to be implemented in the language itself.
How many more decades do you want to wait before programming languages and with them, actual programming practice, become secure? All major languages have failed us in this aspect - and avoiding their shortcomings won't be possible without these primitives. Until people realize this, the world will have to suffer a million hacks that could have been avoided otherwise.
It does require a different mindset, perhaps even a conceptual inversion to understand and apply the security model, but that doesn't make it purely academic. Yes, it will remain that way if its logical truths are not implemented, but their applications and the consequences of ignoring them are very real.
To suggest that they only do it for their own sake is incredibly presumptuous.
I completely agree that we should aim for more secure languages, and I even concede that IF javascript had pervasive use of these (E based) security ideas both in libraries and culture, that it'd be a good thing.
However, I'd argue that the security concept introduced by E is at fundamental odds with the reality of javascript programmers.
There are other language construct that would have really improved security, such as persistent data structures, good functional programming capabilities that focus on pure functions, even E's actors could be used as isolated execution contexts that communicate via said persistent data-structures.
Having just one isolation mechanism, and making it very hard to use wrong, would really address existing security concerns, instead of just throwing a bunch of security primitives that are easy to misuse at a community that neither has the capacity to use them correctly, nor really cares.
I agree that hoisting these onto an existing language, especially such a "mutable" one as Javascript is difficult and introduces unfortunate complexity.
The intuition (and perhaps hope) that Javascript already has such a large install base and that, once the changes are available in all major browsers, a cultural change is possible through it seems to be the main motivator for them to focus on this language.
Even if the syntax of the language cannot be adapted to it, and people won't create constructs themselves with these primitives, there may be a chance that programmers who do not know the fundamental concepts of the theory can still enjoy its security properties by using third party libraries (heh) like SES that provide higher level primitives, e.g. to isolate other imported libraries.
I'm still skeptical myself if the focus on Javascript is the right approach, but i'd prefer their intuition to be right on this. Creating a new language will always be cleaner, but adoption is where E failed.
Proxies are there for security? It wasn't mentioned in the article and I don't see how it providers security, it only makes things easier to use, right?
Freeze is completely inadequate for immutability, persistent data-structures are really what you want for immutability most of the time, and they give you the nice security properties for free.
Most people think of proxies as JavaScripts "method-missing", but that's really not what they are for. They are an isolation primitive to build stuff like membranes [1][2][3].
> One fundamental aspect of E they brought over in ECMAScript 5 was support for the object-capability security model, he said. .... The provider of the object can populate it with methods that capture internal state variables and can encapsulate that state, so the clients of the object cannot tamper with it. By “freezing,” what’s meant is that the properties of the object can no longer be changed, he added.
Calling this "security" is hopefully not serious. "the properties of the object can no longer be changed" yes, unless someone else just unfreezes the object.
> That step addressed a security problem: prototype poisoning, in which objects created in traditional JavaScript were all mutable and can be subverted to confuse or surveil other parts of a program by anyone who had access to them.
This is still a problem, and the "harden" function that is described doesn't actually help because the things that it relies on could be poisoned.
From a practical security perspective, none of this actually accomplished anything or protects against any kind of bad actor doing something nefarious. I guess it's maybe useful as a comparison to E, but this article could have been a lot more direct and a lot less "we once did some stuff that is academically interesting in JavaScript."
Sorry, how do you unfreeze a frozen object? Only references I see online involve cloning it, which preserves the security properties of a frozen object.
As for harden(), whether its vulnerable to it's prototype chain in the way you describe depends entirely on how it's written. That said, these aren't amateurs so I expect they know what they're doing, and transitively freezing an object graph does add important security properties.
The security principle is largely based on OCAP-based permission scheme, where implicit access to an object is equal to the right to access, and freezing said object limits its use.
Capability Myths Demolished (2003) - https://news.ycombinator.com/item?id=22753464 - April 2020 (30 comments)
E Programming Language - https://news.ycombinator.com/item?id=19981720 - May 2019 (53 comments)
Satan Comes to Dinner (1997) - https://news.ycombinator.com/item?id=16512555 - March 2018 (14 comments)
Concurrency Among Strangers: Programming in E as Plan Coordination (2005) [pdf] - https://news.ycombinator.com/item?id=13653503 - Feb 2017 (2 comments)
Vats – Monte documentation - https://news.ycombinator.com/item?id=13295071 - Jan 2017 (1 comment)
E Programming Language: Write Secure Distributed Software - https://news.ycombinator.com/item?id=11608985 - May 2016 (21 comments)
Capability Based Security - https://news.ycombinator.com/item?id=10684129 - Dec 2015 (35 comments)
The E programming language - https://news.ycombinator.com/item?id=2497941 - April 2011 (9 comments)
E, the secure distributed pure-object platform and p2p scripting language - https://news.ycombinator.com/item?id=809714 - Sept 2009 (7 comments)
The E Language in a Walnut - https://news.ycombinator.com/item?id=70712 - Oct 2007 (1 comment)
Other threads?