Archive for the tag 'Ruby'

On the Smalltalk Browser

Some of the comments in a the Barrier To Entry post bring up the point that maybe the Smalltalk IDE itself is one of those barriers.

It’s an interesting thing, the Smalltalk browser. Unlike most IDEs, it’s optimized for reading code rather than writing code. Other IDEs allow you to see any number of methods all at once, cutting and pasting text giant chunks at a time, they sure make you feel like you’re working. They don’t however, allow you to navigate the semantic structure of the code very well nor do they encourage the writing of well organized code.

Modern IDEs are getting better at this, but they’re doing it by copying Smalltalk. Smalltalk’s various code browsers (hierarchy, method, inheritance, senders, implementors, protocol, category, package, refactoring) let you explore the structure and relationships between existing code and its tools (transcript, workspace, method finder, message names) make finding and using existing code, or understanding existing APIs vastly easier than any other language I know of. Seeing the structure of code is always but a context menu or hotkey away.

Smalltalk’s browser is rather opinionated, luckily, thanks to Rails, opinionated software seems to be having somewhat of a revival. When it comes to writing code, the browser forces you into a certain mindset, one that other languages don’t force you into. When I create a method in Java/C#/Ruby, I have to choose little more than what file and class it belongs in. I *can* organize the code well, but there’s little incentive to do so and my unit of work is rather undefined, I could be slicing and dicing methods, classes, namespaces, etc., usually with the full screen devoted to code across various files or even god forbid in one giant file. This encourages a code now and organize later approach. Sadly, later often never comes, and the code is left functional but messy.

Smalltalk on the other hand, defines my unit of work as *the method* and by doing so forces me at every turn, to continually organize my code in semantically meaningful ways. When I create a method, I have to choose a class category, a class, and a method category to put the method in. If I don’t, Smalltalk kindly categorizes the method for me in a protocol called “as yet unclassified”. It’s almost an insult, but it’s also a not so subtle reminder than I’m writing code sloppily, faster than I’m thinking. It reminds me to slow down, think for a second, where does this thing belong.

It only takes a second to pick a meaningful category name, and these names are idiomatic, I see them all the time when I’m looking for code. Aha, we’ve linked writing code to reading code. By taking the time to properly categorize my methods I also learn where to look for code later, when I’m in reading mode. It’s a feedback loop, the more I read the better I write and the better I write the more I learn to read with accuracy, looking only where necessary. It’s as if the code itself *is* a concise form of documentation hyperlinked by semantic meaning using things that Smalltalkers call browsers. Browsers and hyperlinks, bah, that’ll never work!

And RDoc, what the fuck is that, looks curiously like a Smalltalk browser to me, but why should class comments be anywhere except on the class itself? Oh that’s right, Ruby doesn’t have a Smalltalk browser, they code in files, how quaint.

As for editing the method itself, I work on and view only one method at a time, and only the lower half of the browser is for editing code which punishes me if I write long methods that can’t fit into that tiny pane. Smalltalk at every turn encourages me to read more code than I write, reuse more code than I otherwise might, and write smaller simpler methods than I likely would in a text editor.

Writing smaller methods forces me to give them meaningful names. Giving them meaningful names and putting them in meaningful places makes the code easier to read and easier to find. Code that is easier to read and easier to find, is easier to reuse, easier to understand, and easier to compose into new solutions. It’s called bottom up programming, the foundation of which is small composeable methods.

I keep using the word small, maybe that’s a mistake on my part, what I really mean is concise. Methods with a single purpose that is clearly summed up by their name. These kinds of methods happen to be short in general, but that’s a side effect of their being focused on a single task. The Smalltalk browser encourages these kinds of methods by making writing long methods or paying attention to too many methods painful. Text editors are general purpose editor aimed at text, that could be anything from a blog post to a novel. Surely an editor intended only for code, and only for a particular style of code, can be made much more *domain specific*.

The Smalltalk browser is such an editor, its domain is highly factored heavily structured bottom up style object oriented code. If that’s the style of code you like to write, you’ll find the Smalltalk browser wonderful, if not, you’ll find it painfully opinionated and rude.

