Tag: java

Is a large corporate making money off open source or open standards an oxymoron ? In a Sun / Java Context

Posted by – April 22, 2009

The recent acquisition of Sun by Oracle reignited a thought that had been going through my mind for a long time. It simply boils down to whether a large corporate can make money off open source or open platforms. Now quite obviously it in itself is not a truism. But the point remains that large corporates which have become large in the conventional economy do find the going a little difficult when trying to make money off open software.

The way I perceived it, Sun was going through similar difficulties. The hardware business was delivering dwindling margins post the dot com bust, and the software business was under threat from upstarts such as Linux which offered a substantially similar software stack at near zero licensing costs. One of the crown jewels asset Sun had in its stable was Java. And while it was (and continues to be) a wonderful asset, it just was incredibly difficult to make money off it. Now java hasn’t been open source exactly for most of its life, but it was a sufficiently open stack nevertheless to cause the same difficulties that open source software would in terms of monetisation.

There’s an excellent blog post written a year and half ago by Michel Bauwens, Can the experience economy be capitalist? which does refer to some of the underlying issues. I suggest you do read it, but would like to quote a few points from it below.

First of all, in the field of the immaterial, we are no longer dealing with scarce goods, but with marginal reproduction costs and non-rival goods. With such goods, sharing does not diminish the enjoyment of the good, since all parties retain their ability to use them. The emergence of peer production shows a new form of creating value, that is in fundamental aspects “outside the market”. Typically, in commons-based production we have a common pool, accessible to everyone (Linux, Wikipedia), around which an ecology of business can form to create and sell scarcities (usually services and experiences). In sharing-oriented production (YouTube, Google documents), we have proprietary platforms that enable and empower the sharing, but at the same time, sell the aggregated attention (a scarcity), to the advertising market. Finally, in the third crowdsourcing mode, companies try to integrate participation in their own value chain and framework.

So the good news is that indeed business is possible. But I would like the readers to entertain the following proposition, nl. That:

1) The creation of non-monetary value is exponential

2) The monetization of such value is linear

In other words, we have a growing discrepancy between the direct creation of use value through social relationships and collective intelligence (open platforms create near infinite value through the operations of the laws of Metcalfe and Reed), but only a fraction of that value can actually be captured by business and money. Innovation is becoming social and diffuse, an emergent property of the networks rather than an internal R & D affair within corporations; capital is becoming an a posteriori intervention in the realization of innovation, rather than a condition for its occurrence; more and more positive externalizations are created from the social field.

Quite eloquently argued here that open platforms create near infinite value which is difficult to be captured by business and money. I still remember companies such as Borland, HP, Sun, IBM making a fair amount of money through selling C/C++ compilers and IDEs (I remember it used to be almost $5000 per seat). However this was in the days when the community capability of creating similar competing software stacks was only in its infancy. No longer so today. Now communities, open standards, open processes and open source are fairly well established sources of delivering asymmetrically significant capabilities at a fraction of the cost, a fraction which is made even smaller when the same is incurred by a small motivated group of individuals or small highly agile companies. There in lies the difficulty. Companies are trained to and built to deliver linear and symmetric capabilities in the context of costs they incur. However they have a relatively poor handle on monetising in scenarios where small teams can deliver exponentially asymmetric capabilities.

The blog post I referred to above, identifies the right area to look at in this context – Identify what is scarce and Monetise the scarcity. So when any software has a sufficiently large utility and can be managed through open processes to be able to satisfy a globally substantial demand at a fraction of the cost (eg. apache httpd), that particular capability (eg. static and dynamic file serving over http) is no longer scarce enough for a commercially focused company to make money out off. Thats why the money shifts where the scarcity is – how to leverage such software and put it to good use. This is where the existing commercial successes around open source are based on eg. RedHat, JBoss, IBM, Oracle etc. They monetise the support, training, services and consulting around such software. In many ways Sun could be argued to be a victim of its own success. It not only went much further than any other large corporate in terms of creating open specifications, it also contributed substantially to sufficient knowledge dissemination and tooling to allow many other individual, SME and large corporates to be able to compete with Sun in these very areas that Sun could’ve monetised. Sun thus created its own competition for monetising the scarcity that got created around Java even as many others cried out hoarsely that Sun simply wasn’t open enough. Will there be an incentive for Oracle to reverse that somewhat ? I suspect that could be a logical option if it focuses on ensuring a good ROI for Sun’s Java investments and assets and more so to be able to make itself more capable in the space around Java than the competition (ie. IBM).

