Is there a way to enforce types in JavaScript? I'm thinking of a pre-processor which takes an input file written in ActionScript 3 or Java and converts it to JS.
I do not need a big run-time apparatus, I just need to introduce the idea of compile-time in my workflow and run the trivial compile-time checks on my code (and also use interfaces). Neither I need the API from Java or Flex, just the syntax.
The standard browser-functions could also be checked against the IDL definitions, but it is not a must.
Whilst I'm a little late to this party, I think it's definitely worth mentioning Dart (which is a Google product) and TypeScript (which is a Microsoft product).
JavaScript is fast becoming an extremely popular language as applications become more web based. However as you have pointed out, JavaScript lacks type safety, and to name a few other things; classes, interfaces and packages/namespaces/modules.
This is where Dart and TypeScript step in. These languages are essentially supersets of JavaScript. When you write Dart or TypeScript code, it is compiled into clean, standards compliant JavaScript.
The benefits of Dart and TypeScript are that they provide type safety, interfaces, classes etc. Thus allowing you to write cleaner, scalable, manageable applications, which still run in the browser.
Being a Microsoft oriented programmer, I've had a lot of experience with TypeScript, including being somewhat active in the development of the language (you can find information for TypeScript development at codeplex)
My only concern at the moment is that TypeScript is lacking in some fundamental features. It seems that some of the current implementation (0.9.0 alpha) has some equally gaping holes that might deter the savvy developer from using it at the moment (subject to change of course).
I cannot really comment on Dart, as I have only used this a few times, but my overall experience with Dart was good!
You should take a look at the haxe project.
Haxe is a very nice typed language that uses type inference (i.e. you're not forced to write a lot of type declarations) but that enforces type correctness at compile time.
The language has a javascript-like syntax and the compiler can generate code for the neko virtual machine, for javascript, as3, c++ or PHP.
Update
Today the most popular choice is probably Typescript, a superset of Javascript that allows optional type declarations that are enforced compile time.
GWT does what looking for, but its a way oversized for the most cases. You could take a look at googles closure framework which fakes the typed safe with anotations
There are many statically-typed languages that are designed with the specific goal of compiling down to JavaScript (the so-called assembly of the web):
Flow by Facebook
Dart by Google
TypeScript by Microsoft
JXS by DeNA
While typeof will return 'object' for every object or array, you can use the instanceof statement. Say you have a class Person, and want to see whether the object passed to your function is a Person, you can do this:
function someFunc(person){
if(! person instanceof Person)
throw('argument needs to be an instance of Person.');
/* ... do your stuff ... */
}
If you just want to make sure a variable is the number 3 instead of a string '3', you only need to use === instead of ==:
if( var === 3 ){
/* ... do your stuff ... */
}
I agreed that Javascript is a beautiful language, with some glaring holes, the worst and most unremarked of which is the absence of static type-safety.
As eskimoblood pointed out, there are some half-measures in the form of GWT and Closure but the right answer, imo, is Scala, which combines Javascript's flexibility and expressive power with a type system much better than Java's -- or that would be the right answer except that the Scala-GWT project seems to have gotten bogged down.
For now, we wait...
Infernu is a type-safe subset of JavaScript. It doesn't compile into JavaScript - it can run as-is in your browser! The type checker supports full type inference, so no type annotations are needed (in the future they will be supported for documentation and for deliberate distinction between structurally identical types). It isn't ready yet for usage, but a work in progress.
Here's a lightweight typesafe function wrapper for nodejs/browser:
https://www.npmjs.com/package/typeshave
Its 3.9K gzipped, supports jsonschema, and works pretty much everywhere. So:
foo = function(bar){
}
could be rewritten like so:
foo = typesafe({
bar: { type: "object" }
}, function(bar){
}
Or just wrapped later on, including validating deepnested structures, and optional args:
foo = typesafe({
bar: {
type: "object",
required: true,
properties: {
foo: { type: "string", required:true },
items: [{
type: "integer"
}]
}
}
}, foo );
foo({ foo: "helloworld", items:[1,2,3] });
It looks less noisy in coffeescript imho
Related
is it possible to create your own condition/control flow syntax in js? for example:
when( condition ) {
// execute code
}
this would add some sort of listener to a variable/object and execute whenever the condition is true.
I may just have to create my own programming language.
This is actually two questions:
Can syntax be added to JavaScript directly?
Can I set up code that runs when a condition changes?
The answer to the first is no. You can use preprocessing like sweet.js macros to accomplish that but its non-trivial.
The answer to 2 is yes, you can accomplish this in any ES 5 compliant environment (IE 9+):
var condition = {val: null};
Object.defineProperty(condition, "isTrue", {
set: function(val) {
if (val && !this.val) {
runSomeCodeYouWantRun();
}
this.val = val;
},
get: function() {
return this.val;
}
});
So whenever any code changes condition.isTrue the specified code will be run if the change is truthy. But for situations like this I prefer less ad-hoc approach. ES 2015 Proxy traps make this much cleaner (IMHO) but support isn't quite there yet. What you really are looking for here to get the job done today is an Observable.
Also note that writing a language to solve a problem like this is roughly equivalent to building a car out of spare parts to drive to the store for groceries. Just buy a car.
Welcome to the wonderful world of JavaScript transpilers.
JavaScript in and of itself does not have any utilities for creating your own syntax. In response to this, many tools exist online and in the NPM repositories that add just this sort of feature to JS by translating it to browser-compatible JavaScript. Here's a small sampling:
Babel.js adds ES6 syntax to ES5 JavaScript
Browserify adds Node.JS's require() functionality
Uglify.JS compresses JS into the smallest form possible that will still execute the same way
TypeScript (while more technically its own language) adds static type-checking to JavaScript
All of these transpilers, however different, all work the same way: they parse the source file(s) to an abstract syntax tree (or AST), run some transformations on that tree, and then spit out the resulting JavaScript file. If you wanted to create your own special syntax in JavaScript, you would do more or less the same thing. (Uglify.JS stands out as being particularly customizable in this regard).
All of that said, none of these transpilers fundamentally change the way that JavaScript works - you still have to translate whatever fancy syntax you want to use into plain, browser-executable JavaScript. This means that although you will be able to write your when(){} block syntax, the expression inside the parentheses cannot be a simple Boolean expression, but must involve something like an Observable object that inserts a callback (Knockout.JS does have a tool for doing this out of an expression built from its Observables).
I'm building my first open-source JavaScript library as a node module, it's solving a very simple problem and thus it's a very simple module, specifically, it is a single prototype object.
To offer context, I'm from a purely web-tech background and only in the past year have I started to look into other languages, falling in love with statically typed, truly OOP and class-oriented languages and I'm beginning to see the breadth of pros and cons for the languages on either side of the camp.
As far as I understand, when constructing a class with class-oriented you should return nil to specify that construction has failed allowing a user to check with if(instance === nil) for it's success. Alternatively I've seen return 421 for example to provide an error code, I then also assume some also return string e.t.c. But importantly, I've seen that you shouldn't throw an exception.
Is this correct? Also what are the reasons for that? Is this also a problem with prototype-oriented languages or does javascript's dynamic nature make it acceptable?
This leads onto my next question, I've seen a lot of javascript libraries over the years, had a tinker and whatnot. I've found that it's rare to not only to build prototypes in an OOP-ish pattern but it's also rare to come across any frequently implemented type detection or type checking, many people are relying on the convenience of the dynamic typing to offer that productivity boost, but I'd like to mix up the pros and cons of each type system by starting with dynamically typed but also introduce a more stable architecture using some statically typed patterns and methodologies.
To get to the point, is it an acceptable (or even good?) practice to heavily type check javascript scripts? I would love to add serious type checking code to my prototypes constructor and methods but as it's an open-source project I'm worried how the community will approach it, would they want it to be more dynamically typed? I can only assume many people use dynamically typed languages for their... uhh.. dynamic typing, but its worth a ponder.
DISCLAIMER
I understand have seen that many people say javascript is "untyped" rather than "dynamically" typed, but using dynamic purely for its proliferation.
TLDR-Q1: Can I throw exceptions in constructor methods? What about in javascript prototypes? Why!? How should I handle it?
TLDR-Q2: Can I introduce heavy type checking and throw exceptions to give javascript scripts a poor mans static type? Do developers like this? Am I being ignorant and this a really common thing?
TLDR-Q1: Can I throw exceptions in constructor methods? What about in
javascript prototypes? Why!? How should I handle it?
Yes, you can throw exceptions in a constructor. If truly invalid arguments have been passed, then that is probably the cleanest way to do things.
I, myself, would not generally design an expected path of the code to throw an exception, but would instead reserve it for the type of error that probably signifies bad data or wrong usage by the programmer. Exceptions get logged nice and cleanly in the debug console and are one of the quickest ways to communicate to someone using your constructor that they've messed up as it will get logged and you can put a nice descriptive message in the error object when you throw and the developer gets a stack trace.
Returning null is not such a clean or helpful way and adds code the developer probably doesn't normally need to check for null all the time.
TLDR-Q2: Can I introduce heavy type checking and throw exceptions to
give javascript scripts a poor mans static type? Do developers like
this? Am I being ignorant and this a really common thing?
You can write Javascript type checking as much as you need. IMO, you should only do so when you're trying to determine if an argument passed in is valid or not. If you need a string and the developer passes in a number and a numeric string is a reasonable input for the function, then I don't see why you should not just use Javascript's string conversion automatically and let things go.
Javascript developers like type checking when it helps them identify a mistake they've made. Javascript developers don't like type checking when it's just being pedantic and an auto or explicit type-conversion would have worked just fine.
Also keep in mind that you should rarely insist that a passed object is a particular type of object (say using instanceof) because it should be perfectly valid to pass any object that works like the expected object. For example, a promise in Javascript can pretty much be any object that has the desired methods that follow the proper specification. It does not have to be one particular type of object class with one particular constructor.
Javascript isn't a strongly typed language and there really is no reason to try to make it behave like it is something that it isn't. Check types when that's required for the proper operation of your code, not because you're trying to make Javascript behave as strictly as Java. I wouldn't suggest adding type checking just because you think all languages should have type checking. If that's your line of thinking, then perhaps you should write in TypeScript or something like that that adds type specification to the language.
You can extend native objects in javascript. For example, sugar.js extends Array, String, and Function among other things. Native-object extensions can be very useful, but inherently break encapsulation - ie if someone uses the same extension name (overwriting another extension) things will break.
It would be incredibly nice if you could extend objects for a particular scope. E.g. being able to do something like this in node.js:
// myExtension1.js
Object.prototype.x = 5
exports.speak = function() {
var six = ({}.x+1)
console.log("6 equals: "+six)
}
// myExtension2.js
Object.prototype.x = 20
exports.speak = function() {
var twenty1 = ({}.x+1)
console.log("21 equals: "+twenty1)
}
and have this work right:
// test.js
var one = require('myExtension1')
var two = require('myExtension2')
one.speak(); // 6 equals: 6
two.speak(); // 21 equals: 21
Of course in reality, this will print out "6 equals: 21" for the first one.
Is there any way, via any mechanism, to do something where this is possible? The mechanisms I'm interesting in hearing about include:
Pure javascript
Node.js
C++ extensions to Node.js
Unfortunately you cannot do that currently in node, because node shares the same built-in objects across modules.
This is bad because it could brings to unexpected side effects, like it happened in the browsers history in the past, and that's why now everyone is yelling "don't extend built-in object".
Other commonJS environment are following more the original commonJS specs, so that you do not share built-in object, but every module has its own. For instance in jetpack, the Mozilla SDK to build Firefox's add-on, it works in this way: so you the built-in objects are per module and if you extend one you can't clash.
Anyway, in general I believe that extending built-in object nowadays is not really necessary and should be avoided.
This is not possible since a native type only has a single source for its prototype. In general I would discourage mucking with the prototype of native types. Not only are you limiting your portability (as you pointed out), but you may also be unknowingly overwriting existing properties or future properties. This also creates a lot of "magic" in your code that a future maintainer will have a hard time tracking down. The only real exception to this rule is polyfils. If your environment has not implemented a new feature yet then a polyfil can provide you this.
I've recently been playing with the awesome tool from google that does some code-optimization and partial execution, for instance it would take something like:
//Just an alias for an elementByID selector
function $(bar){
return document.getElementById(bar);
}
//Call the selector
alert($("foo").value);
And shorten it into alert(document.getElementById("foo").value);, which is fairly awesome from an optimization viewpoint.
I'm only explaining this because I would have thought this concept works for larger libraries such as jQuery, which basically attempts to abstract away a bunch of things JavaScript does, like select by IDs.
In a quick test, I loaded the whole jQuery production file up to the compiler and appended a single bit of text at the end of it: alert($("#foo").val());
And quite tragically, the compiler wasn't able to map through jQuery's design and result with the simple example I had above, but rather my output is about 85kb of text with alert($("#foo").K()); stuck on the end. Basically, I just have minified code, and didn't take advantage of the awesome feature demonstrated above.
So my question is, if I do end up using a library, how can I code in such a way that closure compiler is able to simplify my code to it's native JS (or something more effective than 85kb of unused code)? Alternatively, what design should someone take if they wanted to make a small library that plays nice?
AFAIK, jQuery is not (yet) written to be optimized by the Closure Compiler's Advanced Mode. It has an "externs" file which will enable its public properties and classes not to be renamed, but it does not enable most of the optimizations (e.g. dead code removal) as you've discovered. Which is quite a pity, because the jQuery object, if property written, does lends itself quite readily and nicely to the Closure Compiler's prototype virtualization feature.
Slightly off-topic
If you are not tied to jQuery, you may consider the Dojo Toolkit, which can be modified to be used with the Closure Compiler while enabling most optimizations (especially dead-code removal).
See this document for details.
jQuery takes special pains to minify itself and in the process makes itself opaque to the Closure Compiler.
Closure Library is an example of a library that is written to make good use of the Closure Compiler.
Generally, the compiler does best with prototype inheritance and simple structures:
/** #constructor */
function Class () {}
Class.prototype.f = function() {};
With an explicitly exported interface:
window['MyLib'] = { 'method', method };
Generally, advanced mode only makes sense for a library if it has a small external interface relative to the amount of internal code. However, I definitely would encourage writing your library so that it can be consumed by an advanced mode compiled project (this requires separating out the export used when it is used as a stand-alone library, if they library itself is minified using advanced mode).
I know both languages are from the same ECMA-262 standard. It seems that the two are becoming very similar with JavaScript adding event listeners for core Object instances through methods like freeze and seal in EMCAScript-262 5th edition and such. I was wondering what the differences are?
First of all ActionScript 3 and JavaScript are both defined in ECMA-262 so they have a lot in common. Both languages feature prototype inheritance for instance. It is however not correct that ActionScript fully implements ES4.
ActionScript implements a couple of features that are not defined in ECMA-262 and some -- but definitely not all -- of ES4.
So what does AS3 add to ECMA-262? Those are also the differences to JavaScript:
Dynamically and statically typed code
Packages, Classes and Interfaces
Standard OO inheritance model (not prototype based, statically typed)
uint and int datatype
E4X (ECMA-357)
Type-safe conditional compilation (ES4)
Vector.<T> datatype (ES4)
Maybe I have forgotten some features. I am not sure if XML, XMLList etc. are already defined in 262 or came with 357.
The key difference however is the standard library. JavaScript comes with a couple of predefined classes like DOMElement and browser dependent additions. ActionScript has a fairly large standard library with features like video streaming and is consistent over all platforms.
I've been programming in both ActionScript and Javascript, and from a less-technical standpoint, I see two main differences.
1) JavaScript is more powerful. You are allowed to do much more with the language because it does not have a "compiler" or types. There are some great frameworks out there like ExtJS and jQuery that try and simplify things for you, but even with them, you are really allowed to do an amazing amount of damage if you want to.
2) ActionScript is much more confining and hence, much easier to maintain. Adobe did a lot of work to keep you out of the difficult parts of ECMAScript. ECMAScript Objects, prototypal inheritance, and closures are three concepts that you really don't need to understand to program in ActionScript. You just need to understand how to use Adobe's "Class" object.
For simple uses, I prefer JavaScript. However, once the project gets large, it depends who you are coding for. If I had a team of 5 developers programming at a scrappy start-up, I'd choose JavaScript in a heartbeat. However, in the girth of a large corporation, or academia, you might be safer relying on Adobe's platform.
Hope that helps.
One is type Safetly. Actionscript requires that you set a type for all objects, and JavaScript doesn't (for that matter, in JavaScript, one variable may be one type and then immediately set to another type).
Actionscript is object oriented. Although you can sort of have this in JavaScript, Actionscript allows for object inheritance, etc.
Essentially the main difference I find is that ActionScript is more a verbose statically-typed class-based language where as javascript is a prototypal language.
Unfortunately there is no type-inference in ActionScript so using Flex Builder gives a warning every time you leave something untyped which I find unnecessary and overly verbose, not only does it make it more verbose than javascript but I find equivalent code to be more verbose than C#.
However the extra verbosity does have yield perf improvements and extra type safety at compile-time. Unfortunately this also adds to build time quite significantly, in Java Script apps of any size I'm used to instant feedback whereas my last ActionScript project had build time exceeding 2 minutes.
From a developer point of view, what matter most:
1) Javascript is not really OOP, it has NO super keyword, which means if you override( by any means ) something, you can't call it through super, and this is the deal breaker for complex programs for which OOP is the key, and Actionscript3 is all OOP, you can have millions line of Actionscript3 code working together, and well maintained.
2) Actionscript3 runs in Flash Player which has only one implementation from Adobe, this means it's consistent all the time, all browsers( as long as installed Flash Player), but Javascript runs in browsers directly, but each browser has its own implementation, which means your Javascript code has to be tested against all targeted browsers to ensure working.
The key differences are that ActionScript 3 supports both class-based inheritance and prototypal inheritance, enforces namespace bindings between class names and file names, and does not support some global JavaScript methods such as eval. Fortunately, you can do several things to bridge the gap.
You can globally set the namespace using ES for ECMAScript or AS3 for ActionScript 3:
use namespace ES;
use namespace AS3;
If you are using the AS3 namespace, any method override must use the AS3 namespace
and the override attribute.
If you are not using the AS3 namespace, you can use the prototype methods and propertyIsEnumerable.
You can selectively use the AS3 namespace version of a property or method in a dynamic function:
var nums:Array = new Array(1, 2, 3);
nums.AS3::pop();
trace(nums); // output: 1,2
To turn off class based inheritance, you can also use the following compiler options:
compc -as3=false -strict=false -es=true
import *
class foo
{
dynamic function foo()
{
}
}
If you do not use the AS3 namespace, an instance of a core class inherits
the properties and methods defined on the prototype object.
If you decide to use the AS3 namespace, an instance of a core class inherits the
properties and methods defined in the class definition.
Here is a common features between ECMAScript-4 and ECMAScript-2017 or later:
Feature ES4/ES6+ ES4 Only
Rest parameter ☑
Destructuring ☑
ByteArrays ☑
Class ☑
Interface ☑
Static fields ☑
Parameter default ☑
Rest Parameters ☑
Bound methods ☑
dynamic this value ☑
multiple catch clauses ☑
short-circuit-and (&&=) ☑
short-circuit-or (||=) ☑
Type Annotations ☑
References
Simulating AS3 language features in JavaScript using AMD and ES5
JavaScript 2 Draft
ECMAScript 4th Edition[proposed]:Predefined Types and Objects
The New Browser War
ECMAScript 1-on-1
The Trouble with JavaScript: JavaScript has no Class
What's New in ECMAScript-4
David Flanagan on JavaScript 2
JavaScript 2 and the Future of the Web
Writing Classes
Faster byte array operations with ASC2
Managing event listeners
frankly it's not the same, cuz action script is loaded with EMQJ24, the new language for high development website. while JS still with it EMCA22, the difference between those are the style and format of the code. and also action script are ages enough, that's why most of programmer nowdays using CSX01 updated language from cSS,it can recognize all type off language without any line.