Think About Java-Joe!

Discussions

News: Think About Java-Joe!

  1. Think About Java-Joe! (132 messages)

    Mikael Grev, on JavaLobby, implores that Java's language designers think about the average programmer when discussing closures. Closures are a hot point for discussion right now, because they might be part of JSE7. Many people have chimed in on whether they'd be good or not; most of the comments seem to indicate that those who don't want closures don't understand them. According to Wikipedia on closures:
    A closure typically comes about when one function is declared entirely within the body of another, and the inner function refers to local variables of the outer function. At run time, when the outer function executes, a closure is formed. It consists of the inner function's code and references to any variables in the outer function's scope that the closure needs.
    In this, a closure is much like an anonymous locally-scoped implementation of an interface. Supporters suggest that this will help make Java more functional (in the functional programming sense), leaving the traditional "Java is object-oriented with a few exceptions, and that's it" mindset behind somewhat. If this small explanation doesn't clarify matters for you, then you're seeing what closures' critics have been saying: it's a complex concept, even though application might be very simple, and as such, the concept is going to appeal to a very small set of programmers. That said, it's hard to argue that some aspects of functional programming might be very useful in Java; Neal Gafter's "What's the point of closures?" post shows both the flaws of closures (in their relative obscurity) and their strengths, by walking through a case where they would simplify some code very much. Mr. Grev closes with a plea that might apply to most expert groups, that the norm be represented in an attempt to protect the non-experts:
    For our expert group We are looking for You that have no more than two years of Java practice and are average, or preferably below average, at what you do. You should never have searched for Java related information online other than for solving practical, work related, problems. Your IQ must not be above 110 (we need paper on this). You will be working in a group with very smart people and your primary job function is to say "I don't get it," when you don't get it. You must have no prior knowledge of closures. In fact you shouldn't even know what a closure is (if such a thing even exist).
    One coder said, "Inner classes get me most of what I want from closures, but being able to specify the interface in place would be handy." What is your opinion on them? Resources:

    Threaded Messages (132)

  2. I kind of like closures[ Go to top ]

    Granted, I've not done much with them, but in my Ajax work, closures are pretty handy to have. I like how they give me automatic access to the local vars of the enclosing function/method. Sure, I can do that an anonymous class, but then I have to manage passing those values into the class, which clutters things up a bit, especially when the would-be closure is only a few lines long. I can go either way... jason lee
  3. Re: I kind of like closures[ Go to top ]

    After some discussion, i think closures is something that can be forgotten very quickly since this feature let's Java away from it's OO nature at all, i would like see the "with" statement in Java instead of closures.
  4. Re: I kind of like closures[ Go to top ]

    OO doesn't mean you have to write 5 lines of code when it can be done with 10 simple characters in one line. Code cluster is no OO. It's simply ugly code whatever the buzz word you want to name it. I like parser.map{a->a.toString()}, not parser.map(new Mapper(){ public Object map(Object obj){ return obj.toString(); } }); The current ugly syntax just scares most programmers away from the combinator style programming.
  5. Re: I kind of like closures[ Go to top ]

    OO doesn't mean you have to write 5 lines of code when it can be done with 10 simple characters in one line.

    Code cluster is no OO. It's simply ugly code whatever the buzz word you want to name it.

    I like parser.map{a->a.toString()},

    not
    parser.map(new Mapper(){
    public Object map(Object obj){
    return obj.toString();
    }
    });

    The current ugly syntax just scares most programmers away from the combinator style programming.
    OO is NOT a panacea of software!
  6. Re: Think About Java-Joe![ Go to top ]

    I'm really excited about closures and it's really good seeing Java evolving. I really think closures are handy. BTW can a closure be returned? ... it's nice to see that some aspects of functional programming are proposed in one form or another in Java because FP really has value. I was wandering if curry-ing is something to be considered as part of Java language.
  7. Re: Think About Java-Joe![ Go to top ]

    I think it is necessary to be able to use closure as return value as well as parameter. I'm kinda conservative about currying though. It looks like going too far.
  8. Re: Think About Java-Joe![ Go to top ]

    it's nice to see that some aspects of functional programming are proposed in one form or another in Java because FP really has value.
    Yes and so does all the paradigms in programming world (declerative, logical etc etc). Are you suggesting Java should follow all of them? If not then why functional? I think this fad is just becuase of c#, and people in this forum are too much obsessed with these kind of esoteric language features with out knowing the consequences. If you like functional programming please go ahead and wirte your code in LISP. If you desire to mix the paradigms (OO, procedural, functional), we have some thing for you called CLOS. Go and play with it, please don't advocate to sabotage Java.
  9. Re: Think About Java-Joe![ Go to top ]

    I need closure so badly. Anonymous class is just a pile of sht compared to closure. Why are these people even discussing it? Bring it on!
  10. The Java API would have to take advantage of them. One of the things that Ruby proponents mention about closures is how integrated they are the API. Particularly with the collection API.
  11. Re: Think About Java-Joe![ Go to top ]

    I think the concept of closures are complicated, but in practice I think they make things easier for the "Java-Joe". The meta programming possibilities are easier so, the "Java-Joe" can write code that fits better with the DRY concept. Joshua
  12. Re: Think About Java-Joe![ Go to top ]

    One thing I think that C# got it right is to have anonymous delegate (and even lambda in C# 3.0) and to dump the anonymous class idea. Actually most of the cases where an anonymous class is used, closure can do a better job. (Runnable, Comparator, Predicate, FileFilter etc.) And in the rare cases where a closure does't suffice, (need to implement more than one methods for example), it almost always turns out that a named class, nested or not, is a better choice.
  13. It's all about syntax[ Go to top ]

    closure matters just because syntax. But is this the proposed syntax? docsWithAnnotations(person) (Document doc, DocAnnotation docAnn) { if (doc.mentions(key) && docAnn.marked(ann)) { return true; } }; And what about parameterless closure? Like this? docsWithAnnotations(person)() { ... }; Hmm, I start to understand why people are reluctant about this whole idea now. Why can't we borrow what people have already been doing in Groovy? docsWithAnnotations(person) { Document doc, DocAnnotation docAnn -> return doc.mentions(key) && docAnn.marked(ann)); }; And docsWithAnnotations(person) { ... };
  14. If closures, why not: first-class regexp first-class maps/lists exception handlers (those are kinda closures) that can access the local vars of the offending code block per-statement exception handler syntax, so we don't need and explicit try...catch. mixins Hell, just do Groovy == java and be done with it. That's where we're headed anyway. I mean, rather than patch new features in slowly, why not do a big huge leap on that level so people can transition and be done? Right now all these slow feature trickles are just creating version hell for code management.
  15. If closures, why not:

    first-class regexp

    first-class maps/lists

    exception handlers (those are kinda closures) that can access the local vars of the offending code block

    per-statement exception handler syntax, so we don't need and explicit try...catch.

    mixins

    Hell, just do Groovy == java and be done with it. That's where we're headed anyway. I mean, rather than patch new features in slowly, why not do a big huge leap on that level so people can transition and be done? Right now all these slow feature trickles are just creating version hell for code management.
    Because nothing new ever works. I'm with a large team now going through the changes from 1.4 to 1.5 and can see that it takes time to use each feature correctly instead of abusing it. Like anything it takes time for the community to internalize each change. Generics come to mind. Java is now a "legacy" platform so any tweaks need to be slowly developed and well thought out - which means they may come up short of people's ideal. Again, Generics come to mind. While having jazzy new features would make some coding easier and more clear it isn't like you can't get your projects done with Java as it exists today. Closures are really handy but they shouldn't be strapped on. If they come two releases down the road at least that is Sun being conservative, which isn't all that bad with a legacy platform. Unlike a newer language, Java doesn't have the ability to drop features and libraries when they become outdated. For example, if closures become standard then why have anonymous inner-classes? Besides, wasn't Sun promising that Java releases would come more quickly to help keep the community used to upgrading? I know there was an eon between 1.4 and 1.5 but now 1.6 is already around the corner. I think you're on to something with Groovy. If it was adopted as a first class JVM language alongside Java by industry and IDEs then I could see having the best of both worlds. For systems that required long-term stability you'd have Java and for prototyping, dynamic web applications, testing, etc you could use Groovy. Looks like October is when we'll finally get a 1.0 release of Groovy to critique. But of course nothing new ever works. ______________ George Coller DevilElephant
  16. Re: Why are they half-assing it?[ Go to top ]

    While having jazzy new features would make some coding easier and more clear it isn't like you can't get your projects done with Java as it exists today. Closures are really handy but they shouldn't be strapped on. If they come two releases down the road at least that is Sun being conservative, which isn't all that bad with a legacy platform. Unlike a newer language, Java doesn't have the ability to drop features and libraries when they become outdated. For example, if closures become standard then why have anonymous inner-classes?
    I don't think closures are a replacement for all anonymous inner classes. Closures only can replace anonymous inner classes that implement interfaces with a single method. It's actually the other way around. Closures can be replaced with anonymous inner classes. It's just too verbose for the problem at hand.
  17. Re: Why are they half-assing it?[ Go to top ]

    While having jazzy new features would make some coding easier and more clear it isn't like you can't get your projects done with Java as it exists today. Closures are really handy but they shouldn't be strapped on. If they come two releases down the road at least that is Sun being conservative, which isn't all that bad with a legacy platform. Unlike a newer language, Java doesn't have the ability to drop features and libraries when they become outdated. For example, if closures become standard then why have anonymous inner-classes?


    I don't think closures are a replacement for all anonymous inner classes. Closures only can replace anonymous inner classes that implement interfaces with a single method. It's actually the other way around. Closures can be replaced with anonymous inner classes. It's just too verbose for the problem at hand.
    Thanks for that clarification. I was wrong on that point. Still, any validity to the argument for keeping the language size stable? Reducing features if you add new ones? I guess I can't see an end other than an over-bloated platform if all we do is add and not trim. Maybe this is more valid for library support than language features.
  18. Re: Think About Java-Joe![ Go to top ]

    Closures in Java should essentially be a short way to implement an implicit one method interface as a anonymous inner class. I don't see why this should be so scary. Closures are a good thing because they solve real problems. You can't truly create a thread safe Collection because the iterator gives away control. Using a closure or a function pointer solves this. How many times have you seen people not close a database connection in a finally block. Solved with functional-style approach. But really, 1.7? Hardly anyone is using 1.5 yet for real work.
  19. Re: Think About Java-Joe![ Go to top ]

    Hardly anyone is using 1.5 yet for real work.
    Really? I've been coding heavily on 1.5 for about the better part of 2 years now and using it extensively. Despite being a bleeding-edge guy in many respects, I'm not sold on a lot of aspects of closures. Sure they reduce the number of characters required to code some use cases, but that can be said for all sorts of gibberish syntax as well. I read the closures proposal and the whole part about non-matching thread exceptions or whatever they were called in the closure proposal is a mess -- requiring final as with anonymous inner classes is much better! Also, non-local returns are rather ugly. Finally, a good deal of the syntax is rather terse to the point of meaninglessness IMHO. All that said, I'd use some bits of closure syntax if it were available today that strike me as terser without losing readability. That is unless I had junior programmers on the team. At that point I'd drop most thoughts of using closures for fear of spending all my time trying to explain them to all the newbies.
  20. Re: Think About Java-Joe![ Go to top ]

    Hardly anyone is using 1.5 yet for real work.


    Really? I've been coding heavily on 1.5 for about the better part of 2 years now and using it extensively.
    Oh, one person? I must be mistaken ;) At my last job and in my current, we are still in the process of migrating to 1.4. In the enterprise space, these things tend to move slowly. As far as the rest of the your post goes, it's not clear to me what the whole deal is with exceptions and this proposal. It sounds like they are trying to get too clever. All I want is a way to write the implementation of a single method of an implicit interface as a stand alone block of code. Anonymous inner classes get the job done but they are overly burdensome. The discourage the use of this pattern of development that I have come to know as one of the most effective. The problems with using anonymous inner classes in this way: 1. The require an explicit interface to be declared. This is a problem because the interface is really not documenting anything. Interfaces should describe abstraction layers. Interfaces for closure type designs are just technical artifacts that become part of the public API. This isn't good. On top of that you need a new one for pretty much any class that you want to do this in. 2. Anonymous inner class declarations are ugly and hard to read. Again, tons of technical artifacts that have nothing to do with what really matters. The actual code is obscured by all the braces and class declaration stuff. Basically, the class is being declared only as a container to get the code to the host. It's not documenting anything. It's not making anything more clear. It's noise. So there's a simple way to do this. Create a way to implement an implicit interface as an anonymous class without the class or method declaration. We already have implicit classes (whenever we declare an array) why not add a simple syntax something like this (or whatever): interface Collection { public void forEach(method(E item):void); } This for help: interface Pointer { static Pointer create(E e) { return new Pointer(e); } E ref; Pointer(final E ref) { this.ref = ref; } } and then: int sum(Collection in) { final Pointer p = new Pointer(0); in.forEach({ p.ref += item; }); return p.ref; } I don't think this is hard to understand. I think it's a lot easier to understand than anonymous inner classes.
  21. Re: Think About Java-Joe![ Go to top ]

    final Pointer p = new Pointer(0);
    That should have been: final Pointer p = Pointer.create(0);
  22. Since the mainstream largely turned it's nose up to Smalltalk in the late eigthies, what have we managed to achieve in the OO language Space? 1. We brought a sort of OO to familiar ground (C) and introduced objects to a load of C programmers (C++). 2. We dumbed down removing a lot of the less familiar features like Message Sends, Closures and Metaprogramming. 3. We have increased performance by firstly eliminating the use of a VM and automatic memory mangement and adding static typing(C++). 4. We realised the error of our ways and added back the VM and automatic memory mangement, but still retained static typing mainly for performance but also for compile time "type-safety" (Java). 5. We had another round of dumbing down (simplifying) by leaving out function pointers etc (Java). 6. Some decided to add back function pointers and a number of other things from C++ (C#). 7. Now we are looking to add back Closures. How about Metaprogramming? The one thing we haven't been able to do is produce something better. What would be better IMO would be a highly performant Smalltalk with optional compile time type safety. That would be nice. The thing is such a beast exists called Strongtalk and Sun Microsystems has been siting on it since 1996. How about realising Strontalk? It would save a lot of time :^). Paul.
  23. Now we are looking to add back Closures. How about Metaprogramming?

    The one thing we haven't been able to do is produce something better.
    Have you had a look at Scala? I don't know that it's got anything new per se, but it's definitely not dumbed down.
  24. Now we are looking to add back Closures. How about Metaprogramming?

    The one thing we haven't been able to do is produce something better.


    Have you had a look at Scala? I don't know that it's got anything new per se, but it's definitely not dumbed down.
    Just had a quick look just now. looks good on the surface. The thing about dumbing down is that by attempting to limit the power of the developer you actually make his job more complex. So ask any VB programmer or Visual C++ prgrammer and they will tell you that to get the best out of those environments you really need to know a lot about what it is going on under the covers, circumventing the environment when required :^). So dumbing down inpractice often means skilling up! Languages like Smalltalk that are explicit, consistent and elegant in their concepts and features provide the programmer with a number of degrees of freedmon which means that they end up actually easier to use in practice. For example anyone trying to use Spring 2.0 with Aspects and XML would definately find Smalltalk Metaprogramming a lot easier. My view is that we have gone down the wrong path and we need to back up the road aways and pick up somewhere near where Smalltalk-80 left off. Ruby has done this and is getting a lot of success. Scala looks as though it is doing the same. Paul.
  25. Just had a quick look just now. looks good on the surface.
    If you go to this page there's a list of all the features on the left. I don't know why but I have hard time navigating to this from the main page. http://scala.epfl.ch/intro/implicit.html
    The thing about dumbing down is that by attempting to limit the power of the developer you actually make his job more complex.

    So ask any VB programmer or Visual C++ prgrammer and they will tell you that to get the best out of those environments you really need to know a lot about what it is going on under the covers, circumventing the environment when required :^).
    I agree to a point. I do feel that limiting the syntax of a language is important. The big problem I have with C++ is that it's all over the place. Two people can easily write code than the other can't read. I agree with idea of Java which is don't add a feature whether it really adds something new, I just don't agree with some of the choices that were made. Perl is another example of a language that I find very inelegant and ugly. I think it's good that they are considering adding closures and function pointers to Java but I think it's a little late in the game. They should have been added long ago.
  26. Just had a quick look just now. looks good on the surface.


    If you go to this page there's a list of all the features on the left. I don't know why but I have hard time navigating to this from the main page.

    http://scala.epfl.ch/intro/implicit.html Had a look at the list. Seems a bit too long. Trying to do too much maybe? And the syntax looks a little complex. Just first impressions. I'm definately will look into Scala further.
    The thing about dumbing down is that by attempting to limit the power of the developer you actually make his job more complex.

    So ask any VB programmer or Visual C++ prgrammer and they will tell you that to get the best out of those environments you really need to know a lot about what it is going on under the covers, circumventing the environment when required :^).


    I agree to a point. I do feel that limiting the syntax of a language is important.
    I agree with you on this one. Smalltalk manages to achieve most of the features on the Scala list and you can define the syntax in about five lines.
    The big problem I have with C++ is that it's all over the place. Two people can easily write code than the other can't read.
    I agree with your here too. I always felt that C/C++ lends itself to writing clever code. I rather code that is simple clear and readable. As for the syntax - way to complex compared to C and I agree Java is a definate improvement in this regard.
    I agree with idea of Java which is don't add a feature whether it really adds something new, I just don't agree with some of the choices that were made. Perl is another example of a language that I find very inelegant and ugly.
    I don't know Perl, but I don't like the look of the syntax either. I think the problem with Java is the lack of conceptual integrity. The everything is an object idea, including numbers, classes, metaclasses, closures etc and the idea of Object Memory gets you a long way with very little syntax. The same conceptual idea repeated - send a message to an object it will give you an answer. I think the compromise on "true" objects made in Java/C++/C# was only ever going to make sense short-term. As processing power becomes cheaper and the scale and nature of the applications we are trying to build grows then the lack of meta-capabilities will become a bigger problem IMO. The lack of object memory also reduces the possibility for experiementation and innovation from within the language itself(e.g. Mixins and Traits were both added to Smalltalk with no new syntax or changes to the VM, they were just new kinds of meta-object).
    I think it's good that they are considering adding closures and function pointers to Java but I think it's a little late in the game. They should have been added long ago.
    Agreed. I don't see them solving the metaprogramming problem this readily though. For example adding something like Mixins would probably break backwards compatibility. It seems to me that we will have a new mainstream language within the next couple of years or perhaps sooner. Paul.
  27. Just had a quick look just now. looks good on the surface.


    If you go to this page there's a list of all the features on the left. I don't know why but I have hard time navigating to this from the main page.

    http://scala.epfl.ch/intro/implicit.html
    Hi James, Spent a bit more time looking at Scala and well... The first mistake I think they've made is to become obsessive about compile time "type safety". As a consequence they have mxed essentially dynamic ideas like polymorphism with static ideas like generics and compound types. How about the polymorphic situation where an argument could be a number of different types so: def func(param: A or B or C) so param could be of type A or B or C. This is valid in a true dynamic polymorphic OO language like Smalltalk or Ruby. Made possible through the use of a message send. As long as types A, B and C supports the messages sent to param in the body of the method func then they are legal types. Scala uses the idea of compound types to identify legal "message" signatures by anding: def func (param: A and B and C) so param can accept all the "messages" that are defined in A and B and C, a super set. What does this mean? Well it means that Scala isn't doing true message sends, which resolve at runtime. So we need to decide interfaces a head of time (developement time). In reality the only true interface is the message. So Scala is no better off then Java. To gain true polymorpism you would need to define an Interface (type) per message signature. This is the fundamental difference between a virtual function call and a message send and the C++ community just don't get it and neither do Java people or Scala from the looks of things. The strength of Strongtalk is that it's type system is built around annotations which can be tested at development time but are ignored at runtime. So func: param {A | B | C} Is valid. and the annotation {A | B | C } can be checked statically by running a type checker over the code, but is ignored dynamically at runtime. So in a years time when you create a new type D that satifies the interface needed by the method func you can legally pass an argument of type D to func and the runtime will check compliance (duck typing) and your code will work: Polymorphism - "many forms". The strength of the Strongtalk approach is that it provides a mechanism to ween developers of their dependency on a static type system and get them thinking more polymorphically so: func: param With no annotation is legal too, since the param can take a number of forms, some yet to be defined. Sorry for the length, but this idea is fundamental. We are talking late binding versus early binding, and for true polymorphic OO your type system needs to be late-bound. Paul.
  28. The first mistake I think they've made is to become obsessive about compile time "type safety". As a consequence they have mxed essentially dynamic ideas like polymorphism with static ideas like generics and compound types. How about the polymorphic situation where an argument could be a number of different types so:

    def func(param: A or B or C)

    so param could be of type A or B or C. This is valid in a true dynamic polymorphic OO language like Smalltalk or Ruby.
    What you are really talking about is the static vs. dynamic typing debate. I really don't want to get into a discussion about this but I will say that I see value in both in different contexts. One of the things about Scala that you must also realize is that while it is statically-typed, it provides many features that allow types fit the required interfaces. One of the most interesting (to me) is the implicit parameter mechanism where an implicit conversion from one type to another can be specified such that I can define the target interface after the class that will implement it. Combined with type-inference, makes static-typing a lot less cumbersome (in theory.) I do value your input however and if you would like to set out an example of a why you think it's essential to have dynamic typing, I will read it with interest.
  29. The first mistake I think they've made is to become obsessive about compile time "type safety". As a consequence they have mxed essentially dynamic ideas like polymorphism with static ideas like generics and compound types. How about the polymorphic situation where an argument could be a number of different types so:

    def func(param: A or B or C)

    so param could be of type A or B or C. This is valid in a true dynamic polymorphic OO language like Smalltalk or Ruby.


    What you are really talking about is the static vs. dynamic typing debate. I really don't want to get into a discussion about this but I will say that I see value in both in different contexts.
    I see value in both too. IMO static typing is good for stable and static interfaces. Generally speaking these are low level deterministic interfaces like a 3D graphics library. When you move to malleable interfaces that will change over time outside your control, for example across the internet, then you need a more flexible approach - dynamic typing. So as we move away from the hardware and deterministic problems into human centric non-deterministic ones late-binding will become more important IMO. Take a look at this video of a late-bound system (again from Sun Microsystems) and you will see why I believe that this approach is inevitably the future: http://video.google.com/videoplay?docid=5776880551404953752&q=label%3Aesug
    One of the things about Scala that you must also realize is that while it is statically-typed, it provides many features that allow types fit the required interfaces. One of the most interesting (to me) is the implicit parameter mechanism where an implicit conversion from one type to another can be specified such that I can define the target interface after the class that will implement it. Combined with type-inference, makes static-typing a lot less cumbersome (in theory.)

    I do value your input however and if you would like to set out an example of a why you think it's essential to have dynamic typing, I will read it with interest.
    Type inference saves typing (key strokes) fine. I do not fully understand what you mean by "implicit parameters", but from what you say it sounds like you need to decide the flexibility points you will need in the future, today at design time. This approach means that you need to guess the future. The idea of Interfaces in Java or virtual functions in C++ is the same, you need to guess your pluggable points ahead of time. What a dynamic approach gives you is that it makes everything pluggable by default. So as you discover where you need change or extension you can do so without affecting existing (possibly running) code. The properties of the Self language: directness, uniformity and liveliness brings software closer to the real world, and in the end it is the real world that we need to model. An example of a real world late-bound system that could not be produced with a static language is croquet: www.opencroquet.org Here is a demo: http://video.google.com/videoplay?docid=-9055536763288165825&q=label%3Aesug The people doing this stuff know a thing or two about objects, they invented the idea :^) Paul.
  30. Take a look at this video of a late-bound system (again from Sun Microsystems) and you will see why I believe that this approach is inevitably the future:
    It's kind of funny because that video is clearly from at least 10 years ago. Anyway, it looks to me a lot like an old Javabeans demo.
    One of the things about Scala that you must also realize is that while it is statically-typed, it provides many features that allow types fit the required interfaces. One of the most interesting (to me) is the implicit parameter mechanism where an implicit conversion from one type to another can be specified such that I can define the target interface after the class that will implement it. Combined with type-inference, makes static-typing a lot less cumbersome (in theory.)

    I do value your input however and if you would like to set out an example of a why you think it's essential to have dynamic typing, I will read it with interest.

    Type inference saves typing (key strokes) fine. I do not fully understand what you mean by "implicit parameters", but from what you say it sounds like you need to decide the flexibility points you will need in the future, today at design time.
    No, it's the opposite. You can make an old type conform to an new interface implicitly an differently depending on the context.
    This approach means that you need to guess the future. The idea of Interfaces in Java or virtual functions in C++ is the same, you need to guess your pluggable points ahead of time. What a dynamic approach gives you is that it makes everything pluggable by default. So as you discover where you need change or extension you can do so without affecting existing (possibly running) code.

    The properties of the Self language: directness, uniformity and liveliness brings software closer to the real world, and in the end it is the real world that we need to model.

    An example of a real world late-bound system that could not be produced with a static language is croquet:

    www.opencroquet.org

    Here is a demo:
    That sounds good in theory but it seems unlikely that I'll just happen to write the exact thing I need before I know I'll need it.
  31. An example of a real world late-bound system that could not be produced with a static language is croquet:
    Can you explain specifically why it could not be done with static binding? I've seen this argument (and been involved in it) about half-a-dozen time so please don't assume I am not familiar with the concepts. Here's my take, dynamic binding languages still require an interface (abstraction layer, whatever) to be determined ahead of time. It's just not specified in the code. For example, you can't call a method on an Object if you don't know what it is or what is does and expect a sensible result. If you know what method you will call in a specific circumstance then that's really a pre-defined interface whether you specify it in the code or not.
  32. An example of a real world late-bound system that could not be produced with a static language is croquet:


    Can you explain specifically why it could not be done with static binding?

    I've seen this argument (and been involved in it) about half-a-dozen time so please don't assume I am not familiar with the concepts.

    Here's my take, dynamic binding languages still require an interface (abstraction layer, whatever) to be determined ahead of time. It's just not specified in the code. For example, you can't call a method on an Object if you don't know what it is or what is does and expect a sensible result. If you know what method you will call in a specific circumstance then that's really a pre-defined interface whether you specify it in the code or not.
    The issue is coupling. When I know the class of an object that I want to sent a message to, then I know something about it's implementation. So the sender object is coupled to the implementation of the reciever. Should I want to change the implementation of the reciever to a new object with a different implementation, but understanding the same protocol (messages) I can't. The only real dependency between the sender and the reciever should be the protocols (message signatures) used, not the Class or (full) Interface. You see this with RMI all the time, if you change a class and recompile and try and send it by value (serialise it) over a remote connection it will break, because the class loader at the remote end thinks that it is a different class (type) to the one the reciever expects. Even though the serialised object still understands the required protocol. To be pluggable the sender needs to know nothing about the reciever accept that it supports the protocol required. Interfaces help a bit, but again should the interface change, with RMI the remote connection breaks. So if I remove protocol from my interface that a given reciever doesn't use, my verifyier? at the remote end will still throw a class cast exception. OK. That's the basic explanation (Ithink :^)). Think about the demo of croquet where David Smith was turning the window into the portal. The contents of the portal was fore-shotened and fore-lengthened as he turned the window. How is this done? Does the world (island) inside the portal know about portals? Does the camera know about islands? My guess is that the portal acts as a proxy for the camera in the current world providing a view into the world behind the portal. So the portal is acting as a camera into the world behind it. So what type is it? A Camera or a Portal? The world behind the portal doesn't care it just renders a perspective in response to messages (either from a camera view or a portal view). Think of the example where Alice (David Smith) was on the platform with the flag and the Rabbit (Alan Kay) was turning the platform and Alice together. How was this done? My guess again is that the platform keeps track of all objects upon it, and updates their location when it moves. The collection of protocols used by the different sender objects may not fall nicely into pre-defined Types, they are a ad-hoc mix depending on the behaviour required. An example that they didn't show was one where they both are editing an html document together. BTW the HTML editor is a standard 2D application placed into a 3D window and as the window is turned the image is fore-shortened and fore lenthened just like with the portal. They both edit the same page at the same time. The browser application doesn't know that it is in a 3D window, and it doesn't know that it has been replicated across a network, also it doesn't know that mouse inputs and key strokes are comming from two different sources. I'm not sure that I've explained this well, but read some of the white papers on the croquet site and you will see why this just can't be done with Java or a static language. The last point I want to make is that we don't need to have the dynamic versus static debate anyway because the Strongtalk approach shows that you can have both. If your object interfaces are typed then that type information can be checked at compile time by a type checker. At runtime the system can relies on dynamic typing. So with the Strongtalk approach you get both. Paul.
  33. At runtime the system can relies on dynamic typing. So with the Strongtalk approach you get both.

    Paul.
    May I point you (yet again) at Groovy? It has both static and dynamic typing. It has closures. It has metaprogramming. It is available now, and runs at reasonable performance on the JVM. There are exciting Rails-type approaches being done with it - Grails. Unlike the currently available Strongtalk implementation, it runs on more than Windows, and is open source.
  34. At runtime the system can relies on dynamic typing. So with the Strongtalk approach you get both.

    Paul.


    May I point you (yet again) at Groovy? It has both static and dynamic typing. It has closures. It has metaprogramming. It is available now, and runs at reasonable performance on the JVM. There are exciting Rails-type approaches being done with it - Grails. Unlike the currently available Strongtalk implementation, it runs on more than Windows, and is open source.
    Hi Steve, Groovy is fine if you believe that the world revolves around the JVM. I don't. Given where we are Groovy is possibly a good pragmatic choice. I'm merely stating that perhaps we shouldn't be where we are now. And that perhaps we should go back to something much better. Paul.
  35. At runtime the system can relies on dynamic typing. So with the Strongtalk approach you get both.

    Paul.


    May I point you (yet again) at Groovy? It has both static and dynamic typing. It has closures. It has metaprogramming. It is available now, and runs at reasonable performance on the JVM. There are exciting Rails-type approaches being done with it - Grails. Unlike the currently available Strongtalk implementation, it runs on more than Windows, and is open source.

    Hi Steve,

    Groovy is fine if you believe that the world revolves around the JVM. I don't.

    Given where we are Groovy is possibly a good pragmatic choice. I'm merely stating that perhaps we shouldn't be where we are now. And that perhaps we should go back to something much better.

    Paul.
    You are missing my point. I saying that Groovy is more than a pragmatic choice if you just want to use a JVM - it is a full and rich language it itself. It is not as elegant as Ruby in some ways, but it has features that Ruby does not have, such as the ability to use static typic if desired. To dismiss Groovy as simply a pragmatic choice and only fine if you want to use the JVM is FUD. I don't believe there is a single feature that you have listed in your requirements for a dynamic language in other threads that Groovy lacks. Have you actually looked at Groovy?
  36. At runtime the system can relies on dynamic typing. So with the Strongtalk approach you get both.

    Paul.


    May I point you (yet again) at Groovy? It has both static and dynamic typing. It has closures. It has metaprogramming. It is available now, and runs at reasonable performance on the JVM. There are exciting Rails-type approaches being done with it - Grails. Unlike the currently available Strongtalk implementation, it runs on more than Windows, and is open source.

    Hi Steve,

    Groovy is fine if you believe that the world revolves around the JVM. I don't.

    Given where we are Groovy is possibly a good pragmatic choice. I'm merely stating that perhaps we shouldn't be where we are now. And that perhaps we should go back to something much better.

    Paul.


    You are missing my point. I saying that Groovy is more than a pragmatic choice if you just want to use a JVM - it is a full and rich language it itself. It is not as elegant as Ruby in some ways, but it has features that Ruby does not have, such as the ability to use static typic if desired.

    To dismiss Groovy as simply a pragmatic choice and only fine if you want to use the JVM is FUD. I don't believe there is a single feature that you have listed in your requirements for a dynamic language in other threads that Groovy lacks.

    Have you actually looked at Groovy?
    I have looked at groovy, and other then the fact that it is Java-like I see nothing to distinguish it from a number of more mature and able dynamic languages. If it does poses distinguishing characteristics please point them out. Paul.
  37. I have looked at groovy, and other then the fact that it is Java-like I see nothing to distinguish it from a number of more mature and able dynamic languages.

    If it does poses distinguishing characteristics please point them out.

    Paul.
    Well, it has some things that I find useful. Firstly, it has option to use static typing if required. Secondly, it has really seamless integration with Java - it can use Java classes directly - there aren't the sort of issues that are turning up with JRuby, such as how to handle numeric types. Thirdly, it can be used either dynamically or it can compile to class files, so you can use Groovy classes just as if they were any other Java class. There are languages for the JVM can can do one or other of these things (Jython will compile to classes), but Groovy has the full set. But anyway, my point about Groovy was not that it was significantly superior to any other mature dynamic language in terms of features. My point was that it was just about equal to them, which is why dismissing groovy as simply a pragmatic choice for the JVM is nonsense - it is not pragmatic, it is full-featured. I raised the issue of groovy because you were harking back to Strongtalk.
    The last point I want to make is that we don't need to have the dynamic versus static debate anyway because the Strongtalk approach shows that you can have both.
    I wanted to point out that this approach can be used on a modern open-source language that is fully supported on a portable and high performance VM (whether or not the world 'revolves around' that VM seems irrelevant). But anyway, back the topic of this thread - I find myself not as enthusiastic about closures in Java as I might be if Groovy were not around. As you can pretty much write Java code in Groovy, with closures (and a range of other features), and as it can be integrated easily with Java, I don't see that much need.
  38. The issue is coupling. When I know the class of an object that I want to sent a message to, then I know something about it's implementation.
    See, this is where I have to disagree. The value of OO is that (ideally) you don't. When I design interfaces, they are implementation agnostic. If this can be done, you avoid string coupling.
    So the sender object is coupled to the implementation of the reciever. Should I want to change the implementation of the reciever to a new object with a different implementation, but understanding the same protocol (messages) I can't.
    OK, but what does this have to do with good OO code written with static-typing? You seem to be setting up a straw-man here.
    The only real dependency between the sender and the reciever should be the protocols (message signatures) used, not the Class or (full) Interface.
    But the interface is the set of the supported messages. How does allowing unsupported messages help you?
    You see this with RMI all the time, if you change a class and recompile and try and send it by value (serialise it) over a remote connection it will break, because the class loader at the remote end thinks that it is a different class (type) to the one the reciever expects.
    That's just an issue with Java serialization. It's actually avoidable if you specify your own version numbers and it's only one of many possible ways to serialize data. I don't think it really has much to do with this discussion. It's not inherently part of static-typing. A lot of work went into making it fail the way you describe.
    Think about the demo of croquet where David Smith was turning the window into the portal. The contents of the portal was fore-shotened and fore-lengthened as he turned the window. How is this done? Does the world (island) inside the portal know about portals? Does the camera know about islands? My guess is that the portal acts as a proxy for the camera in the current world providing a view into the world behind the portal. So the portal is acting as a camera into the world behind it. So what type is it? A Camera or a Portal? The world behind the portal doesn't care it just renders a perspective in response to messages (either from a camera view or a portal view).
    It's just not clear to me why you believe this cannot be accompished with static typing.
    Think of the example where Alice (David Smith) was on the platform with the flag and the Rabbit (Alan Kay) was turning the platform and Alice together. How was this done? My guess again is that the platform keeps track of all objects upon it, and updates their location when it moves.

    The collection of protocols used by the different sender objects may not fall nicely into pre-defined Types, they are a ad-hoc mix depending on the behaviour required.
    But again, this collection of methods (messages) needs to be supported by all the receivers. It's not as if they person who wrote the different pieces didn't know what methods would be called and just happened to make them support the same messages as all the other people writing such components. The interface is pre-defined, it's just not specified anywhere. The point is that it's not that you can do things with dynamic binding that you cannot with static binding, it's just easier to do a lot of these things. That's the strength of dynamic binding. But the lack of specification is also it's weakness. If the controller above now needs to send a new message, what happens to the recievers if they haven't been updated? They will almost surely not be able to handle the message. The only difference is that static-typing will not allow you to send that message until it's sure all the possible receivers support it. Sometimes this is a major drag because it's too much overhead. But it definitely helps to manage complextity and to simplify maintenance. For example, I can track down all the possible recievers of a message with a couple clicks of my mouse even if they aren't actually called by any code yet. Can you do this in a dynamic language? I don't think you can, at least not with the precision that static typing allows.
  39. The issue is coupling. When I know the class of an object that I want to sent a message to, then I know something about it's implementation.


    See, this is where I have to disagree. The value of OO is that (ideally) you don't. When I design interfaces, they are implementation agnostic. If this can be done, you avoid string coupling.

    You are spot on. So where do you place your Interfaces (pulggable points)? Should every Class have an Interface? If so what about the case where a client only uses methods1-4, from 10 methods in the Interface? and another client uses methods 3-10? Ok if you think it through you will realise that to completely decouple everything you will need an Interface for every method call (message) ,so Interfaces 1- 10 for a single class. And if you do this you are left with duck typing. Think about it, and read the post by Erik he sums it up well. BTW don't forget my point that you can still have static typing at compile time, the problem is imposing these Types or Interfaces at run time. So static at compile time, dynamic at runtime. Paul
  40. The issue is coupling. When I know the class of an object that I want to sent a message to, then I know something about it's implementation.


    See, this is where I have to disagree. The value of OO is that (ideally) you don't. When I design interfaces, they are implementation agnostic. If this can be done, you avoid string coupling.

    You are spot on. So where do you place your Interfaces (pluggable points)? Should every Class have an Interface? If so what about the case where a client only uses methods1-4, from 10 methods in the Interface? and another client uses methods 3-10? Ok if you think it through you will realise that to completely decouple everything you will need an Interface for every method call (message) ,so Interfaces 1- 10 for a single class. And if you do this you are left with duck typing. Think about it, and read the post by Erik he sums it up well. BTW don't forget my point that you can still have static typing at compile time, the problem is imposing these Types or Interfaces at run time. So static at compile time, dynamic at runtime. Paul
  41. The issue is coupling. When I know the class of an object that I want to sent a message to, then I know something about it's implementation.


    See, this is where I have to disagree. The value of OO is that (ideally) you don't. When I design interfaces, they are implementation agnostic. If this can be done, you avoid string coupling.


    You are spot on. So where do you place your Interfaces (pluggable points)? Should every Class have an Interface? If so what about the case where a client only uses methods1-4, from 10 methods in the Interface? and another client uses methods 3-10? Ok if you think it through you will realise that to completely decouple everything you will need an Interface for every method call (message) ,so Interfaces 1- 10 for a single class. And if you do this you are left with duck typing.

    Think about it, and read the post by Erik he sums it up well. BTW don't forget my point that you can still have static typing at compile time, the problem is imposing these Types or Interfaces at run time. So static at compile time, dynamic at runtime.

    Paul
    Some further explanation. Just to make it completely clear. The client that uses methods 1-4 (clientA) is now coupled to the client that uses methods 3-10 (ClientB) through the common Interface. Should the interface change ( e.g adding a new method 11), both clients will need recompiling. To completely decouple clientA and ClientB you will need Interfaces that are specific to each client. So for ClientA in Scala terms you would have the compound interface Interface1 and Interface2 ... and Interface4 and for Client B you would have the compound interface Interface3 and Interface4 .. and Interface10. Once you have gone to all this trouble what you are left with is duck typing. Paul.
  42. The issue is coupling. When I know the class of an object that I want to sent a message to, then I know something about it's implementation.


    See, this is where I have to disagree. The value of OO is that (ideally) you don't. When I design interfaces, they are implementation agnostic. If this can be done, you avoid string coupling.


    You are spot on. So where do you place your Interfaces (pluggable points)?
    Ideally you would do it for every logical group of messages. The problem is that this is too burdensome for most purposes so you make the groups larger than scrictly needed. This is burdensome to a degree, no doubt. But that is very different from saying it cannot be done.
    Should every Class have an Interface?
    No. That completely misses the point. It puts classes above interfaces when it should really be the other way around.
    If so what about the case where a client only uses methods1-4, from 10 methods in the Interface? and another client uses methods 3-10?
    methods 1-4 -> one interface methods 3-10 -> another interface Class implements both. The interfaces is be specified "by" the class that calls the methods by using it in a method signature. The interface design in no way should be driven by the class that implements them. I generally create interfaces long before I implement them with more than stubs. Most implementation classes shouldn't even be public.
    Ok if you think it through you will realise that to completely decouple everything you will need an Interface for every method call (message)
    I think that's hyperbole. I've never seen a type that could be dissected that way. I really can't imagine that any class that was should be specified as a single class.
    so Interfaces 1- 10 for a single class. And if you do this you are left with duck typing.
    This whole description seems to completely miss the point of interfaces. I don't know where this idea that the implmentations drive the abstractions is coming from. Implementations exist to satisfy interfaces; not the other way around. I do think that duck-typing could really be great if it actually existed. Duck-typing as I hae seen it is just another way of saying a method has an implicit interface. As far as I can tell the only way to figure out what it is is to read documentation, read the code, or trial and error. If we could have a static typing system that allowed us to specify what methods a method depends on, then you'd have a real duck-typing system. But I think that would probably suffer from the same problem as interfaces in that it would be too verbose for a lot of tasks.
    BTW don't forget my point that you can still have static typing at compile time, the problem is imposing these Types or Interfaces at run time. So static at compile time, dynamic at runtime.
    This I can agree with. I we think of interfaces as a group of methods that are needed to accomplish as specific task, I think you can remove the requirement to implement an interface explicitly. You just implement the methods on that interface. The compiler can easily tell you if they aren't all there. The only potential problem with this is that just because the method is named getName(), it doesn't mean it's the same name I mean when I call it. In practice, however, I think this isn't really a big problem as dynamic langages have proven.
  43. The issue is coupling. When I know the class of an object that I want to sent a message to, then I know something about it's implementation.


    See, this is where I have to disagree. The value of OO is that (ideally) you don't. When I design interfaces, they are implementation agnostic. If this can be done, you avoid string coupling.


    You are spot on. So where do you place your Interfaces (pluggable points)?


    Ideally you would do it for every logical group of messages. The problem is that this is too burdensome for most purposes so you make the groups larger than scrictly needed. This is burdensome to a degree, no doubt. But that is very different from saying it cannot be done.

    Should every Class have an Interface?


    No. That completely misses the point. It puts classes above interfaces when it should really be the other way around.

    If so what about the case where a client only uses methods1-4, from 10 methods in the Interface? and another client uses methods 3-10?


    methods 1-4 -> one interface
    methods 3-10 -> another interface

    Class implements both. The interfaces is be specified "by" the class that calls the methods by using it in a method signature. The interface design in no way should be driven by the class that implements them. I generally create interfaces long before I implement them with more than stubs. Most implementation classes shouldn't even be public.

    Ok if you think it through you will realise that to completely decouple everything you will need an Interface for every method call (message)


    I think that's hyperbole. I've never seen a type that could be dissected that way. I really can't imagine that any class that was should be specified as a single class.

    so Interfaces 1- 10 for a single class. And if you do this you are left with duck typing.


    This whole description seems to completely miss the point of interfaces. I don't know where this idea that the implmentations drive the abstractions is coming from. Implementations exist to satisfy interfaces; not the other way around.

    I do think that duck-typing could really be great if it actually existed. Duck-typing as I hae seen it is just another way of saying a method has an implicit interface. As far as I can tell the only way to figure out what it is is to read documentation, read the code, or trial and error. If we could have a static typing system that allowed us to specify what methods a method depends on, then you'd have a real duck-typing system. But I think that would probably suffer from the same problem as interfaces in that it would be too verbose for a lot of tasks.

    BTW don't forget my point that you can still have static typing at compile time, the problem is imposing these Types or Interfaces at run time. So static at compile time, dynamic at runtime.


    This I can agree with. I we think of interfaces as a group of methods that are needed to accomplish as specific task, I think you can remove the requirement to implement an interface explicitly. You just implement the methods on that interface. The compiler can easily tell you if they aren't all there.

    The only potential problem with this is that just because the method is named getName(), it doesn't mean it's the same name I mean when I call it. In practice, however, I think this isn't really a big problem as dynamic langages have proven.
    Hi James, We are getting close. Think this through some more. So you have split one interface into 2. OK when does this happen? First you create the Interfaace1-10 like you say then you creat the implementation: ServerX. You then create ClientA and deploy. Six months later you create ClientB. When you create clientB you decide to create Interface3-10. But hang on. The Server class (server) implements Interface1-10, so should you change the Server to implement Interface3..10 too? So you need to re-compile the Server. (stop the server chnage the code and restart). Aslo you still have ClientA with access to a load of methods it should not use (methods 5-10) so should we change the ServerX to implement Interface1-4 and Interface3-10 and change ClientA to use a Interface1-4? What happens six months later when I decide that I need clientC? Yes your are correct it is a hyperbole.
    I do think that duck-typing could really be great if it actually existed. Duck-typing as I hae seen it is just another way of saying a method has an implicit interface. As far as I can tell the only way to figure out what it is is to read documentation, read the code, or trial and error.
    Generally speaking yes. It is the round peg square hole problem. How do you know the peg will or won't fit? You try it for size. Interfaces in the sense that you describe are false documentation. I say that I need Interface1-10 when all I really need is Interface1-4, so an implementation of Interface1-4 will fit! The documentation is telling lies :^). Strongtalk gets around this dilema in away, but it is still a dilema. Paul.
  44. We are getting close. Think this through some more. So you have split one interface into 2. OK when does this happen? First you create the Interfaace1-10 like you say then you creat the implementation:
    No, that's not what I said. It's what I said you should NOT be doing. The interface comes before the implementation. A lot of people do what you are saying but I think that is a terrible way to do things.
    ServerX. You then create ClientA and deploy. Six months later you create ClientB. When you create clientB you decide to create Interface3-10. But hang on.

    The Server class (server) implements Interface1-10, so should you change the Server to implement Interface3..10 too?
    You would only need to do that if there was code that needed to see the Server as implementing that interface. In that specific case, it's likely that the second interface is actually a supertype of the original. You can just declare the new interface and add the extends clause to the original. But even if that was not valid, it's not a big deal.
    So you need to re-compile the Server. (stop the server chnage the code and restart).
    Oh God, Nooooo! ;) Actually it's not usually necessary to restart a server to deploy changes. In development a lot of servers allow you to just drop the changes in a directory and they take effect.
    Aslo you still have ClientA with access to a load of methods it should not use (methods 5-10) so should we change the ServerX to implement Interface1-4 and Interface3-10 and change ClientA to use a Interface1-4?
    No because those methods wouldn't be in the interface in the first place. Like I said, I don't write interfaces based on implementations. I write implementations for interfaces. If those methods were never needed in the interface why would they be there in the first place?
    What happens six months later when I decide that I need clientC?

    Yes your are correct it is a hyperbole.
    I'm sure you've heard of separation of responsibilities. If you have a single class that is assuming three distinct roles, there's a problem with your design.
  45. OT: Public methods on classes[ Go to top ]

    No because those methods wouldn't be in the interface in the first place. Like I said, I don't write interfaces based on implementations. I write implementations for interfaces. If those methods were never needed in the interface why would they be there in the first place?
    Hmmm... So should Java prevent people from declaring public fields and methods on classes unless they are on a declared interface? This assumes "public" really represents interface, while package, protected, and private are all varying degrees of implementation details.
  46. No because those methods wouldn't be in the interface in the first place. Like I said, I don't write interfaces based on implementations. I write implementations for interfaces. If those methods were never needed in the interface why would they be there in the first place?


    Hmmm... So should Java prevent people from declaring public fields and methods on classes unless they are on a declared interface?

    This assumes "public" really represents interface, while package, protected, and private are all varying degrees of implementation details.
    No. Interfaces are good because they are flexible but an class can be used in the same way. What I am really talking about is a type. You suggested a scenario where I wrote a class and then I wrote classes that use it. That's backwards. The idea is to define the types and design the highlevel interactions and then write the implementations. I keep seeing your argument over and over again in these debates which makes me think that this is the MO for dynamic languages. My own experience has shown me that this is a bad way to design a system. It's much better to step back and define types in an abstract sense. If you concentrate on a specific implementation, you will end up making a design that is coupled to that implementation. What you seem to be describing is ad-hoc design.
  47. You suggested a scenario where I wrote a class and then I wrote classes that use it. That's backwards. The idea is to define the types and design the highlevel interactions and then write the implementations.
    I don't think it that was me.
    I keep seeing your argument over and over again in these debates which makes me think that this is the MO for dynamic languages.
    I agree.
    My own experience has shown me that this is a bad way to design a system.
    Absolutely.
    If you concentrate on a specific implementation, you will end up making a design that is coupled to that implementation.
    Yup. Although the benefit of not being coupled to an implementation is dependent on context. Often times it is not worth the cost.
    It's much better to step back and define types in an abstract sense.
    This really depends on the situation.
    What you seem to be describing is ad-hoc design.
    Exactly (well, I think it was Paul, not me).
    So the goal is to end up with a working system that meets its requirements, is robust and extensible, has low maintenance, countless other things - and all on budget and schedule. That's the goal. The question is: What is your strategy for achieving it? Personally, I work very differently in Python than I do in Java. It takes far less time to reach a demonstrable result in Python than it does in Java, especially for problems involving more complex data structures or algorithms. The reason is in Java I spend a lot of time pondering types, interfaces, coupling, the whole 9 yards. In Python I tend to use strings, lists, dictionaries, and tuples at first in places where in Java I'd make separate classes to represent different concepts. So in Python it takes me much less time to demonstrate that a concept or algorithm is feasible. However, it also takes less time to produce a large pile of spaghetti that I probably wouldn't have made in Java. Keep in mind this isn't an inherent problem with Python or limitation of Java. It just tends to be how I work. Working in different languages makes me think in different ways. Java encourages me to think about the big picture, while Python encourages me to focus the problem at hand. So if I have a small set of assumptions or requirements that are both critical to success and very weak, I'll tend to use Python to explore the problem space and increase my level of certainty. This is because the amount of code to untangle will be small and the knowledge gained valuable. If I have a better understanding and a higher degree of certainty, or if the complexity of the problem space isn't concentrated around a few concepts, then I'll prefer Java. Because the complexity is more stemming from the need to partition the problem space than from the inherent complexity of the problem. In the end I think it's a wash in terms of productivity - defined as cost to go from system concept to production system - but the two languages tend to get you to different points at different rates. But I'll tell you this - I think it takes a higher caliber programmer to write good Python than good Java. If I'm working with a team or will be after a certain stage, I'll always pick a staticly typed language.
  48. I don't think it that was me.
    Did I get confused? Sorry. As you can probably tell by my typos, I'm pushing my limits here.
    Although the benefit of not being coupled to an implementation is dependent on context. Often times it is not worth the cost.

    It's much better to step back and define types in an abstract sense.
    This really depends on the situation.
    Granted. I should have qualified that statement. I actually am a propent of macro-cleanliness/micro-sloppiness approach. In other words, big important pieces need to be really well designed and the smaller, dirtier parts just need to be quarantined.
    So the goal is to end up with a working system that meets its requirements, is robust and extensible, has low maintenance, countless other things - and all on budget and schedule.

    That's the goal. The question is: What is your strategy for achieving it?
    Lately I'm thinking it's a combination of dynamic and static languages. How that all fits together is still very up in the air. At this point, it's not real for me at work. I'm a pioneer here trying to get Java running on one of our AS/400 servers.


    Personally, I work very differently in Python than I do in Java. It takes far less time to reach a demonstrable result in Python than it does in Java, especially for problems involving more complex data structures or algorithms.
    Absolutely agree.
    The reason is in Java I spend a lot of time pondering types, interfaces, coupling, the whole 9 yards. In Python I tend to use strings, lists, dictionaries, and tuples at first in places where in Java I'd make separate classes to represent different concepts.
    Part of that is the dynamic typing. I use Lists and Maps (no tuples, sadly) in Java much the same way. Generics makes this easier in some ways but has cost too. But really I think a lot of that is that these types are part of the language and are encouraged for such usage.

    So in Python it takes me much less time to demonstrate that a concept or algorithm is feasible. However, it also takes less time to produce a large pile of spaghetti that I probably wouldn't have made in Java.

    Keep in mind this isn't an inherent problem with Python or limitation of Java. It just tends to be how I work. I think you are not atypical in this respect.
    Working in different languages makes me think in different ways. Java encourages me to think about the big picture, while Python encourages me to focus the problem at hand.

    So if I have a small set of assumptions or requirements that are both critical to success and very weak, I'll tend to use Python to explore the problem space and increase my level of certainty. This is because the amount of code to untangle will be small and the knowledge gained valuable.

    If I have a better understanding and a higher degree of certainty, or if the complexity of the problem space isn't concentrated around a few concepts, then I'll prefer Java. Because the complexity is more stemming from the need to partition the problem space than from the inherent complexity of the problem.

    In the end I think it's a wash in terms of productivity - defined as cost to go from system concept to production system - but the two languages tend to get you to different points at different rates.
    The biggest benefit of static-typing is that it forces you to create artifacts of your design in the code (if you are going to create something decent.) A good counter-example is trying to emulate a list in Python. I found this terribly annoying. I wanted to just tell the compiler "I want to implement a list, just tell me what I need to do."
    But I'll tell you this - I think it takes a higher caliber programmer to write good Python than good Java. If I'm working with a team or will be after a certain stage, I'll always pick a staticly typed language.
    I don't know. I'll say it takes a much more responsible developer in Python. Java punishes the undisciplined. Python does not. The problem is that it take a really good developer to avoid the pitfalls (to a reasonable degree) that our friend Paul is describing.
  49. A good counter-example is trying to emulate a list in Python. I found this terribly annoying. I wanted to just tell the compiler "I want to implement a list, just tell me what I need to do."
    Ahhh...I've done this in both Python and Java and they are both annoying. But it is easier to get a complete implementation written in Java. I think this is a good example. If you write a list class in Java that only partially supports the List interface and declare that it supports the list interface, then you will get a compiler error. In Python it will work, until someone tries to use one of the pieces of the list protocol that you forgotted/skipped. For example, I don't use slices very often. I think some Python people use them extensively. Consequently in my unlimited laziness I'd be very likely to skip implementing the slice methods, and my code would work fine because it doesn't use them. Until I passed it into a library that did, or someone else who uses them a lot tried to use my list.
    Lately I'm thinking it's a combination of dynamic and static languages.
    Me too.
    How that all fits together is still very up in the air. At this point, it's not real for me at work.
    The only reason I get to use Python at work is that I'm not well supervised. Every time I mention it to someone who "knows something" about software development I get dirty looks.
    I don't know. I'll say it takes a much more responsible developer in Python. Java punishes the undisciplined. Python does not. The problem is that it take a really good developer to avoid the pitfalls (to a reasonable degree) that our friend Paul is describing.
    Agreed.
  50. A good counter-example is trying to emulate a list in Python. I found this terribly annoying. I wanted to just tell the compiler "I want to implement a list, just tell me what I need to do."


    Ahhh...I've done this in both Python and Java and they are both annoying.
    Yeah, the Collections interfaces are way too expansive in scope. Map is the worst offender, IMO. But that's another discussion.
  51. We are getting close. Think this through some more. So you have split one interface into 2. OK when does this happen? First you create the Interfaace1-10 like you say then you creat the implementation
    No, that's not what I said. It's what I said you should NOT be doing. The interface comes before the implementation...
    Yes. So how can you define two interfaces before you know you've got two clients? or three six months later, or four six months after that?
    I'm sure you've heard of separation of responsibilities. If you have a single class that is assuming three distinct roles, there's a problem with your design.
    OK. This is the crux. If you know what service and interface all your future clients will possibly demand, then you can define seperate interfaces and/or seperate services up front. My point is that you don't. A service can be cohesive, yet a given client may choose not to utlise the full interface. Systems change and evolve over time with new clients that the original authors never even dreamt of. I've achieved what I wanted which is explaining the point. The rest is down to what you want to believe. Thanks for the discussion. Paul
  52. We are getting close. Think this through some more. So you have split one interface into 2. OK when does this happen? First you create the Interfaace1-10 like you say then you creat the implementation

    No, that's not what I said. It's what I said you should NOT be doing. The interface comes before the implementation...

    Yes. So how can you define two interfaces before you know you've got two clients? or three six months later, or four six months after that?
    What does that have to do with your initial question? You are changing the argument that I was replying to. You said I was doing something, which I said I do not do. I don't see why you want to quibble over that. As far as that question goes. You don't you define the interface as they are needed. Clients that need to use the new interface need to know about it. If a client doesn't need to change, it doesn't.
    I'm sure you've heard of separation of responsibilities. If you have a single class that is assuming three distinct roles, there's a problem with your design.


    OK. This is the crux. If you know what service and interface all your future clients will possibly demand, then you can define seperate interfaces and/or seperate services up front.

    My point is that you don't. A service can be cohesive, yet a given client may choose not to utlise the full interface. Systems change and evolve over time with new clients that the original authors never even dreamt of.
    And you can deal with that in staticly typed langauges. People do it every day.
  53. The reason why I'm changing things, is because that is the real world. Things change they are not static.
    And you can deal with that in staticly typed langauges. People do it every day.
    This is the point. They don't. The only way to deal with this problem is to refactor and change the Interfaces in the code. Which is fine if all the code is local. But is not fine if the code belongs to some one else e.g. a remote client over the network or third party code in an off the self component like an EJB, or COM component. James you are showing your lack of experience in this area. I understand what you say about interfaces, I've read the book too. I'm saying in practice it doesn't work that way in all curcumstances. BTW. This is why people often use messaging systems like JMS, because they reduce the coupling between client and server and hence make systems more flexible and malleable to change. Messaging in dynamic languages serves the same purpose between objects. Paul.
  54. The reason why I'm changing things, is because that is the real world. Things change they are not static.

    And you can deal with that in staticly typed langauges. People do it every day.

    This is the point. They don't. The only way to deal with this problem is to refactor and change the Interfaces in the code. Which is fine if all the code is local. But is not fine if the code belongs to some one else e.g. a remote client over the network or third party code in an off the self component like an EJB, or COM component.
    Don't use EJB or COM and use something well thought-out. it's a well-known secret that not all Sun engineers are great developers. So you just change the code in the dynamic environment and then what, let clients blow-up? This is what you keep avoiding. Just because you don't have an interface doesn't mean the client doesn't have to change? Have you provided the client with any form of contract? If so, you need to honor that or the client needs to change. If not that client is going to be coupled to an implementation. This much a much worse case. For example what do you think would happen if a commonly used Python library like os.path suddenly changed in a way that was no longer compatible with it's previous implementation? Do you think my Python scripts would still work? Dynamic languages don't implement the new requirements for you and they don't prevent coupling.


    James you are showing your lack of experience in this area.
    I know it's frustrating when someone asks you to back up an unfounded assertion. The solution is to not make sure assertions not to make ad hominem attacks.
    I understand what you say about interfaces, I've read the book too.
    I don't think you do.
    I'm saying in practice it doesn't work that way in all curcumstances.

    BTW. This is why people often use messaging systems like JMS, because they reduce the coupling between client and server and hence make systems more flexible and malleable to change. Messaging in dynamic languages serves the same purpose between objects.

    Paul.
    What language is JMS used in? I believe it's statically-tyed.
  55. The reason why I'm changing things, is because that is the real world. Things change they are not static.

    And you can deal with that in staticly typed langauges. People do it every day.

    This is the point. They don't. The only way to deal with this problem is to refactor and change the Interfaces in the code. Which is fine if all the code is local. But is not fine if the code belongs to some one else e.g. a remote client over the network or third party code in an off the self component like an EJB, or COM component.


    Don't use EJB or COM and use something well thought-out. it's a well-known secret that not all Sun engineers are great developers.

    So you just change the code in the dynamic environment and then what, let clients blow-up? This is what you keep avoiding. Just because you don't have an interface doesn't mean the client doesn't have to change? Have you provided the client with any form of contract? If so, you need to honor that or the client needs to change. If not that client is going to be coupled to an implementation. This much a much worse case.

    For example what do you think would happen if a commonly used Python library like os.path suddenly changed in a way that was no longer compatible with it's previous implementation? Do you think my Python scripts would still work?

    Dynamic languages don't implement the new requirements for you and they don't prevent coupling.



    James you are showing your lack of experience in this area.


    I know it's frustrating when someone asks you to back up an unfounded assertion. The solution is to not make sure assertions not to make ad hominem attacks.

    I understand what you say about interfaces, I've read the book too.


    I don't think you do.

    I'm saying in practice it doesn't work that way in all curcumstances.



    BTW. This is why people often use messaging systems like JMS, because they reduce the coupling between client and server and hence make systems more flexible and malleable to change. Messaging in dynamic languages serves the same purpose between objects.

    Paul.


    What language is JMS used in? I believe it's statically-tyed.
    Last try. The contract between client and server are the actual messages used by the client and the semantics behind those messages it is NOT the Type of the Server or the public Interface of the Server or the Class of the server. These are all properties of the server they are not the contract. The contract is the protocol used. I am not avoiding anything I'm saying that you can substitute the server with any object that satifies the contract. This object may implement a completely different Interface, or have a different Class or have a completely different Type. For example because an object responses to the message intValue() doesn't make it of type Integer. if a client only calls intValue() on an object then inValue() is the contract, along with the associated semantics. The contract is not Integer Do you get it now? Erik, Steve please help me out :^). Paul.
  56. hi James, A better example in Java is parseInt. So if an Object can be represented as a numeric string themessage parseInt will return that string. That is the contract. If not the method throws and acception. It is hard finding examples in Java because the language doesn't lend itself to the type of flexibility I'm trying to describe. Paul.
  57. hi James,

    A better example in Java is parseInt. So if an Object can be represented as a numeric string themessage parseInt will return that string. That is the contract. If not the method throws and acception.
    And if you don't provide a parseable String, the code doesn't work. Just like if I try to pass in a double to a method that takes an int, the program won't compile. The only diference is that one fails at runtime while the other fails at compile time and forces the callers to prove they have the right type. There's nothing inherently different about these contracts. There are just different costs and beneifts. The result is still that you have a contract whether you've specified it in the code or not.
    It is hard finding examples in Java because the language doesn't lend itself to the type of flexibility I'm trying to describe.

    Paul.
    Like I've pointed out, I use Python too. I'm familiar with dynamic languages. You don't have to limit the examples to Java.
  58. hi James,

    A better example in Java is parseInt. So if an Object can be represented as a numeric string themessage parseInt will return that string. That is the contract. If not the method throws and acception.


    And if you don't provide a parseable String, the code doesn't work. Just like if I try to pass in a double to a method that takes an int, the program won't compile. The only diference is that one fails at runtime while the other fails at compile time and forces the callers to prove they have the right type. There's nothing inherently different about these contracts. There are just different costs and beneifts. The result is still that you have a contract whether you've specified it in the code or not.

    It is hard finding examples in Java because the language doesn't lend itself to the type of flexibility I'm trying to describe.

    Paul.


    Like I've pointed out, I use Python too. I'm familiar with dynamic languages. You don't have to limit the examples to Java.
    Yes and the contract is the same the syntax and the semantics of the method call. In both scenarios they are specified in code (dynamic or static). The contract is not the type. So the advantage is if type A or B or C support the contract then they are all legal types. They do not need to have a common base class or implement the same interface. They will just work. This is the advantage. You may not like it or value it, but it is an advantage. And if an interface was not defined at compile time you can still late bind to a new type. Do you understand me? It's fine if you don't like it. Paul.
  59. Yes and the contract is the same the syntax and the semantics of the method call. In both scenarios they are specified in code (dynamic or static). The contract is not the type.

    So the advantage is if type A or B or C support the contract then they are all legal types. They do not need to have a common base class or implement the same interface. They will just work.

    This is the advantage. You may not like it or value it, but it is an advantage. And if an interface was not defined at compile time you can still late bind to a new type.

    Do you understand me? It's fine if you don't like it.

    Paul.
    I've understood all this the whole time. And like I said from the beginning, I like it in some cases and not in others. It depends on what you are doing. For example, a build tool like Ant would be much better written in a dynamic scritping language than with XML and Java.
  60. Yes and the contract is the same the syntax and the semantics of the method call. In both scenarios they are specified in code (dynamic or static). The contract is not the type.
    I think a contract is a set of methods, not just a single method. IMHO it's very close to an interface. The type specifies the interfaces supported by an object. So the type is the set of contracts (using contract somewhat loosely) supported by an object.
  61. Last try. The contract between client and server are the actual messages used by the client and the semantics behind those messages it is NOT the Type of the Server or the public Interface of the Server or the Class of the server. These are all properties of the server they are not the contract. The contract is the protocol used.
    I think you and James have a fundamental disagreement on how the contract is specified. I tend to agree with James on this point, although type information is an awfully limited specification of a contract. It's still better than nothing.
  62. The contract is not Integer

    Do you get it now? Erik, Steve please help me out :^).

    Paul.
    No point asking me - surely by now you realise I disagree with you on principle? :) But as you did... I see what you are getting at, but I don't see how this is flexibility is, in practice, supposed to be that useful, and I am talking about practical applications, not what are effectively technology demonstrations like Croquet. Referring back to your example, no-one is really going to be leaving a Squeak VM running for years and then want to change the shape of a class. In fact, the kind of flexibility you mention has been shown to cause problems in the past, which is why robust dynamic systems like the Gemstone Smalltalk application server have complex class versioning systems. I don't think anyone could claim just because such runtime class replacement is possible, that managing such things in a robust way is easy. In simpler Smalltalk systems recompiling or reloading a class in a live system can cause trouble (I know from experience). So, I think it is a potentially dangerous practise, unless done with care and a lot of tools, in which case it can be complex. As stated above, you don't need to restart Java app servers to reload things - just place your new WAR (or in some cases, your new class) in the right place, and it will be reloaded, and, if necessary, re-distributed across a cluster. Far easier than the Gemstone approach, in my view.
  63. I don't think anyone could claim just because such runtime class replacement is possible, that managing such things in a robust way is easy.
    ...or a good idea. Sometimes simpler is better. If you can take a few minutes of downtime to redeploy and and restart, it eliminates a lot of complexity from the underlying infrastructure.
  64. The contract is not Integer

    Do you get it now? Erik, Steve please help me out :^).

    Paul.


    No point asking me - surely by now you realise I disagree with you on principle? :)

    But as you did... I see what you are getting at, but I don't see how this is flexibility is, in practice, supposed to be that useful, and I am talking about practical applications, not what are effectively technology demonstrations like Croquet. Referring back to your example, no-one is really going to be leaving a Squeak VM running for years and then want to change the shape of a class.

    In fact, the kind of flexibility you mention has been shown to cause problems in the past, which is why robust dynamic systems like the Gemstone Smalltalk application server have complex class versioning systems. I don't think anyone could claim just because such runtime class replacement is possible, that managing such things in a robust way is easy. In simpler Smalltalk systems recompiling or reloading a class in a live system can cause trouble (I know from experience). So, I think it is a potentially dangerous practise, unless done with care and a lot of tools, in which case it can be complex.

    As stated above, you don't need to restart Java app servers to reload things - just place your new WAR (or in some cases, your new class) in the right place, and it will be reloaded, and, if necessary, re-distributed across a cluster. Far easier than the Gemstone approach, in my view.
    OK. Thanks :^) I'm trying to keep you guys on point. The point was what is the contract between two objects and it is not the Type or the Class or the Interface of the reciever. These things are constructs present in some languages (not all OO languages have classes or interfaces for example). Now hot deploy, starting and stopping servers is another argument. The other point was does duck typing change what is possible without recompiling and redeployed and I sense you agree yes. So the final point is do you agree that duck typing is desireable? Given that this is a Java forum, I'm not surprised that the majority vote is NO :^). Paul.
  65. The other point was does duck typing change what is possible without recompiling and redeployed and I sense you agree yes.

    So the final point is do you agree that duck typing is desireable?
    I think it is, I just wish there was a way to formalize it for use in static-typed applications. I was thinking of this, for example: Imagine a language that's basically like Java with the following difference: * A class implements an interface by implementing all the methods of that interface. Nothing else is required. * union types allowed (not needed for this example but I want them anyway) Now I can create a class like this: abstract class FooBarUser { void methodA(Foo foo); void methodB(Bar bar); void methodC(Bar & Foo foobar); public interface Foo { void foo(); void fu(); void arrrgh(); } public interface Bar { void bar(); void bear(); void arrrgh(); } } Now, if the caller wants to call methodA, it just needs to have the Foo methods. It doesn't need to implement the interface explicitly. If it doesn't have the right methods, the compiler screams. It's a little more effort the dynamic form but that's always true for static languages.
  66. Static 'duck-typing'[ Go to top ]

    Nobody said what they thought of my static duck-typing idea. Was it that bad?
  67. Distributed Computing[ Go to top ]

    http://research.sun.com/techrep/1994/smli_tr-94-29.pdf I just stumbled across this by chance. To my mind, it explains why RMI isn't right for most network communication better than I can.
  68. Re: Static 'duck-typing'[ Go to top ]

    Nobody said what they thought of my static duck-typing idea. Was it that bad?
    Didn't quite understand it. How's this: interface IFoo { String getFoo(); void setFoo(String foo); } class Bar { public Bar() { ... } public String getFoo() { ... } public void setFoo(String foo) { ... } } class FooBar { public FooBar() { ... } public void doSomething(IFoo f) { ... } } class Main { public static void main(String[] args) { Bar b = new Bar(); FooBar fb = new FooBar(); fb.doSomething(b); } } ----------- So Bar implements the methods in IFoo but does not declare that it implements IFoo. Consequently, Java won't compile Main because it tries to use a Bar as an IFoo. Let's say instead that the compiler looked at the definition of Bar, concluded that it could implement IFoo, and generated a wrapper for Bar that implements IFoo and then delegates all the IFoo methods to the corresponding methods in the Bar it is holding. ---- Oh, I also want to be able to do this: class Foo implements IFoo { ... } class Bar implements IFoo { private final delegate IFoo f; public Bar(IFoo f) { if (f == null) throw new IllegalArgumentException(); this.f = f; } } So that the compiler automatically generates methods that delegate calls to IFoo methods to f in cases where I haven't explicitly overridden them. I think a language feature like this would greatly encourage the use of composition/delegation over inheritance. It would also eliminate reams of boiler-plate methods.
  69. Re: Static 'duck-typing'[ Go to top ]

    Let's say instead that the compiler looked at the definition of Bar, concluded that it could implement IFoo, and generated a wrapper for Bar that implements IFoo and then delegates all the IFoo methods to the corresponding methods in the Bar it is holding.
    That's bascially what I was suggesting but without the wrappers. If you try to use a type as an IFoo and it implements all the required methods, it's implicitly considered to be an IFoo.
    Oh, I also want to be able to do this:
    I've been wanting something to that effect too but hadn't thought of that. Scala has something kind of like this in the 'with' keyword. I would also like something to this effect: public class Fooesque { public String getFu() {} public void setFu(String fu) {} } class Bar implements IFoo { private final Fooesque f; public Bar(Fooesque f) { if (f == null) throw new IllegalArgumentException(); this.f = f; } public String getFoo() = f.getFu(); public void setFoo(String foo) = f.setFu(foo); } Not that this buys you a whole lot in terms of typing, but it would again encourage composition.
  70. he other point was does duck typing change what is possible without recompiling and redeployed and I sense you agree yes.
    Largely, but I think a message from this discussion is that the difference in what is possible is a lot less than many think.
    So the final point is do you agree that duck typing is desireable?

    Given that this is a Java forum, I'm not surprised that the majority vote is NO :^).

    Paul.
    You are expressing things too simply. The answer is... it depends! I just don't believe it is a practical solution for the problems you are describing - such as changing the shape of objects in complex live systems. It means you can do this, but it is nowhere near as useful as it seems. I have used this in Smalltalk for my development, but I would not like to use it for large, deployed systems. I think you are misrepresenting things if you think we are saying 'NO' because this is a Java forum. Many of us have considerable experience of dynamic languages as well, and aren't language zealots one way or another - we neither think that Java is the best language ever, or think that it is merely the degraded result of a market-driven Sun+JCP.
  71. we neither think that Java is the best language ever, or think that it is merely the degraded result of a market-driven Sun+JCP.
    Right now I can us java, or I can learn COBOL or RPG. What would you choose?
  72. we neither think that Java is the best language ever, or think that it is merely the degraded result of a market-driven Sun+JCP.


    Right now I can us java, or I can learn COBOL or RPG. What would you choose?
    I choose Java, but that is a result of a careful evaluation of its relative merits many years ago. Up to that point I was a serious Smalltalker. I am still occasionally tempted to use Delphi again, and nearly went with it in place of Java when Kylix (for a while, Delphi for Linux) was introduced, but Kylix seems to be dying or dead. Right now, I find myself working with Groovy more and more in place of Java - I can see potential for it as a serious enterprise language, with the occasional use of JRuby.
  73. Hi Steve,
    I just don't believe it is a practical solution for the problems you are describing - such as changing the shape of objects in complex live systems. It means you can do this, but it is nowhere near as useful as it seems. I have used this in Smalltalk for my development, but I would not like to use it for large, deployed systems.
    This wasn't the example I raised. I've been talking about late-binding and pluggable interfaces that can take objects of varying types. Examples being component models (Croquet, versus COM, EJB etc) and remote method invocation (Croquet versus RMI). In these scenarios I believe that static typing causes more problems then it solves. Paul.
  74. Hi Steve,
    I just don't believe it is a practical solution for the problems you are describing - such as changing the shape of objects in complex live systems. It means you can do this, but it is nowhere near as useful as it seems. I have used this in Smalltalk for my development, but I would not like to use it for large, deployed systems.


    This wasn't the example I raised. I've been talking about late-binding and pluggable interfaces that can take objects of varying types. Examples being component models (Croquet, versus COM, EJB etc) and remote method invocation (Croquet versus RMI). In these scenarios I believe that static typing causes more problems then it solves.

    Paul.
    And I disagree, as you have not come up with a convincing example of how having the kind of late binding available in Smalltalk has real, practical use - precisely what problems does it solve? Are these real, common problems? Late binding can be done in Java - you just have more restrictions on what you can add to, or reload into, a running application. The situations where you would want to change an interface and absolutely require that all instances of the application would need to be running during the change of the interface are very rare indeed. On a side note, I think we need to be careful here, else some new Law might be proposed... 'in any sufficiently long TSS thread, Croquet will be mentioned'..
  75. Hi Steve,
    I just don't believe it is a practical solution for the problems you are describing - such as changing the shape of objects in complex live systems. It means you can do this, but it is nowhere near as useful as it seems. I have used this in Smalltalk for my development, but I would not like to use it for large, deployed systems.


    This wasn't the example I raised. I've been talking about late-binding and pluggable interfaces that can take objects of varying types. Examples being component models (Croquet, versus COM, EJB etc) and remote method invocation (Croquet versus RMI). In these scenarios I believe that static typing causes more problems then it solves.

    Paul.


    And I disagree, as you have not come up with a convincing example of how having the kind of late binding available in Smalltalk has real, practical use - precisely what problems does it solve? Are these real, common problems?

    Late binding can be done in Java - you just have more restrictions on what you can add to, or reload into, a running application.

    The situations where you would want to change an interface and absolutely require that all instances of the application would need to be running during the change of the interface are very rare indeed.

    On a side note, I think we need to be careful here, else some new Law might be proposed... 'in any sufficiently long TSS thread, Croquet will be mentioned'..
    Hi Steve, I made the argument. Refering to the problems with RMI, serialised types and pass by value and brittle remote method calls and remote Interfaces. James response was, rubbish this is down to the implementation. Without writing a PhD thesis on line it is very difficult to prove otherwise. What I've taken from the discussion is that people are very attached to what they know, and will bend over backwards to stick to a familiar approach. Perhaps this is why we are getting a new version of static RPC with SOAP and WS-* even though it has failed several times in the past with DCE then CORBA, then RMI etc. This conversation has convinced me that we will be stuck with static and brittle interfaces in inappropriate places for a long time to come. I conceed that this is unlikely to change anytime soon. Paul.
  76. I made the argument. Refering to the problems with RMI, serialised types and pass by value and brittle remote method calls and remote Interfaces. James response was, rubbish this is down to the implementation.

    Without writing a PhD thesis on line it is very difficult to prove otherwise.

    What I've taken from the discussion is that people are very attached to what they know, and will bend over backwards to stick to a familiar approach.

    Perhaps this is why we are getting a new version of static RPC with SOAP and WS-* even though it has failed several times in the past with DCE then CORBA, then RMI etc.

    This conversation has convinced me that we will be stuck with static and brittle interfaces in inappropriate places for a long time to come. I conceed that this is unlikely to change anytime soon.

    Paul.
    Sorry, but you have ignored what I have asked, and claiming that people are simply attached to the familiar is no argument. My opinion is that the dynamic situation is brittle, because it is not reinforced by the constraints of known interfaces. My evidence for this is the amount of work that has to be put in support possible changes in objects in truly secure and robust dynamic language frameworks like Gemstone. This is not being attached to the familiar; it is based on actual experience use of both static and dynamic languages for real projects. So, yet again - do you have actual examples of how the Smalltalk-style late binding is of real use, or is it just an opinion?
  77. So, yet again - do you have actual examples of how the Smalltalk-style late binding is of real use, or is it just an opinion?
    Romete swervice: class ServerX immplements IServerX { ... } Interface IServerX { void msg1(); void msg2(); void msg3(); } Ist remote Client: Class ClientA { void doSomething(IServerX remoteObj) { remoteObj.msg1(0; remoteObjmsg3(); } Now Six months later, I extend my service interface: Interface IServerX { void msg1(); void msg2(); void msg3(); void msg4(); } To support a new Client: Class ClientB { void doSomething(IServerX remoteObj) { remoteObj.msg2(); remoteObjmsg4(); } I test my new clientB against the server and it works, so I deploy, but I then get a phone call from the remote site using ClientA saying that all of a sudden they are getting a remote method invocation exception. Why? all I've done is to extend the interface and ClientA should still work, and if it was duck typed it would. Paul.
  78. Why? all I've done is to extend the interface and ClientA should still work, and if it was duck typed it would.
    RMI should not be used in situations where both sides of the conversation are not under your control. This is why people use XML, because you can easily add to a schema without breaking existing clients. So I agree with your basic point, it's just that your conclusion that we must use dynamic languages to solve this is not true.
  79. Why? all I've done is to extend the interface and ClientA should still work, and if it was duck typed it would.


    RMI should not be used in situations where both sides of the conversation are not under your control. This is why people use XML, because you can easily add to a schema without breaking existing clients.

    So I agree with your basic point, it's just that your conclusion that we must use dynamic languages to solve this is not true.
    XML is an awfully ugly solution to the problem. I'm not disagreeing with your assertion that people solve the problem with XML and have it work well. I just think it's an ugly way to do it.
  80. Why? all I've done is to extend the interface and ClientA should still work, and if it was duck typed it would.


    RMI should not be used in situations where both sides of the conversation are not under your control. This is why people use XML, because you can easily add to a schema without breaking existing clients.

    So I agree with your basic point, it's just that your conclusion that we must use dynamic languages to solve this is not true.


    XML is an awfully ugly solution to the problem. I'm not disagreeing with your assertion that people solve the problem with XML and have it work well. I just think it's an ugly way to do it.
    I'm not going to say that XML is the best thing ever but what would you choose instead? If you are communicating with many different parties that use mant different platforms, RMI is definitely not a good choice. This may or may not be the reason you think the solution is ugly but I believe most people's problem with XML is that the solutions to the XML to Object mapping problem are repeatedly and are continuing to be completely botched. The approaches are almost all flawed from the start and doomed to failure.
  81. I'm not going to say that XML is the best thing ever but what would you choose instead?
    I don't know. I'm engaging in unconstructive critisism. Especially considering XML is a lot less ugly than many of the things it replaced. It's just one of those things where is seems like there must be a better way.
  82. I'm not going to say that XML is the best thing ever but what would you choose instead?


    I don't know. I'm engaging in unconstructive critisism. Especially considering XML is a lot less ugly than many of the things it replaced.

    It's just one of those things where is seems like there must be a better way.
    Agreed. I think the big problems with XML are that it's too verbose and too complicated for what people want to do with it. The only reason it is so widely used is that the hype around it generated about half-a-gazillion parsers and builders. I think in a lot of cases it's used for things where it doesn't fit (configuration files) where a more readable python-esque format would be better. But for tranfering data between separate organizations, it's hard to beat in terms of support on contemporary language platforms. If people could just learn to write decent schemas we'd be all set.
  83. So, yet again - do you have actual examples of how the Smalltalk-style late binding is of real use, or is it just an opinion?



    Romete swervice:


    class ServerX immplements IServerX {
    ...
    }

    Interface IServerX {
    void msg1();
    void msg2();
    void msg3();
    }


    Ist remote Client:

    Class ClientA {
    void doSomething(IServerX remoteObj) {
    remoteObj.msg1(0;
    remoteObjmsg3();
    }

    Now Six months later, I extend my service interface:

    Interface IServerX {
    void msg1();
    void msg2();
    void msg3();
    void msg4();
    }


    To support a new Client:

    Class ClientB {
    void doSomething(IServerX remoteObj) {
    remoteObj.msg2();
    remoteObjmsg4();
    }

    I test my new clientB against the server and it works, so I deploy, but I then get a phone call from the remote site using ClientA saying that all of a sudden they are getting a remote method invocation exception.

    Why? all I've done is to extend the interface and ClientA should still work, and if it was duck typed it would.

    Paul.
    This is a non-issue. If you are going to deploy new code on the server like that, this is going to involve re-starting the service, so all clients are going to have to know about this and shut down, or you do this at a time when they are already down. If you are going to play about with such interfaces, all you need to do is to ensure that the clients' code is automatically updated, perhaps by some mechanism like webstart, or they fetch classes from some central store each time. That interface is a contract between both sites that is highly protective. Suppose you removed a method from the interface or renamed a method, you would have a serious problem, even with duck typing.
  84. This is a non-issue. If you are going to deploy new code on the server like that, this is going to involve re-starting the service, so all clients are going to have to know about this and shut down, or you do this at a time when they are already down. If you are going to play about with such interfaces, all you need to do is to ensure that the clients' code is automatically updated, perhaps by some mechanism like webstart, or they fetch classes from some central store each time. That interface is a contract between both sites that is highly protective. Suppose you removed a method from the interface or renamed a method, you would have a serious problem, even with duck typing. A nonsense. Well this is how RMI works, and I know of no out the box solution. What people do is sen out a new client.jar to the remote site with the right stubs etc. If you've got 30 client sites then you need 30 updates. CORBA works the same way. As I've said several time the contract is not IServerX the contract for ClientA is: void msg1(); void msg3(); And the contract for ClientB is: void msg2(); void msg4(); Read Betrand Myer design by contract and he concors. Now if I brake the contract by changing the semantics of any of these methods or deleting one, then the associated client should fail. But like I said the contract is still in tact and yet it fails anyway. Let change implementation and replace RMI with a JMS message queue. So no remote Interface. Lets define 4 messages as before: MSG1 MSG2 MSG3 MSG4 And implement new clients: Class ClientA { void doSomething(ServerQ q) { q.sendMessage(MSG1); q.sendMessage(MSG3); } } Class ClientB { void doSomething(ServerQ q) { q.sendMessage(MSG2); q.sendMessage(MSG4); } } And create a new server: Class ServerX { void listen(ServerQ q) { for(;;) { msg = q.getMessage(); if(msg == MSG1) msg1(); ... } } Blimey! It works even if I add ten new messages, all my existing clients do not break. So what is the diference? Go figure. Paul.
  85. This is a non-issue. If you are going to deploy new code on the server like that, this is going to involve re-starting the service, so all clients are going to have to know about this and shut down, or you do this at a time when they are already down. If you are going to play about with such interfaces, all you need to do is to ensure that the clients' code is automatically updated, perhaps by some mechanism like webstart, or they fetch classes from some central store each time. That interface is a contract between both sites that is highly protective. Suppose you removed a method from the interface or renamed a method, you would have a serious problem, even with duck typing.
    A nonsense. Well this is how RMI works, and I know of no out the box solution. What people do is send out a new client.jar to the remote site with the right stubs etc. If you've got 30 client sites then you need 30 updates. CORBA works the same way. As I've said several times the contract is not IServerX the contract for ClientA is: void msg1(); void msg3(); And the contract for ClientB is: void msg2(); void msg4(); Read Betrand Myer design by contract and he says the same. Now if I brake the contract by changing the semantics of any of these methods or deleting one, then the associated client should fail. But like I said the contract is still in tact and yet it fails anyway. Lets change implementation and replace RMI with a JMS message queue. So no remote Interface. Lets define 4 messages as before: MSG1 MSG2 MSG3 MSG4 And implement new clients: Class ClientA { void doSomething(ServerQ q) { q.sendMessage(MSG1); q.sendMessage(MSG3); } } Class ClientB { void doSomething(ServerQ q) { q.sendMessage(MSG2); q.sendMessage(MSG4); } } And create a new server: Class ServerX { void listen(ServerQ q) { for(;;) { msg = q.getMessage(); if(msg == MSG1) msg1(); ... } } Blimey! It works even if I add ten new messages, all my existing clients do not break. So what is the diference? Go figure. Paul.
  86. As I've said several times the contract is not IServerX the contract for ClientA is: void msg1(); void msg3();
    We have a fundamental disagreement here. Bertrand Meyer's concept of a contract is an interface, albeit a significantly richer definition of an interface than what is supported by Java, C++, C#, Python, Ruby, etc. http://www.cs.nuim.ie/~jpower/Courses/formalMethods/dbc/dbc.pdf#search=%22Bertrand%20Meyer%20DBC%20interface%22
  87. As I've said several times the contract is not IServerX the contract for ClientA is:

    void msg1();
    void msg3();


    We have a fundamental disagreement here.

    Bertrand Meyer's concept of a contract is an interface, albeit a significantly richer definition of an interface than what is supported by Java, C++, C#, Python, Ruby, etc.

    http://www.cs.nuim.ie/~jpower/Courses/formalMethods/dbc/dbc.pdf#search=%22Bertrand%20Meyer%20DBC%20interface%22
    Hi Erik, Missed this post. I looked through the slides and I can see why you say what you say. The term interface is rather broad and the idea of an "Interface" as used in the Java language is very different then what Bertrand means. I've read his book and I've learned Eiffel his language. What Bertrand means by interface is the interface to a method, commonly known as the method signature (method name, paremters and return type). He then goes on to say that this isn't sufficient. What is also part of the interface is the semantics. So he talks about pre-conditions that should exist before the method call (e.g parameters in bounds checking) post conditions (e.g return value is valid) and invariance (things that should not chnage e.g. no unexpected side effects in a functional language sense). If you read his book you will see that what I say is true. Paul.
  88. Contracts of an interface[ Go to top ]

    Paul, A contract is a specification for some software component. The contract for a method is its parameters, preconditions, and postconditions (anything else?). The contract for a class is its interface, which is the union of its methods, plus the class's invariants (anything else?). From the reading I've done online, which certainly is not exhaustive, this is what I believe Bertrand Meyer means. If not, it's what I think, based on reading material from Bertrand Meyer, material from many others, and personal experience.
  89. Re: Contracts of an interface[ Go to top ]

    Paul,

    A contract is a specification for some software component.

    The contract for a method is its parameters, preconditions, and postconditions (anything else?).

    The contract for a class is its interface, which is the union of its methods, plus the class's invariants (anything else?).

    From the reading I've done online, which certainly is not exhaustive, this is what I believe Bertrand Meyer means.

    If not, it's what I think, based on reading material from Bertrand Meyer, material from many others, and personal experience.
    OK, Design By Contract only refers to methods. Take a look at the book "Object Orientated Construction". Or look on the Eiffel website. I can understand your view, but this is not what design by contract says. Paul.
  90. Re: Contracts of an interface[ Go to top ]

    Paul, http://www.eiffel.com/developers/presentations/dbc/parttwo/player.html?slide= Goto slide 6 - Contract for a Class. You have to actually be playing it for the text to come up. It's pretty consistent with my definition. It adds data members to the contract as well method contracts and class invariants.
  91. Re: Contracts of an interface[ Go to top ]

    Paul,

    http://www.eiffel.com/developers/presentations/dbc/parttwo/player.html?slide=

    Goto slide 6 - Contract for a Class. You have to actually be playing it for the text to come up. It's pretty consistent with my definition. It adds data members to the contract as well method contracts and class invariants.
    Hi Erik, The first edition of Betrand Meyers Book came out in the late 90's, 1998 I think and I read it many moons ago. Now you mention it I do vaguely remember it mentioning contracts and classes. As far as I can remember Eiffel has no concept of Interface as used in Java. From what I can see from these slides the concept of Class contract relates only to inheritance, in the sense that the contracts of all methods are inherited by sub-classes. In a sense this is just another way of stating the standard OO idea of inheritance. There is a big difference between knowledge and understanding. As I understand it DBC is to do with pre-conditions/post conditions and invariants on methods, and is supported in the Eiffel language through additional syntax for creating asserts within methods. Classes are a collection of these contracts, so in a sense do have a contract, but most of the detail of the contract is defined in the methods. There is nothing in the slides that say that a class must have a fixed set of methods and if that number of methods change over time then it invalidates the class contract. The only thing in the class contract worthy of not is the invariant on member variables, but actually this invariant applies to all the methods, so is a shorthand to express a common method invariant. DBC is equally as valid in a dynamic language as it is in a static language. Infact a good way of doing design by contract is TDD where you can apply Eiffel like asserts, but in seperate test code. This approach can be applied as equally well with Dynamic or Static languages. My understanding may be wrong, but I'm quite confident. I still say read the book (some over 300 pages as I remember) then decide for yourself. Paul.
  92. This is a non-issue. If you are going to deploy new code on the server like that, this is going to involve re-starting the service, so all clients are going to have to know about this and shut down, or you do this at a time when they are already down. If you are going to play about with such interfaces, all you need to do is to ensure that the clients' code is automatically updated, perhaps by some mechanism like webstart, or they fetch classes from some central store each time.

    That interface is a contract between both sites that is highly protective. Suppose you removed a method from the interface or renamed a method, you would have a serious problem, even with duck typing.


    A nonsense. Well this is how RMI works, and I know of no out the box solution. What people do is send out a new client.jar to the remote site with the right stubs etc. If you've got 30 client sites then you need 30 updates.
    No, you need 1 update sent out to 30 sites, and the sites can almost certainly update themselves. To imply that this is a major issue is not realistic. You are almost certain to want to send out updates to software anyway - why make this such a big deal when it relates to RMI/CORBA interfaces etc?
    CORBA works the same way.

    As I've said several times the contract is not IServerX the contract for ClientA is:

    void msg1();
    void msg3();

    And the contract for ClientB is:

    void msg2();
    void msg4();

    Read Betrand Myer design by contract and he says the same.

    Now if I brake the contract by changing the semantics of any of these methods or deleting one, then the associated client should fail. But like I said the contract is still in tact and yet it fails anyway.
    No, if you break the contract (however you define it), it is not intact.
    Lets change implementation and replace RMI with a JMS message queue. So no remote Interface.

    Lets define 4 messages as before:

    MSG1
    MSG2
    MSG3
    MSG4


    And implement new clients:

    Class ClientA {

    void doSomething(ServerQ q) {
    q.sendMessage(MSG1);
    q.sendMessage(MSG3);
    }
    }


    Class ClientB {

    void doSomething(ServerQ q) {
    q.sendMessage(MSG2);
    q.sendMessage(MSG4);
    }
    }


    And create a new server:

    Class ServerX {
    void listen(ServerQ q) {
    for(;;) {
    msg = q.getMessage();

    if(msg == MSG1)
    msg1();
    ...
    }
    }


    Blimey! It works even if I add ten new messages, all my existing clients do not break. So what is the diference? Go figure.

    Paul.
    So what have you illustrated? That one approach is better than another, which is irrelevant to the issue being discussed. You have shown that you can bypass some of the inflexibilities of RMI without using late binding, but by using JMS. I agree that duck typing is a better solution here, but what I was after was a convicing example of how in regular use it provides a significant benefit, overcoming a major problem with static typing. All you have done is reveal what you think are issues with RMI, and then shown how that can be worked around by using other approaches. Which is what others here have been suggesting all along. Nice to know you have finally come around :)
  93. I agree that duck typing is a better solution here, but what I was after was a convicing example of how in regular use it provides a significant benefit, overcoming a major problem with static typing.
    A minute ago you where saying that I had still to show one example. I mentioned this example about 20 posts ago. I also mentioned a few others (not having to guess where to put Interfaces ahead of time, sending serialised objects over a remote link, and component frameworks and plugging in components of varying types). They all rely on the same idea. The JMS example communicates with the server by sending messages. So JMS is effectively a late-bound solution. The sender (Client) knows nothing about the reciever (Server), only what is a valid message, just like duck-typing. BTW if the message is invalid then the sender will get a negative acknowledgement, just like a doesNotUnderstand exception. Not significant, then fine. Paul.
  94. I agree that duck typing is a better solution here, but what I was after was a convicing example of how in regular use it provides a significant benefit, overcoming a major problem with static typing.


    A minute ago you where saying that I had still to show one example. I mentioned this example about 20 posts ago. I also mentioned a few others (not having to guess where to put Interfaces ahead of time, sending serialised objects over a remote link, and component frameworks and plugging in components of varying types).

    They all rely on the same idea. The JMS example communicates with the server by sending messages. So JMS is effectively a late-bound solution. The sender (Client) knows nothing about the reciever (Server), only what is a valid message, just like duck-typing. BTW if the message is invalid then the sender will get a negative acknowledgement, just like a doesNotUnderstand exception.

    Not significant, then fine.

    Paul.
    But this leaves little room for arguing a dramatic benefit for duck typing. Which is my point.
  95. I agree that duck typing is a better solution here, but what I was after was a convicing example of how in regular use it provides a significant benefit, overcoming a major problem with static typing.


    A minute ago you where saying that I had still to show one example. I mentioned this example about 20 posts ago. I also mentioned a few others (not having to guess where to put Interfaces ahead of time, sending serialised objects over a remote link, and component frameworks and plugging in components of varying types).

    They all rely on the same idea. The JMS example communicates with the server by sending messages. So JMS is effectively a late-bound solution. The sender (Client) knows nothing about the reciever (Server), only what is a valid message, just like duck-typing. BTW if the message is invalid then the sender will get a negative acknowledgement, just like a doesNotUnderstand exception.


    Not significant, then fine.

    Paul.


    But this leaves little room for arguing a dramatic benefit for duck typing. Which is my point.
    Hi Erik, Steve, and James, I'm glad we are all on the same page finally. Whether this difference between dynamic versus statis is significant or not depends on the problem IMO. Where the problem is intrinsically late-bound (you do not have acces to all the source code), like buying off the shelf components (e.g NextStep versus COM) or like you say Eric remote method invocation (Gemstone versus EJB), then this approach does make a signififacnt difference IMO. Like I said many posts ago you can still have the best of both. IMO static is suited to compile time (I have all the code under my control), and dynamic is suited to runtime (the code code be from several different places with different authors). I believe Strongtalk achieve this, I don't think Scala does. Paul.
  96. IMO static is suited to compile time (I have all the code under my control), and dynamic is suited to runtime (the code code be from several different places with different authors). I believe Strongtalk achieve this, I don't think Scala does.

    Paul.
    I say it's the opposite. The structure of dynamic code is much harder to see and therefore does not communicate enough information for group projects. If someone changes the contract of the interface I am using, I won't know unless I'm there to see it fail. Static typing shows what is required and lets you know when an incompatible change is made.
  97. IMO static is suited to compile time (I have all the code under my control), and dynamic is suited to runtime (the code code be from several different places with different authors). I believe Strongtalk achieve this, I don't think Scala does.

    Paul.


    I say it's the opposite. The structure of dynamic code is much harder to see and therefore does not communicate enough information for group projects. If someone changes the contract of the interface I am using, I won't know unless I'm there to see it fail. Static typing shows what is required and lets you know when an incompatible change is made.
    I actually agree with you here James. The scenario I'm talking about is where all you have is the object at runtime (no source code) and you want to plug it into another object. So think of drag or drop or something like that. Now the two objects where written at different times with different authors, but as long as they have an agreed protocol they will plug together (they do not need to agree on Interface in the Java sense). You get this with Java and Interfaces too, but the RMI example I showed earlier shows the limits of the Interface approach with Java. Also with Java you need to decide where you want to be able to plugin an object at design time and make sure you place an interface there. Paul.
  98. Also with Java you need to decide where you want to be able to plugin an object at design time and make sure you place an interface there.
    This could just as easily be seen as a strength as a weakness. Sometimes you don't want someone to just plugin an object. Sometimes you have a group of closely related classes and decoupling them to the point where they are pluggable is way more effort than it's worth, so you don't want someone coming along and breaking your objects by attempting to do it.
  99. Also with Java you need to decide where you want to be able to plugin an object at design time and make sure you place an interface there.


    This could just as easily be seen as a strength as a weakness. Sometimes you don't want someone to just plugin an object. Sometimes you have a group of closely related classes and decoupling them to the point where they are pluggable is way more effort than it's worth, so you don't want someone coming along and breaking your objects by attempting to do it.
    The time when it is useful is when you want to unplug one implementation and plug in another. A good example is how I said you can plug in any 2D Morphic Application into Croquet and it immedaitely becomes 3D. BTW in Smalltalk you can inspect any object at runtime and see all the messages it will accept, you can also look through the method dictionary and see how those methods are implemented. Think of it as documentation on the message interface. Armed with this information every object becomes a component, no application server or deplyment descriptor needed. BTW, on a slightly different point, you mentioned that you shouldn't use RMI when you don't control the code at both ends. So what about WSDL and SOAP? With WSDL/SOAP the WSDL remote interface description replaces the RemoteInterface in RMI. SO with WSDL/SOAP any chANge to the WSDL also breaks all the clients as I understand it. So IMO the only safe remoting with a static language is to use a message queue. Apparently messaging could be the next big thing, going under the guise of ESB (Enterprise Services Bus). I've used Tuxedo which is a bit old (~1984), but it works just fine for me. Paul.
  100. on a slightly different point, you mentioned that you shouldn't use RMI when you don't control the code at both ends. So what about WSDL and SOAP? With WSDL/SOAP the WSDL remote interface description replaces the RemoteInterface in RMI. SO with WSDL/SOAP any chANge to the WSDL also breaks all the clients as I understand it.
    I'm not 100% percent sure but I don't think that adding a new operation to a WSDL will break and existing client. I don't believe that there is a version checking mechanism like in Java serialization that checks the WSDL. You can definitely add optional fields to the schema of an message without breaking existing clients. As far as SOAP goes, I think it's on the way out. It's really overdesigned for what it does and what people want out of it. [Insert comment about Redmond here] Now people talk about how WebServices don't imply SOAP. When I first learned about WebServices they were defined as being based on SOAP. This leads me to believe that it's falling out of favor across the industry.
  101. BTW, on a slightly different point, you mentioned that you shouldn't use RMI when you don't control the code at both ends. So what about WSDL and SOAP? With WSDL/SOAP the WSDL remote interface description replaces the RemoteInterface in RMI. SO with WSDL/SOAP any chANge to the WSDL also breaks all the clients as I understand it. So IMO the only safe remoting with a static language is to use a message queue.
    If I used the word "control" then that's a little stronger of a statement than I intended. You need to be able to "manage" it. I'm not an expert in what I'm discussing, so if I'm wrong about some details please correct me. I think the choice of a remote method invokation technology really depends the requirements. RMI and CORBA try to preserve the semantics of a live local objects in a distributed setting. If that's what you need, then that's what you should use. However, at least in my experience, most cases of over-the-wire communication is much more "data centric" than "object centric." I don't there's a clear line between an RPC and a "query" or "data push," but I think if you look at the requirements you'll be able to tell. It all boils down to coupling. Tight coupling of domain objects to each other (as opposed to coupling to other layers) can be essential to building a rich domain model. So if you need to have your domain object(s) exist in multiple address spaces at once, use RMI or CORBA and pray the network doesn't kill you. If you just need to beam a reasonably recent copy of the data in a domain object to to a remote client, then don't. Use XML or some other serialization technology. I think RMI and CORBA have failed to meet their promises because good models contain relatively fine grained operations, and performing fine grained operation over-the-wire just doesn't work that well. So then developers make DTOs and implement more coarse-grained operations - in other words move to a more data-oriented arrangement. Futhermore, if you need to transport both data and behavior you can always send the code with the object data (or make sure the code already exists on the client). You don't need full-fledged remote references for this. Bottom line: Do you need one object accessible on N clients, or can you just replicate the object onto N clients?
  102. Hi Erik, You make some good points and I tend to mostly agree. I don't think remote RPC was ever a good idea. AFAIK repeating remote RPC again using SOAP won't make it any better tis time too. I agree that coupling is the issue. Static interfaces whether in IDL, Java or XML leave you in a situation where everything becomes dependent on the interface so you change the interface and everything else breaks. I also agree that for data you don't need RPC. If data is all you need then perhaps REST and XML is sufficient (http get, put etc), pushing and pulling state. Personally I like messaging where possible because it minimises dependencies.
    Bottom line: Do you need one object accessible on N clients, or can you just replicate the object onto N clients?
    I thought we got there with Java, with object serialisation (pass-by-value) and RMI/JINI. I've heard good things about JINI but it didn't take off, not sure why. Having said this I have had big problems with pass by value (serialisation) with RMI so perhaps JINI suffered from the same. Looking on the dynamic side of things, replication as a way of distributing both data and behaviour has been used for a long time. Gemstone did it in the 90's. The way that worked is that there was an object database on the server, and objects were replicated to clients (like a transactional L2 cache in Hibernate). The transaction would occur by sending messages to the local replica on the client and a commit would cause the replica to get written to the central OODMS. Like I've said before Croquet works in pretty much the same way. I've never used Gemstone, but replication as a means of object distribution works well in Croquet. Paul.
  103. I thought we got there with Java, with object serialisation (pass-by-value) and RMI/JINI. I've heard good things about JINI but it didn't take off, not sure why. Having said this I have had big problems with pass by value (serialisation) with RMI so perhaps JINI suffered from the same.
    I think in a theoretical sense we did get there. I know RMI gives us references to remote objects. Don't know much about Jini.
    Looking on the dynamic side of things, replication as a way of distributing both data and behaviour has been used for a long time.
    The problem is replication doesn't work for all scenarios. Replication only works when your working data set is either small enough to be replicated very quickly or static enough where you can lock the whole thing on the server while a single client performs extended modifications and then beams it back. Basically, if you have a big working dataset you do long-lived user transactions with pessimistic locking, and if you a have a small working dataset you do short transactions with optmistic locking. Either way you replicate the entire working set - even if everything is in a single address space. The bigger the working set, the longer-lived the transaction. There are of course other ways to solve the problem, but they are hard.
  104. Basically, if you have a big working dataset you do long-lived user transactions with pessimistic locking, and if you a have a small working dataset you do short transactions with optmistic locking. Either way you replicate the entire working set - even if everything is in a single address space. The bigger the working set, the longer-lived the transaction. There are of course other ways to solve the problem, but they are hard.
    I agree with what you say here, but I think there is mileage in the replicated approach, after all Hibernate and as I understand it all the other ORM solutions use pretty much this approach. Hibernate replicates the working set (data) from the relational database into objects in a client side cache. With Hibernate, the issue as you say is keeping the transaction short. Gavin King has spoken about detached objects and long lived application transactions which are pretty similar as far as I can tell to what I have described. I guess that it will work for Croquet because the data in croquet is pretty static (similar to web pages). For more transactional systems though, I agree, it gets tricky. I've spoken to people that used GemStone and their reports was that it worked well so perhaps they overcame the intrinsic problems. From reading the docs, I think the replicas broadcasted state changes amongst themselves and manged locking that way. Not sure though. Paul.
  105. If I used the word "control" then that's a little stronger of a statement than I intended.
    That was me.
    You need to be able to "manage" it.

    I'm not an expert in what I'm discussing, so if I'm wrong about some details please correct me.

    I think the choice of a remote method invokation technology really depends the requirements. RMI and CORBA try to preserve the semantics of a live local objects in a distributed setting. If that's what you need, then that's what you should use.
    I guess I could intepret that last sentence a few ways but here's my point. RMI is basically a way to distribute and application. I would say that what that really means is that these remote installations are actually part of your appliction. If these installations are not part of your organization... Well, it seems pretty sketchy, doesn't it? When you are communicating across disparate organizations, asynchronous operations are vastly more manageable and much more fault-tolerant. RMI works really well for clustering. That is, when you have a single application spread across many machines. But for a 3 tier model, I find it to be more trouble than it's worth. For a service oriented model, it's pretty much useless.
    However, at least in my experience, most cases of over-the-wire communication is much more "data centric" than "object centric." I don't there's a clear line between an RPC and a "query" or "data push," but I think if you look at the requirements you'll be able to tell.

    It all boils down to coupling. Tight coupling of domain objects to each other (as opposed to coupling to other layers) can be essential to building a rich domain model. So if you need to have your domain object(s) exist in multiple address spaces at once, use RMI or CORBA and pray the network doesn't kill you. If you just need to beam a reasonably recent copy of the data in a domain object to to a remote client, then don't. Use XML or some other serialization technology.

    I think RMI and CORBA have failed to meet their promises because good models contain relatively fine grained operations, and performing fine grained operation over-the-wire just doesn't work that well.
    I'm not sure they didn't meet their promises. I think they've been mis-marketed. In the right context, they are very effective. But your point about data centric network communication is right on the mark. Most people end up using RMI to transfer but chunks of data and it just doesn't work well for that.
  106. IMO static is suited to compile time (I have all the code under my control), and dynamic is suited to runtime (the code code be from several different places with different authors). I believe Strongtalk achieve this, I don't think Scala does.

    Paul.


    I say it's the opposite. The structure of dynamic code is much harder to see and therefore does not communicate enough information for group projects. If someone changes the contract of the interface I am using, I won't know unless I'm there to see it fail. Static typing shows what is required and lets you know when an incompatible change is made.
    Absolutely; and this is where I see real dangers in dynamic features, such as the open class capabilities of languages like Ruby, especially for large group projects. This is where I feel lessons have not been learned - we have been here before, with Smalltalk in the 80s. One of the issues of incompatible changes led to ugly and incompatible namespace extensions to the language and its implementations. I so many articles and blogs today I see people discovering the sense of fun that can come with the use of dynamic and highly interactive languages, but also repeating the same mistakes that were made decades ago.
  107. RMI or Static Typing[ Go to top ]

    Paul,
    I test my new clientB against the server and it works, so I deploy, but I then get a phone call from the remote site using ClientA saying that all of a sudden they are getting a remote method invocation exception. Why? all I've done is to extend the interface and ClientA should still work, and if it was duck typed it would.
    I think that's more a result of RMI that an inherent trait of statically typed remote interfaces. Although I'm not so sure throwing the remote method invocation exception is a bad thing. A well designed client should have checked that it had the latest version of the remote interfaces before launching into real work, anyway. Java is exhibiting fail-fast behavior. Now you're saying Java fails too fast here, and that could be the case. But a counter argument could be made that dynamic languages fail too slowly. If I was building a system based on some sort of remote method invokation protocol, I didn't have any real influence over the clients (e.g. it's over the iternet to individuals rather than corporate machines), and I wanted reasonably reliability I would implement some sort of version-checking on startup. Then old clients could either receive new code, or if the new code would require them to recompile their old code, they could be notified and fail to a service running the old version of my code. The class of changes that duck typing allows w/o breaking where static typing will break is, in my opinion, relatively small. If you have a requirements to deal with clients loaded with different versions of interfaces, than you should handle it in the general sense - something that requires work no matter what language is being used.
  108. Hi James, Just thought of a couple more examples of late-binding in Croquet. Any standard 2D Squeak application can be run in a 3D window in croquet. So a standard 2D application immediately becomes 3D and remotable way later then compile time. The original authors of these apps did not intend this behaviour. They merely wrote to a 2D graphic interface (Morphic), but in Croquet, the implementation of that interface gives the hosted applications behaviour way beyond that envisioned by the original authors. This is late-binding. The way Croquet works is that as you enter a space all the objects in that space are replicated to your machine on a peer-to-peer basis. If other actors in the same space then send messages to those objects (e.g. mouse events) then those messages are broadcasted to all the remote replica objects by the Croquet infrastructure. The replicas are given a syhcronised time slot to respond with an answer (calculate an outcome). So they all have a time slot to calculate the new state in a 2 phase commit. Once the new state is calculated all the Croquet enviroments involved in the transaction update their I/O (graphics) synchronously. The effect is that you have the same objects acting bit identically on different machines in a virtual shared space replicated across the network. The only communicaton needed is the broadcast of event messages to the replicas requiring only 10s of Kb/s of bandwidth. The processing and graphics rendering is all done locally. This is late-binding, the receiver objects (applications) assume that the implementation of the runtime is a conventional 2D standalone operating system, when in effect the implementation is a replicating, peer-to-peer, message broadcasting, distributed operating system. So the same protocol, but a radically different implementation which can be changed and improved at any time. Paul.
  109. Hi James,

    Just thought of a couple more examples of late-binding in Croquet. Any standard 2D Squeak application can be run in a 3D window in croquet. So a standard 2D application immediately becomes 3D and remotable way later then compile time. The original authors of these apps did not intend this behaviour. They merely wrote to a 2D graphic interface (Morphic), but in Croquet, the implementation of that interface gives the hosted applications behaviour way beyond that envisioned by the original authors. This is late-binding.
    That is a non-sequitur. It's just a system design and one that could be developed with static binding. There's no reason why I can't take an existing 2D display interface and skew it in a 3D decorator without changing the 2D interface. If you are denying this, I need you to give specific reasons why.
  110. Hi James,

    Just thought of a couple more examples of late-binding in Croquet. Any standard 2D Squeak application can be run in a 3D window in croquet. So a standard 2D application immediately becomes 3D and remotable way later then compile time. The original authors of these apps did not intend this behaviour. They merely wrote to a 2D graphic interface (Morphic), but in Croquet, the implementation of that interface gives the hosted applications behaviour way beyond that envisioned by the original authors. This is late-binding.


    That is a non-sequitur. It's just a system design and one that could be developed with static binding.

    There's no reason why I can't take an existing 2D display interface and skew it in a 3D decorator without changing the 2D interface. If you are denying this, I need you to give specific reasons why.
    The reason why is because the 2D implementation would name classes of the 2D API (implementation) it depends upon and expects to use at runtime. For example the Win32 API or the Swing API. Not all the classes on these API's are Interfaces and every class in the API would need to be an Interface so that you could late-bind to a different 3D implementation as you describe. And even if it was (which it isn't)you would still have coupling problems on those interfaces themselves (see my later posts). Paul.
  111. Hi James,

    Just thought of a couple more examples of late-binding in Croquet. Any standard 2D Squeak application can be run in a 3D window in croquet. So a standard 2D application immediately becomes 3D and remotable way later then compile time. The original authors of these apps did not intend this behaviour. They merely wrote to a 2D graphic interface (Morphic), but in Croquet, the implementation of that interface gives the hosted applications behaviour way beyond that envisioned by the original authors. This is late-binding.


    That is a non-sequitur. It's just a system design and one that could be developed with static binding.

    There's no reason why I can't take an existing 2D display interface and skew it in a 3D decorator without changing the 2D interface. If you are denying this, I need you to give specific reasons why.

    The reason why is because the 2D implementation would name classes of the 2D API (implementation) it depends upon and expects to use at runtime. For example the Win32 API or the Swing API. Not all the classes on these API's are Interfaces and every class in the API would need to be an Interface so that you could late-bind to a different 3D implementation as you describe.

    And even if it was (which it isn't)you would still have coupling problems on those interfaces themselves (see my later posts).

    Paul.
    Maybe I'm misunderstanding what you are saying. Are you talking about displaying a 2D screen in a 3D view or a 3D view in a 2D window?
  112. Maybe I'm misunderstanding what you are saying. Are you talking about displaying a 2D screen in a 3D view or a 3D view in a 2D window?
    I'm talking about taking an app written to a 2D API and placing it on a 2D plane (window) in a 3D space. So imagine walking around a 2D image in a 3D space, viewing it from varying angles. So in Croquet you can have a 2D window which you can walk around and move and view at an acute angle in just the same way you can walk around the flat panel display on your laptop. Again, I do not want to get into Static versus Dynamic, I'm just pointing out the limitations of static typing at runtime when you want to perform late-binding. Paul.
  113. Maybe I'm misunderstanding what you are saying. Are you talking about displaying a 2D screen in a 3D view or a 3D view in a 2D window?


    I'm talking about taking an app written to a 2D API and placing it on a 2D plane (window) in a 3D space.
    OK, that's what I thought.
    So imagine walking around a 2D image in a 3D space, viewing it from varying angles. So in Croquet you can have a 2D window which you can walk around and move and view at an acute angle in just the same way you can walk around the flat panel display on your laptop.

    Again, I do not want to get into Static versus Dynamic, I'm just pointing out the limitations of static typing at runtime when you want to perform late-binding.

    Paul.
    But you're not. You saying here's something you can't do in a static-typed language but I know that you can. You haven't given a real reason why one could not. I don't see any reason why the 2D api needs to know that it's being rendedered in 3D. It doesn't affect it's 2D behavior in any way. I agree that doing this is in Swing or AWT would probably not be feasible but that's a property of Swing and AWT, not static typing. If you migrated the design of Swing to a dynamic language, I don't think your task would be any easier. Swing classes have a very high degree of internal coupling and are implemented with native methods. If you had a GUI framework that was designed around the Builder pattern and was coupled only to a target 'Renderer' interface, there's no reason why I can't add a 3DRenderer at a future date.
  114. Maybe I'm misunderstanding what you are saying. Are you talking about displaying a 2D screen in a 3D view or a 3D view in a 2D window?


    I'm talking about taking an app written to a 2D API and placing it on a 2D plane (window) in a 3D space.


    OK, that's what I thought.

    So imagine walking around a 2D image in a 3D space, viewing it from varying angles. So in Croquet you can have a 2D window which you can walk around and move and view at an acute angle in just the same way you can walk around the flat panel display on your laptop.

    Again, I do not want to get into Static versus Dynamic, I'm just pointing out the limitations of static typing at runtime when you want to perform late-binding.

    Paul.


    But you're not. You saying here's something you can't do in a static-typed language but I know that you can. You haven't given a real reason why one could not. I don't see any reason why the 2D api needs to know that it's being rendedered in 3D. It doesn't affect it's 2D behavior in any way. I agree that doing this is in Swing or AWT would probably not be feasible but that's a property of Swing and AWT, not static typing. If you migrated the design of Swing to a dynamic language, I don't think your task would be any easier. Swing classes have a very high degree of internal coupling and are implemented with native methods.

    If you had a GUI framework that was designed around the Builder pattern and was coupled only to a target 'Renderer' interface, there's no reason why I can't add a 3DRenderer at a future date.
    By binding to the classes in your 2D API at compile time, your 2D application is permanently linked to a 2D library implementation. To get around this in a static language you could use a DLL (dynamically linked library). But you would need to know ahead of time that you will want to swap out the implementation and where. If you did not know you could place each class in it's own DLL just in case, but the overhead would be prohibitive. So such things are possible in a static language, examples are COM and DCOM, but the orginal authors need to make the decision up front where you can and can't plug alternative implementations. The Squeak application authors did not need to make such a decision, they just wrote to the Morphic API. In squeak everthing is pluggable by default. So you do not need to design this capability in up front. Some one else can come years later and add it even whilst your code is still running. Paul.
  115. Hi James, Incidently you can mix static applications with Croquet, but again you need to rely on late-binding mechanisms. You can use VNC and X Windows to display 2D applications in a 3D window in Croquet, but again this is relying on hooks in the X Window toolkit or VNC. If your OS doesn't support VNC or you did not write your app to X Windows your stuck without access to the source code and recompiling. Paul.
  116. By binding to the classes in your 2D API at compile time, your 2D application is permanently linked to a 2D library implementation.
    I feel like you are not following. I just pointed out that there is nothing about static-typing that forces you to bind a GUI to a 2D implementation. Which is what you are asserting. Swing is coupled to a 2D interface. Swing is not all possible designs. Swing's design (IMO) sucks in a lot of ways. Just because you find a bad apple on a tree, it doesn't mean all that tree's apples are bad. I guarantee you there are horribly coupled designs implemented in dynamic languages too. Are you suggesting that it's impossible to write a GUI in a dynamic language that is coupled to a 2D interface? If we ported Swing to Python, without removing all the calls to the native widgets, that it would be better? You've pointed out the exact reason why this was possible: the Morphic API is not bound to a 2D interface. You comparing APIs but we are talking about static vs. dynamic typing. I think you may not realize what is possible with static typing. You keep claiming things that are obiously (to me) possible and maybe even relatively simple are not possible.
  117. By binding to the classes in your 2D API at compile time, your 2D application is permanently linked to a 2D library implementation.


    I feel like you are not following.
    James, it is you that are not following. It is like Alan Kay says in the video you have too much prior context. You are seeing everything I say in the familiar context of what you already know and use. Stand back, go back to first principles and read through my posts. I am saying that Interfaces and Static typing are not a silver bullet and as well as solving some problems they also create other problems too. Read what I say carefully and you will see. Whether the points I make are an overriding concern is a different issue. A language that is static at compile time and dynamic at run-time provides for the best of both worlds IMO. But there are problems with static typing when it comes to late-binding at deployment or runtime and I have experienced these problems first hand with frameworks like RMI, EJB as I've described. Paul.
  118. By binding to the classes in your 2D API at compile time, your 2D application is permanently linked to a 2D library implementation.


    I feel like you are not following.

    James, it is you that are not following.
    Really, just because you say so? Explain how I have not followed.
    It is like Alan Kay says in the video you have too much prior context. You are seeing everything I say in the familiar context of what you already know and use.
    I know and use dynamic languages. You aren't telling me things that I don't already know, other than the things I know to be false. My arguments are not about what is possible in dynamic languages. I know about that. My argument is about what you are claiming (incorrectly) cannot be done in static typed languages. Perhaps you should consider your own advice. Perhaps you have too much prior context to see that the limitations you imagine are not real.


    Stand back, go back to first principles and read through my posts. I am saying that Interfaces and Static typing are not a silver bullet and as well as solving some problems they also create other problems too.
    Read through mine and you will see I never once argued otherwise.


    Read what I say carefully and you will see. Whether the points I make are an overriding concern is a different issue. A language that is static at compile time and dynamic at run-time provides for the best of both worlds IMO. But there are problems with static typing when it comes to late-binding at deployment or runtime and I have experienced these problems first hand with frameworks like RMI, EJB as I've described.

    Paul.
    I've never said that dynamic typing doesn't make certain things a lot easier. It does. But that's very different from saying you can't do the same things with static typing. I do believe that there is a cost to dynamic typing because the code is not nearly as self-documenting. But that's another discussion. The point here is that design is not making a set of classes or types or objects or whatever you want to call it. The interactions between the different components are what matters. Whenever parts have to interact, there will be some degree of coupling. Whether you use a dynmic language or a static language this is true. What is frightening to me is this blaise attitute that suggests (to me) that you feel that tight coupling in dynamic language designs is not a problem. I think that is a very dangerous belief.
  119. I've tried. I've shown you demos of things that would not be possible with a static language. I tried to walk you through an example of the limitations of Interfaces and you still fail to see. Worst still you acuse me of making up falsehoods :^) I really do wish you the best. Paul.
  120. I've tried.

    I've shown you demos of things that would not be possible with a static language.
    You've said they weren't possible. I still haven't seen any explanation of why. That's what I'm interested in learning. If you can explain why, then that's helpful. But you have not said why. You just keep restating the same assertions.
    I tried to walk you through an example of the limitations of Interfaces and you still fail to see.

    Worst still you acuse me of making up falsehoods
    No. First of all I didn't mean to accuse you of anything. What am saying is that you have said that I could not do something in a static-typed language that I know that I could. I'm not doubting your sincerity. I just wish you would explain why you think it's not possible so that we could discuss it. You might convince me. But just handing down a statement "you can't do this" like you are the Pope isn't going to get you anywhere with me. I never said interfaces don't have limitations. This is where I feel you aren't understanding me. I am not saying interfaces are necessary. I'm not saying dynamic programming doesn't have some huge benefits. I believe dynamic programming has some huge benefits. I can't count the number of times someone has said "you can't do this in Java" and then I did it. The biggest problem in Java is that most Java developers (including a good number of Sun engineers) don't have the first clue of how to write OO code. One great thing about dynamic languages is they make OO much easier to use and understand. I think all Java developers should do some dynamic (and functional) programming. The point I am making is that you can do most of these things in static-typed languages. It's just a LOT more work and sometimes a lot more unweildy. Think about this: Python is implemented in C and also in Java. How would that be possible if these dynamic features were not possible in static-typed languages?
  121. The point I am making is that you can do most of these things in static-typed languages. It's just a LOT more work and sometimes a lot more unweildy. Think about this: Python is implemented in C and also in Java. How would that be possible if these dynamic features were not possible in static-typed languages?
    I think we are beginning to understand each other. What you get in a dynamic language is extra layers of indirection. So all bindings are indirect. What this allows you to do is intercept and subsitute alternative bindings (implementations) at runtime for all calls. So back to the graphic library, you intercept the call to a 2D API and substitue a 3D library. You can do this in a static lanuage too which is why I've mentioned X Windows and VNC, but it is not available for all calls. So for example I can redirect an X windows application to any display I want, binding to the IP and screen number of the display device at runtime, but I can't get my X windows app to bind to a remote hard-disk for example, because this flexibility is not built in. So you can do indirection in a static language. What I am talking about is indirection by default. Indirection for everything. Which is what I mean by pluggable and is what the Self demo was all about. Plugging together bits of software (objects) written at different times by different people. Paul
  122. The point I am making is that you can do most of these things in static-typed languages. It's just a LOT more work and sometimes a lot more unweildy. Think about this: Python is implemented in C and also in Java. How would that be possible if these dynamic features were not possible in static-typed languages?


    I think we are beginning to understand each other.
    You are just starting to understand me ;)
    What you get in a dynamic language is extra layers of indirection. So all bindings are indirect. What this allows you to do is intercept and subsitute alternative bindings (implementations) at runtime for all calls. So back to the graphic library, you intercept the call to a 2D API and substitue a 3D library.

    You can do this in a static lanuage too which is why I've mentioned X Windows and VNC, but it is not available for all calls.
    Of course. But there are designs that would allow wholesale replacement of the rendering. There are tradeoffs, however. It's a lot slower, noticeably so in some cases.
    So for example I can redirect an X windows application to any display I want, binding to the IP and screen number of the display device at runtime, but I can't get my X windows app to bind to a remote hard-disk for example, because this flexibility is not built in.
    Let's be clear, the functionality isn't built into the harddisk. I could (theoretically) write code (or hardware) that would make the harddisk look like an X target. X shouldn't have to worry about what is implementing the protocols. Are you saying that dynamic languages would allow you to bind to something that does not support your contracts?
    So you can do indirection in a static language. What I am talking about is indirection by default. Indirection for everything. Which is what I mean by pluggable and is what the Self demo was all about. Plugging together bits of software (objects) written at different times by different people.


    Paul
    Yes, it can make things easier but it can also make things a lot harder. The problem is that if everyone is making changes and there is no common understanding of the contract, things can quickly devolve into chaos.
  123. The point I am making is that you can do most of these things in static-typed languages. It's just a LOT more work and sometimes a lot more unweildy. Think about this: Python is implemented in C and also in Java. How would that be possible if these dynamic features were not possible in static-typed languages?


    I think we are beginning to understand each other.


    You are just starting to understand me ;)

    What you get in a dynamic language is extra layers of indirection. So all bindings are indirect. What this allows you to do is intercept and subsitute alternative bindings (implementations) at runtime for all calls. So back to the graphic library, you intercept the call to a 2D API and substitue a 3D library.

    You can do this in a static lanuage too which is why I've mentioned X Windows and VNC, but it is not available for all calls.


    Of course. But there are designs that would allow wholesale replacement of the rendering. There are tradeoffs, however. It's a lot slower, noticeably so in some cases.

    So for example I can redirect an X windows application to any display I want, binding to the IP and screen number of the display device at runtime, but I can't get my X windows app to bind to a remote hard-disk for example, because this flexibility is not built in.


    Let's be clear, the functionality isn't built into the harddisk. I could (theoretically) write code (or hardware) that would make the harddisk look like an X target. X shouldn't have to worry about what is implementing the protocols.

    Are you saying that dynamic languages would allow you to bind to something that does not support your contracts?

    So you can do indirection in a static language. What I am talking about is indirection by default. Indirection for everything. Which is what I mean by pluggable and is what the Self demo was all about. Plugging together bits of software (objects) written at different times by different people.


    Paul


    Yes, it can make things easier but it can also make things a lot harder. The problem is that if everyone is making changes and there is no common understanding of the contract, things can quickly devolve into chaos.
    OK James. I'm glad we finally understand each other. There are pros and cons like you say, but it does make a number of things possible, that wouldn't be possible otherwise. So is duck typing worth it? We can disagree, but I'm glad we finally understand each other. Paul.
  124. Sensible Results[ Go to top ]

    Here's my take, dynamic binding languages still require an interface (abstraction layer, whatever) to be determined ahead of time. It's just not specified in the code. For example, you can't call a method on an Object if you don't know what it is or what is does and expect a sensible result. If you know what method you will call in a specific circumstance then that's really a pre-defined interface whether you specify it in the code or not.
    Failure to understand a message just becomes another exceptional condition that you either handle or pass up to the next layer of the software. Think about a system like Croquet. You're not going to guarantee that every node is going to be running the same code. Not even close. So RMI-style remote method invokation won't work, because changes will break everything. Instead, failing to understand a method because just another failure mode that you need to handle. So in dynamic languages a missing method is an exceptional condition rather than an illegal state. Consequently, it can be recoverable. For sufficiently large systems this makes a certain amount of sense. But that's an extreme. If you have a "closed system" where the code and the nodes running it are under your control, I think static typing is very valuable.
  125. Re: Sensible Results[ Go to top ]

    But that's an extreme. If you have a "closed system" where the code and the nodes running it are under your control, I think static typing is very valuable.
    Is it really? Think about people trying to create component frameworks. In the mid 90's IBM tried to produce a component framework in C++ known as Commonpoint. It failed. The main reason for its failure was said to be the fact that it was written in a static language, C++. The most successful component model is NextStep written in Objective-C which is a dynamic language. Ask anyone who as used Nextstep and they will tell you. Think about the other attempts to achive late-binding with a static language, examples: RMI, CORBA, DSOM, OpenDoc, COM, DCE etc. They all failed. And they were rather conservative in their goals compared to Croquet. Imaging trying to implement the repicated object architecture I've described above for Croquet in Java or C++. It just wouldn't work. Paul.
  126. Re: Sensible Results[ Go to top ]

    Is it really? Think about people trying to create component frameworks. In the mid 90's IBM tried to produce a component framework in C++ known as Commonpoint. It failed. The main reason for its failure was said to be the fact that it was written in a static language, C++.
    There are countless successful C++ component libraries in existence and they continue to evolve and expand today, and everything I've read about CommonPoint indicates that it's failure had little to do with C++.
    Think about the other attempts to achive late-binding with a static language, examples: RMI, CORBA, DSOM, OpenDoc, COM, DCE etc. They all failed. And they were rather conservative in their goals compared to Croquet.
    Failed to be extremely useful, robust technologies or failed to meet expectations set by marketing?
    Imaging trying to implement the repicated object architecture I've described above for Croquet in Java or C++. It just wouldn't work.
    I think it will be a long, long time before something like Croquet works in an enterprise setting. Probably decades.
  127. Re: Sensible Results[ Go to top ]

    Is it really? Think about people trying to create component frameworks. In the mid 90's IBM tried to produce a component framework in C++ known as Commonpoint. It failed. The main reason for its failure was said to be the fact that it was written in a static language, C++.


    There are countless successful C++ component libraries in existence and they continue to evolve and expand today, and everything I've read about CommonPoint indicates that it's failure had little to do with C++.

    Think about the other attempts to achive late-binding with a static language, examples: RMI, CORBA, DSOM, OpenDoc, COM, DCE etc. They all failed. And they were rather conservative in their goals compared to Croquet.


    Failed to be extremely useful, robust technologies or failed to meet expectations set by marketing?

    Imaging trying to implement the repicated object architecture I've described above for Croquet in Java or C++. It just wouldn't work.


    I think it will be a long, long time before something like Croquet works in an enterprise setting. Probably decades.
    Please name the succesful static language component frameworks? The only successful static one I can think of is ActiveX, but my understanding is that it was mostly combined with Visual Basic, a dynamic language. Time will tell. We have been trying to deliver off the shelf component objects using static languages since 1986 and failed. Alan Kay and others say the reason why is because the problem is essentailly late-bound. After spending over 10 years trying to use these frameworks (CORBA, OpenDoc,DSOM, EJB, RMI) myself I tend to agree. I've been programming in Croquet for about 6 months and compared to my experience with the other static component frameworks it is much simpler and much more robust. Reading the experiences of Objective-C, NextStep and Cocoa programmers, they say similar things to what I have personally experienced with Croquet, and aside from ActiveX (which I have never used) Nextstep has been the only commercially succesful third party object component framework that I know of. I would suggest that you try and program with these environments for yourself before passing judgement. Paul.
  128. Re: Sensible Results[ Go to top ]

    Here's my take, dynamic binding languages still require an interface (abstraction layer, whatever) to be determined ahead of time. It's just not specified in the code. For example, you can't call a method on an Object if you don't know what it is or what is does and expect a sensible result. If you know what method you will call in a specific circumstance then that's really a pre-defined interface whether you specify it in the code or not.


    Failure to understand a message just becomes another exceptional condition that you either handle or pass up to the next layer of the software.

    Think about a system like Croquet. You're not going to guarantee that every node is going to be running the same code. Not even close. So RMI-style remote method invokation won't work, because changes will break everything. Instead, failing to understand a method because just another failure mode that you need to handle.

    So in dynamic languages a missing method is an exceptional condition rather than an illegal state. Consequently, it can be recoverable.
    Sure, of course. But handling this as an error is not anywhere nearly as good as actually doing the thing you were trying to do. I'm not trying to be pedeantic here, the point is if the method isn't there, the interface isn't there. In order to get the expected behavior, you need to implement that abstraction layer whether it's there or not.
  129. Re: Sensible Results[ Go to top ]

    In order to get the expected behavior, you need to implement that abstraction layer whether it's there or not.
    That should say "In order to get the expected behavior, you need to implement that abstraction layer whether it's specified or not."
  130. Re: Sensible Results[ Go to top ]

    Sure, of course. But handling this as an error is not anywhere nearly as good as actually doing the thing you were trying to do. I'm not trying to be pedeantic here, the point is if the method isn't there, the interface isn't there. In order to get the expected behavior, you need to implement that abstraction layer whether it's there or not.
    This about a new version of an existing network protocol. Part of the design probably includes a way to fallback to an older version in cases where one side only supports the old version. It's kind of a weak analogy. The bottom line is that it changes the nature of the problem. Personally, I'm a huge believer in "fail-fast" behavior, with a red underline in my IDE being the fastest way to fail. I'm not working anything where I'd like the problem changed. IMHO the good arguments for late-binding tend to be similar in spirit to the good arguments given for pointer arithmetic and "manual" memory management. Only the pointer arithmetic people have a slight edge on rationality. But I think both are extremely useful in very limited circumstances.
  131. Re: Sensible Results[ Go to top ]

    Sure, of course. But handling this as an error is not anywhere nearly as good as actually doing the thing you were trying to do. I'm not trying to be pedeantic here, the point is if the method isn't there, the interface isn't there. In order to get the expected behavior, you need to implement that abstraction layer whether it's there or not.


    This about a new version of an existing network protocol. Part of the design probably includes a way to fallback to an older version in cases where one side only supports the old version.
    Again, yes. But there is nothing stopping me from doing something like this in a staticly-typed langauge. No one says I have to use vanilla Java serialization if I'm using Java. In fact I would say in most cases that it is not a good choice. If the argument is that dynamic objects are easier to serialize, then I agree. You can still implement network communication in Java without running into this issue.
  132. How about realising Strontalk? It would save a lot of time :^).

    Paul.
    They did release it. StrongTalk.org
  133. Re: Think About Java-Joe![ Go to top ]

    Closures ? Nope, don't need that. A development environment that rivals Visual Studio's support for productivity ? Yup, need that. Please, no NetBeans lies. We all know better.