So is a large corporate making money off open source or open standards an oxymoron ? Viewed narrowly yes. Because while it is possible for a small team to make some money with adequate ROI off open source or open standards, it is unlikely to be feasible for large corporates. They really need to figure out what is the new scarcity that gets created off such initiatives, come to a judgment that the opportunity arising from such scarcity is large enough and worthy of their time, attention and investment, ensure that there is no current available capability of anyone else disruptively delivering exponentially asymmetric value in that space, and finally occupy that space before other large corporates do.

It does boil down to the fact that while individuals and small companies may find it easier to monetise open source and open standards, the same is going to be generally tough for large corporates. Or as Michel Bauwens said in the blog post I referred to (in my opinion perhaps a little exaggerated but not entirely off the mark)

For all of this, we will need new policies, major reforms and restructurations in our economy and society.

But one thing is sure: we will have markets, but the core logic of the emerging experience economy, operating as it does in the world of non-rival exchange, is unlikely to have capitalism as its core logic.

Will Rails go the Struts 1 way ?

Posted by – December 24, 2008

Just saw the story Merb gets merged into Rails 3. Quickly reminded me of another story that played itself out similarly around Nov. 2005 ie. Webwork Joining Struts. And there really are some parallels indeed. (Disclaimer: While I can claim to know struts quite well and webwork exceptionally well, my knowledge of Rails is limited and that of Merb is rather superficial)

  • Struts 1 was the grand daddy with a massive market share, whereas Webwork 2 was the upstart
  • Struts 1 established its dominance by being far ahead of its competition in its time. Webwork 2 was the exceptionally well designed, highly compartmentalised, granular and flexible MVC framework which clearly established a strong design lead over Struts 1
  • Struts 1 was monolithic, Webwork 2 was far more fine grained and pluggable
  • Struts 1 primarily had a single controller servlet, Webwork offered more fine grained controllers

In the post Rails and Merb merge, Katz explicitly refers to the Struts / Webwork 2 Migration. However there was one big difference, while Webwork 2 made some movement towards being just a little bit more struts like during the migration, for all practical purposes the next version after Webwork 2.2.x became Struts 2, and Struts 1 got confined to legacy. In this case it just seems unclear how Rails and Merb will move towards each other. As a designer, I really cannot imagine easily merging two frameworks and have the best of both of them be reflected in the result (it is exceedingly tough but feasible). There is a practical driving necessity of ensuring consistency which is likely to favour one of the two frameworks. I am really left with this feeling that one of them will dominate the other in the end – and this whole effort will be quite unnecessary if Rails has to dominate eventually. Definitely an interesting space to watch.

Java : the perpetually undead language

Posted by – December 11, 2008

It has been quite some time that people have been coming out with statements of Java’s demise. But to see Elliotte Rusty Harold in his post Java is Dead! Long Live Python! do it caused me consternation to no end. You may want to check out his web page to get a sense of his contributions. He has written at least four books on Java including those related to XML Processing, IO, network programming. Incidentally he has also written a book on Beautiful Code (more on that later). I would suggest you read the post first, if the remainder of this post is to make any sense.

I must confess that after having spent years in Java, I like Python more. But I like Python more because of the nature of language that it is. It is natural in its flow (I like the mandatory indentations), its ultra slick programming constructs (ruby actually is a tad slicker but I dont find myself comfortable with its syntax / style and the special characters in the variable names), and its ability to really get a lot of work done with very little code. But having said that, I have no reason to believe or assume that Java is getting threatened in any particularly significant manner from these upstarts such as PHP, Python and Ruby. They are collectively not strong enough as java and are unlikely to pose a threat to Java in the market the matters the most (at least yet) – corporate enterprise software development. Corporates need comfort, and they need comfort that stems from a strong support and promise that they can count on. And they especially need that for enterprise (non workgroup / non department level) applications, and enterprise level application development hires most of the programmers (I can almost hear others starting to yell – buts its true).

I don’t intend to suggest that the newer languages cannot take on the challenges of enterprise software development. But choice of language and platforms in this context is a rather complex process – a process that involves far more than syntax and aesthetics of coding. Backward compatibility is a big deal. A very big deal in this world. You can (and I do) blame Microsoft for all its sloppy software and bloated code base but the fact remains – they made sure that they maintained backward compatibility. In fact, I believe maintaining backward compatibility and compatibility across a large number of devices is what definitely bleeds Microsoft of a lot of time and attention that they could have spent elsewhere.

