I'm a computer science student and as part of a school projet I have been asked to either find an exploit in the v8 engine, make some really good optimisation or add a new feature.
I chose to add a new feature and here it is:
function* numbers() {
i = 1;
while (true) {
yield i++;
}
}
var gen = numbers();
var l = [...gen];
var n = l[42];
Putting it in words I want to have the possibility to use the destructuring syntax to create a list that can hold an infinite number of objects and access them.
It's possible to do it in Haskell and I want to try and do the same with JavaScript.
If of the developers at v8 could point me in the right direction it would be so great.
I already have a working environment, can compile the engine, read the source code, and run the debugger on the d8 binary file with symbols.
V8 developer here.
First off: just to be clear, stackoverflow is not a machine that does your homework. (You're only asking for "the right direction", that's okay.)
Secondly: V8 implements JavaScript as spec'ed, so any arbitrary "new feature" is not going to land in our repository, please be aware of that.
Thirdly: Keith has several good points. In particular, the syntax you propose is already valid JavaScript and eagerly evaluates the generator. Was your idea to switch to lazy evaluation iff the generator produces an infinite stream of values? Take a step back and think about the implications of that idea for a minute.
Finally, if you come up with workable syntax/semantics, then it'll still be a chunk of work to do this in V8, because there's no precedent of something similar. You'd probably want to use an elements interceptor, and store the generator in a private property. I think it would be much easier to polyfill the whole thing in pure JavaScript using a Proxy.
(It might be a good idea to reconsider your choice of project, but that's up to you. It's also quite a funky project description to begin with... what do they think how hard it is to "find an exploit or make some really good optimisation"? Do let us know if you find an exploit though!)
This question already has answers here:
When is JavaScript's eval() not evil?
(27 answers)
Closed 8 years ago.
I am building a little game and I've gotten to the point where I need to calculate data in the tips of abilities which is unique to each individual unit. So to do this I figured I'm gonna basically need a formula. I don't know if this is the way it's supposed to be done but here's what I've come up with
tip = 'Hurls a fire ball at your enemy, dealing [X] damage.';
formula = '5 * unit.magicPower * abilitylevel';
So for each unit's tool tip I use
tip.replace('[X]', eval(formula))
Which appears to work fine, but what I'm concerned about is the safety of this code. It hasn't been once or twice that I've seen people discouraging the use of it. Are there any potential issues that may occur with the way I'm using eval()?
As long as you control the input into eval, it's safe to use it. The concern comes in when you're using it to process input that you don't control. At that point, it becomes unsafe because it's a full JavaScript parser but people sometimes try to use it as just an expression evaluator (for instance, when parsing JSON from a source they don't control).
The other objection is that it's firing up a full JavaScript parser (and so in theory costly), but frankly unless you're doing this hundreds of thousands of times in a tight loop, it's not going to matter.
eval is very dangerous if any of the expression is supplied by the user. If you're constructing it entirely from built-in components, it's not very dangerous. However, there are still usually better ways of accomplishing it, such as calling closures.
The basic rule of thumb is to make sure that by default you pass your data/information through eval() only.
You can't stop someone with tools like Firebug if they want to mess with stuff obviously but that is what server-side validation is about.
Now if you're talking about server-side eval() then you really have to be careful. Unfortunately there are a lot of uncooperative people working on JavaScript and it's implementations in browsers so you'll be forced to use eval() in JavaScript, I've never had to use it in PHP.
I'm trying to understand what is asm.js and what does it do, and I am reading this article here, by Alon Zakai: What asm.js is and what asm.js isn't
He first talks about emscripten.js and explains that the pattern by which it compiles C++ to JS uses a singleton-typed array to make C++ feel at home in JS:
That pattern involves using a singleton typed array to represent
memory (p. 7)
I know what a singleton object is and what the 'singleton pattern' looks like in Javascript, but what is a singleton-typed array? A Google search came up with nothing.
EDIT: I also do understand what Emscripten does and that pattern in question of implicitly-typed, but statically-typed variables (i.e. variables' types don't change throughout runtime), but still, the wording "singleton typed array" is beyond me.
I got it. It's not "singleton-typed array", but "singleton typed-array". Bah. I find English to be a vague language at certain areas. Here you go, curious ones: Typed Arrays (MDN)
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.
Is ruby strongly or weakly typed ?
Presumably the same is true for Javascript.
Ruby is "strong typed".
Strong typing means an object's type (not in the OOP sense, but in a general sense) is checked before an operation requiring a certain type is executed on it.
Weak typed means that no checking is done to ensure that the operation can succeed on the object. (For example, when a function accesses a string like and array of floats, if no type checking is done then the operation is allowed)
Edit:
It's been 6 years since this answer was posted and I think it warrants some extra clarifications:
Over the years the notion that "type safety is a dial not an absolute" started to be used in favor of the binary meaning (yes/no)
Ruby is "stronger" typed (with an "er") than most typical dynamic languages. The fact that ruby requires explicit statements for conversion IE: Array("foo"), "42".to_i, Float(23), brings the Ruby typing dial closer to the "Strong Typed" end of spectrum than the "weak typed".
So I would say "Ruby is a stronger typed dynamic language than most common dynamic languages"
Wikpedia labels it as "dynamic ('duck') typed".
Regarding Pop's comment about it being "strong-typed" - I'm not sure his explanation actually fits with what goes on under the covers. The MRI doesn't really "check" to see if an operation can be performed on an object; it just sends the object the message, and if that object doesn't accept that message (either by a method declaration or by handling it in #method_missing) it barfs. If the runtime actually checked to make sure operations were possible, #method_missing wouldn't work.
Also, it should be noted that since everything in Ruby is an object (and I do mean everything), I'm not sure what he said about "not in an oo-sense" is accurate. In Ruby, you're either an object or a message.
While you can get into arguments about the definition of those term I'd say:
Ruby dynamically and strongly typed while JavaScript is dynamically and weakly typed.
IMHO Ruby is strongly but dynamically typed.
I would consider these languages duck typed.
The over-simplified answer is that both ruby and javascript are weakly typed.
However this question is not quite as clear-cut as it may seem - see this wikipedia article for a more in-depth discussion on the difference between strongly and weakly typed languages.
I just stumbled-on this old thread but thought it proper that I could offer my opinion. (No, I'm not "hijacking" a zombie-thread.)
My colloquial interpretation of the term "strongly typed™" specifically refers to "compile time." (Which is something that many languages today, including Ruby, "simply do not have.")
For instance, a simple assignment statement such as a = b; could be judged by the compiler to be acceptable or not, based on its assessment of the "types" of a and b, and based on provisions for type-conversion (if applicable) provided by the programmers. If the statement was judged unacceptable, a compile-time error would be thrown and no "executable" would ever be produced.
This notion, of course, is not compatible with the fundamental design precepts of languages such as Ruby, PHP, Perl, JavaScript, or a great many other languages that are in extremely-wide (and, extremely-successful) use today. (Mind you, I do not mean this as a "judgment" either for or against them. They are what they are, and they sure do bring home the bacon.)
Because these languages do not have a "compile time," to my(!) colloquialism they cannot be called, "strongly typed." They are obliged to make decisions at runtime which, by their design, could not have been made sooner.
(Also please note that I am specifically excluding from consideration the various "lint tools" that have emerged for this-or-that language in an effort to catch more bugs in advance. These are very useful, yes yes, but not the same thing.)
(I am also purposely excluding various excellent(!) tools that generate source-code in the various target-languages in question ... for the same reasons.)
And – I say once again – I am making a classification, not a judgment.