Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Monday, April 04, 2011

Easier Memory Release In Objective C with Blocks

I've been getting my head around Objective C recently and remembering all that is great about about manual memory management. I found myself repeating code that either a) autoreleased or b) released with try finally loops. The autorelease puts a drag on your pool so you want to use it sparingly (with APIs where you don't know who will be calling it) and it's mentioned in several places in the Apple documentation to favor "release" over "autorelease". So, that leaves me with option b in most of my code with a lot of boilerplate code. And I hate boilerplate code. Well, did some more reading and found out that blocks are a new thing in Objective C and I quickly whipped this up:
typedef void (^Monadic)(id value);
typedef id (^Niladic)();

-(void)use: (Niladic)calc during:(Monadic)monadic {
    id toUse = calc();
    @try {
        monadic(toUse);
    }
    @finally {
        [toUse release];
    }
}
Basically, it allows you to send in one block to get the allocated object and then use it in a try finally. It automatically cleans up after itself! I then decided to try it out on some code:
-(IBAction)calculateClicked:(id) sender {
    [self 
     use: ^() { return [[Cents alloc] initWithString: [startView text]]; } 
     during: ^(id startAmount) {
         [self 
          use: ^() { return [[Cents alloc] initWithString: [eachYearAmountView text]]; }
          during: ^(id eachYearAmount) {
              [self
               use: ^() { return [[NSDecimalNumber alloc] initWithString: [interestView text]]; }
               during: ^(id years) {
                   Cents *answer = [startAmount
                          atRetirementAdd: eachYearAmount 
                          earning: years 
                          for: [[yearsView text] intValue]];
                   [resultView setText: [answer description]];
               } ];
          } ];
     } ];
}
I think I made it too generic in that I now have to type "^() { return [blah blah blah]; } every time. I realized I could get rid of those blocks and just pass in the object I want to clean up. Remove Niladic block and take two looks like this:
typedef void (^Monadic)(id value);
-(void)use:(id)toUse during:(Monadic)monadic {
    @try {
        monadic(toUse);
    }
    @finally {
        [toUse release];
    }
}
And this is what it looks like when you use it:
-(IBAction)calculateClicked:(id) sender {
    [self 
     use: [[Cents alloc] initWithString: [startView text]]
     during: ^(id startAmount) {
         [self 
          use: [[Cents alloc] initWithString: [eachYearAmountView text]]
          during: ^(id eachYearAmount) {
              [self
               use: [[NSDecimalNumber alloc] initWithString: [interestView text]]
               during: ^(id years) {
                   Cents *answer = [startAmount
                          atRetirementAdd: eachYearAmount 
                          earning: years 
                          for: [[yearsView text] intValue]];
                   [resultView setText: [answer description]];
               } ];
          } ];
     } ];
}
As long as the Monadic blocks stay on the stack we don't need to do the copy autorelease business on block objects. I like this code better than nested try finally code because I'm not repeating the name of my variable to release in the clean up code. I'm still not 100% happy with the code, but I'll keep playing around with other things until then. I do like the fact that it is simple. Just something I wanted to share as I learn Objective C.

Friday, March 11, 2011

Singleton Pattern in Dojo

Recently, I needed to have a singleton object. So, I came up with the following implementation to give me just that.
var makeSingleton = function (aClass) {
    aClass.singleton = function () {
        var localScope = arguments.callee;
        localScope.instance = localScope.instance || new aClass();
        return localScope.instance;
    };
    return aClass;
};

When declaring my class in Dojo, I did the following:
makeSingleton(dojo.declare(...));
Then, to use it:
var instance = myClass.singleton();
I like the fact with this implementation that it's obvious that I'm creating a singleton object up front around the dojo.declare. Of course, there's nothing preventing someone from creating the class with new, but we could easily get around that with throwing an exception in our constructor after our singleton has been initialized.

Saturday, October 10, 2009

Freezing Objects in Python

Someone stop me. I like freezing simple objects or what Eric Evans calls "Value Objects" in his excellent "Domain Driven Design" book. Python doesn't have immutable objects (ala freeze in Ruby) explicitly, but we can easily create it. Python gives us the power to get under its covers. Here's my implementation:
class ValueObject(object):
def __setattr__(self, name, value):
if name == 'value' and hasattr(self, 'value'):
raise AttributeError("Can not change value attribute")
else:
self.__dict__[name] = value


Do you have to ask? Yes, I made a test. Here they are:
import unittest
class Test(unittest.TestCase):

def testSimple(self):
class Cents(ValueObject):
def __init__(self, value):
self.value = value
def __str__(self):
return str(self.value) + " cents"
subject = Cents(5)
self.assertEquals(5, subject.value)
def set_value():
subject.value = 6
self.failUnlessRaises(AttributeError, set_value)

Monday, October 05, 2009

method_missing in Python

OK, I know there is a few implementations of this knocking around on the net already, but I'm in learning mode. So, here's my implementation of Ruby's method_missing:
class PossibleMissingAttribute(object):
def __init__(self, object, name):
self._object = object
self._name = name

def __call__(self, *args, **kwargs):
return self._object._method_missing(self._name, *args, **kwargs)

def __str__(self):
return self.__class__.__name__ + ": " + str(self._object) + "." + self._name

def __getattr__(self, name):
return None

def __nonzero__(self):
return False

class MethodMissingError(Exception):
def __init__(self, object, name, *args, **kwargs):
self.object = object
self.name = name
self.args = args
self.kwargs = kwargs

def __str__(self):
return repr(str(self.object) + "." + self.name)

class Missing(object):
def __getattr__(self, name):
return PossibleMissingAttribute(self, name)
def _method_missing(self, name, *args, **kwargs):
raise MethodMissingError(self, name, *args, **kwargs)


Three objects and that's it! One to be a placeholder when an argument is missing. One object to represent the MethodMissingError and the last to be an abstract class to inherit from. But, you could easily just put these methods anywhere. Here's my tests:
import unittest

class TestMissing(unittest.TestCase):
def test_missing(self):
class TestClass(Missing):
def __str__(self):
return self.__class__.__name__
def existing(self):
return "i am"
def _method_missing(self, name, *args, **kwargs):
return args[0]
self.assertEquals("am not", TestClass().missing("am not"))
self.assertEquals("i am", TestClass().existing())
self.assertEquals(None, TestClass().missing.something_else_missing)
self.assertFalse(TestClass().missing)
self.assertEquals("PossibleMissingAttribute: TestClass.missing", str(TestClass().missing))

def test_exception(self):
class TestClass(Missing):
def __str__(self):
return self.__class__.__name__
self.failUnlessRaises(MethodMissingError, lambda: TestClass().missing())



You've seen my implementation. Here's another one that I found on the net: method_missing in Python
class MethodMissing(object):
def method_missing(self, attr, *args, **kwargs):
“”" Stub: override this function “”"
raise AttributeError(”Missing method %s called.”%attr)

def __getattr__(self, attr):
def callable(*args, **kwargs):
return self.method_missing(attr, *args, **kwargs)
return callable

Um, this version is much shorter than mine. It gets the same job done and is more obvious of what it is doing. Simply returning a function on __getattr__ is the best way to go. It's what my PossibleArgumentMissing was doing. But, where I tried to get all fancy using __call__ to mimic a function which caused my version to be longer. I was also trying to get the argument to come back to return false in if conditions and be almost like None (again, I'm learning and was looking at what was possible). Simplest is best.

This was a fun thought exercise. I love all the hooks Python provides to allow you to get underneath the hood if need be. I will be soon doing a post on descriptors and even decorators. I find Python tends to sway heavier on the functional side of programming versus object-oriented. I'm loving the succinct, yet readable code. Too many languages get into the being so terse that they sacrifice readability or debugability (is that a word? Is now!).

Wednesday, August 06, 2008

Update on Javascript

I've been meaning to write an update to my post on Javascript prototypes. Let me just show the updated code and then I'll explain what's changed.

Base = new Object();
Base.clone = function() {
var creator = function() {
this.constructor = arguments.callee
};
creator.prototype = this;
var result = new creator();
if (result.initialize)
result.initialize.apply(result, arguments);
return result;
}

Base.mixIn = function(properties) {
for ( var each in properties)
if (properties.hasOwnProperty(each))
this[each] = properties[each];
return this;
}

ZipCode = Base.clone().mixIn( {
initialize : function(standard, extension) {
this.standard = standard;
this.extension = extension;
},
toString : function() {
return this.standard + "-" + this.extension;
}
});

print(ZipCode.clone('56777', '4567'));

