Monday, March 29, 2010

When we last left our hero…

He had finished writing an implementation of Hughes’ arrows in F# and  was dangling precariously over the concept of object-oriented design patterns in JavaScript.

I shall return to that eventually. (I think.) But, I have two major things that are going on in my coding life. One is translating an ASP.Net WebForms based website to ASP.Net MVC 2. The other is writing an IOC adapter for integrating Ninject into the FubuMVC framework.

Well, I’ll be talking about these things in the coming weeks. Plus, I’ll get back to that Javascript thing.

Wednesday, June 17, 2009

Design Patterns in Javascript: Part 1 Template Method

The Template Method pattern is good for time when you have an algorithm that is pretty stable except at a specific point. So if you have a task defined as :

var worker = {
doTask : function() {
while(!done){
this.doStep1();
this.doStep2();
this.doStep3();
}
return done;
},
done : false
};

So here we have our basic worker. All our workers repeatedly do 3 steps until done to complete task. Let’s define three different types of workers.


First let’s we will need to take care of a deficiency with Javascript prototypal inheritance model:


if (typeof (Object.create) !== 'function'){
Object.create = function (oldObject) {
function F() {}
F.prototype = oldObject;
return new F();
};
}

OK, on to the worker objects:


var oneTimer = Object.create(worker);
oneTimer.doStep1 = function() {
// Step 1...
};
oneTimer.doStep2 = function() {
// Step 2...
}
oneTimer.doStep3 = function() {
// Step 3...
this.done = true;
}

var twoTimer = Object.create(oneTimer);
twoTimer.times = 2;
twoTimer.doStep3 = function() {
// Step 3...
this.times--;
this.done = this.times === 0;
};

var tireless = Object.create(oneTimer);
tireless.doStep3 = function() {
// Infinite worker
this.done = false;
};

Now I can call the doTask of the worker object that I need. So if I, by some strange occurrence, need a tireless worker I’d do this:


tireless.doTask();


Not much to implement this pattern, is there? This is just like a C# or Java implementation where worker would be and abstract class.

Tuesday, June 16, 2009

Design Patterns in Javascript: Introduction

I have a bit of extra time on my hands right now so I decided to do a series on design patterns in Javascipt. I know some of you have probably heard rumors that Javascript is an object oriented language, right? Well, that is true.
Now some folks used to tell you that Javascript is not object-oriented. They'll probably say something like it's object-based. They'll reason that Javascript doesn't have true inheritance, encapsulation, or polymorphism. What these people really were (and some may still be) saying is that JS does not have class-based object oriented programming, natively. But, classes are not the only way to implement OOP. JS, Lua, and Perl implement OOP using prototypes.

Now since JS is an object-oriented language, we should find at least some of the GOF design patterns useful.

In the next post we will look at the Template Method pattern.

Sunday, March 1, 2009

A strange fight, indeed.

It was strange to see the cowboy coders and the artisan coders go at it. For those that don't know SO #38 sparked a discussion that has been brewing for some time now. You know you've seen it around the office. That guy who doesn't get why you'd waste your time on using factory pattern instead of a giant switch block to choose which derived classes you should use. Or the chick who is always waxing poetic about the virtues of the current standards. Well these two side have had at it.

The funny thing is that this whole argument about principles in software design/engineering/development/architecture/whatever you want to call it is because of one word, PRINCIPLE. What is a principle? A principle is a comprehensive and fundamental law, doctrine, or assumption. OK, so a principle is a law of some sort. And that is where a lot of people stop in the definition. But what about the other words in that list of possibilities. A doctrine is something that is taught or a set of strategies. An assumption is a fact or statement (as a proposition, axiom, postulate, or notion) taken for granted. Those other to choices don't seem as finite as a law.

OK that all fine, well, and good, but why was it such a big deal about five documents that are about 13 years old. Well, other than the misspoken and rescinded statement of one particular developers credentials, a lot of developer seem to resent being told that their programming doctrine is wrong. (Oops, there is that word again) But what they fell to realize is they them selves are the ones that assumed that it was being criticized. No where does it say you must follow these "principles". Even the author of the referenced papers does not say that you have to. He believes that if you are able to craft good, clean code by some other standards then by all means do so.

Well, one last thing. The word principle probably shouldn't have been used in naming these tenants. It was the authors artistic license to do so. It would seem he wanted to emphasize the importance of them. However, they are not principle in the commonly known sense of being a law. Rather, they are principles in that they are doctrine for a certain style of programming. If you don't subscribe to that style of programming then don't worry about them.

Robert C. Martin, the aforementioned author, has likened our craft to martial arts. You have different dojos, with different ways and motivations for doing what they do. Even in the same style, there are subtle differences. There are also differences in the way individual practitioners of approach the style. The true martial artist doesn't criticize other styles they except it as different. So I think that programmers, software developers, code monkeys, whomever put finger to key for the purpose of solving problems through logic should be able to accept the differences in coding style.