So we find the academics sitting on large campuses, joined by many people in the web 2.0 / cloud computing environment and some from the workgroup / department application development space, getting gung ho about the newer languages and their cuter syntax, the brevity and the sheer power of productivity (I am one of them). But what they miss is that java solves important plumbing problems. They will realise it even more if they had attempted to deal with distributed cross platform computing in the years of yore with tools such as RPC / DCE / Encina / the various CORBA servers and services etc. etc, and deliver on the same across a whole range of platforms. Through 1996 – 2005 I believe Java solved the problem of platform independence, distribution and binary portability. And that too in an extremely impressive and credible way. You have to realise that the strength of Java is its inclusivity. It attempts to work with everyone and everybody who may want to work with it. Including those who long since adopted it in its early versions and continue to use those versions today. While many language communities attempt to crowd the etherspace with pro-my-language messages, java stands out in the fact that it doesn’t attract deliberately but it does not turn anybody away. Ever.

Sure Python 3.0 made some very welcome changes, and sure many of the changes make the code become much more intutive, but make no mistake if java generics had broken backward compatibility, its economic impact would’ve been far in excess of that triggered by all the version upgrades of Python, Ruby and PHP put together. I do believe that this approach will eventually lead to substantial subobtimisation but thats still some time away. Moreover Java needs new features and enhancements like Yul Bryner required a hair cut. Java already has so many features and capabilities, new features wont matter much in the overall scheme of things for quite some time. Java is fine, it doesn’t particularly need to grow.

Whenever I write a new application for myself, Python shall always have the first right of refusal (ie if Python doesn’t meet the requirements adequately, only then will I evaluate other languages). However when required to build an application for a customer, who wants the comfort that his application will continue to run for another 10 years at least without him having to make any changes or enhancements to the code and be able to move it around from hardware to hardware, you exactly know which language I shall choose – Java. Thats why despite all the assertions of java being threatened, and even as other languages continue to grow thanks in no small part due to the additional developer productivity promise, I think java shall remain undead for a long long time (all the versions continue to coexist). For java we shall have to say something of the sort – Java 6 is undead, Long live java 7. And 10 years from now just like today, no one is likely to lose his job for having chosen Java. Thats why I strongly believe Eliotte was so wrong.

Python from a Java perspective – Part 2 – How duck typing influences class design and design principles

Posted by – September 25, 2008

Update: Modified the title to make it a little shorter.

This post talks about applying Open Closed Principle, Liskov’s Substitution Principle, Dependency Inversion Principle and Interface Segregation Principle in Python, coming from a Java programming background.

Background :
A few days ago I blogged about Commentary on Python from a Java programming perspective. In that post I avoided getting into the specific details with code snippets etc since I wanted to focus on how it feels.

One of the observations I made was that I thought coming from a Java background, that background helped me from a class design perspective. I ran into a couple of posts from the ObjectMentor blog, namely The Open-Closed Principle for Languages with Open Classes, and The Liskov Substitution Principle for “Duck-Typed” Languages. The gentleman behind ObjectMentor is Robert Martin, who wrote a number of articles in the mid 90s related to these design principles. (Links to PDF : Open Closed Principle, Liskov Substitution Principle, Dependency Inversion Principle and Interface Segregation Principle)

Sidebar : A Hat Tip to Robert Martin : Robert Martin used to contribute heavily to a number of newsgroups including comp.lang.c++ and comp.object in the early and mid 90s. I must confess a tremendous debt to him since my view of OO Design in those days was substantially influenced by his writings, and the design principles he talked about and later published as articles. These continue to guide my thinking about Object Oriented Design to this day. A hat tip to Robert Martin. He wouldn’t know me or recall me, but I used to participate in some threads occasionally, and read him regularly and that helped me tremendously learn so much about OOD and how to apply it in C++.

Having had applied these principles a countless number of times,in C++ and Java, I thought it would be an interesting exercise to document how class design changes even when the same underlying design principles are applied to a dynamic language (in this case – Python). The remainder of this post summarises the design principles and the examples that Robert Martin talked about in his articles, and how these get implemented perhaps a little differently when used in static typed (Java) and dynamically typed (Python) languages. His original source snippets in the C++ language can be found in the articles I have hyperlinked to earlier.

Open Closed Principle (OCP)

Software entities (classes, modules,functions etc.) should be open for extension but closed for modification

What this basically means is that the code you write should be in a manner where it does not need to be modified when you need to extend it – the design of the code should allow for the extension to be made by new code being added, not old code being modified.

In the example below Circle and Square are two Shapes which can be rendered. The design essentially sets out with an objective that it should be easy to add newer shapes (say triangles) without modifying existing code. Lets straight away get into the Java version of the code.

public class Painter {

    public static void main(String[] args) {
        // We sould like the shapes to be drawn in the
        // order of the shape types as found in this list
        List classOrder = new LinkedList();
        classOrder.add(Square.class);
        classOrder.add(Circle.class);

        // The shapes
        List shapes = new LinkedList();
        shapes.add(new Circle(1,1,5));
        shapes.add(new Circle(3,3,7));
        shapes.add(new Square(2,4,3));
        shapes.add(new Square(4,2,4));

        Collections.sort(shapes, new ShapeComparator(classOrder));

        for (Shape shape : shapes)
        {
            shape.draw();
        }
    }
}

