Sunday, July 10, 2005

Small features, bugfixes

Today I worked all over the map. Maybe the most interesting aspects are that nested types and truly polymorphic containers don't crash the compiler anymore.. :-) They actually seem to work. The following example compiles and runs fine for example:
def duplll(x):             # x: [list(A)]
return [x] # [list(list(A))]

a = duplll([1]) # [list(list(int))]
b = duplll([1.0]) # [list(list(float))]

def ident(x): # x: [list(list(A))]r
return x # [list(list(A))]
def meuk(x): # x: [list(list(A))]
return ident(x) # [list(list(A))]

c = meuk(a) # [list(list(int))]
d = meuk(b) # [list(list(float))]

def makel(x): # x: [list(A)]
return [x] # [list(list(A))]

def dupl(x): # x: [list(list(A))]
return [makel(x[0])] # [list(list(list(A)))]

dupl([[1]]) # [list(list(list(int)))]

y = [[('1',)]] # [list(list(tuple(str)))]
dupl(y) # [list(list(list(tuple(str))))]

d = [[1]] # [list(list(int))]
d = [[1.0]] # [list(list(float))]
d # [list(list(pyobj))]
It contains a polymorphic call chain ('meuk' and 'ident'), nested (in the first iteration even recursive) types and a truly polymorphic container in the end. It's nice to see all the C++ crap that is generated just for the last assignment, especially considering that in Python often much more involved datastructures are used than a list of lists of floats (I'll show some nice examples later on :-))
d = ((list[list[pyobj *] *] *)(new list[list[double] *>(1,
new list[double](1, new double(1.0)))));
The cast is necessary because C++ won't (rightly) accept the assignment otherwise, and the float is allocated on the heap, because that's how I currently represent 'confused' objects (it can't be unboxed, because floats and integers are confused inside the container.) I believe it's a nice example of how static type checking gets in the way of programming. I dare not show the entire generated C++ program :-)

Other than the above, I fixed many small bugs, rediscovered my affinity for unit testing, made some old unit tests work again and improved the splitting at confluence points (by actually looking at which creation sites come in via the data flow edges - for example, the two edges may provide the same sets, in which case splitting is not very useful.)

Still, there is so much more to do it makes me feel a bit discouraged at the moment. I'll just have to take it feature by feature and bug by bug at a time.. sometimes I feel like the guy in 'Touching the Void'. Watch the movie and you'll know what I mean :-)

No comments: