On Triangles

In SICP 1.2.2 Tree Recursion we have Exercise 1.12 which asks us to code up a recursive solution to compute the elements of Pascals Triangle. 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 Pascals Triangle has two rules - the numbers on the edge are 1 and the numbers inside the triangle is the sum of the two numbers in the previous row. A recursive solution is fairly simple : (in Clojure) (defn triangle [col row] (if (or (= col 0) (= col row)) 1 (+ (triangle (dec col) (dec row)) (triangle col (dec row))))) If the column is the first or the last one return 0 otherwise recurse up to get the two values in the prior row. »

Cond and friends

There are a number of different cond’s in Clojure. cond The classic cond. This replaces the standard if...else if....else that you find in other languages. It takes a set of test and expression pairs. For the first test that evaluates to true it will evaluate and return its corresponing expression. (cond (is-banana? me) "I am a banana" (is-slug? me) "I am a slug" :else "I am a turnip") => "I am a slug" cond-> Now cond short circuits - it will stop at the first true expression. »

Creating a plugin system in Angular JS with the $compile service

Angular JS directives are powerful. Using them allows you to manipulate pretty much everything in the DOM that you would want to. But there is one exception. Dynamically creating a directive depending on data received from the server, something often used for plugin systems. Luckily we can access the $compileProvider directly to work around these limitations. Plugins Say you are designing a plugin system. Each plugin is implemented as a different directive. »

Javascript Schönfinkeling

In Javascript is it extremely common to pass function as parameters to other functions. function addOne(a) { return a + 1; } [1,2,3,4].map(addOne); This is all good. However when your function takes more than one parameter, you can’t just pass the function directly so you need to create a new function which calls the original one: function add(a,b) { return a + b; } [1,2,3,4].map(function(a) { return add(a,1); }); This does work, but you do lose some expressiveness by doing so - the semantics of the code gets lost in the syntax. »

Studying the Angular JS Injector - loading modules

(This post is part of a series studying the AngularJS injector) A module gets loaded with the following code: function loadModules(modulesToLoad){ var runBlocks = [], moduleFn, invokeQueue, i, ii; forEach(modulesToLoad, function(module) { if (loadedModules.get(module)) return; loadedModules.put(module, true); try { if (isString(module)) { moduleFn = angularModule(module); runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks); for(invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) { var invokeArgs = invokeQueue[i], provider = providerInjector.get(invokeArgs[0]); provider[invokeArgs[1]].apply(provider, invokeArgs[2]); } } else if (isFunction(module)) { runBlocks.push(providerInjector.invoke(module)); } else if (isArray(module)) { runBlocks.push(providerInjector.invoke(module)); } else { assertArgFn(module, 'module'); } } catch (e) { if (isArray(module)) { module = module[module.length - 1]; } if (e.message && e.stack && e.stack.indexOf(e.message) == -1) { // Safari & FF's stack traces don't contain error.message content // unlike those of Chrome and IE // So if stack doesn't contain message, we create a new string that contains both. »

Studying the Angular JS Injector - the twin injectors

(This post is part of a series studying the AngularJS injector) When Angular creates the injector, it actually creates two injectors: providerInjector = (providerCache.$injector = createInternalInjector(providerCache, function() { throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- ')); })), instanceInjector = (instanceCache.$injector = createInternalInjector(instanceCache, function(servicename) { var provider = providerInjector.get(servicename + providerSuffix); return instanceInjector.invoke(provider.$get, provider); })); Two parameters are passed to the createInternalInjector function. The first is the cache to use to look up instances (a simple object). »

Studying the Angular JS Injector - getService

(This post is part of a series studying the AngularJS injector) The getService function is the work-horse of invoke. This is the method that takes a service name and attempts to locate it in the list of registered services. function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] === INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- ')); } return cache[serviceName]; } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } } When the injector is created it is passed two parameters, cache and factory. »

Studying the Angular JS Injector - invoke

(This post is part of a series studying the AngularJS injector) The invoke method invokes the given function with the parameters injected. function invoke(fn, self, locals){ var args = [], $inject = annotate(fn), length, i, key; for(i = 0, length = $inject.length; i < length; i++) { key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('itkn', 'Incorrect injection token! Expected service name as string, got {0}', key); } args.push( locals && locals.hasOwnProperty(key) ? »

Studying the Angular JS Injector - instantiate

(This post is part of a series studying the AngularJS injector) Whilst invoke calls a function with it’s parameters injected, instantiate will contruct a new object with it’s constructor parameters injected. instantiate gives us an excellent insight into how javascript objects work. In javascript, a class is just a function and an class instance is just a function that has been invoked with the new operator. Say we have a simple class : function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } We can add methods to this class via the functions prototype property. »

Studying the Angular JS Injector - annotate

(This post is part of a series studying the AngularJS injector) In order for the Injector to know what to inject into a given functions parameters, it needs a list of these parameters. This is what the annotate function does. There are three different ways in Angular to annotate your methods. Use an array. The last element of the array is the function, the rest is a list of the parameter names. »