// This declaration defines the contract across shapes
public interface Shape {
    public void draw();
}

public class ShapeComparator implements Comparator {
    private List orderedClasses;
    public ShapeComparator(List orderedClasses) {
        this.orderedClasses = orderedClasses;
    }

    @Override
    public int compare(Shape s1, Shape s2) {
        return this.orderedClasses.indexOf(s1.getClass()) -
            this.orderedClasses.indexOf(s2.getClass()) ;
    }
}

public class Circle implements Shape {
    private int x;
    private int y;
    private int radius;

    public Circle(int x, int y, int radius) {
        super();
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    @Override
    public void draw() {
        System.out.println("Drawing Circle at (" +
                x + "," + y + ") with radius " + radius);
    }
}

public class Square implements Shape {
    private int x;
    private int y;
    private int width;

    public Square(int x, int y, int width) {
        super();
        this.x = x;
        this.y = y;
        this.width = width;
    }

    @Override
    public void draw() {
        System.out.println(
            "Drawing Square at (" + x + "," + y +
            ") with width " + width);
    }
}

The Painter class here defines the order in which the various shapes need to be rendered (classOrder), creates a list of all the shapes (shapes), sorts the shapes list using classOrder and then renders all the shapes.

The ShapeComparator is a class which implements the comparator interface for Shapes (public class ShapeComparator implements Comparator) and implements the compare method which compares two shape instances and decides the relative order between them.

The remainder of the code should be rather self explanatory.

So where is OCP being applied here ? For that you have to imagine a new shape, say a triangle now being introduced into the mix. In this case, Triangle would be a new class which would implement Shape. No existing line of code will change. However the Painter main method will now add the new class in the classOrder list in the appropriate place, and if you want to modify the order in which the types should be rendered, just modify their corresponding class placement in the classOrder list. The essential thing to be noted is that Shape, Circle, Square and ShapeComparator are all “open for extension but closed for modification.”

So what does the corresponding python code look like ?

# Look ma ! No Shape class
class Circle(object):
    def __init__(self,x,y,radius):
        self.x = x
        self.y = y
        self.radius = radius
    def draw(self):
        print "Drawing Circle at (%s,%s) with radius %s" % \
                (self.x, self.y,self.radius)

class Square(object):
    def __init__(self,x,y,width):
        self.x = x
        self.y = y
        self.width = width
    def draw(self):
        print "Drawing Square at (%s,%s) with width %s" % \
            (self.x, self.y,self.width)

if __name__ == "__main__":
    order = [ Circle , Square] # the order in which to draw the shapes
    shapes = [Circle(1,1,5), Circle(3,3,7), \
                    Square(2,4,3), Square(4,2,4)]
    for shape in sorted(shapes,
            # Comparison function is embedded inline using a lambda
            lambda s1,s2 : order.index(type(s1)) \
                     - order.index(type(s2))):
        shape.draw()

What learnings can we get from this ?

The first most apparent difference is – No Shape Class. Where did it go ? Well, static typed languages use polymorphism as a powerful mechanism of extensibility. In other words, in many cases the extensions are likely to be newer derived types. Thus design the rest of your code to work on the base type and introduce the newer derived types later as required without having to necessarily change existing code. However static languages primarily depend upon inheritance as the vehicle for delivering polymorphism. Dynamic languages on the other hand depend upon duck typing. Duck typing supports polymorphism without using inheritance. In this context you need the same set of relevant methods to be implemented in each of the extension classes. The role of the abstract base class or interface as the one which specifies the contract / api has been made redundant. You can still choose to define a base class / interface if you want to, but you no longer have to.

Another thing to be noted is the way the comparator is implemented. While java required us to create a new one method class implementing a required interface, and then required us to instantiate the same and then trigger its functionality, python allowed us to implement it inline as a lambda. In a very different way this is OCP being applied (okay okay .. for those insisting on theoretical correctness thats not true .. but close enough) inside the language design itself. A function is an object in python, and a lambda is a special kind (not a subtype) of a function, and there are capabilities built into python to easily manipulate function objects / lambdas. The sorter method functionality was extended to allow custom comparators by specifying a particular evaluation expression as lambda. In java we actually had to implement the inheritance hierarchy ourselves before being able to leverage the extensibility in the list class for custom comparisons.

In the context of OCP, the learning is that dynamic type languages allow you to build extensibility by leveraging duck typing instead of type inheritance.

Dependency Inversion Principle (DIP)

