James Gosling: on the Java Road

« RADlab, scripting... | Main | The new Macintoshes »

20051219 Monday December 19, 2005


Safety is Freedom

Get the e-newsletter: Sign up now for the On Demand Business e-newsletter. On Demand Business is helping smaller companies like yours win big. Learn how. I sure stirred up a pile of flaming with my previous post. The internet flame-before-reading tradition is alive and strong. I've always been a big scripting language fan (the first language I ever learned was a "scripting" language called FOCAL). Looking at the design tradeoffs between the two language categories has always been fascinating.

One of the slogans that was brought up in the commentary to my previous blog entry was "freedom vs. safety". Once upon a time I used to believe that: it has certainly been conventional wisdom for years. But a lot of the time, the truth is actually that safety is freedom (eg. a good safety harness and rope give you the freedom to climb a mountain).

When I'm writing a function and declare a parameter to be an Image, I am free to trust that it is an Image. I'm free to trust that no one's array access has smashed my data structure. Examples abound.

(Mon Dec 19 14:47:15 PST 2005)
Permalink Comments [37]

Comments:

Sara Gates has a similar analogy for how safety is freedom: "Why do cars have brakes? ... the real reason cars have brakes is so they can go fast." Accelerate Without Fear

Posted by Tom Ball on December 19, 2005 at 09:40 PM PST #

yes, the trust you get in knowing an Image is an Image is very nice. Seeing something that has methods called on it lets you know that something is having methods called on it. It also helps in comprehending the program to a great extent. the language wars have started, :D leouser

Posted by leouser on December 20, 2005 at 06:24 AM PST #

I don't find myself firmly in any language camp. However, I do find some use and strength with duck typing. Having done component oriented programming, written containers, enjoyed the NIH syndrome, I find myself wanting to just invoke methods on Java objects without concern for the interface, etc.

I have two frustrations with Java's type system. First: the type system and the security system is so completely tied together that you have to resort to black magic to treat objects with fine-grained controls (something useful for component containers). Second: the method invoked is decided at compile time instead of selecting the most appropriate method at run time. That means a recompile is necessary to call a more strongly typed variant of a method when a class is updated.

I don't have that problem with some of the more recent scripting languages--and they are just as strongly typed as Java. They have the safety you speak about. They just don't have the frustrations that I have to work around in Java. Of course, they do let you invoke any method you like as long as it exists.

Getting back to the security system, I can't understand how you can load the exact same bytecode in two different classloaders, and not have the classes be equivalent. All that would be desired is to have the permissions different depending on which classloader's version we called. It makes no sense--which is why Java's security system needs an overhaul. It only comes into play here because it is tied to the type system.

There is a point where there is too much "safety". "Any society that would give up a little liberty to gain a little security will deserve neither and lose both." -- Benjamine Franklin.

Posted by Berin Loritsch on December 20, 2005 at 07:09 AM PST #

My Response: http://www.cincomsmalltalk.com/blog/blogView?showComments=true&entry=3312529287

Posted by James Robertson on December 20, 2005 at 08:03 AM PST #

I rely upon the property of same bytecode different classloader, different classes in my code so its a benefit for me. In my current application I create a several instances of the Jython interpreter, the total isolation of same bytes/different classes is what I want. 'I have two frustrations with Java's type system. First: the type system and the security system is so completely tied together that you have to resort to black magic to treat objects with fine-grained controls (something useful for component containers). .' this doesn't seem right to me. Its been awhile since I really looked at the security system but I do remember being able to secure the code beyond the object with it, and at the method level. Ill have to relook at it. 'That means a recompile is necessary to call a more strongly typed variant of a method when a class is updated.' Im not sure what you mean here, can you give me a code example to clarify it? leouser

Posted by leouser on December 20, 2005 at 08:46 AM PST #

Let's say you have an object that calls an object from a library. The first version of the library had the class defined like this:
class Called {
    public void print(Object o) {
        System.out.printf("Object: %s\n", o);
    }
}
If it was called with this code:
Called called = new Called();
called.print(new Integer( 45 ) );
You get the phrase "Object: 45" printed. If the library is updated and called has a new overloaded method that accepts the Integer object nothing changes:
class Called {
    public void print(Object o) {
        System.out.printf("Object: %s\n", o);
    }
    public void print(Integer i) {
        System.out.printf("Integer: %d\n", i);
    }
}
The code will still print out "Object: 45" until you recompile against the new library. Then you will see "Integer: 45". Statically typed.

