Everything is An Expression - javascript

I've noticed many languages like Ruby and CofeeScript (well a transcompiler) support everything being an expression.
Now it makes the language somewhat simple to understand and definitely seems neat at the surface, but I was looking maybe for some scholarly publications about the positives and negatives of the two approaches.
It would be beneficial if the publications had clear examples that compared the benefits of having everything be an expression vs., well, not.
Examples in CoffeeScript vs Javascript would be nice, but not required.
The concept is definitely cool, but I'm still slightly unsure how revolutionary the whole idea really is (obviously something being revolutionary is somewhat an opinion).
Thanks!

There is nothing revolutionary about this per se. The expression-oriented approach is a functional programming technique.
Expression-oriented code is simpler and less cluttered than statement-oriented code, because of fewer assignments and no explicit return statements. The lack of distinction between expressions and commands enables conceptual uniformity (see Referential transparency) and bottom-up structure.
Some modern languages have adopted functional programming concepts (e.g. C#, Python, Ruby).
Some scholarly insight on the benefits of functional practices:
Can Programming Be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs - John Backus
Interesting articles:
Why Functional Programming is Important in a Mixed Environment
Is C# becoming a functional language?
As to the comment about performance concerns, the possible overhead related to choice of paradigm is probably negligible. Even in C, most statements evaluate as an expression - however, a comparison between a compiled language (C) and an interpreted language (CoffeeScript) is rather useless.
On a theoretical note, an imperative language represents the control flow in more of a machine-oriented way, which may allow for easier hand-optimization than a functional language.
Language performance and its significance depend heavily on the use case. Concerning JavaScript and whatever code transformation on top of it, this performance discussion is completely irrelevant. The gains in productivity outweigh any slight performance hit.

By "everything is an expression," I assume you mean what is described at http://jashkenas.github.com/coffee-script/
It kinda sounds like what you're asking about are functional languages. Consider, for example, Lisp, which did this sort of thing back in the '50s. This ultimately comes out of the Lambda Calculus, in which code and data are really the same thing, and you can pass code around as though it were data (because it is).
I don't know of any scholarly articles discussing this specifically, but now you at least have some more keywords to search for.

Related

OLOO vs. OO in reactjs front-end web dev

I read Kyle's book, and I found it really informative.
But I am a little confused on the discussion in "You Don't Know JS: this & Object Prototypes".
That series say that Object Linking to Other Object design pattern is cleaner and simpler then object oriented design pattern. I do agree with this.
But I notice that many react code snippet prefer using ES6 class keyword which represents object oriented code style.
First and foremost you don't have to teach programmers that you introduce to your project to OOP pattern as it is by far the most popular one and people are used to it. Teaching someone consumes time and money - two things that business value the most.
Second thing would be that it is hard to prove that one programming paradigm is better than the other - especially if you can count on one hand implementations of OLOO when OOP has hundreds of thousands.
Just because something is better (I also agree with Kyle) doesn't mean it will be the most popular choice.

Javascript used to be a lisp? [duplicate]

A friend of mine drew my attention the welcome message of 4th European Lisp Symposium:
... implementation and application of
any of the Lisp dialects, including
Common Lisp, Scheme, Emacs Lisp,
AutoLisp, ISLISP, Dylan, Clojure,
ACL2, ECMAScript, ...
and then asked if ECMAScript is really a dialect of Lisp. Can it really be considered so? Why?
Is there a well defined and clear-cut set of criteria to help us detect whether a language is a dialect of Lisp? Or is being a dialect taken in a very loose sense (and in that case can we add Python, Perl, Haskell, etc. to the list of Lisp dialects?)
Brendan Eich wanted to do a Scheme-like language for Netscape, but reality intervened and he ended up having to make do with something that looked vaguely like C and Java for "normal" people, but which worked like a functional language.
Personally I think it's an unnecessary stretch to call ECMAScript "Lisp", but to each his own. The key thing about a real Lisp seems like the characteristic that data structure notation and code notation are the same, and that's not true about ECMAScript (or Ruby or Python or any other dynamic functional language that's not Lisp).
Caveat: I have no Lisp credentials :-)
It's not. It's got a lot of functional roots, but so do plenty of other non-lisp languages nowadays, as you pointed out.
Lisps have one remaining characteristic that make them lisps, which is that lisp code is written in terms of lisp data structures (homoiconicity). This is what enables lisps powerful macro system, and why it looks so bizzare to non-lispers. A function call is just a list, where the first element in the list is the name of the function.
Since lisp code is just lisp data, it's possible to do some extremely powerful stuff with metaprogramming, that just can't be done in other languages. Many lisps, even modern ones like clojure, are largely implemented in themselves as a set of macros.
Even though I wouldn't call JavaScript a Lisp, it is, in my humble opinion, more akin to the Lisp way of doing things than most mainstream languages (even functional ones).
For one, just like Lisp, it's, in essence, a simple, imperative language based on the untyped lambda calculus that is fit to be driven by a REPL.
Second, it's easy to embed literal data (including code in the form of lambda expressions) in JavaScript, since a subset of it is equivalent to JSON. This is a common Lisp pattern.
Third, its model of values and types is very lispy. It's object-oriented in a broad sense of the word in that all values have a concept of identity, but it's not particularly object-oriented in most narrower senses of the word. Just as in Lisp, objects are typed and very dynamic. Code is usually split into units of functions, not classes.
In fact, there are a couple of (more or less) recent developments in the JavaScript world that make the language feel pretty lispy at times. Take jQuery, for example. Embedding CSS selectors as a sublanguage is a pretty Lisp-like approach, in my opinion. Or consider ECMAScript Harmony's metaobject protocol: It really looks like a direct port of Common Lisp's (much more so than either Python's or Ruby's metaobject systems!). The list goes on.
JavaScript does lack macros and a sensible implementation of a REPL with editor integration, which is unfortunate. Certainly, influences from other languages are very much visible as well (and not necessarily in a bad way). Still, there is a significant amount of cultural compatibility between the Lisp and JavaScript camps. Some of it may be coincidental (like the recent rise of JavaScript JIT compilation), some systematic, but it's definitely there.
If you call ECMAScript Lisp, you're basically asserting that any dynamic language is Lisp. Since we already have "dynamic language", you're reducing "Lisp" to a useless synonym for it instead of allowing it to have a more specific meaning.
Lisp should properly refer to a language with certain attributes.
A language is Lisp if:
Its source code is tree-structured data, which has a straightforward printed notation as nested lists. Every possible tree structure has a rendering in the corresponding notation and is susceptible to being given a meaning as a construct; the notation itself doesn't have to be extended to extend the language.
The tree-structured data is a principal data structure in the language itself, which makes programs susceptible to manipulation by programs.
The language has symbol data type. Symbols have a printed representation which is interned: when two or more instances of the same printed notation for a symbol appear in the notation, they all denote the same object.
A symbol object's principal virtue is that it is different from all other symbols. Symbols are paired with various other entities in various ways in the semantics of Lisp programs, and thereby serve as names for those entities.
For instance, dialect of Lisp typically have variables, just like other languages. In Lisp, variables are denoted by symbols (the objects in memory) rather than textual names. When part of a Lisp program defines some variable a, the syntax for that a is a symbol object and not the character string "a", which is just that symbol's name for the purposes of printing. A reference to the variable, the expression written as a elsewhere in the program, is also an on object. Because of the way symbols work, it is the same object; this object sameness then connects the reference to the definition. Object sameness might be implemented as pointer equality at the machine level. We know that two symbol values are the same because they are pointers to the same memory location in the heap (an object of symbol type).
Case in point: the NewLisp dialect which has a non-traditional memory management for most data types, including nested lists, makes an exception for symbols by making them behave in the above way. Without this, it wouldn't be Lisp. Quote: "Objects in newLISP (excluding symbols and contexts) are passed by value copy to other user-defined functions. As a result, each newLISP object only requires one reference." [emphasis mine]. Passing symbols too, as by value copy, would destroy their identity: a function receiving a symbol wouldn't be getting the original one, and therefore not correctly receiving its identity.
Compound expressions in a Lisp language—those which are not simple primaries like numbers or strings—consist of a simple list, whose first element is a symbol indicating the operation. The remaining elements, if any, are argument expressions. The Lisp dialect applies some sort of evaluation strategy to reduce the expression to a value, and evoke any side effects it may have.
I would tentatively argue that lists being made of binary cells that hold pairs of values, terminated by a special empty list object, probably should be considered part of the definition of Lisp: the whole business of being able to make a new list out of an existing one by "consing" a new item to the front, and the easy recursion on the "first" and "rest" of a list, and so on.
And then I would stop right there. Some people believe that Lisp systems have to be interactive: provide an environment with a listener, in which everything is mutable, and can be redefined at any time and so on. Some believe that Lisps have to have first-class functions: that there has to be a lambda operator and so on. Staunch traditionalists might even insists that there have to be car and cdr functions, the dotted pair notation supporting improper lists, and that lists have to be made up of cells, and terminated by specifically the symbol nil denoting the empty list, and also a Boolean false. Insisting on car and cdr allows Scheme to be a Lisp, but nil being the list terminator and false rules
The more we shovel into the definition of "Lisp dialect", though, the more it becomes political; people get upset that their favorite dialect (perhaps which they created themselves) is being excluded on some technicality. Insisting on car and cdr allows Scheme to be a Lisp, but nil being the list terminator and false rules it out. What, Scheme not a Lisp?
So, based on the above, ECMAScript isn't a dialect of Lisp. However, an ECMAScript implementation contains functionality which can be exposed as a Lisp dialect and numerous such dialects have been developed. Someone who needs wants ECMAScript to be considered a Lisp for some emotional reasons should perhaps be content with that: that the semantics to support Lisp is there, and just needs a suitable interface to that semantics, which can be developed in ECMAScript and which can interoperate with ECMAScript code.
No it's not.
In order to be considered a Lisp, one has to be homoiconic, which ECMAscript is not.
Not a 'dialect'. I learned LISP in the 70's and haven't used it since, but when I learned JavaScript recently I found myself thinking it was LISP-like. I think that's due to 2 factors: (1) JSON is a list-like associative structures and (2) it's seems as though JS 'objects' are essentially JSON. So even though you don't write JS programs in JSON as you would write LISP in lists, you kind of almost do.
So my answer is that there are enough similarities that programmers familiar with LISP will be reminded of it when they use JavaScript. Statements like JS = LISP in a Java suit are only expressing that feeling. I believe that's all there is to it.
Yes, it is. Quoting Crockford:
"JavaScript has much in common with Scheme. It is a dynamic language. It has a flexible datatype (arrays) that can easily simulate s-expressions. And most importantly, functions are lambdas.
Because of this deep similarity, all of the functions in [recursive programming primer] 'The Little Schemer' can be written in JavaScript."
http://www.crockford.com/javascript/little.html
On the subject of homoiconicity, I would recommend searching that word along with JavaScript. Saying that it is "not homoiconic" is true but not the end of the story.
I think that ECMAScript is a dialect of LISP in the same sense that English is a dialect of French. There are commonalities, but you'll have trouble with assignments in one armed only with knowledge of the other :)
I find it interesting that only one of the three keynote presentations highlighted for the 4th European Lisp Symposium directly concerns Lisp (the other two being about x86/JVM/Python and Scala).
"dialect" is definitely stretching it too far. Still, as someone who has learned and used Python, Javascript, and Scheme, Javascript clearly has a far Lisp-ier feel to it (and Coffeescript probably even more so) than Python.
As for why the European Lisp Symposium would want to portray Javascript as a Lisp, obviously they want to piggyback on the popularity of the Javascript for which the programmer population is many, many times larger than all the rest of the Lisp dialects in their list combined.

Can regular JavaScript be converted to asm.js, or is it only to speed up statically-typed low-level languages?

I have read the question How to test and develop with asm.js?, and the accepted answer gives a link to http://kripken.github.com/mloc_emscripten_talk/#/.
The conclusion of that slide show is that "Statically-typed languages and especially C/C++ can be compiled effectively to JavaScript", so we can "expect the speed of compiled C/C++ to get to just 2X slower than native code, or better, later this year".
But what about non-statically-typed languages, such as regular JavaScript itself? Can it be compiled to asm.js?
Can JavaScript itself be compiled to asm.js?
Not really, because of its dynamic nature. It's the same problem as when trying to compile it to C or even to native code - you actually would need to ship a VM with it to take care of those non-static aspects. At least, such a VM is possible:
js.js is a JavaScript interpreter in JavaScript. Instead of trying to create an interpreter from scratch, SpiderMonkey is compiled into LLVM and then emscripten translates the output into JavaScript.
But if asmjs code runs faster than regular JS, then it makes sense to compile JS to asmjs, no?
No. asm.js is a quite restricted subset of JS that can be easily translated to bytecode. Yet you first would need to break down all the advanced features of JS to that subset for getting this advantage - a quite complicated task imo. But JavaScript engines are designed and optimized to translate all those advanced features directly into bytecode - so why bother about an intermediate step like asm.js? Js.js claims to be around 200 times slower than "native" JS.
And what about non-statically-typed languages in general?
The slideshow talks about that from …Just C/C++? onwards. Specifically:
Dynamic Languages
Entire C/C++ runtimes can be compiled and the original language
interpreted with proper semantics, but this is not lightweight
Source-to-source compilers from such languages to JavaScript ignore
semantic differences (for example, numeric types)
Actually, these languages depend on special VMs to be efficient
Source-to-source compilers for them lose out on the optimizations done in those VMs
In response to the general question "is it possible?" then the answer is that sure, both JavaScript and the asm.js subset are Turing complete so a translation exists.
Whether one should do this and expect a performance benefit is a different question. The short answer is "no, you shouldn't." I liken this to trying to compress a compressed file; yes, it is possible to run the compression algorithm, but in general you should not expect the resulting file to be smaller.
The short answer: The performance cost of dynamically-typed languages comes from the meaning of the code; a statically-typed program with an equivalent meaning would carry the same costs.
To understand this, it is important to understand why asm.js offers a performance benefit at all; or, more generally, why statically-typed languages perform better than dynamically-typed ones. The short answer is "run-time type checking takes time," and a longer answer would include the improved feasibility of optimizing statically-typed code. For example:
function a(x) { return x + 1; }
function b(x) { return x - 1; }
function c(x, y) { return a(x) + b(y); }
If x and y are both known to be integers, I can optimize function c to a couple of machine code instructions. If they could be integers or strings, the optimization problem becomes much harder; I have to treat these as string appends in some cases, and addition in other cases. In particular, there are four possible interpretations of the addition operation that occurs in c; it could be addition, or string append, or two different variants of coerce-to-string-and-append. As you add more possible types, the number of possible permutations grows; in the worst case for a dynamically-typed language, you have k^n possible interpretations of an expression involving n terms which could each have any number of k types. In a statically typed language, k=1, so there is always 1 interpretation of any given expression. Because of this, optimizers are fundamentally more efficient at optimizing statically-typed code than dynamically-typed code: There are fewer permutations to consider when searching for opportunities to optimize.
The point here is that when converting from dynamically-typed code to statically-typed code (as you'd be doing when going from JavaScript to asm.js), you have to account for the semantics of the original code. Meaning the type-checking still occurs (it's just now been spelled out statically-typed code) and all those permutations are still present to stifle the compiler.
A few facts about asm.js, which hopefully make the concept clear:
Yes you can write the asm.js dialect by hand.
If you did look at the examples for asm.js, they are very far from being user friendly. Obviously Javascript is not the front end language for creating this code.
Translating vanilla Javascript to asm.js dialect is not possible.
Think about it - if you already could translate standard Javascript in a fully statically manner, why would there be a need for asm.js? The sole existance of asm.js means that the Javascript JIT people at some people gave up on their promise that Javascript will get faster without any effort from the developer.
There are several reasons for this, but let's just say it would be really hard for the JIT to understand a dynamic language as good as a static compiler. And then probably for the developers to fully understand the JIT.
In the end it boils down to using the right tool for the task. If you want static, very performant code, use C / C++ ( / Java ) - if you want a dynamic language, use Javascript, Python, ...
asm.js has been created by the need of have a small subset of javascript which can be easily optimized. If you can have a way to convert javascript to javascript/asm.js, asm.js is not needed anymore - that method can be inserted in js interpreters directly.
In theory, it is possible to convert / compile / transpile any JavaScript operation to asm.js if it can be expressed with the limited subset of the language present in asm.js. In practice, however, there is no tool capable of converting ordinary JavaScript to asm.js at the moment (June, 2017).
Either way, it would make more sense to convert a language with static typing to asm.js, because static typing is a requirement of asm.js and the lack thereof one of the features of ordinary JavaScript that makes it exceptionally hard to compile to asm.js.
Back in 2013, when asm.js was hot, there has been an attempt to compile a statically typed language similar to JavaScript, but both the language and the compiler seem to have been abandoned.
Today, in 2017, JavaScipt subsets TypeScript and Flow would be suitable candidates for conversion to asm.js, but the core dev teams of neither language is interested in such conversion. LLJS had a fork that could compile to asm.js, but that project is pretty much dead. ThinScript is a much more recent attempt and is based on TypeScript, but it doesn't appear to be active either.
So, the best and easiest way to produce asm.js code is still to write your code in C/C++ and convert / compile / transpile it. However, it remains to be seen whether we'll even want to do this in the forseeable future. Web Assembly may soon replace asm.js altogether and there's already popping up TypeScript-like languages like TurboScript and AssemblyScript that convert to Web Assembly. In fact, TurboScript was originally based on ThinScript and used to compile to asm.js, but they appear to have abandoned this feature.
It may be possible to convert regular JavaScript to asm.js by first compiling it to C or C++, and then compiling the generated code to asm.js using Emscripten. I'm not sure if this would be practical, but it's an interesting concept nonetheless.
There is also a compiler called NectarJS that compiles JavaScript to WebAssembly and ASM.js.
check this http://badassjs.com/post/43420901994/asm-js-a-low-level-highly-optimizable-subset-of
basically you need check that your code would be asm.js compatible (no coercion or type casting, you need to manage the memory, etc). The idea behind this is write your code in javascript, detect the bottle neck and do the changes in your code for use asm.js and aot compilation instead jit and dynamic compilation...is a bit PITA but you can still use javascript or other languages like c++ or better..in a near future, lljs.....

Would it make sense to run JavaScript on the Lua VM?

Lua is small and can be easily embedded. The current JavaScript VMs are quite big and hard to integrate into existing applications.
So wouldn't it be possible to compile JavaScript to Lua or Lua bytecode?
Especially for the constraints in mobile applications this seems like a good fit. Being able to easily integrate one of the most popular scripting languages into any iPhone or Android app would be great.
I'm not very familiar with Lua so I don't know if this is technically feasible.
With Luvit there is an active project trying to port the Node.js architecture to Lua. So the evented JavaScript world can't be too far away from whats possible in Lua.
The wins of compiling Javascript to Lua are not as great as you might first imagine. Javascript's semantics are very different to Lua's (the LuaJIT author cites Lua's design as one of the main reasons LuaJIT can compete so favourably with Javascript JIT compilers).
Take this code:
if("1" == 1)
{
print("Yes");
}
This prints "Yes" in Javascript. The equivalent code in Lua does not, as strings are never equal to numbers in Lua. This may seem like a small point, but it has a fundamental consequence: we can no longer use Lua's built-in equality testing.
There are two solutions we could take. We could rewrite 1 == "1" to javascript_equals(1, "1"). Or we could wrap every Javascript value in Lua, and use Lua's metatables to override the == operator behaviour.
So we already lost a some efficiency from Lua by mapping Javascript to it. This is a simple example, but it continues like this all the way down. For example all the operator rules are different between Javascript and Lua.
We would even have to wrap Javascript objects, because they aren't the same as Lua tables. For example Javascript objects only support string keys, and coerce any index to a string:
> a = {}
{}
> a[1] = "Hello"
'Hello'
> a["1"]
'Hello'
You also have to watch out for Javascript's scoping rules, vararg functions, and so on.
Now, all of these things are surmountable, if someone were to put the effort into a full compiler. However any efficiency gains would soon be drowned out. You would essentially end up building a Javascript interpreter in Lua. Most Javascript interpreters are written in C and already optimised for Javascript's semantics.
So, doing it for efficiency is a lost cause. There may be other reasons - such as supporting Javascript in a Lua-only environment, though even then if possible just writing Lua bindings to an existing Javascript interpreter would probably be less work.
If you want to have a play with a Javascript->Lua source-to-source translator, take a look at js2lua, which is a toy project I created some time back. It's not anywhere complete, but playing with it would certainly give some food for thought. It already includes a Javascript lexer, so that hard work is done already.

What subset of functional programming aspects and Lisp-like features does JavaScript provide?

Right to the point, in https://stackoverflow.com/questions/4696618/is-haskell-a-lisp?answertab=votes#tab-top, there is a comment by Kevin Cantu saying:
Yeah, moving beyond the syntax alone, JavaScript is probably more of
a Lisp than Haskell. (Originally conceived as a Scheme
implementation...)
Also, in Lambda the Ultimate: A Lisp to JavaScript Compiler in 100 Lines, they say:
It's immediately quite clear that JS and Lisp have strong ties at the
semantics level [...]
I am familiar with Lisp and functional programming, but not with JavaScript. So these propositions made wonder how powerful is JavaScript. What I've read so far is that it provides lambda expressions and closures. What more functional programming concepts and Lisp-like features does it provide? Does it provide, for instance, tail call recursion, or macros, or ability to manipulate code as data (like Lisp)?
Some things that JavaScript provides that can be considered "Lisp-like":
First class functions (inc. lambdas and closures)
Dynamic typing
Dynamic object model that has some similarities with CLOS
A readable data format that matches the source code format (JSON)
Run time evaluation with an "eval" function (that can be used in an interactive REPL)
Some things that Javascript doesn't have that are pretty common or central to other Lisps:
A homoiconic representation for both code and data (S-expressions)
Built in literals for linked lists / sequences
Support for immutable data structures in general (especially true for Clojure, where every data structure is persistent and immutable)
An extensive macro system for meta-programming
Optional static typing for performance optimisation (e.g. type hints in Common Lisp or Clojure)
Concurrency support
Tail call optimisation

Categories

Resources