Take a peek at decompiled .Net framework sources, or Ruby sources and what you’ll find, are average line per method counts in the 50+ to even 100+ ranges. In Smalltalk, around 10 or so. To me, this is a clear indication that text editors are the wrong interface for writing clean simple well factored reusable code. Sure, I just pulled these numbers out of my ass, but they reflect my experiences and even then, I’m being polite, 1000 line methods are not at all uncommon in .Net.

Maybe adjusting to the Smalltalk browser is similar to adjusting to Lisp’s parenthesis. It’s something you desperately want to fix as a newbie and make it work like other languages. In Lisp’s case, trying to design an infix Lisp while in Smalltalk it’s a text and file based editor. In both cases, once you stop fighting the language and realize the difference is actually a great strength of the language rather than something that needs fixed. You realize it’s you that needs to change, you open your mind, accept that sometimes different is good, and take advantage of the new power these tools give you.

Experienced Lispers love their parenthesis and experienced Smalltalkers love their browsers. Rather than seeing the Smalltalk browser as a barrier, maybe, just maybe, you’d be better off seeing it as a new toy to play with. Something new to learn.

UPDATE: Here’s a few admitidly cramped screenshots of the various browsers. They do of course look much better maximized on your monitor.

browser8.jpg

browser7.jpg

browser6.jpg

browser5.jpg

browser4.jpg

browser3.jpg

browser2.jpg

browser1

Functional Programming in Smalltalk

Smalltalk is generally considered to be an object oriented language but it’s actually a mixture of object oriented and functional techniques that made it so great. It’s the functional stuff, closures, anonymous functions, and higher order functions that make Smalltalk code so terse and easy to read. The objects provide the overall structure, but the functional stuff glues them all together and makes Smalltalk what it is.

I was considering writing more about it but a quick Google search turned up this great reference Smalltalk for Lispers from the Smalltalk/X Programmers Guide that gives an excellent introduction from a more functional point of view.

If you mix object oriented programming, manifest types, and procedural programming, you get Java or C#, not exactly a fun or flexible combination of language features. Mix object oriented programming, dynamic types, and light functional programming and you get Smalltalk and Ruby, much more fun and much more flexible and productive.

People often seem to forget “object” is meant as an abstract term that means “thing”. Object oriented programming is about programming with “things”. In that sense, functions are objects too. Not all objects need be created with named classes, and all too often people who complain about OO are really complaining about their misguided view of OO and the often made newbie mistake of trying to model everything with a class. It’s not called class oriented programming, it’s called object oriented programming. Maybe approaching Smalltalk from a more functional point of view will shed some light on more interesting ways to solve problems.

Why Smalltalk

As always, I enjoy reading what someone thinks of Smalltalk after a proper demonstration. I find Edwards thoughts on Smalltalk typical of that aha you get when you really see what Smalltalk’ers can do.

Edward was lucky, he had a Smalltalker handy to show him the ropes, few have that opportunity. I’m still amazed by how many people think they can grok Smalltalk by seeing syntax examples. Smalltalk isn’t its syntax, it’s its environment. Smalltalk is a living world of running objects, there are no files, no applications, just what’s running. To understand Smalltalk, you have to either actually use it for a while, or have a seasoned Smalltalker demonstrate it to you. Reading sample code just won’t cut it.

For better or for worse, Smalltalk is a world unto itself. It’s much more an operating system than a programming language. When Steve Jobs stole the idea for a windowing system and mouse from Xerox (not that they invented it), it was Smalltalk he was seeing. Even he readily admits he was so dazzled by the GUI he didn’t even notice Smalltalk, or the fact it was all networked with email, things we take for granted now but didn’t exist widely back then.

Sure, we package code and use source control, but our methods aren’t file based. Our source control systems are language aware, they can diff and merge code at the method level, auto merge and allow you to select, method by method, which version you want to keep. Smalltalk is different, top to bottom, it’s just different. Everything is live, code changes are live, applications don’t start, they’re simply always running. Object oriented programming means something entirely different to a Smalltalker than to someone doing OO in another language.

Ruby comes very close to Smalltalk. It’s a nice introduction to many if not most of Smalltalk’s ideas. It’s very pragmatic, fits in with the world around it, it’s based on files, works with your favorite text editor, etc. etc. But Ruby still isn’t Smalltalk. I use Ruby, I like Ruby, but Smalltalk is more productive when I’m working in unknown territory. Smalltalk is better for prototyping ideas quickly. A read eval print loop and hyper-linked documentation just doesn’t compare to a real Smalltalk workspace and a real Smalltalk browser where the code itself is hyper-linked and navigable and objects are things you can actually pick up and shake.

Smalltalk doesn’t have to be pragmatic, because it’s better than its imitators and the things that make it different are also the things that give it an advantage. Its syntax isn’t weird, C’s is. Weird isn’t even the right word, because what’s weird is totally relative and very dependent on your background experience. Smalltalk’s syntax is simply better.

Window window = new Window(0, 0, 800, 600);

Simply isn’t as expressive as…

window := Window top: 0 left: 0 width: 800 height: 600.

And this is a trivial example, the more complicated the code gets, the more of an advantage Smalltalk has. Ruby chose to go with a C’ish syntax, but by convention, mostly tries to fake the Smalltalk style anyway because it’s simply better.

window = Window.new :top => 0, :left => 0, :width => 800, :height => 600

So, if you still haven’t tried Smalltalk, and I mean really tried it, by writing an application in it, give it a go. You’ll never regret it, because everything you learn, and you’ll learn a lot, you’ll be able to bring back with you to whatever language you call home. Smalltalk will change the way you think, no matter what language you’re coming from. Whether it changes it for better or for worse is of course entirely up to you. If you’re afraid to try Smalltalk, then at least try Smalltalk Lite… uh, I mean, Ruby, you’ll enjoy it and still be able to use your existing tools. You can work your way up to the real thing.

PS: Lisp and Haskell are two other equally mind bending languages that I think everyone should learn, however, neither of them can touch Smalltalk’s development environment. That being said, learn them anyway.

Featured Resources

Just like Smalltalk stands different than the rest, there is a wide range of cheap web hosting companies offering their best hosting packages. You will be able to register domain very quickly with some of these. If you have many domains, you can still avail this facility. For small business owners, the hosting companies like startlogic are coming up with the best solutions for their needs.

Scaling Seaside

UPDATE: This advice is a bit outdated and only applied back when I was hosting Seaside on Windows servers (which I advise against), see Scaling Seaside Redux Enter the Penguin for more up to date advice.

I’ve been busy with non Seaside projects lately, but one of the things I have squeezed in was a bit of configuration to make Seaside scale better. I was having some performance problems when more than a few sessions were running concurrently and after discussing the issue on the Seaside developers list, Avi popped in from DabbleDB and told us the way to scale was load balance many VMs with a few sessions running on each. So I had to read up a bit on the issue and learn what to do.

It turns out one of the best ways to learn about scaling Seaside is to read about scaling Ruby on Rails. The architecture for scaling both is pretty much the same. Ruby developers use a web server called Mongrel, a light weight single threaded server that works well with Rails but isn’t a heavy duty web server like Apache. This is much the same position Seaside is in with Comanche, though not single threaded, the Squeak VM can’t take advantage of multiple processors and doesn’t do well with too many concurrent connections.

UPDATE: I neglected to mention one major requirement of Seaside, your load balancer must support sticky sessions. Seaside uses sessions heavily and does not support the shared nothing approach where every request can hit a different server. This isn’t an issue unique to Seaside, many frameworks use sessions and must deal with this. Other frameworks handle such issues either by sticking a session to a server, or by having a shared session cache that all the servers can access, such as memcached or a sql server. Currently, to the best of my knowledge, no one has externalized Seaside sessions in this manner, so sticky sessions is the only viable approach.

The solution for both is quite simple really, setup a heavier duty web server/load balancer (Apache/LiteHttpd) to serve up static content, and load balance and proxy connections to a farm of light weight application servers (Mongrel/Comanche) running on other ports. I’m actually using an F5 as my front end load balancer, but Apache has all the necessary features including the ability to create pools of virtual servers which it will load balance requests across with its new mod_proxy.