Posted by Berin Loritsch on December 20, 2005 at 09:13 AM PST #

As to the comment about security system and typeing, I understand the desire for isolation. However, that functionality should not be performed through classloading. That's a different function altogether (I'm thinking isolates here, which are still in JCP).

The security model relies on permissions, which you query the static AccessController to determine if you can perform some action. These permissions are again set statically within a ProtectionDomain which is locked in at load time. The reason your isolation works is because the two classloaders have different ProtectionDomains. The only way to provide a different set of permissions to classes within the same JAR is to override the classloader to assign the different classes a unique ProtectionDomain.

Quite often it is useful to have interfaces within the same ProtectionDomain shared across implementations so that it is easier to use the components that belong to separate ProtectionDomains to further restrict what they can do. However, most interfaces are included in the JAR along with the implementations. The only other trick is to generate dynamic proxies to invoke methods on the object that implements the interface in the opposing ProtectionDomain.

Lastly, I don't like things being static as a general rule. Static fields force the need for overloading the classloader to perform a function it was not intended for. Classloader tricks are error prone and ugly.

Posted by Berin Loritsch on December 20, 2005 at 09:23 AM PST #

Hi James.

It's nice to see you're starting to address this topic more head-on in these last two blog entries.

My sense from wandering around the web is that advocates of the new "dynamic" languages feel these are fundamentally different from, and a great improvement over, both untyped (or loosely types) scripting languages that came before, and also an improvement over Java, because Java's static type checking causes so much busywork (in their argument) and in the end the modern "latent" type-checked languages do check types, but at runtime. The argument is also that static type checking doesn't buy you as much when you can launch your code immediately (without a slow compile step) and test it, and that developers aren't seeing their code blow up at 30,000 feet, so to speak.

Right now it seems that Sun is responding by pointing out how solid and great Java is, but an alternate approach is to suggest that the JVM is a much better home for dynamic languages than either the CLR or home-grown VMs. While it's great to have a statistic that there are 200 "languages" for the JVM, from my own experience these have negligible use outside of the Java community (and in many cases, within the Java community), and almost no use overall compared to Python, Ruby, Perl, PHP, etc. The problem seems to be the messiness in using JNI (many of the new dynamic languages rely on compiled libraries for extensions), difficulty in some types of dynamic invocation, among other things. So what can Sun do to make the JVM more palatable for dynamic languages? And how many years do we have to wait?

Anyway--this long comment just to say that as a Java user and promoter, I think Sun should face this "rising tide" of dynamic languages with a welcoming attitude, as both sides stand to benefit from each other. Welcoming meaning--let's hear both sides state more openly where the benefits and disadvantages lie, admit them, and see where everyone can benefit from the larger set of tools available.

I am glad about the scripting support being added to Mustang, by the way.

Cheers! Patrick

Posted by Patrick Wright on December 20, 2005 at 09:26 AM PST #

interesting points. I would argue against the behavior of my compiled class changing if the another piece of the code is recompiled. When I execute the line print(Object o) in the original code, that's the method I wrote my code against. My code( an myself) knows nothing about the method print( Integer o ) at the time of writing and I don't want my class to magically break on me because the it starts to rely upon a method whose effect may not be the same as the one I called originally. Ill take the recompile in this case, new surprises no thanks. I would think that a ClassLoader as the being the creature that defines classes should be the creature responsible for defining isolation. Its purpose is to create classes, why push that responsibility off somewhere else. If you need a common interface between the different ClassLoader, load that interface in the parent ClassLoader and reuse it for the children. This works. Overloading methods is a benefit. There are many times when Im writing Python I wished I had an overloaded method. You have the option of writing a convulted method that does different things based off of the types of params passed in or you can write a slew of differently named methods. Not much fun in either case. Having one constructor flat out stinks. leouser

Posted by leouser on December 20, 2005 at 10:44 AM PST #

I wish I could rewrite my last post, yeash speed typing makes you look illiterate... :D leouser

