Friday, March 23, 2012

My dream editor

I was watching an amazing video today: "Inventing on Principle" by Bret Victor. http://vimeo.com/36579366  Even if you don't read this blog post, go watch that video. Then, if you feel like it, read this :).


I was inspired to think about what features The Great Ultimate Editor of All Time would have in it. So here's the start of my ridiculous wishlist. In particular, I'm concentrating on thinking about any and all kinds of code analysis, visualisation or tools which help the reader to understand code as quickly as possible, and show it to them in ways that makes understanding as simple as humanly possible. It's probably not very deep thinking, so don't shoot me if you think this is all a bit silly to the thinking about :)


Inbuilt:
  • nosier / test re-execution
  • sphinx docs of file
  • code inspections (pylint, pep8)
  • develop-with-example / standard test / default input view
  • advanced folding / hiding
  • embedded images and formulas in docstrings
  • "hg replay" / "instant history"
  • integrated visual diff
  • Code re-use heat-map (number of times function is referenced)
  • coverage heat-map
  • Maybe a performance heat-map (slow lines, fast lines etc)

Wednesday, March 21, 2012

Polymorphism: Beyond the Factory Method

So here's the basic idea. There is some situation, where you have several or many similar classes. Let's say we have customers. They are broken into a bunch of categories, based on buying habits, geographic location, blah blah blah.

Faced with this situation, it's a clear case for inheritance. Common attributes are set in the base class, and specific attributes and/or method overrides are set in the subclasses. A frequent approach to this is to build a factory for building these, which can recognise from the initialisation arguments and maybe some context what kind of customer to build in each situation.

That's all fine and great, but I'd like to propose a new approach: doing all that inside the base class constructor. I initialise a base class Customer with all the relevant info. I get back a customer, but maybe I get back an AustralianCustomer or a FilthyRichCustomer.

Here's an example of how to do that in Python.


class BasicClass(object):
  def __new__(cls, value, category):
    if category == 1:
       return CatOne.__new__(CatOne, value, category)
    if category == 2:
       return CatTwo.__new__(CatTwo, value, category)

class CatOne(BasicClass):
 
   def __new__(cls, value, category):
      instance = object.__new__(CatOne)
      #instance.__class__ = CatOne
      return instance
   def __init__(self, value, category):
      self.value = "CatOne: %s " % value

class CatTwo(BasicClass):
   def __new__(cls, value, category):
     instance = object.__new__(CatTwo)
     return instance
   def __init__(self, value, category):
      self.value = "CatTwo: %s" % value

foo = BasicClass("Hello", 1)
bar = BasicClass("World", 2)
print foo
print foo.value


What's going on here is that the category classes *do* inherit from BasicClass. Any methods I put onto BasicClass will get inherited down the stack. However, when I initialise it, what I actually get back is one of the category classes. I have effectively pushed the factory pattern into the base classe's constructor methods in order to simplify how I create objects.

I think I like it :)


I just wanted to see what would happen...

>>> class Foo:
...    def __init__(self):
...       self.info = "I am a foo"
... 
>>> foo = Foo()
>>> foo.info
'I am a foo'
>>> class Bar(foo):
...    def __init__(self):
...       self.info2 = "This should be interesting"
... 
Traceback (most recent call last):
  File "", line 1, in
TypeError: Error when calling the metaclass bases
    __init__() takes exactly 1 argument (4 given)
>>>