  • High level modules should not depend upon low level modules. Both should depend upon abstractions.
  • Abstraction should not depend upon details, details should depend upon abstractions

To understand the principle, the reference point should be structured and modular programming scenarios prior to OO. If I wanted to book a tour, the tour booking function would in turn call functions to book a flight, book a car and book a hotel. All four function implementations would be in the parlance of the definition – “details”. And anytime you had to change the way any of them worked it would require a relatively high amount of effort to do the changes. If you applied DIP in such a scenario, you would perhaps have a function say TripBooker which would in turn call methods on other classes which implement the methods in an interface / abstract class to book a flight, car and a hotel. The actual detailed booking logic would now be implemented in another class. Thus TripBooker now depends upon an abstraction which specifies the contract, and it becomes much easier to change or plugin the concrete implementations.

As an aside I must note that I have found code which properly applies DIP creates enormous frustration amongst people coming from a procedural background and lesser oriented to this OO style when attempting to statically browse the source. (Java Eclipse users will understand the quote : “I was attempting to understand the logic. I did F3, F3, F3 and then I reached a interface.”, thats because attempting to decipher the logic invariably leads to an abstraction and the programmer has to now separately figure out which was the detailed implementation which would now get triggered). But thats a learning curve issue – not really an issue with DIP.

In the following example which is largely similar to (but not identical to) the example in Robert Martin’s article, we are having a Lamp with a button. All the class names from the example are retained. These are the two specific details – Lamp and ButtonImpl. The lamp has capabilities to turn on and off, but one would like to to move the exact mechanism of turning on and off (which might be hardware specific) into the detail but treat the ability to turn on and off as an abstraction (ButtonClient). Meanwhile buttons can have a variety of possible implementations one of which is ButtonImpl, which all share the essential characteristic that a button has one state with two possible values, can toggle between the states and have a reference to a ButtonClient to which they can communicate with.

Thus the model instead of having two details Lamp and ButtonImpl, with the details communicating with each other directly, one has the following design :

  • Detail Lamp implements (depends upon) abstraction ButtonClient
  • Detail ButtonImpl implements (depends upon) abstraction Button
  • Abstraction Button has a reference to (depends upon) abstraction ButtonClient

Here’s the code in Java.

public class ButtonHappy {
    public static void main(String[] args) {
        Button button = new ButtonImpl(new Lamp());
        button.toggle();
        button.toggle();
        button.toggle();
    }
}

public interface ButtonClient {
    public void on();
    public void off();
}

public class Lamp implements ButtonClient {
    @Override
    public void off() {
        System.out.println("Lamp turned off");
    }   

    @Override
    public void on() {
        System.out.println("Lamp turned on");
    }
}

public abstract class Button {
    private ButtonClient client;
    public Button(ButtonClient client){
        this.client = client;
    }
    public void toggle(){
        boolean newstatus = ! getStatus();
        if (newstatus) client.on();
        else client.off();
        setStatus(newstatus);
    }
    public abstract boolean getStatus();
    public abstract void setStatus(boolean status);
}

public class ButtonImpl extends Button {
    private boolean status;

    public ButtonImpl(ButtonClient client) {
        super(client);
    }   

    @Override
    public boolean getStatus() {
        return status;
    }   

    @Override
    public void setStatus(boolean status) {
        this.status = status;
    }
}

There’s probably no additional explanation required, so here’s the equivalent implementation in python.

class Lamp(object):
    def on(self):
        print 'Lamp turned on'
    def off(self):
        print 'Lamp turned off'

class Button(object):
    def __init__(self,client):
        self.client = client
    def toggle(self):
        status = self.get_status()
        if self.status : self.client.on()
        else: self.client.off()
        self.set_status(not status)

class ButtonImpl(Button):
    def __init__(self,client):
        self.status = False
        super(ButtonImpl,self).__init__(client)
    def get_status(self):
        return self.status
    def set_status(self,status):
        self.status = status

if __name__ == "__main__":
    btn = ButtonImpl(Lamp())
    btn.toggle()

    btn.toggle()
    btn.toggle()

We can again see here that one class that is missing but is no longer being missed ( ;) ) is ButtonClient and the reason is the same as in OCP – Duck Typing. In terms of the definition of DIP itself – abstractions no longer necessarily have to be implemented. They exist implicitly in the detail classes but are no longer explicitly documented.

Liskov Substitution Principle (LSP)

What is wanted here is something like the following substitution property:

If for each object o1of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.

