Born-Again Javascript

While most of my coding for fun is in Python, a whole lot of my coding at work is in Javascript. Over the years I have tried many, many frameworks for extending Javascript to add new widgets to the browser, to handle functional-style programming in Javascript, or simply to make the browser DOM easier to use. They pretty much all suck. Much of the suckitude comes from trying to support beasts such as Netscape 4 or IE Mac, neither of which are supported by any sane company these days. Of course, now that Netscape 4 is finally settling into the dim recesses of history where it belongs, we still have all the flavors of IE to plague us. Microsoft does their best work when they are playing catch-up. Everyone predicted that as soon as they were the dominant browser they would stop caring about standards and stop updating their browser in any significant way. Microsoft denied it, but can anyone really say they’re suprised that it’s exactly what they did? Only when Firefox began to seriously erode their “market share” did they reanimate the moribund IE team. I can’t wait to see what kind of nightmares we get when that monster walks out of the laboratory.

Despite all this, I’m still somewhat of a fan of Javascript. It doesn’t get much respect, in part because of poor implementations, and in part because it wasn’t designed to be very modular. It ignores modern concepts such as threading. You could go on for days on the problems of Javascript, and others have, so I won’t. What all this is getting to is that I’m excited about seeing good uses of Javascript in Google Maps and Backpack. I’m going to try using Script.aculo.us to see what I can get away with (using my new fave web framework, CherryPy). And I’m really, really looking forward to what Bob Ippolito is cooking up with his semi-stealth project: Mochikit. Bob has done some amazing work with PyObjC, and Mochikit could well be the Javascript framework I’ve been looking for, complete with documentation and unit tests. I can’t wait.

50-Year Language

A post by Patrick Logan on languages, in response to something Bill de hÓra wrote on language and communication inspired me to think some more about the language I’d like to be programming in. If you follow those links you might be interested to know that KIF is the Knowledge Interchange Format, FIPA is the Foundation for Intelligent Physical Agents, and ACL is the Agent Communication Language.

Paul Graham has an essay, The Hundred-Year Language in which he argues, in part, “Unlike physics in a hundred years, which is almost necessarily impossible to predict, I think it may be possible in principle to design a [programming] language now that would appeal to users in a hundred years.”

It’s a hard argument to back up, because we have no evidence in our existing programming languages. Lisp and Fortran are a little over fifty years old at this point, so those are the oldest examples we have to go by. And only Lisp is still gaining new adherents, as far as I can tell. It took Unix over 30 years to begin winning the OS wars, so who knows, maybe Lisp’s time has come.

There are some trends that have been showing up in recent mainstream languages like Java, Python, etc. The ability to handle Unicode for internationalization. Threads for scaling. Making network connections easier, especially for HTTP connections. Various layers of support for HTML.

If we assume that adding these facilities into programming languages is progress, if it is a kind of encapsulation of best practices, or at least making common cases of complex behaviour more accessible (if you’ve ever managed network connections in C you’ll understand what I mean), then what does that say for the next 50 year language? What would a language with the staying power of Lisp look like?

Well, what are the trends and emerging best practices today? Testing is a big one. Designing for testability, unit testing, test-driven development, these are all current buzzwords and for good reason. If Extreme Programming manages to get one idea into the mainstream, test-driven development would be a good one. But certain types of code are very hard to test, and these are some of the code that most needs to be tested. Code that results in persistent state changes (databases) are hard to isolate for testing because by nature they keep changing. Threaded code is hard to test, and multi-process code is even harder. User interfaces are incredibly hard to test well. Web code is difficult to test because you have no control over the environment it runs in–how do you automate a test which needs to run over several versions of several browsers under various operating systems? Performance is difficult to test well, it’s hard to isolate the bottlenecks of code to see where a minimum of effort (and disruption) can make a maximum performance impact.

So, one thing I’d like to see in the language of the future is the language designed for testability. What would a language deigned for testing look like? In part it might look like Eiffel with all the knobs turned to 11.

