I put the code on GitHub and starting to clean it up, making it suitable for use ...
Watch this space ...
it would depend on my users being dumb, and as I said earlier, my users are anything but. They're the smartest people on the planet and I want to keep it that way. And I think anyone who makes software for dumb people in the end gets what they deserve. :-)
I've never had a good relationship with Java.
My first OO experience was with Smalltalk. And that spoiled me for the whole C++ / Java family of strongly typed, compiled OO languages.
Because I'd learned Smalltalk and this new fangled OO thing when it was still relatively new (in the sense of the late 80s!) I thought I had it sussed. But actually I had very little clue. I enthusiastically grabbed the first C++ compiler I could get my hands on and proceeded to spend 10 years writing dreadful programs in C++ and then Java. I had assumed that the OOness of both these languages made them as flexible as I remembered Smalltalk to be. I thought that OO was the reason for Smalltalk's elegance and that C++ and Java automatically had the same magic.
Instead I created bloated frameworks of dozens of classes (down to ones handling tiny data fragments that would have been much better as structs or arrays). I wrote hugely brittle inheritance hierarchies. And then would spend 3 months having to rewrite half my classes, just to be able to pass another argument through a chain of proxies, or because somewhere in the depths of objects nested inside objects inside objects I found I needed a new argument to a constructor. The problem was, I was programming for scientific research and in industry but I hadn't really been taught how to do this stuff in C++ or Java. I had no knowledge of the emerging Pattern movement. Terms like "dependency injection" probably hadn't even been invented.
I was very frustrated. And the funny thing I started to notice was that when I had to write in other languages : Perl, Javascript, Visual Basic (Classic), even C, I made progress much faster. Without trying to model everything in class hierarchies I found I just got on and got the job done. Everything flowed much faster and more smoothly.
Perl's objects looked like the ugliest kludge, and yet I used them happily on occasion. In small simulations C structs did most of what I wanted objects to do for me (and I did finally get my head around malloc, though I never really wrote big C programs). And I had no idea what the hell was going on with Javascript arrays, but I wrote some interesting, very dynamic, cross browser games in js (this is 1999) using a bunch of ideas I'd seen in Smalltalk years before (MVC, a scheduler, observer patterns etc.) and it just came out beautifully.
It wasn't until the 2000s that I started to find and read a lot of discussions online about programming languages, their features, strength and weaknesses. And so I began my real education as a programmer. Before this, a lot of the concepts like static and dynamic typing were vague to me. I mean, I knew that some languages you had to declare variables with a type and in some you didn't. But it never really occurred to me that this actually made a big difference to what it was like to USE a language. I just thought that it was a quirk of dialect and that good programmers took these things in their stride. I assumed that OO was a kind of step-change up from mere procedural languages, but the important point was the ability to define classes and make multiple instances of them. Polymorphism was a very hazy term. I had no real intuitions about how it related to types or how to use it to keep a design flexible.
Then, in 2002 I had a play with Python. And that turned my world upside-down.
For the first time, I fell in love with a programming language. (Or maybe the first time since Smalltalk, which was more of a crush).
Python made everything explicit. Suddenly it was clear what things like static vs. dynamic typing meant. That they were deep, crucial differences. With consequences. That the paraphernalia of OO were less important than all the other stuff. That the fussy bureaucracy of Java, the one class per file, the qualified names, the boilerplate, was not an inevitable price you had to pay to write serious code, but a horribly unnecessary burden.
Most of all, Python revealed to me the contingency of Java. In the small startup where I'd been working, I had argued vehemently against rewriting our working TCL code-base in Java just because Java was OO and TCL wasn't. I thought this was a waste of our time and unnecessary extra work. I'd lost the argument, the rewrite had taken place, and I hated now having to do web-stuff with Java. Nevertheless, I still accepted the principle that Java was the official, "grown up" way to do this stuff. Of course you needed proper OO architecture to scale to larger services, to "the enterprise". Ultimately the flexibility and convenience of mere "scripting" languages would have to be sacrificed in favour of discipline. (I just didn't think we or our clients needed that kind of scaling yet.)
What Python showed me was we weren't obliged to choose. That you could have "proper" OO, elegant, easy to read code, classes, namespaces, etc. which let you manage larger frameworks in a disciplined manner and yet have it in a language that was light-weight enough that you could write a three line program if that's what you needed. Where you didn't need an explicit compile phase. Or static typing. Or verbosity. Or qualified names. Or checked exceptions. What I realised was that Java was not the inevitable way to do things, but full of design decisions that were about disciplining rather than empowering the programmer.
And I couldn't stomach it further. Within a few months of discovering Python I had quit my job. Every time I opened my machine and tried to look at a page of Java I felt literally nauseous. I couldn't stand the difference between the power and excitement I felt writing my personal Python projects, and the frustration and stupidity I felt trying to make progress in Java. My tolerance for all Java's irritations fell to zero. Failing to concentrate I would make hundreds of stupid errors : incompatible types, missing declarations or imports, forgetting the right arguments to send to library methods. Every time I had to recompile I would get bored and start surfing the web. My ability to move forward ground to a halt.
I was so fucking happy the day I finally stopped being a Java programmer.
Postscript :
1) Something I realized a while after my bad experience was how important the tools are. My period in Java hell was trying to write with Emacs on a small-screen laptop without any special Java tools (except basic Java syntax colouring). I realize this is far from the ideal condition to write Java and that those who are used to Eclipse or IntelliJ have a totally different experience and understanding of the language.
2) A few years later, I taught the OO course in the local university computer science department. All in Java. By that time, I'd read a couple of Pattern books. Read Kent Beck's eXtreme Programming. Picked up some UML. And I had a much better idea what Polymorphism really means, how to use Interfaces to keep designs flexible, and why composition is better than inheritance. I tried to get the students to do a fair amount of thinking about and practising refactoring code, doing test driven development etc. It all seemed quite civilized, but I'm still happy I'm not writing Java every day.
3) A couple of years ago I did do quite a lot of Processing. I was very impressed how the people behind it managed to take a lot of the pain of Java away from novice programmers. I wonder how far their approach could be taken for other domains.
In practice, a few Unix classics : SSH, the diff / patch formats, rsync, finger. All used on a grand scale by many parties. Multiple implementations. Multiple pieces of software committed to them. No one really trying to change them.
Email protocols are pretty widely supported and fixed.
Git. It's notionally owned by Linus Torvalds, but he doesn't seem to have any commercial interest in extending or breaking it. GitHub showed you can build a great commercial site around it without trying to make proprietary extensions. And I can use the same clients to push and pull from my server running the default Git daemon, from Github, or from rival offerings (I'm pretty sure BitBucket / SourceForge / Google Code now offer Git as an option)
Possibly Jabber / XMPP
How might such a world (of universal programming literacy) come about?
Most likely from a continuing trend to automate the way a lot of work gets done, and then people would learn programming as a way of engaging with that world.
For example, instead of spending half an hour in the supermarket or even 10 minutes browsing a supermarket site on the web, you might be able to compose an augmented shopping list on your phone.
6 Apples
4 bread rolls
Could become :
"Apples".
prefer("Pink Lady" or "Fuji").
take(6).
otherwise.take(4)
"Bread rolls".
only("Wholemeal").
take(4).
prefer("Top=Poppy Seed")
Deliver("Wednesday")
Order_from(
priorities("Waitrose","Asda","Sainsbury","Tesco")
)
Similar little languages can be developed for most activities. So I'd guess that we'll all be writing little scripts for robots or large automated services. There's an assumption that people must prefer navigating rather laborious graphical interfaces to get stuff done. But if they were more programming literate they may learn to use and love such small scripts instead.
Well, you already know but I still think wiki has a future, as pointed to by Smallest Federated Wiki. There are some flaws / issues with SFW, mainly I think because not enough people are working on it, but it’s still the signpost for how wiki could evolve.
Would still love to see you and other UseMod / OddMuse people look at ways to engage, even if you don’t switch over.
2012 is the year when it just became more and more clear that we need our own space and shouldn’t be dependent on Fb / Tw / G+ etc.
Fb / Tw / G+ offer two compelling things : 1) an aggregate river of stuff from people we care about, 2) really easy transclusion from various rich media sites.
We could have a distributed river architecture if we took RSS and some kind of pubsub architecture (eg. RssCloud) seriously. SFW has made transclusion protocols central to its philosophy. If we pick up on both, figure out how to get the most important things we get from the mainstream working smoothly, we can create a compelling alternative on our terms. And one of the interesting, overlooked, facts about G+ is that it showed that significant numbers of people are still willing to experiment with alternatives. As long as you can get a critical mass of around 20 people you care about to use it, G+ is as valuable as anything else. You don’t need 1 billion users. You aren’t trying to take over the world at this point, just to have a syndication / discussion architecture which isn’t owned by THEM.
Iterative, "test driven", development.
Break your idea down into a number of simple "stories", each of which describes a single chunk of activity which goes all the way through from the beginning to the end of a user's experience with the software. Importantly a story is not a traditional "component" ... but represents a complete, working but minimal slice through the functionality.
For example, a story could be "the user goes to our site at a URL and sees a page describing our idea" or, for a drawing program, "the user can create and save a jpg file" (even though that jpg file is just a blank canvas).
Once you have some stories, order them by importance. If you could only get one story working, what would be the most valuable? If you could only get two stories, which would those be?
Start on the most important story. As any particular story shouldn't be too complicated, you can probably figure out fairly intuitively the components you need in order to make it happen. (If you can't, you're trying to fit too much into a single story.) Those components might be functions, they might be objects which have several methods (if so, ONLY worry about the methods of the object which satisfy the current story, ignore any others), they might be HTML forms or templates.
Now write AUTOMATED TESTS for the components you need for this story. Unit tests for the functions and objects. Ideally something like Selenium for the web forms.
Write code to pass the tests in a test-driven style ... ie. write test, write code to pass test, refactor your code to eliminate redundancy, write next test etc. When one story is finished, start figuring out how to do the next most important and work on that.
Somewhere down your list of stories you have your minimum viable product: that is, the minimal thing which is worth releasing to your customers in order for them to give you feedback on whether this is useful to them. That is not necessarily just one story, it might be after the first three. Or the first ten. Whatever it is, once you hit it, release your product to the customers and start getting their reaction.
From now on you are in maintenance / iterative growth mode. You'll be taking the feedback from the customer to rewrite and reorder the stories. While continuing to implement them according to your best, most up-to-date, sense of priorities. You'll want to release new development to the customer as fast as reasonably possible so you can collect the feedback on your improvements too.
Don't assume that one story has to equal one release, because you'll be tempted to inflate your individual story to contain more than it should. But try to keep releases down to as few stories as possible so they can happen frequently : which maximizes both your information, and the customer's sense of progress.
The job was really to take C++, which was a fairly static language, and show people how to write dynamic programs in a static language. That's what most of the patterns in that book were about. And in the process, patterns extended the life of C++ by a decade, which is not what I thought would happen. What I thought would happen is people, when they learned these patterns, would look at them and say, "Wow, these patterns are hard in C++ and they're easy in Smalltalk. So if I want to think in terms of these patterns, I might as well use a language where they're easily expressed." And extend the life of Smalltalk by a decade. But the opposite happened.I always suspected that the patterns everyone got so excited about were basically a way of overcoming static typing. Ward confirms it :-)
These days, I'm thinking a lot about 3D printers, desktop manufacturing and software to create physical things.
Last year I did some art pieces using software to generate drawings for laser cutters and 3D printers, and I'm continuing along the same line. I want to move this stuff into the browser, and the combination of CoffeeScript and Raphael.js is turning out to be pretty good for this. (Did I mention I really, really like CoffeeScript?)
I also dabbled a bit with Prolog, wondering whether it can be used as a high-level description language for machines or other complex objects. The really interesting question is if you can use the built-in inference engine of Prolog to help with the design. (Aside, here's a silicon layout engine in Prolog) I haven't got very far with that yet, but I'm now considering how Prolog can be combined with or made to output OpenScad (or PyScad) code.
A couple of days ago Simon Wardley posted on his blog that he was searching for a SpimeScript :
So, I want to return to ... the formation of Spime Script. We're entering a phase where hardware will become increasingly as malleable as software which leads to a problem of choice - if I want to change the function of something, do I do this in software or hardware? The tendency today is obviously towards software because its more malleable but the future is never the past. However this creates a problem of skill - will I need to become proficient in both software and CAD / electronic design?
In reality both CAD and whatever software language you use, compile down to instruction sets and the function of the device is the interaction of these instruction sets - one which is substantiated physically and the other which is substantiated digitally.
Turning this on its head then why not write the function of what you want, the function of the device? Compilers can therefore undertake the complex decision trees (which is what they're good at) required to determine what element of that function is encoded as physical and what element is digital.
A future language is needed, something whereby the output is both physical and digital and I describe merely the function of what I'm after.
That's a really exciting vision.
Now, here's what I think is really important for a SpimeScript.
It should learn from HTML / CSS.
While HTML / CSS is a pain in many ways, there's a very interesting insight in it about design. That design comes in layers. It's partly about the separation of logical structure and visual style. It's partly about the cumulative effect of the Cascade in Cascading Style Sheets. It's partly about the fact that the browser has reasonable defaults for the geometric properties of logical structure. (Today, those defaults look rather out-of-date but there would be little to stop a browser manufacturer making their defaults look more like Readability or Twitter Bootstrap.)
So here's the main feature request for a SpimeScript. It should be possible to define the logical structure of, say, a machine and have some layout-engine give it plausible default geometric properties. But it should also be possible for designers to layer optional design hints on top of that layout in the form of extra constraints and have the engine deal with fitting them together.
As with the silicon design case, there must be some prior art here, but I'm not quite sure where it is. Electronic Design Automation maybe.
Surely all practical knowledge is anecdotal and, therefore, an unwarranted step from the particular to the universal. All advice in this “genre” (Tom Peters, Charles Handy, Seth Godin etc. etc. etc. ) comes with an implicit health warning. And anyone with any experience of the world will apply salt as a matter of course.
Should we hold that against Ries in particular?
So his models come from the software industry. OK. But someone else’s advice will come from banking, or food retail or oil or the military. Each with some parallels to your business but each with its own idiosyncrasies as well.
One thing you can say in favour of Ries’s bias is that more and more things are getting automated and so more and more of our world “is made of software”. Software processes are replacing other kinds of process that were embodied in administrative or managerial practices or hardwired into physical machines. In this world, improvements in software are often more effective than improvements in other areas.
You’re a coder yourself. You probably know your Mythical Man Month etc. You know perfectly well that software doesn’t benefit from heavy bureaucratic management. But that exciting and effective software usually does come from small, enthusiastic, “agile” teams.
So, if software is becoming an increasingly important factor in business. And software thrives under agile conditions, it would follow that business in general will probably benefit from agile.
Disclosure : I’m a software guy myself, so I’m totally down with the land-grab programme.
One of my favorite business model suggestions for entrepreneurs is, find an old UNIX command that hasn't yet been implemented on the web, and fix that. talk and finger became ICQ, LISTSERV became Yahoo! Groups, ls became (the original) Yahoo!, find and grep became Google, rn became Bloglines, pine became Gmail, mount is becoming S3, and bash is becoming Yahoo! Pipes. I didn't get until tonight that Twitter is wall for the web. I love that.Marc Hedlund via Coding Horror
What "templating" means to most people is a way of having the developer write out HTML basically the way that you would send it to the browser and then having a way to include a few things -- typically variable substitution by using special tags lik <% ... %> or similar.
In our case, no one writes any code that looks like HTML/XML literals, so there's nothing in our codebase that really matches what most people think of as templates. We do have view code but that interleaves calls into the model and application logic along with a Python code description of what the HTML for that component should be, which is different from templates which are usually based around the ideas of separating logic and data fetching from this.
# HTML library
# basic level
def tag(name,x,*argv) :
if x is None :
return u"<"+name+u"/>"
if argv != (None,) :
inside = u''.join(argv)
else :
inside = u''
if isinstance(x,dict) :
# we're passing a dictionary of attributes for the tag
s = u"<%s " % name
s = s + ' '.join(['%s="%s"'%(k,v) for (k,v) in x.iteritems()])
s = s + u">"+inside+u"</"+name+u">"
return s
# or there are no attributes, just inner
return u"<"+name+u">"+x+inside+u"</"+name+u">"
# Now we'll actually make some tags
tags = ['html','head','body','script','p','div','table',
'tr','th','td','ul','ol','li','dt','dd','h1','h2',
'h3','h4','h5','h6', 'style','pre']
loc = locals()
def setit(loc,t) :
loc[t] = lambda x=None,*argv : tag(t,x,*argv)
for t in tags :
setit(loc,t)
# Use like this
html(
head(),
body(
h2("Header"),
p('para1'),
p('para2')
)
)