First thing you will notice is that I got rid of Object.prototype. I'll admit all of my recent Javascript code has been scripting on the server side. I do sometimes forget about all of the legacy code running on the browser(Adding properties to the Object.prototype can cause bugs in naive for loops). Not to fear, I created a Base object and put the clone and mixIn functions on it.

The next change is to the clone function where I introduced code that will setup the new clone if an initalize function is present. It calls the initialize function with the arguments passed into the clone function. I love doing things like this with Javascript.

Lastly, I had mixIn return itself. The reason is so that I could put the clone and mixIn on one line and only name the prototype once. This means I'm not duplicating the names of my objects and can more easily refactor the names. It also makes it easy to see the name and what prototype it is inheriting from.

I've always been infatuated with prototype-based programming languages. Javascript makes it possible to play with a real life prototype-based language. It saddens me to know that the next release of the standard introduces classes and that so many frameworks force classes into it. Once you get into using prototypes, you don't want to go back. You can use prototypes for a primitive versioning system, change tracking, and more that I haven't thought of yet. If you find more, let me know. Have fun using Javascript in new excting ways.

Thursday, May 22, 2008

Reading other people's code is good

Reading other people's code is the needle lost in the hay buried deep in this article entitled "Language Dabbling Considered Wasteful". Forget the dreadful title that makes my eyes roll back in my head. It's still too close to Dijkstra's famous paper. But, I digress. This is not a pointless rant on over abused trivia.

If you want to become a better programmer, read code and understand it. There's no way around it. Read code, experiment with it, and figure out if you like it or not. Bad code can teach just as much. It's no fun to read, but it shows how not to do things. The danger with bad code is being picking up incorrect habits. Get into the practice of reading code and not the Javadocs. If you're learning a new language you will see the idioms and be able to apply them. Plus, you will know how to find how things work underneath the covers if you run into a super thorny issue.

Yeah, give me the source any day. I love reading code and it's how I learn. Once I get past the basics, I start reading and understanding others code. I will say it again, there are no shortcuts.

Tuesday, May 13, 2008

Javascript: Stop Fighting It

I recently came to the realization that I've been fighting Javascript too much. It's because I've been going against the grain with it. It's like trying to force the OO paradigm in a functional language or the opposite. You might say that I've been treating Javascript like an OO language and you would be right. But, I've been forcing my class-based thinking on it and it's been not so nice.

I've been reacquainting myself with Self and Io again. And it hit me like a rhino slamming into me. I've been doing Javascript all wrong. I should have treating it like the prototype-based language that it is. Sure, it doesn't have the ability to inherit from multiple prototypes like Self, but the way to succeed is with prototypes. Forcing class-based OO is like walking up the rainbow and finding no pot of gold at the end.

First, let's write the following:
Object.prototype.clone=function() {
var creator=function() { this.constructor=arguments.callee };
creator.prototype=this;
return new creator();
}

Object.prototype.mixIn=function(definitions) {
for (var each in definitions) if (definitions.hasOwnProperty(each)) {
this[each]=definitions[each];
}
}

It's just two methods up on the Object prototype. Why clone is not part of the Javascript standard is beyond me. Clone is required in all the other prototype-bases languages I have seen. It is the only way to create new objects. Enough complaining, it was only a few lines of code. All my clone method does is make the object I call it on the prototype of the result. I get a clean object with all of the properties of the receiver inherited. Nice. This is the behavior we want. Next, I added a convenience method to Object to mix-in in other objects. This is helpful to keep my code organized. I can just create a hash object with my functions and properties like before. So far, this is standard stuff. But, here is how I use it:

Pounds = new Object();
Pounds.mixIn({
of: function(value) {
var result=this.clone();
result.value=value;
return result;
},
toString: function() {
return this.value.toString() + " lbs";
},
value: 0
});

print(Pounds.of(5)); // => 5 lbs
print(Pounds); // => 0 lbs
print(Pounds.isPrototypeOf(Pounds.of(5))); // => true

Notice, normally, you define the constructor with the first letter of the name upper cased. I no longer need the constructor, so I upper case on the prototype that will be the example for all the instances that I clone off it. The example above is a measurement class. "Pounds" is my example so I default it with values that the objects that I clone from will have. This is how prototype-based languages work. It feels slightly unusual coming from the class-based background, but I think it makes my Javascript look a lot less alien. I like it.