Posted by leouser on December 20, 2005 at 10:45 AM PST #

;P
We can agree to disagree about the statically checked types. C# behaves the way I would expect in this case, and Java behaves the way you would expect (note, C# does a number of things more that I would not expect--part of the reason I never attempted to learn it in depth).

I crave simplicity in my code, and there are a greater number of ways to achieve that if I don't have to worry about types--i.e. if you tell an object to quack and it obeys we are all happy. The bottom line is that your style of programming changes when you think dynamically as opposed to statically.

Don't get me wrong, there are a number of things I like about Java. I make my living off of Java programming. I've done many advanced things, looked at the results, and had a strange mixture of the joy of conquering and remorse of the hoops I had to jump through to get the job done.

Along comes languages that have lived about as long, but not really corporately backed, and it fits most of my needs very well. Since I employ TDD near religiously, I don't miss the type declaration abilities of Java in the least. In fact I am amazed at how much more efficient I am in getting a solution done.

I'll be honest that much of the efficiency comes from other improvements other than the type model. For example, the ability to edit in place, the ability to pass in closures to a method, etc. Even the ability to add new methods to a class is terribly useful in some cases (e.g. mixins).

So again I am faced with a strange combination of feelings. I am growing more disalusioned with Java because I can be more efficient with other languages, but at the same time I want Java to be better. Naturally we can't all agree on the "one true way" which is why there is diversity in programming languages.

I just don't like broad sweeping generalities that lump old weakly typed languages with new strong dynamically typed languages. I'll concur that not everyone will agree with my views on language design, and there are reasons for whatever road you pick. I just find myself stumbling over the same features that are designed to "protect" me. I'm not your average newbie, I know some fairly advanced stuff with Java. My least favorite being, "we won't write code that implements your interfaces because it polutes our project--even though we are using your code".

That inane philosophy of Not Invented Here (NIH) syndrome is a cause asking for duck typing. In some ways I have worked around this political problem using reflection and idioms, but it is a terribly clumsy solution to a problem that shouldn't exist. Then you have the whole problem of interfaces that are similar or identical in purpose and declaration but because they are different interfaces (different classes altogether) you can't use them interchangeably. I've used dynamic proxies in those cases as well, but again it is an inelegant solution that wouldn't be necessary without static typing.

Posted by Berin Loritsch on December 20, 2005 at 11:15 AM PST #

Thanks, for the comments. As someone who writes software in Jython and Java I can understand your liking of languages like Python. I like them as well. Ill have to do a count sometime about how much code is written in Jython and how much is written in Java. I do know one thing for certain, that I find myself muttering occasionally thank god for the compiler. :D Productivity wise, I have no idea how much more efficient I am in Jython vs. Java. It took me like 5 minutes yesterday to do a translation from some Jython code to Java code. And it wasn't hard. The biggest problem Ive ran into is how to do a translation from Python's sense of truth to Java's truth. translating: if reference: ... to java code is a pain in the butt. Its much simpler to have things like: if( true ){ } Its probably because of this that I take people saying "dynamic languages" are the future with a grain a salt. When you start disecting other people's Python code it can be a real chore figuring out what exactly it means. Or even your own after a duration. I write a JythonShell in Java. It was probably 6 months between times when I worked on it. I had the pleasant experience of easily picking up all the pieces after that duration, the program was easily comprehensible. Part of this is definately tied to the fact that I can look at a List<TYPE> and know exactly whats in it. I don't have to skip around the code desparately looking to where its created to determine its type. Ive seen stuff where a reference to one object becomes a completely different object. From a List to a Set. That's not fun to find and not fun to experience. Yeash, C# changes the method you call if its added to a class or interface? How in the world can someone program to that. When I program its to a method that specifically does something. I don't program to an unknown method whose docs or code Ive never read before. When the method that gets called changes to something you've never seen before, that's not programming that's gambling. Im surprised C# allows you to do that, sounds like a flaw in the language design. gotta run! leouser

Posted by leouser on December 20, 2005 at 11:52 AM PST #

As someone who inherited > 100K lines of TCL code, let me say I know how easily and quietly a scripting language will fail you as a platform. Maybe the current generation will need to relearn that lesson the hard way. And don't speak to me of brevity! TCL cleans the floor with most all languages in terms of clear and simple syntax. James is completely right with regards scripting languages failing to scale. Whether is expanding the feature set, or reaching performance, or consolidating even how it is used, scripting languages suffer from the exact same thing that makes them so powerful; "freedom". Java has a single universal way to integrate and develop in. Due to its clarity, it's been able to scale to being multi-platform, desktop, embedded, and online. Currently it's focused on scaling down and with JSR-223, I don't doubt that will be another item off the checklist. To me, comparing Java to a scripting language is like comparing an adult to a child. Yes the responsibilties of the child are carefree and easy, but if it wants to be able to reap the benefits of being an adult, it will have to grow into one.

Posted by functionform on December 20, 2005 at 01:40 PM PST #

True.. But it isn't just about freedom. It is also about the ability to express a solution. Many java frameworks require a lot of XML to get things done.. because the language itself is difficult for metaprogramming. Languages like Lisp or Smalltalk however, allow you to easily define domain level languages for your solutions. Java's restrictive syntax makes this harder to do...

Posted by am on December 20, 2005 at 01:43 PM PST #

One might fault the developers of unnamed frameworks instead of the language itself. ;) There's a reason these frameworks leapfrog each other in terms of popularity. I'll agree in that describing the problem well in the code is power and ease of use. Perhaps the first Java-born scripting language should be one that specializes in clarity and powerful expression (although Javascript is nice as well)

Posted by functionform on December 20, 2005 at 02:52 PM PST #

functionform: Relating experiences about inheriting codebases written in scripting languages disintegrating is not really meaningful. I've worked on plenty of Java codebases, and more recently an Objective C codebase, and let me tell you they suck too, and the problem is developers. One reason I avoid the "enterprise" world is precisely because its full of incompetence. Even if Java was the best language in the world, it would not save these "senior architects" from producing junk. You can stick with Java, which caters to the low 80%; enterprise, corporate IT, whatever you want to call it. Good programmers will pick languages that allow them to be more productive. Who cares about the dumbass "systems analyst" with 10 years "experience" who doesn't know data structures?

Posted by Slava Pestov on December 20, 2005 at 05:33 PM PST #

well, why isn't his experience meaningful? What if the developers didn't stink? Why wouldn't I want to hear about this and ponder the outcome? Hmmm, the code was well structured but it had reached its limits in size with Tcl.... You can't chalk up all problems to bad enterprise developers. A good developer is a good developer no matter the context. There are plenty of stinky Open Source developers out there( maybe Im one of them :D ). leouser

Posted by leouser on December 20, 2005 at 06:45 PM PST #

Slava: it's true that people write c**p in every language available to them. I would restate functionform's complaint in a different way: are there limitations imposed by dynamic languages that make inheriting codebases harder? For example, if parameter types to a function/method are not declared, then reading the code you have to infer what the type of that parameter is (maybe by reading all around the code). Or maybe you can't rely on the compiler and syntax tree to tell you what methods are actually bound on a given call--you have to use text searches and hope you found the right one. Those limitations, whatever makes it more difficult to inherit a large codebase, are something we should be able to talk about more clearly. With Java, it's certainly a hassle how much configuration is now maintained outside of the application classes themselves.

I think there is a lot of confusion in this debate (not just here, but all over blogolovia) in large part because people are speaking out their frustration in working with one language or another. And it seems to me (as I wrote earlier) that Sun should confront that frustration more openly as regards Java, because *that* denial is causing more frustration. People want to be heard. I've just joined an ongoing J2EE project, and the number of layers of code + configuration makes my head ache. Isn't this patently clear to anyone who uses it?

I doubt that Java is past its prime, but the fact that well-known writers and bloggers are moving away from it (at least to try something new out) should tell us that there are problems not being addressed.

Patrick

Posted by Patrick Wright on December 21, 2005 at 02:13 AM PST #

James,

You are conflating positive freedom (freedom to do something) with negative freedom (freedom from some constraint). Yes, Java/C# give the developer assurances that they won't overstep , which is what makes them so suited to corporate IT development.