Actually LSP is more of a test of whether two classes qualify to share an inheritance or is-a relationship, rather than a prescription for the design itself. In simple terms it sets out a requirement that if you define a new derived class, it should be possible to substitute an instance of a base class in a program (and though it doesn’t state it, an instance of a peer derived class ie a class in the same inheritance hierarchy) with an instance of a derived class without introducing any negative or unexpected side effects whatsoever. A rather simple example would be if we were to attempt to define a derived class of java.lang.String (say ConstrainedString) which now had an additional constraint (max characters – say 20 for a particular instance). To support this constraint a new runtime exception MaxLengthExceededException would need to be defined. It would have to be a runtime exception as you do not have the ability to add to the checked exceptions thrown by the java.lang.String class in ConstrainedString. Now programs that concatenated strings have no notion of having to react to a String overflow situation and this would create undesirable side effects in the program. Thus using LSP one could conclude that it would be incorrect to implement ConstrainedString as a derived class of java.lang.String.

I could not think of a good way of showing LSP in action in code since it is a test of candidate relationship and does not have any structural manifestation itself. However it is still a valid test to be applied in Dynamic Languages as well with one change as recommended in the post The Liskov Substitution Principle for “Duck-Typed” Languages .

What is wanted here is something like the following substitution property:

If for each object o1of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of substitutable for T.

Duck typing introduces looser coupling than inheritance but a coupling that has no static checks whatsoever. So the application of LSP in a designer’s mind is a little more interesting. Because the modified LSP is now a rather obvious statement which in loose term says “If A can be substituted by B without any side effects then A is substitutable by B”, on the face of things, it is no longer such a useful principle. But if you explore under the covers, the real interesting part has now shifted from “B is a subtype of A” to “If A can be substituted by B”. In static type languages, the places where A was being used was clearly known and easily searchable or navigable into from IDEs. Because this is now so much more difficult even though you are no longer explicitly attempting to apply LSP, you are on your toes the time far more often to avoid the situations that LSP was setup to warn you about.

A Sidebar : Refactorability : I received some interesting comments on my earlier post Commentary on Python from a Java programming perspective on this thread. My submission is that it requires you to come from a static typing background into a dynamic typing background to realise how much more difficult refactoring is. And the above mentioned implication of LSP in dynamic typing languages just goes out to demonstrate that there are indeed situations where the burden on you as a programmer / designer just went up due to the lack of explicit type information. This is but one of many aspect of many pros and cons between the two (static and dynamic typing) paradigms. To acknowledge it allows you to deal with it and work with it.

Interface Segregation Principle (ISP) :

Clients should not be forced to depend upon interfaces that they do not use

This is a little anticlimactic. The good news here is that thanks to duck typing, the client is actually now making the choice of what interface they choose to use. This is one principle that no longer needs to be explicitly applied. No more discussion required here.

Summary :
As we have seen duck typing does imply some changes to your class design. While the first three design principles continue to be relevant, their relevance is now a little different in your design process. It is important to be aware of these changes to adjust your design models in a more appropriate and idiomatic way. One would typically create lesser complex class hierarchies, especially with all the interfaces / pure abstract classes now no longer mandatory. Not only type information but even some of your abstractions are now less explicit.

Commentary on Python from a Java programming perspective

Posted by – September 17, 2008

After having worked with Java (and earlier C++) for a number of years, I have been working with Python for the last few months. Since I came to Python from Java, I thought it might be useful to share my experiences, which might be of interest to many programmers. This is not intended to be a language or feature comparison or something that contrasts the various advantages or disadvantages, but is intended to reflect on the softer aspects of how it feels to write Python programs. Hence I have refrained from including code snippets and other programming constructs in this post, but if you believe I am unclear in some of the comments I am making, do let me know and I shall be glad to update the post or write a new one as required.

Programming is Easier and Enjoyable

I think the most dominant impression from the last few months is that python does make programming feel a lot more easier and often more enjoyable. The feeling is not very different between riding a bicycle without gears then riding one with gears. In the latter case one just feels one can cover a lot more distance much more easily though any physicist will tell you the actual effort is not particularly different. It just feels like one has a much bigger toolbox (ie a wider assortment of tools) to work with and therefore the task seems simpler. Why do I think that way ? I believe the following features of python do help (in no particular order) :

  • Concise Coding style : The code typically is much more concise, with much lesser verbosity
  • Dynamic typing : You really do not need to worry about declaring data types and making sure the inheritance hierarchies especially for all the interfaces and implementations well laid out. The various objects do not even need to be in the same inheritance hierarchy – so long as they can respond to the method, you can call it. This is a double edge sword, but that doesn’t take away the fact that programming under dynamic types environment does seem a lot easier.
  • Easier runtime reflection : Java seems to have all the reflection capabilities but I think these are just way too painful to use as compared to python. In python the entire set of constructs (classes, sequences etc.) are available for easy reflection. In case you need to use metaprogramming constructs, python really rocks.
  • More built in language capabilities : Items such a list comprehensions, ability to deal with functions as first class objects etc. give you a broader vocabulary to work with.
  • Clean indentation requirement : It took me about 2-3 days to get over it but, it seems that python code is much easier to read since if you do not indent it correctly it will be rejected.

