In clojure, (var some-function) and #'some-function are equivalent.
What is the clojurescript equivalent of var?
ClojureScript also has var as a special form. And, in ClojureScript (var foo) and #'foo are equivalent.
Having said that, ClojureScript's var is a bit limited compared to Clojure:
Vars are not reified at runtime. When the compiler encounters the var special form it emits a Var instance reflecting compile time metadata. (This satisfies many common static use cases.)
(Taken from Differences from Clojure.)
Related
I have heard that ES6 now finally permits subclassing Array. Here's an example given by
class Stack extends Array {
constructor() { super() }
top() { return this[this.length - 1]; }
}
var s = new Stack();
s.push("world");
s.push("hello");
console.log(s.top()); // "hello"
console.log(s.length); // 2
Sure, that works. But in Traceur at least, setting the length explicitly does not truncate the array. And when printing via console.log, the output is in object form rather than array form, suggesting that somebody is not looking at it as a "real" array.
Is this a problem with how Traceur implements subclassing built-in objects, or a limitation of ES6?
Long answer
In the normal case, the subclassing in Ecmascript 6 is just syntactic sugaring, so it still does the prototypical chaining that Ecmascript 5 does. This means that extending types in Traceur is in most cases exactly the same as extending in "real" ecmascript 6.
Array instances are special – the ECMAScript 6 specification calls them exotic. Their handling of the property length can’t be replicated via normal JavaScript. If you invoke your constructor then an instance of Stack is created, not an exotic object (exotic is actually the official name in the ES6 spec).
But do not despair, the solution is not provided by the class extends sugaring itself, but by the (re)introduction of the __proto__ property.
The solution
Ecmascript 6 reintroduces the writable __proto__ property. It was once only available on Firefox and was deprecated, but is now back in full force in ES6. This means that you can create a real array and then "upgrade" it to your custom class.
So now you can do the following:
function Stack(len) {
var inst = new Array(len);
inst.__proto__ = Stack.prototype;
return inst;
}
Stack.prototype = Object.create(Array.prototype);
Short answer
So subclassing should work in ES6. You might have to use the __proto__ trick manually if they have not manage to sugar the process using the new class extends syntax with some yet undisclosed trickery. You will not be able to use the transpilers such as Traceur and Typescript to accomplish this in ES5, but you might be able to use the code above in ES5 using Firefox that (as far as I remember) have supported __proto__ for quite some time.
The problem is that you are overriding the constructor. If you remove your constructor () { super(); }, your example works perfectly, including s.length = 0 truncating the array.
I'm relatively new to ClojureScript and having never worked in a lisp-like language before, I must say that the documentation is rather... lacking. I just want to transform the following JavaScript statement into ClojureScript:
var obj = new namespace1.namespace2.SomeObject();
I know that you can create new instances of an object in cljs by writing something like
(SomeObject.)
but trying
(def obj (namespace1/namespace2/SomeObject.))
didn't compile. What should I be doing instead?
Have a look at this answer, it is exactly the same question:
https://stackoverflow.com/a/23653459/1400662
Pasted here:
Using js/a.b.c.d is a bad practice and is likely to break in future versions of the compiler (because it is not a clojure compatible version of interop from what I know)
The good way would be:
(def LatLng (.. js/google -maps -LatLng))
(LatLng. 100 100)
According to documentation (https://developers.google.com/closure/compiler/docs/api-tutorial3#externs), it seems the closure compiler should rename variables when no external declaration exists, including when using functions/variables from an external bit of code. The example they give is
function makeNoteDom(noteTitle, noteContent, noteContainer) {
// Create DOM structure to represent the note.
var headerElement = textDiv(noteTitle);
var contentElement = textDiv(noteContent);
...
}
where the textDiv function is declared in the global scope by a third-party lib of some sort. It says textDiv should be declared external to prevent renaming.
My question is - when I put this code or similar into the Closure Compiler without any extern declarations why is textDiv not renamed (which would break the code), as the documentation indicates?
The compiler assumes that calls to an undefined function are in fact calls to an external functions. Using the command line compiler, you can use --warning_level VERBOSE to have the compiler treat this condition as an error.
The Web Application is primarily built for demos and assumes this by default. While you can set a VERBOSE warning level, it will not change this functionality. See the Additional Web Service Options page for information on options. I've filed a bug report about this.
Due to the renaming algorithm for properties, undeclared properties will be renamed in a breaking way if that same property name isn't declared on an object in externs.
I have been trying to figure out the best way to write GAS libraries for a while now but I have a hart time figuring it out. I read Douglas Crockford's - Javascript: The good parts and I'm trying to implement these lessons in GAS. Every imported library adds global variable to your project (of the ScriptModule type), so the modular design pattern seems like a good place to start. Borrowing from the article I linked to such a pattern might look like this:
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
}());
This module could then be called like this:
var module = LibName.MODULE;
var property = module.moduleProperty; // 1
var method = module.moduleMethod; // ...
From what I gather it is best have as few global variables as possible, so the general advice seems to be to save everything in one global variable. So the naming convention should then look something like this: LibName.PROJECT_NAME, where project name is the name of your single global variable which holds a module with everything else.
My goal here is to design secure, non-conflicting libraries. Am I right to use this design pattern? Has anyone developed their own robust design patterns for GAS libraries yet?
When you import a script as a library in GAS a new "namespace" is already created for it, so there's no need or gain in creating another one yourself. You'd have have to "deference" it, like you did:
//there's no purpose for this
var module = LibName.MODULE;
var method = module.method;
//comparing if you write code directly on the library
var method1 = LibName.method1;
GAS is not client-side javascript, most of things you learn don't really apply to Apps Script, e.g. there's no DOM, no namespace conflict, no browser compatibility issues, etc.
By the way, I don't think this object nesting structure even works on Apps Script libraries.
Mootools classes have an initialize() method that's called when a new object is instantiated.
It seems that setup() is a commonly used method as well.
Most classes I've observed call this.setup() from initialize() and nowhere else, which has left me wondering:
What's the purpose of setup()? Why not just put the setup() code in initialize()? When does it make sense to use a setup() method?
as oskar says, there's no benefit to using that very name. If you wanted to, you could only use a single initialize function with a bunch of anonymous functions within and events but it does not make for very easy code to read, extend and maintain.
i tend to use methods like this.setupScene() and this.attachEvents() to abstract different actions. within these methods, i tend to loop through items and call smaller pseudo-private methods that do the singular dom manipulation required or element.addEvent, aka, this.elements.each(function(el) { this._attachEvent(el, "something"); }, this);
If you are sharing code with other users, there are certain conventions most mootools authors try to adhere to when releasing plugins or contributing to the core and more forks.
for example, if the class relates to an element or an array of elements, always set this.element = document.id(el); etc.
for reference on best practices: http://ryanflorence.com/11-tips-for-creating-great-mootools-plugins/
or even http://davidwalsh.name/mootools-class-tips
after a while, they start making perfect sense and will help you tremendously in your work.
There is no benefit whatsoever in using a setup/build/whatever function that is only called from the initialize function of a mootools Class.
I guess the distinction comes from languages where you don't have variable function arguments but rather overload function names with different sets of arguments. Like Java.
In Java this makes perfect sense. When you have multiple constructors that differ in the arguments they accept, then you handle the argument specific operations in your constructor and the common stuff, that every constructor needs to call in a method that is called by all constructors.
Personally I don't make this distinction in my mootools Classes, but rather only outsource functionality in its own function, if there is need to reuse the code from another function.
Don't get confused by setup functions, there is no hidden power to them.
setup is not a private MooTools method. It's not going to do anything until you create an actual method named this way.
There's one instance of this method in MooTools-more, and it's nothing beyond a simple keyword, just like createDefaults() or setInitialStuff() would be.
Keep in mind that MooTools classes are all about extending and reusing existing code. When you extend a class, you might want to change the initialization, but not the setup code. Of course you can run the parent initializer by using this.parent(), but that might introduce unwanted side-effects.
Take this (very simple) example (view live):
var Counter = new Class({
initialize: function(i){
this.i = i;
this.setup();
},
setup: function(){
new Element('p', {
'text': this.i
}).inject(document.body);
}
});
var MultiplyCounter = new Class({
Extends: Counter,
initialize: function(i){
this.i = i * 2;
this.setup();
}
});
new Counter(5);
new MultiplyCounter(5);
The extended class only changes the initialization of i, not the whole implementation of the class. For more complex classes, this creates faster (initialization is only run once) and cleaner (divide and conquer) code.