Let's look at a more complicated example shall we?

Animal = new Object();
Animal.mixIn({
name: "Unknown",
sound: function() {
return "?";
},
toString: function() {
return this.name
+ " goes " + this.sound()
+ " and weighs "
+ this.weight.toString();
},
weight: Pounds.of(0)
});

Cat = Animal.clone();
Cat.mixIn({
name: "Unknown Cat",
sound: function() {
return "Meow";
},
weight: Pounds.of(10)
});

grendel = Cat.clone();
grendel.mixIn({
name: "Grendel",
sound: function() {
return this.constructor.prototype.sound.call(this) + " and Purr";
},
weight: Pounds.of(20)
});

gracie = Cat.clone();
gracie.mixIn({
name: "Gracie",
sound: function() {
return "Purr";
}
});

print(Animal); // => Unknown goes ? and weighs 0 lbs
print(Cat); // => Unknown Cat goes Meow and weighs 10 lbs
print(Animal.isPrototypeOf(grendel)); // => true
print(grendel); // => Grendel goes Meow and Purr and weighs 20 lbs
print(gracie); // => Gracie goes Purr and weighs 10 lbs

"super" is implemented with "this.constructor.prototype". It seems wordy, but prototype on the object is not built-in to Javascript. Besides, you should use "super" sparingly. To me, this reads better and works better for inheritance. I have dropped all references to classes. This makes meta-programming easier as well (I simply walk up the prototype chain with "this.constructor.prototype" and iterate through the properties.

The constructor function used as a class always seemed awkward to me. It was inelegant, but the above fits Javascript coding better. The reason is because I'm now using it as a prototype-based language and not forcing class-based OO on it. The above is meant to get started playing around. Prototype-based programming is so cool and I'm still exploring all of the possibilities. There's little documentation, but the little that is well worth the effort to track down. Have fun!

The example above was tested in SpiderMonkey. A great little REPL for playing with Javascript.

Sunday, May 11, 2008

Quote that describes OO perfectly

I grabbed this from Io Language Guide:
In all other languages we've considered [Fortran, Algol60, Lisp, APL, Cobol, Pascal], a program consists of passive data-objects on the one hand and the executable program that manipulates these passive objects on the other. Object-oriented programs replace this bipartite structure with a homogeneous one: they consist of a set of data systems, each of which is capable of operating on itself.
- David Gelernter and Suresh J Jag

I couldn't have said it better myself. It's not what Paul Graham says at all. I can't help it if he never took the time to understand it.

Friday, May 09, 2008

Seaside at Bar Camp Kansas City

If you are in Kansas City tomorrow and want to learn more about Seaside, then come to BarCampKC. I will be giving a presentation on Seaside. It's the one you can download from SqueakMap, but beefed up. I've included how to do GLORP, script.aculo.us, and more! I will be showing off Smalltalk and Squeak in the process. If you ever wondered why Smalltalk was so cool, now is the time to find out. See you there!

Tuesday, May 06, 2008

I cried

I almost cried for joy when I read this post on one of my favorite topics: Small Classes, Short Methods. Someone has been reading my mind. I love the set of rules. It's something that I strive for in my code. I've run into problems with other developers though (they generally think I am nuts when I wrap things like phone numbers, ids, domain specific codes, etc into objects instead of strings). But, by wrapping the primitive into an object that states it's role, you start moving logic closer to where it belongs. The books "Genius Within" and "Prefactoring" were the books that really brought this home for me (especially "Genius Within"). Lots of great advice. Go read it now!

Monday, April 14, 2008

Missing Explanations

I was looking over my last post and forgot that I didn't discuss these two methods below:
Function.prototype.everyTimeButFirst=function() {
var self=this;
var toCall=function() {
toCall=self;
return null;
};
return function() {
return toCall.apply(this, arguments);
};
}

Array.prototype.toString=function() {
var result="[";
var addComma=function() { result = result + ", " };
var addCommaOnlyAfterFirst=addComma.everyTimeButFirst();
Array.prototype.each.call(this, function(every) {
addCommaOnlyAfterFirst();
result = result + every;
});
return result + "]";
}

It might seem a little overkill to have the everytimeButFirst function, but I think it reads better in the method and communicates the intent. Normally, you could implement putting in the comma in between items in the collection like so:

Array.prototype.toString=function() {
var result="[";
var shouldAddComma=false;
Array.prototype.each.call(this, function(every) {
if (shouldAddComma) {
result = result + ","
} else {
shouldAddComma=true;
}
result = result + every;
});
return result + "]";
}

It's a little bit longer. I hate the boolean variable "shouldAddComma". I really do. It just doesn't read well. It's hard to see what's going on. The naming makes it better. But, it's just adding unnecessary noise.

But, all is not well in the first version that I used either. Not all programmers are versed in functional programming, but even a functional programmer would scoff at the first version. Why? It changes state. Plus, the implementation of everytimeButFirst while clever would not be obvious. Basically, what you're seeing is my experiment in using nothing but functions instead of a boolean. Fun for blogging and brain stretching, but not for production systems. Clever is the enemy of the maintenance programmer. But, what if we did this:
Function.prototype.everyTimeButFirst=function() {
var shouldExecute=false;
return function() {
if (shouldExecute) {
return toCall.apply(this, arguments);
} else {
shouldExecute=true;
return null;
}
};
}

You might say I just displaced the boolean to somewhere lese and you would be right. But, I got it out of the method toString which is where I didn't like it. It's safely behind a wall where it makes sense to have. The internal implementation of everyTimeButFirst was too clever the first time around. It is still using higher-order functions, but one is easier to understand than nested ones that change themselves out.

Remember I said the original implementation would make a functional programmer gag because of the side-effects. We could make it side-effect free by making it recursive. But, Javascript is not optimized for tail-recursion. So, I did what I thought was best.

Friday, April 04, 2008

Monkey Patching

Monkey patching seems to be all the debate rage currently in the dynamic language blogosphere. The one that caught my attention was Gilad Bracha's in particular. I don't disagree with him at all. I know it's strange reading that from a Smalltalker. But, I view monkey patching like inheritance. It's a great device to have in your programmer back pocket, but can be dangerous. Use with caution and look at your options. Don't use it without thinking of the implications it can cause. The reason its dangerous is because it's a global change that widens the protocol of the affected object or worse changes the contract for an already existing method.

The main reason monkey patching is so dangerous is the global change it makes and the increased probability of having a collision if another project names a method the same. Or worse, another project overrides the default behavior and replaces it with their own. Both can cause subtle bugs that can be hard to catch and find. It's the global nature of it that can bite. It's convenient, but you should think twice before doing it. It's limits your project's options.

Groovy has a novel approach to monkey patching in that it allows them to be scoped for the duration of a block called categories. This reduces the risk of a global change and the addition is only in affect for the duration of the block. Now, it can cause issues if something gets called outside of the block by accident, which is why I wish it had different ways of scoping (class, package, etc). But, with AspectJ these problems can be reduced. Categories reduce a lot of the risk of monkey patching in that collisions are highly unlikely and the protocol is only widened for that invocation. It also ensures that unknown project dependencies will not creep in. I worry less about monkey patching in this instance because if you get burned, it will be your project not everyone else. I think categories are the way to go (if they added class scoped categories, I would be in heaven).

I don't hate monkey patching. Far from it. It is handy to override method implementations during debugging. I can change pre-existing methods if they have bugs in them even before the next release is out. I don't have to wait on the vendor. These are great pluses. I'm just advocating thought before you monkey patch in your own projects. Much like before you swing the inheritance hammer, you should do the same with monkey patches.

Wednesday, March 12, 2008

Uh oh

I should have played the Adventure in Emacs before I went wildly blogging. It is not the original Adventure, but another one entirely. Oh well, it's still fun to play.

Tuesday, March 11, 2008

Houston, We Have Zork

Malyon is a Z-code interpreter written in Emacs Elisp. Now, I have an Infocom mode to play Zork, Enchanter, Starcross, Hitchhiker's Guide To The Galaxy, and more. Love is. I have all of the Infocom Z files and a bunch from other interactive fiction authors. I've got some reading and adventuring to do while I continue my Emacs journey. Maybe I'll play a little Stationfall during my next *cough*compile*cough*.

Giggling With Emacs

I started out with AquaEmacs, but quickly switched to Carbon Emacs. The reason was because I still use Windows in other places and it was easier switching between GNU Emacs on Windows and Carbon Emacs on Mac. After my efforts tonight, I have line numbers displaying in the left column thanks to linum.el. I'm finding Emacs Wiki to be a great resource for information. I'm mainly learning by reading other people's code and .emacs files. As with anything, I'm finding lots of things that don't work and performing tons of searches into what certain commands do. Emacs has great help support built-in and is proving to be indispensable in my journey.

But, these are not the reasons for my giggling. I was going through the menus and saw Games under the Tools menu. How quaint. I'm not a big game player. I look at the games listed and see "Adventure". I think to myself, "No way". I click and "XYZZY!" It's the real deal. Oh, I love interactive fiction (Infocom is my fave) and I have never played Adventure. This might keep me busy for a little while. The one kind of game that I love, Emacs has the original built-in. How cool.

Sunday, March 09, 2008

Emacs

To see what I have been missing, I have decided to really get into and learn Emacs. So far, I can I configure the modes and know a lot of the basic commands. I have the Erlang, Ruby, Slime, and Javascript modes working. The thing that has made the difference this time has been making Emacs my editor for everything everywhere. There's no way to fall into old habits.

Some might be wondering why am I torturing myself? I want to see and experience what so many developers that I respect love about Emacs. It's a different viewpoint than mine. Everything is viewed as text whereas I view the world as all objects. It's interesting. It's pushing me out my comfort zone of rich IDEs. I'm not going to say that I've been dealing with is better yet. But, I am making an effort in earnest to learn.

Next steps, I would like to start customizing Emacs through ELisp. Should be exciting and fun!

Wednesday, February 13, 2008

Yet More On Tools

I got so many good comments on Tools that I couldn't just let the replies go to waste. Here's another one from Sam Tesla:
Sooner or later I was going to bite on one of your posts.

While I agree that tools for a language should be written in the language, I have to disagree on specifics.

Why should I have to write Yet Another Yet Another Yet Another Editor for my language in my language when a perfectly good one already exists?

The Erlang/OTP team asked that question and decided they shouldn't. Instead they made an elisp module that turns your Emacs into an Erlang node and uses Erlang's distribution primitives to hook into a live Erlang node.

They provide many of the tools you'd expect from a Smalltalk, including the ability to inspect and interrogate (inasmuch as it makes sense for a functional language) running processes.

It's in Emacs, sure, but that's because Emacs has had at least ten years more to mature than Erlang, let alone any editor written in Erlang.

Good programmers don't repeat themselves if they don't have to.

My answer to this is simply why write a new language to begin with? The reason is simple: to solve a specific problem better than before. We shouldn't stop trying. Now, with that being said, let's move on. I know Erlang is a powerful language and have many times sang its praises. There's a lot of languages in the same boat (Io, Mozart, and many more). I can understand not wanting to do another editor in the beginning, but it's a good exercise. There are non-trivial problems to solve in doing your own editor. Plus, it allows new developers to see a non-trivial example of your new language's code. Again, let's move on.

My main rant was on tools (not necessarily editors), yes, I know I picked on Eclipse and Emacs. But, Eclipse is really much more than a text editor. It has several tools to reason about your code (Refactoring), give your different viewpoints (Call Hierarchy, Class Hierarchy), and ways to ignore what you don't care about. These are the kinds of tools that I am interested in. I think a code beautifier and debugger are the price of admission. You are not even playing the game without those. Now, Erlang is a different way of thinking, it should have tools to support that thinking. Much like the Refactoring Browser changed the way we view code in Smalltalk. I think Ruby is ripe with opportunities to change the way we think about code. Again, the tools should reflect that.

I'll use a simple example: AspectJ. Now, it's not a language per se. But, it's a different way of viewing code and a different way of developing. I liked the idea of aspects, but it didn't click until the Eclipse support came. Once it was easy to see the consequences of my actions, my mental model became stronger. It also made it easier to reason about what my systems were doing. Tools should aid and enhance your mental model. They should allow you to ignore details and quickly hone on the ones you do.

Lastly, I'll add that I wouldn't even think about doing Java code without Eclipse. It's the tools. But, when I'm programming in another language like Ruby for example. I want to stay thinking in that language. So, if I have an idea for a nice tool, it should be easy to whip it up in the language I'm working in. I shouldn't have to switch gears to another language. We should think of languages as playgrounds to change the way we program and change it for the better.

More On Tools

Friedrich had this to say about my Tools post:

I wrote about this on the Squeak mailing list and I guess somewhere else also. I asked for decent editor written for Squeak, AFAIKT such a thing does not exist. But does that mean that Smalltalks are not good for programming an editor? And if no-one sees that this would be good thing, am I expected to step in?

First off, I could give the quick flippant Smalltalker response and say, "If you need a text editor that can handle large chunks of text, then you're doing something wrong." But, I'm not. Sure, we don't need to handle large chunks in coding for Smalltalk, but the world is a different place now. The need is there. Today we need to handle XML documents, source from other languages, HTML, and that's just a start. But, an editor that can handle large amounts of code and makes it easier for new Smalltalkers to get them into the swing of things so to speak.

Secondly, the Smalltalk community might not know they need it. Write it! If anything you might deficiencies through the exercise and decide to fix those as well. I wrote a Java Serialization framework to learn its format, but to fix bad streams as well. Nobody wanted it, but me. You got to do things for yourself and for your own journey as a developer. If you need any help, feel free to contact me. But, don't expect any community to follow along. The best you can hope for is to make the music and hope other people like the melody to join in.

Monday, February 11, 2008

Tools

I'm a firm believer in that tools should be written in the language that they are to be used for. I always treat a language with caution if the only tools for it are written in Emacs Lisp or Java and not itself.

But, why does it matter? It matters because writing tools for your language in another language tells me something. It tells me that:

  1. It's possibly harder to write in than Java

  2. It's hard to parse

  3. Limited or no reflection support

  4. Not user friendly

  5. Can not perform well enough to support tools written in itself


Any of the above points are bad in my book. But, I see it constantly in new programming languages (even in ones 10+ years old). Now, I love languages and learning them. Why? Because I always walk away with a new way of thinking about things. It's also nice to see how other people solve certain problems. It shocks me though that so many languages depend on Eclipse or Emacs for their tools. At some point, a language moves from command line pet project to a true programmer amplifier. The language has to be elegant in syntax, yet have the tools to make debugging and reasoning about the system simple.

Now, before you get angry with me, I do realize that using Emacs or Eclipse gives a huge boost in the beginning with their frameworks. But, by never leaving them, it could also mean there are holes in your frameworks or in your language itself. Tools written in your language help to expose issues like limited reflection or that your language is hard to parse. I believe writing tools should be easy and for everyone to do. If writing tools in your language is hard, then you might need to redesign your language.

I think if we had more languages that had their tools written in them, we would all benefit. Plus, with tools written in your language, new developers have some example code that has real world applications. The way to prove to me if your language is elegant is not to show me how easy factorial is to write, but to show me how easy it is to write an inspector.

Wednesday, November 28, 2007

Some Metrics






LanguageAvg Methods/ClassMax Methods/ClassAvg Params/MethodMax Params/MethodAvg Fields/ClassMax Fields/Class
Squeak9.397800.64161.02100
Ruby12.696830.4270.7631
Java8.671810.91122.42343

I ran the metrics, that I talked about in my last post, in three environments and the results are above. Nothing really shocking, but the maxes did surprise me. I was mainly interested in the averages and the maxes were there just to see how huge the big boys really are.

I wonder what developers would think of a language that restricted the number of things that they could define. What if by looking at the numbers of above, I designed a language that didn't allow more than 256 methods/class, 8 parameters/method, and 16 fields/class. It would force the developer to write smaller entities, but would it annoy more than help?

Where I'm going with this is simply, what if the language enforced certain hard restrictions instead of allowing any incredibly large number of possibilties? If elements were kept to a certain size, would it make programming in the system more pleasurable since it would be difficult to create a god object? Objects would not get out of hand before refactoring thus making maintenance easier.

My gut instinct is that constraints would annoy and ugly code would still live. Developers would just figure out ways around them. I would love to think that by adding constraints, we could get better code. But, no matter what you measure quality by, there will be developers that will figure out how to get around it. Pessimistic, I know. But, it's simply human nature.

Still, I wouldn't mind if the language did have some limits, so that individual items stayed small. If the constraints were not dogmatic, it would make the need to get around them less attractive. Of course, with smaller things comes naming them and that would still be a problem. But, that's a problem with mammoth sized objects as well. I'll keep thinking on this. There's got to be a way to have flexibility to dream the impossible and yet gently nudge us into more maintainable programs at the same time. The problem with balls of glue is that slowly become that way. It would be nice to not allow them to become Godzilla.