Need to spend time on understanding how to write code in Python

One of the statements I have heard in different contexts is that Java programmers when they start using python write it as if they are writing a java program using python syntax (unpythonic in python parlance). This actually took me a fair amount of time to understand. I did look at a lot of other python code to attempt to understand this in greater detail. I realised that python offers many more capabilities than java and that as a person who had written java code earlier, I was able to be immediately productive using the constructs in python which mapped onto the equivalent constructs in java easily. However it did take a long time to be able to start using the other constructs. One of the exercises that did help was to get away from the problem at hand and try to work on something entirely different (especially a program which had a strong algorithms element to it with complex data structures), and slowly review each line with how it might be better done in python.I realised it is easy to start coding in python but it takes some effort and time to start using the entire python toolbox effectively. While I reviewed other programs written in python, I did think there was one area where the prior exposure to java helped. Class design. I am not sure if this was an issue with the programs I read and thus there was an issue with the sample references I used. However while these helped me understand how to write code in python differently, I have a strong feeling that the programs I wrote were much stronger in terms of class design. There are many situations especially given the fact that python supports both function oriented programming and object oriented programming, where one wonders what is a better way to design the logic in a particular context. I thought it generally made sense to use proper class based design and use the functional constructs in situations which started getting a little loopy or algorithmic.

No Compile Cycle

Another thing I really enjoy about python is – no compile cycle (its implicit). So while in the middle of my editor, I could exit to the shell prompt, run the source immediately without trying to deal with an ant script in between which compiles java code and then recycles the web application. This has boosted my net productivity quite a bit.

Productivity

So are the statements that one can be 5 to 10 times more productive in python supported by my experience. While I haven’t gotten through the full life-cycle yet, prima facie I do believe 5 times does seem like a good number. However I would introduce the following caveats. It will not happen for your first project .. more like your second project onwards, primarily since it does require a lot of effort to start understand how to write pythonic code and that does take away a lot of those benefits initially. Secondly it does not factor in refactoring. Point refactoring is much much easier in python, but bulk refactoring is much much more difficult since automatic refactoring is tough. Thus when I am refactoring, I sometimes feel I was able to get it done faster in python, but in many other cases I thought I ended up taking a lot more time.

Switched to python completely ?

Not really. But I feel happy I have more options available to me. One thing that really sucks is the poor refactoring capabilities. This is unlikely to be an issue with python alone and is likely to be an issue with all dynamically typed languages. However if you want to use dynamic languages, be prepared to spend some more effort during refactoring since many of the automatic refactoring capabilities you may have gotten used to, may not be available. The other issue is performance. Java wins hands down on performance by a big margin. If I have to ever get back to another project where performance was particularly important and the primary constraint in performance was not network or disk IO but was likely to be the CPU, and it would be acceptable to substantially reduce development productivity in order to get the performance gains, I shall be found to be writing Java code for certain. The next project I work on, I am likely to “first” evaluate whether python fits the bill and switch to other languages if I do not find it appropriate enough.

Should Sun focus more on Java-Ruby or Java-Groovy integration

Posted by – January 18, 2008

