Tech Ed Australia is over for another year and my brain is bubbling away with all sorts of stuff:
• Users rarely appreciate stuff happening on screen that they didn’t initiate. If they didn’t click on it, they probably didn’t want it to change. Something to keep in mind next time you’re adding the next batch of enhanced CSS “functionality” to your web site.
• PhotoSynth is so very much more than I gave it credit for previously. Don’t think photo viewer. Think Metaverse.
• REPL is coming back into fashion again. Cool.
• The demo gods are rarely kind to those who don’t pay proper respect.
• What is the exact value of an email address without a relationship to support it?
• If you’re an IT admin for medium to large business and you don’t have a toolkit and some policies in place for dealing with forensic investigation then you’re signing yourself up for a whole world of hurt at some point in the not too distant future. Get educated on the subject and sleep a little easier at night. To quote the Texan “The job you save may very well be your own”
• Bring on CardSpace!
• Seemingly few people realise how little time an hour really is when you’re doing the speaking instead of the listening.
• You haven’t downloaded the .Net Micro Framework yet? Are you insane?
• Windows Mobile... umm... okay... well I suppose there’s always next year... or maybe the year after that.
• Developers are not users. Believing users think the same as you is just a good way of really annoying everyone involved. Test and retest *every* assumption that you make about your users.
• I feel so very sorry for anyone who has to listen to my voice. It’s just so freakingly annoying.
• Ruby’s “Method Missing” functionality is so very very cool. I want the same ability in all the languages I use.
• The browser “Back” button means “Undo” to a significant number of users... not “Previous page”. I’d suggest stopping to think about that for a few minutes. Feeling nauseous yet?
• The business world really needs to start looking its game and movie producing peers. They’re doing a lot of cool stuff (outside of the pretty graphics) that could really make a big difference to how a lot of software is produced.
• The TED conference keeps on demonstrating why it’s *the* conference to attend. If it’s hip, new and funky, there’s a good chance it’s already been shown at TED. Go to Tech Ed to find out what you can you do today. Go to TED to find out what you'll being doing tomorrow.
A few more hours and my Scheme’ish interpreter has gained the ability to make decisions:
>(define (abs x)
(if (< x 0)
(- x)
x))
>abs -5
5
Followed shortly by:
>(define (abs x)
(cond ((< x 0) (- x))
(else x)))
> abs -5
5
And just to show off:
>(define (p) (p))
>(define (test x y)
(if (= x 0)
0
y))
>(test 0 (p))
0
For those who don’t feel stretching their brains with trying to work out what the deal is with the last example: it’s an example of how the interpreter holds off evaluation until the last possible moment. (Known in Functional circles as applicative-order evaluation ...as opposed to the initially more simplistic substitution strategy known as normal-order evaluation).
If my interpreter has adopted a simple substitution plan and attempted to evaluate both outcomes of the ‘if’ condition straight away then it stood a good chance of getting into an endless loop of asking what ‘p’ is, answering back with ‘p’ and repeating ad infinitum.
All of this was leading up to the majestic:
>(define (square x) (* x x))
>(define (sum-of-squares x y)
(+ (square x) (square y)))
>(define (abs x)
(if (< x 0)
(- x)
x))
>(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x)))
>(define (improve guess x)
(average guess (/ x guess)))
>(define (average x y)
(/ (+ x y) 2))
>(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
>(define (sqrt x)
(sqrt-iter 1.0 x))
>(sqrt 9)
3.00009155413138
Newton would be so proud.
Of course all of this didn’t work first go. I discovered surprisingly late in the process, for example, that my method of parameter substitution was merely a thin facade of rubber bands, chewing gum and old tissue paper.
The test that revealed this most clearly was:
>define (bob x) (* x x)
>define (jane x) (bob (bob x) (bob x))
>define (jack x) (jane (jane x) (jane x))
>jack 5
152587890625
If the interpreter can’t distinguish between the various ‘x’ parameters when evaluating the ‘jack’ procedure then the chances of it arriving at the right answer are remote to say the least.
So where to go from here?
Well I’m thinking adding the ability to read from a file wouldn’t hurt as continually testing manually through copy and pasting from notepad feels way too much like work. I really would like to return to my comfort zone of being able to slowly build up a library of automated unit tests as I go along.
The next stop mentioned in the book is that of internal and block definitions.
Basically it’s the ability to place definitions in the middle of any other definition / evaluation so that instead of the half dozen separate definitions required for Newton’s square root , for example, we can amalgamate it into one big definition:
>(define (sqrt x)
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(sqrt-iter 1.0 x))
Why would we want to do this?
The main reason for me is that we don’t pollute the wider namespace with procedures such as ‘good-enough?’ and ‘improve’. In this way, we don’t need to worry about other procedures accidently overwriting or being overwritten by our unimaginative naming choices.
I doubt implementing internal definitions will require any significant changes to my code’s logic... although it may force some slightly painful refactoring as I drag my essentially hardcoded definition handling code into a more... dynamic... world.
Recently I was inspired by Craig Andera’s recent post to start playing with Lisp’s smaller and cuter sibling: Scheme... or more correctly I was inspired to attempt to write my own functional language that’s loosely based off Scheme.
(This is about the third occasion where I’ve been inspired to write a whole swag of code from one of Craig’s blog posts. Must be the soothing choice of green background by the Pluralsight guys or something)
Outside of my usual strange attraction towards writing compilers and interpreters, this project should hopefully let me play around with a few other ideas that have percolating in the old brain recently:
• Concurrency - One of the ways to deal with hitting the physical limits of processing speed is to “scale out” to across multiple cores. The catch is that thread concurrency becomes a whole lot more difficult to manage. Joel has a nice write up of the issue so I’ll just cut to the chase and say that functional languages look like they might provide some of the answers on how to solve such issues.
• Map / Reduce - The process at Google’s heart (and also mentioned as possible strategy for the aforementioned concurrency issues). Ever since reading Google’s whitepapers on the subject, I’ve been itching to explore problem domains that can be solved using a Map / Reduce process. While it’s more than possible to do it C#, I wouldn’t mind trying my hand at achieving it in something a little closer to the language that inspired it in the first place.
• DLR - Microsoft’s new support library for dynamic languages in .Net. It’s the exciting new kid on the block that’s ushering a few favourites and I want to see what makes it tick.
Having a look at one of the one of the seminal works on the subject, you’d swear writing a Scheme interpreter is ridiculously easy and something that most people would tackle successfully just after completing the much loved “Hello World” application.
Apparently I’m a little dumber than I thought.
It’s actually taken me quite a while to stumble upon an architecture that works... and I think most of my issues came about not so much from my choice of architecture but more from my choice of development strategy.
For a long time, I was attempting to write the compiler with a top down approach. i.e. Start by writing the high level stuff and slowly drill down into each problem area until a working compiler / interpreter arose from the dust.
The catch with this approach is that I ended biting off more than I could metaphorically chew.
Before I knew it I was knee deep in type conversions, late binding confusion and op codes... without actually getting any closer to my intended goal.
So last night I shifted strategies and took the same approach to compiler / interpreter design that a lot of the brighter people same to take when writing such things: Baby steps.
Instead of attempting to produce an all singing all dancing functional language in one giant step, I instead focused on producing bits of a functional language; one piece at a time.
The text parser was pretty easy given Scheme’s simplistic syntax and explicit prefix ordering. Much to my own surprise, I was even able to knock out a working “pretty print” routine without too much blood or loss so it wasn’t long before I was able to type in:
(+ (* 3 (+ (* 2 4) (+ 3 5))) (+ (- 10 7) 6))
And get back:
(+ (* 3
(+ (* 2 4)
(+ 3 5)))
(+ (- 10 7)
6))
For each example given in Structure and Interpretation of Computer Programs, I added a little more functionality.
At first, all I could do was add two numbers:
>(+ 1 2)
3
But then some other mathematical operators came to the party:
>(+ (* 3 (+ (* 2 4) (+ 3 5))) (+ (- 10 7) 6))
57
And then simple naming was added:
>(define size 2)
>size
2
Allowing me to perform simple stuff such as:
>(define pi 3.14159)
>(define radius 10)
(* pi (* radius radius))
314.159
>(define circumference (* 2 pi radius))
>circumference
62.8318
And then it was a small hop skip and a jump across to being able to support parameters and thus compound procedures:
>(define (square x) (* x x))
>square 5
25
>(define (sum-of-squares x y)
(+ (square x) (square y)))
>(sum-of-squares 3 4)
25
Which brings me up to my current challenge:
>(define (abs x)
(if (< x 0)
(- x)
x))
Creating the ‘if’ condition code isn’t too hard in itself but it does require some more difficult challenges to be tackled first.
Namely values that aren’t numbers.
All the calculations (and supporting code) up until this point have been dealing with numbers but conditional blocks such as ‘if’ work on Boolean values so it’s time to complicate the code a little more and add in support for non-numerical types such as Booleans.
I’m not quite sure at this point which path I’ll take to supporting multiple data types but I do know that I’ll be inspired at the very least by Jim and DLR team’s work. Whether my new interpreter actually comes to rely upon the DLR is a question best answered in a future baby step.
Okay, I admit it.
One of the major reasons why I got into software development in the first place wasn’t to make myself a better person, track stock prices or solve the world’s issues.
It was to write games. (... and also produce my own version of the ED-209 from the RoboCop movies... but that's another story)
At the grand old age of 10, being able to sit down and construct my own little animated universe of characters, locations and plots for the amusement of myself and my friends was an absolute blast.
Admittedly the graphics were a little rough around the edges... and the sound was a little harsh on the ears... and the story lines often had less depth than an ordinary television commercial... but all of that didn’t matter. Suddenly anything that I could imagine could be translated into a living, breathing... thing... albeit an extremely pixelated virtual one.
In 1985, a chunky looking 2D spaceship drawn in 16 colours on a 160x200 resolution screen would have people gawking in hushed amazement. A few lines of BASIC typed into machine that rattled along at a shuddering 2MHz and the world was your oyster.
These days, with commercial games spewing forth space ships in glorious high definition photorealistic 3D surround-sound force-feedback glory, it’s hard not want something a little more than a collection of simple coloured 2D blocks from your own creations.
So you dutifully sit down at your modern multi-core, multi-gigahertz, multi-tasking beast of a machine and attempt to recreate some of the gaming magic that the big gaming companies are producing... and discover that it’s hard. Annoyingly hard.
Suddenly, in order to produce a game, you’ve either got to spend months dealing cryptic APIs, mind numbing maths and enough reading material to make a PhD student sweat.
And for what?
All you wanted to do was sit down, write a little bit of code and produce a cool game for the joy of you and your friends. When did it all get so difficult?
Well... rock up to my Cabana talk (DEV301CT) at Tech Ed 2007 on this Gold Coast this year and I might just have a solution for you. (You knew there was going to be a sales pitch in here somewhere didn’t you?)
Microsoft recently released XNA Game Studio Express. It’s a package designed to help us mere mortals write cool games... without having the need of a degree... or an annoying preteen relative to condescendingly instruct us.
I’ll show you how, with relatively little effort, you can have the best of both worlds.
Write code that doesn’t hurt the brain... yet still produces the spectacular graphics and sound of a modern game.
Of course whether the world actually appreciates your vision of shuriken wielding monkeys fighting robotic sharks in outer space is anyone’s guess...
My wild and whacky idea for today: Add an RSS feed to my blog.
Crazy I know but that's just the kind of wild child I am.
Okay, hands up all those who know the words to the following tune:
“It’s been so long since I last blogged. I’m sorry. I was unable to blog because...”
Well I’m not got sing it this time. This time I’m going to have a stab at actually fixing some of the underlying issues on my lapse blogging efforts.
Step 1: Change blogging engines.
Whilst I appreciated the graphical goodness of my previous blogging engine, it took a *long* time to construct each blog entry. The brand new engine that I’ve just written should hopefully go a long way towards correcting that.
“Yet another blog engine?” you ask.
Yep. Don’t get me wrong. I have no major issue with any of the existing selection of blogging engines. It’s just that I, being a developer at heart, feel happiest when I can tinker freely beneath the hood.
The new engine, along with the pages it creates, is pretty simple at the moment. As time progresses I’m hoping to add bits to it as I need them and, if all goes well, wind up with something a little more personal (and a little different for those who define themselves by such things).
Step 2: Insert idea here
No ideas yet... but I’m flirting with micro-blogging (think along the lines of twitter) as one possible way to keep the blogging ball rolling.