a life of coding

Saturday, November 17, 2007

Some Things Never Change

I just finished watching a half hour video on computer graphics. It covers the basics of 2D and 3D graphics and basic animation in a way that the average person can understand, but with enough detail to provide basic understanding.

The information itself isn't particularly blog-worthy; there are plenty of resources for learning about computer graphics. There are two reasons that this is interesting to me. First, television seems to have a dwindling amount of educational content. I remember watching 3-2-1 Contact, Mr. Wizard, and NOVA as a kid. The programs currently on PBS don't seem to show the same interest in science, substituting fantasy, social interaction, and ironically, reading. This may be related to my perception that they are also oriented to a younger audience, but I can't help but feel that kids should be learning these things instead of watching TV, not by watching it.

Second, this video is from a program called For All Practical Purposes and was filmed in the late '80s. The computer systems used are from Symbolics, a company that made their own hardware and operating system written entirely in lisp. This idea is similar to the current Squeak project, which is written in smalltalk instead of lisp. The video is old, the computers are old, the technology is old, and yet, it isn't particularly different from the basic concepts that I learned at Georgia Tech a few years ago. The biggest changes have been in the hardware that allows us to animate using physical simulation, and have realtime rendering.

Modern computing doesn't seem that different from 80's computing, except that everything is faster, larger, less efficient, prettier, more connected, and cheaper (much, MUCH cheaper). Just today I learned of a London startup that is writing games that would have run on a 1.2 MHZ Atari 2600 in Macromedia Flash - which uses most of my 1,200 MHZ CPU. But ultimately, its all the same. In my eyes, this makes a stronger case for the idea of Computer Science, because if you ever really learned how computers work, you might understand them forever.

Friday, November 16, 2007

parent and __parent__ and __proto__, Oh My!

Sometimes Javascript development can be rather scary. Unlike C or Java, which have well known standards, Javascript (like HTML) is often described by what works on one or more of the current implementations. On top of that, few people see Javascript as a legitimate language, and a vast number of novices are out there writing code that would make your skin crawl.

In short, if you are a knowledgeable programmer, quickly picking up Javascript is much harder than it should be. The syntax is C-like (generally regarded as a plus), the functions are first class (almost universally positive), and the object system is prototype based (at least smalltalk people like this). Soon there will be a common just-in-time compiler, and some people have suggested that it might displace currently popular languages. Personally, I wish that it ditched the prototype object system for a Python-like one, and had lisp-like macros, and just-in-time compilation can't come soon enough.

When a question about a Javascript feature like "x.__proto__" arises, it can be difficult to answer. In my experience so far, the best places to look are MDC and the IRC channel listed on the page.

What is __proto__?

When you make a Javascript "class" (ie constructing function), you can specify a prototype:
function Example() {
this.foo = 1;
}

Example.prototype = {
sample : function memberFunction() {},
}
This attribute is copied onto constructed objects as __proto__, like so:
ex = new Example();
if (ex.__proto__ == Example.prototype) print("same!");
__proto__ is a special attribute that is searched if an attribute is not found on the object, it is analogous to a parent class.

parent and __parent__ are substantially different. parent comes from the DOM, and is the tag that encloses the current tag. __parent__ is a special variable that is a reference to the scope that created the object. Like __proto__ is checked when a variable lookup fails. Where __proto__ is checked when the failure looks like this.missing_attribute, __parent__ is checked when the failure is in the form missing_global. According to Mozilla, __parent__ and __proto__ have been deprecated, which is unfortunate since they can be quite useful.

Monday, November 05, 2007

Debugging Python

Above all else, my greatest annoyance with python is the lack of good documentation and defaults. I bet that there is a group somewhere that knows everything there is to know about python... I beg of them, write that knowledge down!

Here's an example. I want to debug a faulty program:
x = [1,2,3]

def foo():
sum = 0
for i in range(4):
sum += x[i]

import pdb
pdb.run("foo()")
I'm then prompted by pdb: (> replaced with ])
] [string](1)?()
(Pdb)
Good, now I'm in the debugger. To get things started, I type "c", return, and get:
Traceback (most recent call last):
File "[stdin]", line 1, in ?
File "c:\Python24\lib\pdb.py", line 996, in run
Pdb().run(statement, globals, locals)
File "c:\Python24\lib\bdb.py", line 366, in run
exec cmd in globals, locals
File "[string]", line 1, in ?
File "[stdin]", line 4, in foo
IndexError: list index out of range
]]]
You should notice that the last line is the standard python prompt (with the aforementioned character replacement to make blogger behave), not the debugger. I have finished my debugging session due to an error. Gee, it sure would have been nice to debug that, since my state is now lost! I was already using the debugger to run this code, why did it not catch this exception?

It turns out that exception handling is done by sys.excepthook, and pdb.run doesn't set the excepthook. Some searching turned up two options. The first is simple but crude - add the following to site-packages/sitecustomize.py:

Thomas Heller
import pdb, sys, traceback
def info(type, value, tb):
traceback.print_exception(type, value, tb)
pdb.pm()
sys.excepthook = info
The second is more sophisticated, and checks for interactive mode:

ActiveState Python Cookbook.
# code snippet, to be included in 'sitecustomize.py'
import sys

def info(type, value, tb):
if hasattr(sys, 'ps1') or not sys.stderr.isatty():
# we are in interactive mode or we don't have a tty-like
# device, so we call the default hook
sys.__excepthook__(type, value, tb)
else:
import traceback, pdb
# we are NOT in interactive mode, print the exception...
traceback.print_exception(type, value, tb)
print
# ...then start the debugger in post-mortem mode.
pdb.pm()

sys.excepthook = info
Here's what I'm currently running:
# code snippet, to be included in 'sitecustomize.py'
import sys

def info(type, value, tb):
if (#hasattr(sys, "ps1") or
not sys.stderr.isatty() or
not sys.stdin.isatty()):
# stdin or stderr is redirected, just do the normal thing
original_hook(type, value, tb)
else:
# a terminal is attached and stderr is not redirected, debug
import traceback, pdb
traceback.print_exception(type, value, tb)
print
pdb.pm()
#traceback.print_stack()

original_hook = sys.excepthook
if sys.excepthook == sys.__excepthook__:
# if someone already patched excepthook, let them win
sys.excepthook = info
The original ActiveState script doesn't debug if you are running in interactive mode. To me, this makes no sense at all - thats a case where I specifically want to debug.

Alas, if the debugger shows an obvious error that could be fixed, python exceptions cannot be resumed. The code listed here will let you see the stack and move around in it, but your program is no longer running and can never finish where it left off. Allowing this requires call/cc, and as far as I can tell there is no plan to ever support that in python.

If this was helpful, or should be changed, let me know. I've just started using it myself.