The difference between designs, whether of computer languages or whole societes, guided by positive versus negative freedom is that designs based on positive freedom are aimed at fulfilling some ideal or telos of the designer and thus not very accomodating towards conflicting ideals. This can be seen in socialism, and in an extreme form communism. I'm not implying that Java users are communist ; ) Its just that Java is pretty single-minded on alot of things, very verbose, and not very flexible. Myself, as a programmer, much prefer the flexibility, and the attendant pitfalls, of C++/Lisp.

Posted by Brian Azzopardi on December 21, 2005 at 02:23 AM PST #

Patrick, just about every refactoring tool in all the major IDEs rely on the parse tree--not on the inherent structure of Java. If it didn't rely on the parse tree then you would have to get your code to compile before you could refactor (ala JBuilder 8 or 9). Nowadays, the ability to split functionality into a new method even while the class can't be compiled yet is normal.

Because there is no type specified in methods, there can be no overloaded methods (see the code example above). Because there is no type specified, I just need to pass in something that supports the operations performed on the object I pass in. Most of the time that's fairly easy, and avoids the whole "value object" necessity. Many times you also have fewer parameters as well.

Posted by Berin Loritsch on December 21, 2005 at 06:48 AM PST #

yes, but many times you end up having more parameters and uglier code as well. As I posted earlier having one constructor can really hurt. Ive had to play this type of game too often: if obj.__class__ == classofsomething: ...do stuff once too often, when a good overloaded constructor would have made things that much simpler. leouser

Posted by leouser on December 21, 2005 at 10:46 AM PST #

leouser:
I would argue against the behavior of my compiled class changing if the another piece of the code is recompiled. When I execute the line print(Object o) in the original code, that's the method I wrote my code against. My code( an myself) knows nothing about the method print( Integer o ) at the time of writing and I don't want my class to magically break on me because the it starts to rely upon a method whose effect may not be the same as the one I called originally.
That's <em>polimorphism</em>, and is the "Open" (for Extension) in the Open-Closed Principle. It enables you to evolve a design without having to re-think the whole thing.
For this to work, you should program to <em>operations</em>, not <em>methods</em>.

Posted by Daniel Serodio on December 21, 2005 at 01:11 PM PST #

No my friend you aren't listening to my warning: Do not execute methods against methods you have never seen. It would be acceptable if as a software writer to execute against it if that was what I explicitly set. But as the post I was responding to, to paraphrase: adding a method to class that is called in a compiled class should automatically result in the new method being called. to this I say NO! :D #1 You have never seen the method. #2 You have no idea what it does. #3 You wrote your method at the time against the specific method, not the one added. You expect it to execute this one method. To suddenly have it execute a method you never have seen before will result in unexpected behavior. #4 Because a method shares a name with the another method does not indicate with any certainty that they do the same thing. if I wrote some code against: executeCode( Object o ) this is what I wrote it against. if a new method of the name: executeCode( Subclass p ) shows up I still want it to execute against the first one since that is my intent. Unless I explictly recompile against the code with the new method, the behavior should remain the same. I have no idea what the second method does until I have had the chance to inspect it and make the decision that it is ok to execute the method. To let this situation occur is pure gambling. In the contrived example of 'print' the code doesn't present any danger. But we will never have this safety in reality. When the interface changes and you want to change the behavior of your code, what method you explicitly call, you as a developer should make this decision. When I call a polymorphic method I call a polymorphic method. I do not want this to unexpectedly happen. The lack of the ability to make a rational decision in this case is what I consider bad. gotta run! ( thanks for the lesson in polymorphism ) leouser

Posted by leouser on December 21, 2005 at 03:08 PM PST #

leouser:

Imagine that I provide you with a library containing <code>executeCode( Object o )</code> ... and you write code against that. Now I release a new version of my library, and without even overloading <code>executeCode( Object o )</code>, I change its functionality. Now, even in the Java compile-time-bound world, the functionality of your program will change.

You state that "because a method shares a name with another method does not indicate with any certainty that they do the same thing." In reality, even if a method shares its name AND parameter types with an older version, it might not do the same thing.

Replace an existing method with updated functionality could be the whole purpose of releasing a new version of my hypothetical library, and it's one of the main ideas behind OOP, as Daniel explains above. I think you missed his point about programming to operations instead of methods.