One only need Google scaling Rails to find many examples of detailed setup information and articles for such a setup, so I won’t repeat it here. I will mention that neither Mongrel or Comanche are anywhere near as rock solid stable as Apache, so one thing you’ll want when having a setup like this to ensure maximum uptime is a process running to poll all of your servers to ensure they aren’t hung up for any reason.

UPDATE: I don’t want to imply Comanche is unstable, it is very rare that a service needs reset, I only do this because it “can” happen, not because it happens a lot. Seaside is very stable and under normal conditions, doesn’t crash.

Here’s a little bash script I found somewhere that makes checking a site for a specific response string simple and easy to use from the command line allowing you to easily schedule some scripts to reset any hung processes. Oh, I use cygwin on all my servers so I can have a decent Unix command line on my Windows servers.

checkSite.sh UPDATE: This script eventually freaks out Windows and causes random network errors because lynx somehow eats up network resources. Don’t use it, Seaside is quite stable without it.

#!/bin/bash

if [ $# -lt 2 ]; then
    exit
fi

URL=$1
findText=$2

lynx -dump -error_file=/tmp/x$$ $URL 2>/dev/null | grep “$findText” &>/dev/null
if [ $? != 0 ]; then
    echo WARNING: Specified search text was not found
fi

stcode=`awk ‘/STATUS/{print $2}’ /tmp/x$$ 2>/dev/null`
if [ $? != 0 ]; then
    echo site is down
fi

for code in $stcode
do
    case $code in
      200) echo OK;;
      302) echo redirecting
           awk -F/ ‘/URL/{print ”  “,$3}’ /tmp/x$$;;
      *)   echo $code
    esac
done

if [ -f /tmp/x$$ ]; then
    rm /tmp/x$$
fi

Then I use this in another script built specifically to monitor instances of my Seaside app. Though this could be more generic, I haven’t bothered yet because I only have one Seaside site in production to worry about.

checkSeaside.sh

echo "$1 $2 $3..."
sh checkSite.sh http://$1:$3/seaside/someApp "Some Required Text" | grep WARNING &>/dev/null
if [ $? = 0 ]; then
    echo “restarting $2 on $1″
    psservice \\\\$1 restart “$2″ >/dev/null #NT util to restart services on remove machines
    echo “Restarting $1 $2″ | wsendmail — -CGI -Ssome.mail.server.com -s”App Monitor reset $1 $2″ someEmail@someAddress.com -Fmonitor@someAddress.com -P1
fi

Then on each web server, I’m running a pool of 10 instances of Seaside setup as services and ensuring they’re up by scheduling a simple batch file with the windows task scheduler.

monitorSomeApp.cmd

@echo off
bash checkSeaside.sh serverName "Some Service1" 3001
bash checkSeaside.sh serverName "Some Service2" 3002
bash checkSeaside.sh serverName "Some Service3" 3003
bash checkSeaside.sh serverName "Some Service4" 3004
bash checkSeaside.sh serverName "Some Service5" 3005
bash checkSeaside.sh serverName "Some Service6" 3006
bash checkSeaside.sh serverName "Some Service7" 3007
bash checkSeaside.sh serverName "Some Service8" 3008
bash checkSeaside.sh serverName "Some Service9" 3009
bash checkSeaside.sh serverName "Some Service10" 3010

Yea, I’m mixing and matching bash and dos scripts, so sue me! Anyway, the setup works great, I’m running 30 instances of Squeak across 3 servers and these scrips ensure they’re always up and responding, and reset them and email me if they go down for any reason. Response time is now much better and I can fully take advantage of the multiple processors on the web boxes.

My process isn’t nearly as fancy as Avi’s (he’s dynamically bringing images up and down based on the host header), but balancing the connections across a bunch of fixed sized pools works well. I started with 10 processes per box, just for the hell of it, but I’ll increase or decrease the size of the pool as load dictates to eventually find the sweet spot for the pool size. For now, 10 per box works, I’ve got plenty of spare ram.

Of course, doing a setup like this means you’ll need to automate your deployment process for new code as well. So far this mean keeping a master image I upgrade with new code and test, then a script to take down each process, copy the image file over the old one, and bring the process back up. Seems Avi’s doing the same thing, works pretty well so far.

« Previous PageNext Page »