We can look at some of the most heralded features of existing languages, some mainstream, some more esoteric, to see what else might go into this future language.

  • Scalability [Erlang]
  • Robustness [Erlang]
  • Testability [Eiffel]
  • Flexibility [Smalltalk/Lisp]
  • Support for Little Languages< [Lisp]
  • Native UI [C#]
  • XML as a native datatype [ECMAScript2]
  • Small core language [Ruby/Lua]
  • Web as a core competency [ECMAScript/PHP]
  • Refactorability [Smalltalk]
  • Prototyping [ECMAScript/Smalltalk]
  • Security [What does this now?]
  • Manipulate units as well as numbers [Frink]
  • Able to compile efficiently when needed [Lisp]

The specific languages I chose are meant as examples, and reflect what I have some knowledge of. If I’ve left out Haskell, or Oz, etc., it’s largely because I’m less familiar with them and their benefits. The languages I chose are definitely weighted towards the dynamic end of the spectrum because that’s just the way things are going and I can only see that trend accelerating.

I’ve also mixed up language and libraries a bit freely. This will be one of the axes that languages will be measured on. Python would probably be easier to port to new platforms if the language core were smaller and the standard library could be defined in terms of that core. Lua wins in this regard, if someone wants a small, embeddable language. Some of the list above may be mutually contradictory. Paul Graham theorizes that there will be only a small number of languages in the future, but there will certainly be more than one, depending on the needs of the programmer.

Smalltalk and Lisp are mentioned above as “Flexible” and I should probably mention what I mean by that. In both languages you can create new core language features: operators, flow control, code rewriting, etc. Most languages do not support that level of manipulation (and Java specifically goes to lengths to prevent it).

When I think about what I’d like to see in the next fifty-year language, I call it Rotfl, which comes from ROTFL (Rolling on the floor laughing), which is what a programmming language should lead to. I spend far too much of my coding time in computer-induced Tourette’s Syndrome (i.e., swearing uncontrollably). I want to put the fun back in functions. This is at the core of Programming for the Fun of It. Some people spell Rotfl as Python 3000. We’ll see.

Coming attractions

I’m slowly making progress on ZenPaint, a simple animation tool for kids. I started writing it using PyGame, but hit the wall in terms of display, having to redefine my own widgets, etc. So I’ve taken a couple of step back and now I’m working on it using PyObjC. I keep waffling back and forth on whether to use Interface Builder or not. I don’t find Interface Builder very intuitive at all, but maybe I need to buckle down and get good at it. Knowing about nibtool helps–at least I can do text diffs and simple renames from the command-line.

One thing I would like to point out, the Apple NSDocument FAQ is one of the best bits of documentation I’ve ever seen out of Apple. So I’m mentally translating it into Python and trying to apply it to ZenPaint. As soon as I can load and save files reliably I’ll post the program and code up here for comments.

Slides up

After much delay, my slides are finally up from the VanPyZ talk last week.

Using Python and Cocoa on OS X

Again I’m using Eric Meyer’s S5 tool for HTML slides, but it still ends up being a large download because it includes a completely unneccesary quicktime movie. My daughter and I have been playing with iStopMotion and this was one of our first forays into claymation.

The reason it’s in the slideshow, is that movie making is now completely accessible to an eight-year-old, and I want to writing games and other programs equally accessible to her.

Still a ways to go…

Extending NSBezierPath

Yesterday I wrote about how to extend NSImage so it can save to a file. Today we’ll tackle NSBezierPath. NSBezierPath is pretty cool for drawing, but it doesn’t support arbitrary regular polygons, just rects and ovals (and lines and arcs). And there’s not an easy way to extract the points that make up a path. And if you could extract the points, there isn’t a way to draw dots for the points instead of stroking or filling the path. OK, enough already, let’s look at some code.

First thing in the code, we’ll define some basic trigonometry routines to calculate the points for a polygon. Then we’ll create the class itself.

from objc import Category
from AppKit import NSBezierPath
import math
def poly_point(center, r, degrees):
    x = r * math.cos(degrees) + center[0]
    y = r * math.sin(degrees) + center[1]
    return x,y
def polypoints(center, r, numPoints, degreesRotation=0):
    if numPoints < 3:
        raise ValueError, 'Must have at least 3 points in a polygon'
    rotation = math.radians(degreesRotation)
    theta = (math.pi * 2) / numPoints
    return [poly_point(center, r, i*theta+rotation)
        for i in range(numPoints)]
class NSBezierPath(Category(NSBezierPath)):
    def points(self):
        points = []
        for i in range(self.elementCount()):
        elem, pts = self.elementAtIndex_associatedPoints_(i)
        points += pts
        return points
def appendBezierPathWithPolygonWithCenter_radius_numberOfPoints_(self, center, radius, numberOfPoints):
	''' Creates a regular polygon '''
	pts = polypoints(center, radius, numberOfPoints) self.moveToPoint_(pts[0])
	for pt in pts[1:]:
		self.lineToPoint_(pt)
	self.closePath()
    def dot(self):
        '''
        Similar to stroke: and fill:, but draws dots for each point in the
        path. Dot size is based on linewidth. Not as efficient, because it
        creates a separate NSBezierPath each time it is called.
        '''
        tmp_path = NSBezierPath.alloc().init()
        width = self.lineWidth()
        offset = width / 2
        for point in self.points():
            rect = (point[0] - offset, point[1] - offset),(width, width)
            tmp_path.appendBezierPathWithOvalInRect_(rect)
        tmp_path.fill()

OK, hopefully the above is reasonably clear. You can follow along with any calls which are unfamiliar by firing up AppKiDo or the Apple documentation for NSBezierPath. If you’re going to use the dot: method a lot you might want to cache the path so you’re not creating a new NSBezierPath every time, it depends on what you need.

Here’s a short script you can run on the command line to create a hexagon and demonstrate fill:, stroke: and dot:

from AppKit import NSApplication, NSBezierPath, NSColor, NSImage
from Foundation import NSInsetRect, NSMakeRect
import image_ext, bezier_path_ext

app = NSApplication.sharedApplication()
image = NSImage.alloc().initWithSize_((64,64))
image.fillWithColor_(NSColor.clearColor())
image.lockFocus()
hex = NSBezierPath.alloc().init()
hex.appendBezierPathWithPolygonWithCenter_radius_numberOfPoints_((32,32), 26, 6)
NSColor.greenColor().set()
hex.fill()
hex.setLineWidth_(2)
NSColor.blueColor().set()
hex.stroke()
hex.setLineWidth_(8)
NSColor.redColor().set()
hex.dot()
image.unlockFocus()
image.writeToFilePath_('hex.png')

Which results in this: 

Why am I so interested in points and dots? Well, they let me visualize control points for arcs for one thing. Perhaps tomorrow we can explore more along those lines.

« Previous Page« Previous entries « Previous Page · Next Page » Next entries »Next Page »

google

google

asus