Obviously you trust me as the library implementer to not change things TOO drastically on my existing method. If I don't give you the source, or if you don't take the time to really study every change, you won't be sure, but that's part of my implied obligation because if DO break things for you, you'll stop buying my library.

So now if I introduce <code>executeCode( Subclass p )</code>, you would generally trust me not to break things.

In fact with Java you could see some weird issues... if you drop in version 2 of my library, with the new overridden method, on your live server, it won't use the new method (no recompile). But then if you load things up in your IDE, you'll probably be using my new override method. Could get messy. :)


Anyway... if you accept the potential value and purpose of altering the functionality of the existing method (again, Java already supports this inherently), it shouldn't be much of a leap to see the value of run-time polymorphism instead of compile-time polymorphism.

Posted by Ben on December 21, 2005 at 11:01 PM PST #

Hi Ben, I find your argument quite persuasive. (I have not tested the code above though) I wonder if this is not something that could be changed easily in Java. As you argue, it does not really make sense to have compile time polymorphism. If you are going to change the library, then any number of things could have changed in that library. So would removing this really cause a problem anywhere in existing code? Or does this bring some serious speed advantages?

Posted by Henry Story on December 22, 2005 at 12:02 AM PST #

'Obviously you trust me as the library implementer to not change things TOO drastically on my existing method. If I don't give you the source, or if you don't take the time to really study every change, you won't be sure, but that's part of my implied obligation because if DO break things for you, you'll stop buying my library. So now if I introduce executeCode( Subclass p ), you would generally trust me not to break things.' this is a good point, but I still state that I when I explicitly compile against an interface that has: methods or operations: 1. A 2. B and I call B that is what I call. When the interface changes to: 1. A 2. B 3. B and I have not compiled against the new interface with B in 3 I want it to remain 2. 3, I still have not seen or read about, too risky to automatically swap to calling it. Trust is faulty, proof of properly running execution is much better. Which means I want to have the oportunity to read and possible alter my code in response to this new interface. what if we have this situation: public String operate( Object o ) Ive writen and compiled against this method. This is what I want to execute: List<String> data = new ArrayList<String>(); String result = operate( data ); Then the writer of this library has some reason( maybe user input ), to add: public void operate( List<String> ) where did my String go? I need that. Should my code start going crazy in the face of this? gotta run! keep the debate up, leouser

Posted by leouser on December 22, 2005 at 06:29 AM PST #

Is scripting vs. general purpose strongly typed really the burning issue for RAD? For what component of an envisioned RAD system does this question come up? -t

Posted by Tom Lord on December 22, 2005 at 09:09 AM PST #

I have to admit that I feel more comfortable with leouser's point of view. If runtime polimorfism existed in Java, we would never know what overloaded methods of an object would be called at runtime. Also, doesn't it also add an even greater runtime overhead? I mean, when invoking a method on an object, we would not only need to perform the lookup for the correct virtual method implementation, but we would also need to determine whether there is an overloaded version of the method that more precisely matches the given parameter. And what if the method accepts multiple parameters?

Any way, I think it is not possible to change the language to acomodate this feature. Code obfuscators already use the property of compile-time polimorfism:

void add(int i){...}

void subtract(byte b){...}

can be potentialy converted by the code obfuscator to:

void a(int i){...}

void a(byte b){...}

and the virtual machine would execute the code without complaining, because it differentiates the two methods by their parameter list. But if runtime polimorfism was permited right now in Java, calling method **add** passing a byte could have the virtual machine actually make the call of **subtract**, if you used code obfuscation.

Posted by Fernando Kronbauer on December 22, 2005 at 09:52 AM PST #

Fernando, is C# significantly slower than Java? It's not as if the check is made on every invocation of the method. It's just checked at class load time and bound then.

Leouser, Java has carried over some of the bad habits of C++ while trying to learn some (albeit very few) lessons from SmallTalk. I would suggest taking the time to learn SmallTalk enough to get used to it. The process will cure you of the uneasy feelings you may have.

Bottom line is that any time you introduce logic based on type--whether overloaded methods or <tt>instance_of</tt> checks--you are not using Object Oriented Programming/Design. You are using Object Based Programming which is different. Java carried forward the C mentality of structs and functions and put them together in an object.