Sunday, September 28, 2008

A stab at Arrow, Part 3

Well I had an interesting breakthrough today. I got the |||, left, right, and +++ operators, uhmm, operational. The code is as follows

#light

type Arrow<'inp, 'out> (f:'inp ->; 'out) =
let func = f
member a.run x = func x

let arr f = new Arrow<'i,'o>(f)

let (>.>) (f:Arrow<'inp,'mid>) (g:Arrow<'mid,'out>) = arr (f.run >> g.run)

let (&.&) (f:Arrow<'b,'c>) (g:Arrow<'b,'d&>) = arr (fun i -> (f.run i, g.run i))

let first (f:Arrow<'a, 'b>) = arr (fun (i,x) -> ( f.run i, x))

let second (f:Arrow<'a, 'b>) =
let swap (x,y) = (y,x)
(arr swap) >.> (first f) >.> (arr swap)

let ( *.* ) (f:Arrow<'a,'b>) (g:Arrow<'c,'d>) = (first f) >.> (second g)

type either<'a, 'b> =
| Left of 'a
| Right of 'b

let ( |.| ) (f: Arrow<'a, 'c>) (g:Arrow<'b, 'c>) =
arr (fun x -> match x with
| Left a -> f.run a
| Right b -> g.run b
)

let left (f: Arrow&<'a,'b>) =
arr (
fun x -> match x with
| Left a -> Left (f.run a)
| Right a -> Right a
)

let
right (f: Arrow<'a, 'b>) =
let mirror = fun x -> match x with
| Left a -> Right a
| Right a -> Left a
(arr mirror) >.> left f >.> (arr mirror)
let ( +.+ ) (f: Arrow<'a,'b>) (g: Arrow<'c,'d>) = (left f) >.> (right g)





I have kind of gotten the loop combinator working, But it is a loop combinator combined with a delay function.

Well I guess next, it about time to explain some of this mess.

Monday, September 22, 2008

A bit of a snag

Well it seem that I have hit a bit of a snag in implementing the arrow combinators. I can't for the life of me figure out how to write the loop or the ( ||| ) combinator. The later is problem with my understanding of how to use the Choice type and discriminating unions. But with the former I am genuinely lost. Here is the Haskell signature for loop:

Class Arrow arr => ArrowLoop arr where
loop :: arr (a,c) (b,c) -> arr a b

So in F# that should be either:

val loop : Arrow<('a*'c),('b*'c)> -> Arrow<'a,'b>

or :

val loop: ArrowLoop<('a*'c),('b*'c)> -> Arrow<'a,'b>

Again in Haskell the loop combinator for functions is defined as:

instance ArrowLoop (->) where
loop f a = b
where (b,c) = f (a,c)

Now how would you implement that in F#?

Friday, September 12, 2008

A Stab at Hughes Arrows in F#

Well it's been awhile since I have posted. For one I 've been a bit bogged down with work. But that's another story that I might go into at a later date. What I wanted to blog about today is arrow. Some of you may be familiar with them. They are abstract constructs that can be very useful in things like animation or event driven programing. How did I go from Euler problems to abstract patterns?

Well it started with my love of video games. Since I like a lot I have hidden aspirations of being a game programmer. (Although to this date I have work only on one game which as far as I know never saw the light of day.) So I was looking into using functional programming techniques with game programming. (BTW there is an interesting journal here by a functional programmer.) So I started looking at animation. I came across an old paper about the Fran framework. It is based on the functional reactive (FR of Fran) programming. But that wasn't the interesting part. It is what this library spawned which is Yampa. Yampa makes extensive use of arrows. So my interest was piqued. I went to look for information on these arrows.

Through the use of the "Programming with Arrows" and "Directing JavaScript with Arrows", I was able to get a little bit of a hold on the concept of arrows. So with a dangerous amount of knowledge of arrows and F# I wrote this:


#light
module Arrow =
type Arrow<'inp, 'out> (f:'inp -> 'out) =
member a.run x = f x

let arr f = new Arrow<;'i,'o>(f)

let op_RightShift (f:Arrow<'inp,'mid>) (g:Arrow<'mid,'out>) =
arr (fun i -> g.run(f.run i))

let (&&&) (f:Arrow<'b,'c>;) (g:Arrow<'b,'d>) =
arr (fun i -> (f.run i, g.run i))

let first (f:Arrow<'a, 'b>) =
arr (fun (i,x) -> ( f.run i, x))

let second (f:Arrow<'a, 'b>) =
let swap (x,y) = (y,x)
(arr swap) >>> (first f) >>> (arr swap)

let ( *** ) (f:Arrow<'a,'b>) (g:Arrow<'c,'d>) =
(first f) >>> (second g)

I was surprised how quickly I was able to get this together. So what do you think? How can I improve it? What did I do wrong? All comments are welcome.