Rick Hightower presents an argument to encourage sun to support groovy rather than ruby (“Quit pimple pimping ruby”:http://www.jroller.com/RickHigh/entry/thanks_zed_btw_syntax_matters)

bq. Can we just get some decent support for Groovy? No instead Sun invests in Ruby via JRuby. DOH! Groovy looks a lot like Java. It is much easier to get started with it. The syntax does not make developers want to hurl. Why is Sun investing so much money in JRuby?

The investment should be in Groovy. Developers who know Java can learn Groovy quickly and are more likely to do so if the tools support it. Ruby is a non-starter.

One of the arguments based on a chart similar (not the same) to the one below is :

bq. Here is another reason not to invest heavily in Ruby. For the color blind: RUBY COMES IN DEAD LAST!

Ruby comes in dead last. If there was going to be a revolution, it would have happened already. Ruby is a little long in the tooth to finish this poorly. Don’t you think?

More…

Code’s worst enemy is size (not language)

Posted by – January 18, 2008

Steve Yegge writes a rather long but interesting post related to “Code’s worst enemy”:http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html .

He starts off making a nice point.

bq. I happen to hold a hard-won minority opinion about code bases. In particular I believe, quite staunchly I might add, that the worst thing that can happen to a code base is size.

Great point. Not sure if it is a minority but if it is, I am there too.

He goes on to add some more interesting stuff

bq. I say my opinion is hard-won because people don’t really talk much about code base size; it’s not widely recognized as a problem. In fact it’s widely recognized as a non-problem. This means that anyone sharing my minority opinion is considered a borderline lunatic, since what rational person would rant against a non-problem?

….

bq. My minority opinion is that a mountain of code is the worst thing that can befall a person, a team, a company. I believe that code weight wrecks projects and companies, that it forces rewrites after a certain size, and that smart teams will do everything in their power to keep their code base from becoming a mountain. Tools or no tools. That’s what I believe.

However my opinions start to differ soon thereafter.

bq. The problem with Refactoring as applied to languages like Java, and this is really quite central to my thesis today, is that Refactoring makes the code base larger. I’d estimate that fewer than 5% of the standard refactorings supported by IDEs today make the code smaller. Refactoring is like cleaning your closet without being allowed to throw anything away. If you get a bigger closet, and put everything into nice labeled boxes, then your closet will unquestionably be more organized. But programmers tend to overlook the fact that spring cleaning works best when you’re willing to throw away stuff you don’t need.

Refactoring is not just adding new classes and methods and therefore introducing the syntatic sugar that accompanies them. Refactoring involves a bit of redesign, a bit of cleanup, a bit of clever consolidation and in many cases these actually *reduce* the code size.

bq. Java is like a variant of the game of Tetris in which none of the pieces can fill gaps created by the other pieces, so all you can do is pile them up endlessly.

Wake up. There’s nothing about the above scenario which is specific to _Java_. You can be in this situation any time you want in any language so long as you are sufficiently careful not to do any refactoring and keep on piling on more functionality. Come to think of it – in the above analogy probably the refactorings are indeed analogous to the blocks taking themselves off the board to create space for more.

bq. I’ll give you the capsule synopsis, the one-sentence summary of the learnings I had from the Bad Thing that happened to me while writing my game in Java: if you begin with the assumption that you need to shrink your code base, you will eventually be forced to conclude that you cannot continue to use Java. Conversely, if you begin with the assumption that you must use Java, then you will eventually be forced to conclude that you will have millions of lines of code.

This is really strange. I pride myself on writing concise and short code, and have learnt to write code in more languages than the fingers on my palms. However even after having spent a better part of the last decade writing in Java, I cannot really imagine myself reaching those conclusion.

bq. The rational response would be to take a very big step back, put all development on hold, and ask a difficult question: “what should I be using instead of Java?” …. It took me six months to realize it can’t be done with Java, not even with the stuff they added to Java 5, and not even with the stuff they’re planning for Java 7 (even if they add the cool stuff, like non-broken closures, that the Java community is resisting tooth and nail.) *It can’t be done with Java.*

This is almost getting close to being a flame bait. Again, I would be hard pressed to reach a conclusion even remotely close.

I do believe the post deserves to be mentioned for raising the point about about code size and perhaps for bringing in the analogy about Tetris. To a sufficient extent I think the argument is independent of the language (which is unfortunately where Steve headed in the mail). The point is that the emphasis on small code sizes is worth having. It is worth having for the following reasons :

* Emphasis on small code leads to much cleaner design which in turn makes the software much more maintainable and flexible (because of the design and not just the reduced lines of code)
* Emphasis on small code increases the motivation for continuous refactoring and reduces the incentive for the Copy/Paste shortcuts.
* Emphasis on small code leads to precisely that – small code.

Dynamically Extend Classpath during Unit Testing

Posted by – January 3, 2008

A lot of times I need to load data from configuration files which are supposed to be on the classpath. I also find the need to often change the configuration files for a variety of unit tests. Here’s a useful trick I borrowed and restructured from Sun Java Forum Thread “Java Runtime Environment (JRE) – Modify Classpath At Runtime”:http://forum.java.sun.com/thread.jspa?threadID=300557

The following is a Utility class with a static method that gets a class name. In this particular case the assumption is that the directory that needs to be added is same as that in which the class resides (Not necessarily always true – but its a convention I like and have adopted)

public class TestUtils
{
	public static void addURL(Class< ?> clazz)
	{
		try
		{

			URLClassLoader sysloader = (URLClassLoader) ClassLoader
					.getSystemClassLoader();
			Class sysclass = URLClassLoader.class;

			String path = sysloader.getResource(
					clazz.getCanonicalName().replace('.', '/') + ".class")
					.getPath();
			int lastSlash = path.lastIndexOf('/');
			path = path.substring(0, lastSlash+1);
			URL url = new URL("file://" + path);

			Method method = sysclass.getDeclaredMethod("addURL", URL.class);
			method.setAccessible(true);
			method.invoke(sysloader, new Object[] { url });
		}
		catch (Throwable t)
		{
			t.printStackTrace();
		}
	}
}

More…