A library that is designed for polymorphism and to be extended without rewriting sections of code is a very beautiful thing. I have yet to need to check for a type of an object in SmallTalk or Ruby. IMNSHO there is something wrong in the design if you believe you need type checking.

Posted by Berin Loritsch on December 22, 2005 at 10:44 AM PST #

why exactly should I go and learn Smalltalk( beyond the fact that its always nifty to learn a new language )? I already program in Python/Jython, so if its to teach me about dynamic languages and typedness it probably wouldn't go too far in teaching me anythin new. There is without a question a difference. You do have to think in a different mindset. One example would be when I used a closure in Jython/Python, which in my thinking is a class defined within a method. That's what I identify as a closure. In Python each time I executed the method I got a brand new class that did the same thing as the others. In Java I believe you would get the same class( someone correct me if Im wrong here ). This isn't a bad thing as long as you understand what's going on. But I had to pay the penalty in this case, I had very bad memory leak because of it and it wasn't too much fun to track down either. When I did a dump of the heap I saw this large accumalation of reflective machinery but no classes( should have inspected the bottom of the list ). It was somewhat astounding to me when I realised that the closure was acting as a class factory. I think you may have a good point there that if your doing type checking alot there is possibly something wrong with your design. I use similar metrics when I run into kludges or find myself relying too much on exotic language features. Though I do have to say again, I sure miss having overloaded constructors. :) gotta run! leouser

Posted by leouser on December 22, 2005 at 12:18 PM PST #

The purpose of going to SmallTalk as oposed to Python or Ruby is to go to the source. It is a different mindset completely, even from the newer dynamically typed languages. It's where OOP was made. The OOP/D from a good SmallTalker is more mature than in the other languages.

Posted by Berin Loritsch on December 22, 2005 at 01:42 PM PST #

really? So what am I going to learn? Is there some concept Im going to pick up from it that's absent from modern day languages? leouser

Posted by leouser on December 22, 2005 at 04:01 PM PST #

You'll learn the power of getting back to the absolute basics. You'll learn how to think in a more object oriented manner. Of course there are some features in SmallTalk (due to its environment) that neither Ruby nor Python have. SmallTalk's strength and weakness is that it is developed in its environment. Once the application is done, you remove all the stuff you don't need.

What is cool is that you can modify your class on the fly and play with it interactively to get a feel for how the object is used.

The differences are subtle, but I find it helps to go back to the source to really understand a concept. Too many people develop <em>using</em> objects instead of developing objects. It's a subtle distinction that will change how you look at problems.

Posted by Berin Loritsch on December 22, 2005 at 07:36 PM PST #

I can't remember correctly but Im fairly certain you can do that kind of thing in Python. You certainly can modify the object on the fly, which may seem nifty, in my experience isn't such a great thing. Being able to modify everything on the fly damages your ability to rationalise about your program. To be honest I usually write in Classes in Java and Python so Im not sure how this is going to help me. I don't equate not knowing SmallTalk with not knowing how to program in OO. Of course, you may think this of me if you want. :D leouser

Posted by leouser on December 23, 2005 at 06:38 AM PST #

Berin,

I think such checkings can't be done at class load time, the same way that virtual functions can be devirtualized only at runtime, if de virtual machine determines that there is only one implementation of it.

Let's leave Java as it is, for writing high performance components, and than have the scripting language of your choice to bind them.

Merry Christmas

Posted by Fernando Kronbauer on December 24, 2005 at 04:00 AM PST #

Berin,

Before you say anything, I did not mean Smalltalk is a scripting language. I just meant scripting languages are suitable for binding and integrating components writen in other languages.

Cheers

Posted by Fernando Kronbauer on December 24, 2005 at 04:25 AM PST #

:) I didn't think you meant that. I covered a number of things, and I assume you are referring to the difference between Java's method resolution and C#'s method resolution (compile time vs. load time). Of course when you throw Ruby which I believe I also referred to, method resolution is at run time. There are several different models, all of them have their tradeoffs. Merry Christmas

Posted by Berin Loritsch on December 24, 2005 at 12:02 PM PST #

Post a Comment:

Comments are closed for this entry.