<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8866592669665585195</id><updated>2012-01-13T15:18:17.358+02:00</updated><category term='ruby'/><category term='beatles'/><category term='scala'/><category term='java'/><category term='software engineering'/><category term='newspeak'/><category term='properties'/><title type='text'>Red and Sensual Java</title><subtitle type='html'>Thoughts about software engineering (mostly)</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>54</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-2959730580067903340</id><published>2010-03-03T12:20:00.007+02:00</published><updated>2010-03-03T13:22:21.620+02:00</updated><title type='text'>Sayeret Lambda</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_GnOWSH314CY/S45Er4YxkvI/AAAAAAAAAgM/1mDlsqN0oa8/s1600-h/lambda3small.gif"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 151px; height: 150px;" src="http://1.bp.blogspot.com/_GnOWSH314CY/S45Er4YxkvI/AAAAAAAAAgM/1mDlsqN0oa8/s200/lambda3small.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5444364520198869746" /&gt;&lt;/a&gt;&lt;div style="text-align: left;"&gt;After delivering the keynote at &lt;a href="http://www.alphacsp.com/web/guest/javaedge-2009/about"&gt;JavaEdge2009&lt;/a&gt;, &lt;a href="http://www.tedneward.com/"&gt;Ted Neward&lt;/a&gt; asserted that &lt;a href="http://blogs.tedneward.com/2009/11/29/Thoughts+From+The+JavaEdge+2009.aspx"&gt;Israel is ready&lt;/a&gt; for the "polyglot" era. Ronen, Ophir and I decided to verify this assertion, so we are happy to announce the creation of "&lt;a href="https://sites.google.com/site/sayeretlambda/"&gt;Sayeret Lambda&lt;/a&gt;", the Israeli "&lt;a href="http://lambdalounge.org/"&gt;Lambda Lounge&lt;/a&gt;"! The group contains researchers, consultants, students, and industry professionals, interested in Scala, Clojure, Erlang, Lisp, Prolog, Smalltalk, Ruby, Fan, Groovy and so on...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Our first meeting is going to take place on March 10th, and is dedicated to Lisp and Clojure. In April we are going to host Gilad Bracha's talk about Newspeak. Both talks will be in Hebrew. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Programming language geeks in Israel are &lt;a href="http://groups.google.com/group/sayeret-lambda"&gt;welcome to join&lt;/a&gt; us! &lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-2959730580067903340?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/2959730580067903340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=2959730580067903340' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/2959730580067903340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/2959730580067903340'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2010/03/sayeret-lambda.html' title='Sayeret Lambda'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GnOWSH314CY/S45Er4YxkvI/AAAAAAAAAgM/1mDlsqN0oa8/s72-c/lambda3small.gif' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-4144704129790297295</id><published>2009-05-19T19:59:00.027+03:00</published><updated>2009-05-22T01:06:53.826+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Lessons we learn, lessons we teach</title><content type='html'>&lt;div&gt;Lately I've been a little involved in both (learning and teaching that is), and wanted to share some thoughts on the subject.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Do you like science fiction? I used to like it (when I was younger, so much younger than today). Asimov, Bradbury and such. It's especially fun when the story mixes past, future and present; reality and imagination. What fascinates me most in these stories, is how the author is making deep and painful observations about reality through moving the characters into a completely unrealistic setting - future comes handy, because it is hardest to imagine . It's just amazing how, by disguising things beyond recognition, the author breaks the thought conventions and emotional associations built in our brain, and doing that lets us understand the reality beyond what we were able to before. John Lennon &lt;a href="http://www.youtube.com/watch?v=NzJ2NKp23WU"&gt;said&lt;/a&gt; "nothing you can see that isn't shown", right, but you can&lt;a href="http://www.youtube.com/watch?v=-b7qaSxuZUg"&gt; imagine&lt;/a&gt; what you don't see, and that's how you "know the unknown" a little bit better. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There's this recurring theme in sci-fi stories "smart man builds machine, machine becomes smarter than man, machine rules man".  Is it a real threat? If so, how can we prevent it? Should we stop building smart machines? Is high-tech going to destroy mankind? I don't think so. For one, if I did think so, I would quit and become an organic farmer, and I haven't done so... so far. But the question does bother me. And the answer is, I think, that if we want to continue building smarter machines, we absolutely need to keep building smarter people, or we'll end up like in those sci-fi stories. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The main purpose of education is often perceived as passing on what we already know to the next generation, so they don't waste time on rediscovering it. But it's only secondary. The real goal should be passing on the ability to explore the unknown and solve what previous generation haven't solved. Because if students can think at least as well as their teachers, rediscovering something will be just a small detour for them on the road to Knowledge. But without a developed mind they have no legs to walk that road. And it's a steep road up, so when they stop, they (inadvertently perhaps, but) inevitably slip to the bottom.  So how do we nourish the ability to think?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;It's not what we know, it is how we learned it.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;When asking ourselves how to teach, we should first turn to introspection - how did we learn? If the way we've been taught made us discover all those great things that we are so anxious to pass on, why don't we teach what we've been taught? Sure, we will throw in a bit or two of what we've discovered, but basically why don't we build from the same grounds? They say it about parenting - if you like the way you were raised, you'll likely be a good parent, because you'll repeat what you saw. However, if you look around in what's going on in education system, in almost every level, you see the curriculum constantly changing, "updating", "modernizing" etc. "It was true then, it's wrong now. We don't need it." Why? Because we have the technology? Big mistake. Ancient Greeks, Hebrews, Egyptians, not having the technology, weren't even tiny bit stupider than us. Without the wheel, there would be no Internet, speaking of which, who invented &lt;a href="http://sensualjava.blogspot.com/2008/05/net-goddess-of-wisdom.html"&gt;the Net&lt;/a&gt;? But no, we don't need old men, old books and such, religion, history... we have TV commercials to teach us how to live, we have the technology.  And once technology costs money, suppliers of technology don't want us thinking independently, because, Google forbid, we may decide we don't need it! In computer science, this is the nightmare sci-fi writers were warning us against, and we should at least try to prevent it from happening. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We can't go forward without understanding the past. Students can't possibly understand Java and Object Orientation before they understand procedural programming, functions, math, logic. Then, when (and if) we show them objects, let's show how they &lt;a href="http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html"&gt;came about&lt;/a&gt;, and not a &lt;a href="http://java.sun.com/"&gt;popular imitation&lt;/a&gt;. If we have a &lt;a href="http://mitpress.mit.edu/sicp/"&gt;great book and curriculum&lt;/a&gt; that generations of computer scientists and engineers grew on, why are we&lt;a href="http://danweinreb.org/blog/why-did-mit-switch-from-scheme-to-python"&gt; throwing it away&lt;/a&gt;? Let Java, Python and their patrons wait. They will lay their heavy paws on the students in just very few years anyway and will turn them in Dilberts, Wallies, and Alices, converting large XML files to long stack traces. Let's give freedom of thought and curiousity a chance to grow just a little bit in students' minds, so at least some of it can survive through corporate development.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;It's not what a technology does, it is how and why it works&lt;/b&gt;&lt;/div&gt;&lt;div&gt;We're all the time obsessively looking for solutions to our problems. We barely stop and analyze them, until the solution itself becomes our biggest problem. I watched &lt;a href="http://www.infoq.com/presentations/Making-Roles-Explicit-Udi-Dahan"&gt;this QCon presentation&lt;/a&gt; a while back, and it was a deja vu in many senses. I encountered problems like that, and I even solved them in somewhat similar way. I may be wrong, but what I get from the presentation on the technical level, is that sometimes Object Orientation as we know it (C#, Java), with all the patterns and practices and such, does not solve our problem. The problem in the presentation reminds me of the &lt;a href="http://www.daimi.au.dk/~madst/tool/papers/expression.txt"&gt;expression problem&lt;/a&gt; - data and operation-set need to evolve, how do we express the relationships? The proposed solution (although I may be getting it wrong) is to have interface per operation; then the implementation of the interface, using reified generic type parameter, stores the type of object it applies to; then at start-up something wires together data types and implementations; then it all becomes a big happy family of &lt;a href="http://en.wikipedia.org/wiki/Multiple_dispatch"&gt;multi-methods&lt;/a&gt;, operation implementation chosen via dynamic dispatch on the data type. And an old saying goes "when the problem is hard enough, you will find yourself re-inventing Lisp to solve it". It's interesting how Udi describes arriving at this design - a team of people were struggling with the problem for years, until an "old programmer" came to the project retrospective meeting and said "make your roles explicit". Udi took the guy aside and made him explain. Then Udi (and his team, I suppose) implemented it, and now reported the success at QCon. Who was that "old geezer"? What was he? Udi didn't say, in the presentation he is portrayed as a little green troll. Anyway, why do I care who that mysterious character was? Because I didn't come to computer science for some wise Merlin to tell me where the Holy Grail is, I want to &lt;i&gt;be&lt;/i&gt; that Merlin! Unfortunately, I am probably not smart enough, but someone else is. That's why I think we need more wanna-be Merlins; wanna-be Kings we already have plenty. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Since I became interested in functional programming, for example, my Java coding style changed significantly. I thought I knew how to use Generics, only after a taste of OCaml and Benjamin Pierce's writings I realized how little I knew about types. I thought I knew how to write object-oriented programs, only after playing with Smalltalk I realized what object oriented really meant. I may not be able to use Haskell for the day job, but the concepts of immutability, closures, function composition, laziness, are helpful no matter what language I use. Let's look at one example - the (in)famous problem of object-oriented design: does square extend rectangle, or in other words does circle extend ellipse? In both cases the former has 2 distinct properties (edge sizes or focal points) and the latter has only 1. Bob Martin discusses the problem in his article "Design Principles and Design Patterns". Does he offer a solution? No - "design by contract" and Eiffel and some hand-waving. On the other hand, understanding types helps, because then I can "design for subsumption":  I ask myself - if Ellipse is a type that describes all ellipses in the world, do they all have 2 distinct focal points? No. Then maybe I shouldn't have methods to get and set them. Maybe my API should try to follow the definition of ellipse more precisely. That surely helps to design good APIs. Furthermore, magically, once we turn the shapes to immutable, the problem almost goes away. If Rectangle has a method Rectangle transform(x,y) that produces a &lt;b&gt;new&lt;/b&gt; Rectangle with given sizes, then Square can inherit it with no problem, it would simply produce a Rectangle, not a Square when x != y. Same trick would work for Ellipse. After all, shapes are math definitions, why should they be mutable?! See, a bit of "functional" thinking solved the problem. And the moral - understanding the classic foundation of computer science is necessary for programmers. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Reality distracts clarity of thought.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;If there is one more thing that we can learn from these sci-fi stories, it's that detaching things from reality may actually increase our ability to grasp them. However education in recent years is insisting on "examples", or worse - "realistic examples", or even worse "examples of being used in the industry". I am not saying the above is worthless, or unnecessary, but it should not be overrated. At some point education ministry decided to teach elementary school math with actual objects - sticks and such, rather than teaching kids the abstract idea of numbers, and it was a disaster. Math, in general, cannot be taught by following "real world" intuition. Nor logic. Physics has evolved way beyond relatively "intuitive" mechanics. So why are so many educational institutions chasing "real life" technologies, at the expense of classics, and ignoring the "too innovative to be popular"? I know why, of course, - money, pressure from the industry, pressure from students who want real jobs after they graduate. But resisting that pressure is absolutely necessary, for the sake of future generations, to save our civilization! Luckily we still have some universities in Northern Europe :-) &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I noticed an interesting phenomena with students - when they are "fresh" and don't carry a baggage of "field experience" (C, Java, curly braces etc.), it is easier for them to take a "different" point of view, to understand more abstract ideas. Generics is one example. Teaching them to experienced Java programmers is extremely hard. But with undergraduates it is, surprisingly, much easier. So why don't we teach Haskell for types, Smalltalk for objects, and maybe C for low-level stuff? Then when they meet Java, or any language they will likely encounter in the industry, it will be a piece of cake to learn. Furthermore, some of them will be able to design the next Java!&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-4144704129790297295?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/4144704129790297295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=4144704129790297295' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4144704129790297295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4144704129790297295'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2009/05/lessons-we-learn-lessons-we-teach.html' title='Lessons we learn, lessons we teach'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-1584282884726685086</id><published>2009-05-19T16:51:00.014+03:00</published><updated>2009-05-19T19:56:53.771+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Java nested classes - tips and tricks</title><content type='html'>&lt;div&gt;I had to prepare this anyway, so I thought I might as well post. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First of all to get the &lt;a href="http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html"&gt;terminology&lt;/a&gt; straight: normal classes and interfaces are top-level. But class or interface can also be &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;nested&lt;/span&gt;, if it is defined inside another class or interface. Nested classes originate in &lt;a href="http://www.daimi.au.dk/~beta/"&gt;Beta&lt;/a&gt; programming language, and are available in Java since version 1.1. Non-static nested classes are called &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;inner&lt;/span&gt;. Inner classes can be &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;members &lt;/span&gt;(declared immediately inside outer class definitions), like this:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;class Outer { class Inner { ... } }&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Inner classes can also be declared within methods and other blocks, then they are called &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;local&lt;/span&gt;, like:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;class Outer { void foo() { class Local { ... } ... }&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;A more popular breed of local inner classes are &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;anonymous &lt;/span&gt;classes: &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;class Outer { void foo() { ... new Bar(...) { ... } ... }&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;For visual impression - check out &lt;a href="http://blogs.sun.com/darcy/entry/nested_inner_member_and_top"&gt;this diagram&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Tip - construction:&lt;/span&gt; Creating new instance of nested or inner class within the outer class is simple. From outside it's a bit trickier, suppose we have a class like this:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;class Outer {&lt;/div&gt;&lt;div&gt;   static class Nested { ... } &lt;/div&gt;&lt;div&gt;   class Inner { ... } &lt;/div&gt;&lt;div&gt;} &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;We can reference and instantiate the classes like this:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;Outer.Nested nested = new Outer.Nested(...);&lt;/div&gt;&lt;div&gt;Outer out = ...  &lt;/div&gt;&lt;div&gt;out.Inner in = out.new Inner(...); //translated by javac to new Inner(out, ...)&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;The magic behind inner class constructor is that compiler implicitly adds &lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;Outer &lt;/span&gt;parameter to all &lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;Inner &lt;/span&gt;constructors, and passes the enclosing instance when constructor is invoked. From then on, inner class instance (for its entire lifetime) holds a &lt;span class="Apple-style-span" style="font-weight: bold; "&gt;strong reference &lt;/span&gt;to the enclosing instance.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Tip - instanceOf: &lt;/span&gt;If we have two distinct instances &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Outer out1, out2&lt;/span&gt; then &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;out1.Inner&lt;/span&gt; and &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;out2.Inner&lt;/span&gt; denote the same class, but &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Inner&lt;/span&gt; instances will refer to a different enclosing instances. This is different from &lt;a href="http://www.scala-lang.org/node/115"&gt;Scala&lt;/a&gt; and &lt;a href="http://blog.3plus4.org/category/newspeak/"&gt;Newspeak&lt;/a&gt;, where inner class is distinct for every enclosing instance.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Tip - access enclosing instance: &lt;/span&gt;To access the instance of outer class from within a contained inner class use &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Outer.this&lt;/span&gt;. Nested/inner class methods/fields &lt;span class="Apple-style-span" style="font-weight: bold; "&gt;hide &lt;/span&gt;outer class ones, to access outer class elements prefix them with &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Outer&lt;/span&gt; class name, e.g. &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Outer.staticMethod(...) &lt;/span&gt;or &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Outer.this.anyMethod(...)&lt;/span&gt;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Tip - nesting and inheritance: &lt;/span&gt;Generally, method lookup rules in Java nested classes follow "&lt;a href="http://blogs.sun.com/jrose/entry/scope_ambiguities_between_outer_and"&gt;comb semantics&lt;/a&gt;" - first search inheritance hierarchy, then enclosing lexical scopes. This behavior can &lt;a href="http://dyla2007.unibe.ch/?download=dyla07-Gilad.pdf"&gt;introduce some wierd puzzlers&lt;/a&gt;, like &lt;a href="http://www.javapuzzlers.com/java-puzzlers-sampler.pdf"&gt;#9 here&lt;/a&gt;. In Newspeak the enclosing scope is considered before inheritance, which makes it easier to follow from programmer's perspective.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Tip - generics: &lt;/span&gt;Generics type parameters of enclosing class (or method) can be used within inner classes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Tip - interfaces: &lt;/span&gt;Interfaces may have nested classes (necessarily and implicitly static), it may be particurlaly useful for declaring nested enums.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Tip - statics: &lt;/span&gt;Inner class &lt;a href="http://blog.zvikico.com/2008/07/static-members-in-inner-classes-the-answer.html"&gt;cannot have static declarations&lt;/a&gt; in it, except compile-time constants. To overcome this, static declarations canbe moved to the top-level class.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Trick - loading: &lt;/span&gt;Nested class is treated just as any other class by the JVM, e.g. it is not loaded/initialized until used. This fact is used to implement &lt;a href="http://crazybob.org/2007/01/lazy-loading-singletons.html"&gt;thread-safe lazy singletons&lt;/a&gt; using the Holder pattern.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Tip - final: &lt;/span&gt;Anonymous inner classes and local classes can access variables in the surrounding scope only if the variables are &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;final:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;void invokeAnon(final int number) {&lt;/div&gt;&lt;div&gt;   final String word = “hello”;&lt;/div&gt;&lt;div&gt;   someObject.pass(new Runnable() { &lt;/div&gt;&lt;div&gt;      public void run() { &lt;/div&gt;&lt;div&gt;         System.out.println(word.substring(number));&lt;/div&gt;&lt;div&gt;      }&lt;/div&gt;&lt;div&gt;   });&lt;/div&gt;&lt;div&gt;} &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Trick - double braces: &lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;a href="http://www.c2.com/cgi/wiki?DoubleBraceInitialization"&gt;Double brace initialization&lt;/a&gt; is a trick of putting initialization block inside anonymous inner class declaration, like:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;   final Map&lt;string,integer&gt; numbers = new HashMap&lt;string,integer&gt;(){{&lt;/string,integer&gt;&lt;/string,integer&gt;&lt;/div&gt;&lt;div&gt;      put("one", 1);&lt;/div&gt;&lt;div&gt;      put("two", 2);&lt;/div&gt;&lt;div&gt;      put("three", 3);&lt;/div&gt;&lt;div&gt;      //...&lt;/div&gt;&lt;div&gt;   }};&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Trick - tokens: &lt;/span&gt;A cool Generics trick that uses local class to capture type parameters is &lt;a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html"&gt;super-type-token&lt;/a&gt;, a.k.a. Gafter Gadget. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Tip - reflection: &lt;/span&gt;Starting from Java 5 a &lt;a href="http://blogs.sun.com/darcy/entry/nested_inner_member_and_top"&gt;bunch of methods&lt;/a&gt; have been added to reflection with regards to nested classes. For example, &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getEnclosingClass()"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Class#getEnclosingClass()&lt;/span&gt;&lt;/a&gt; method will let you find out the enclosing class for an inner class, for example:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;class Enigma {    &lt;/div&gt;&lt;div&gt; final static Class MY_CLASS = new Object(){}.getClass().getEnclosingClass();  &lt;/div&gt;&lt;div&gt;}  &lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold; "&gt;Prolog: &lt;/span&gt;Last, but not least &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html"&gt;JLS&lt;/a&gt; is the ultimate resource for finding out more.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-1584282884726685086?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/1584282884726685086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=1584282884726685086' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/1584282884726685086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/1584282884726685086'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2009/05/java-nested-classes-some-facts.html' title='Java nested classes - tips and tricks'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-9038407998974962214</id><published>2009-05-08T12:13:00.011+03:00</published><updated>2009-05-10T14:37:32.258+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='newspeak'/><title type='text'>Community Choice Award</title><content type='html'>&lt;a href="http://sourceforge.net/community/cca09/nominate/?project_name=Newspeak%20Programming%20Language&amp;amp;project_url=http://sourceforge.net/projects/newspeakpl/"&gt;&lt;img src="http://sourceforge.net/images/cca/cca_nominate.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I nominated &lt;a href="http://newspeaklanguage.org/"&gt;Newspeak Programming Language&lt;/a&gt; for "Most Likely to Change the Way You Do Everything" &lt;a href="http://sourceforge.net/community/cca09/"&gt;Community Choice Award&lt;/a&gt;. I don't know how exactly they choose winners, apparently:&lt;div&gt;&lt;blockquote&gt;The first phase will be to nominate finalists for each of the Categories. Nominations will be accepted at ... between May 6, 2009 at 10:00 a.m. PDT and May 29, 2009 at 4:00 PDT. Among the nominees for each of the Categories, the finalists for the Awards will be chosen. Voting for the final winners will commence at ... on June 22, 2009 at 10:00 a.m. PDT and end on July 20, 2009 at 4:00 pm PDT. ... The odds of winning in any category are dependent upon the total number of eligible nominations received.&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;Anyway, clicking the orange bot on &lt;a href="http://sourceforge.net/projects/newspeakpl/"&gt;Newspeak sourceforge page&lt;/a&gt; might help the odds - I ask all my readers to contribute a click for a good cause!&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Thank you.&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;UPDATE: &lt;/span&gt;Why does Newspeak deserve it? Newspeak is a class-based dynamically-typed object-orientated language that revives the ideals of Smalltalk and Self.  It incorporates many great ideas, but one of the major innovations is its modularity support. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No other language or framework today provides comprehensive solution for creating modular software. Some languages support hierarchical code organization, there are tools that build components, tools that manage dependencies between components, yet another set of tools and formats deal with module deployment, there are platforms and tools that facilitate versioning and patching, hot and cold updates. &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Newspeak has it all&lt;/span&gt; - the language, development environment, and platform together provide easy and intuitive end-to-end modularity support. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Newspeak supports both mixin-based inheritance and class nesting - modules are top level classes, while all other classes are nested in them. Dependencies between modules are specified using constructors, the absence of global (static) scope enforces complete isolation of modules and prevents creation of incidental or implicit dependencies. Since all objects communicate via virtual method invocations, there is no hard wired dependency on a particular module implementation. Everything is virtual, including the parent-child relationship between classes, which allows for great flexibility and extensibility. The platform supports construction, serialization and loading of module instances, and therefore effectively supports building and deploying applications without the need for any external tools (even though some of this is still under development). Dynamic platform underneath Newspeak has rich meta-programming support and allows querying module definitions, extending modules and supports hot (incremental) updates. Multiple versions of the same module can coexist without interference. Security is maintained by capability-based model where access to resources is guarded by capability objects (also under development). Modules may access their execution environment (the virtual machine, or platform) and through it interact with external resources. Newspeak is also network-aware, and is designed to support distributed component management using service objects. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Newspeak is open-source, it was not widely, but successfully, used in an industrial environment, until financial situation deteriorated and corporations turned their back on funding innovation. There are several publications, and more on the way, conference presentations are received with great excitement. Newspeak is modern, it combines "best-of-breed" ideas of computer science and decades of Smalltalk and Java practical experience. It is easy to learn and very pleasant to code in (and not just for Smalltalkers and programming languages afficonados, but also for averagely skilled Java programmers like yours truly). Newspeak philosophy is inspiring. The people who work on it are extremely smart, but also nice and cool guys... Need I say more?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-9038407998974962214?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/9038407998974962214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=9038407998974962214' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/9038407998974962214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/9038407998974962214'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2009/05/community-choice-award.html' title='Community Choice Award'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-8473991968311947892</id><published>2009-03-31T15:06:00.013+03:00</published><updated>2009-04-01T00:28:12.073+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Oh Null, Null</title><content type='html'>&lt;blockquote&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;blockquote&gt;&lt;/blockquote&gt;Introduction&lt;/span&gt;&lt;div&gt;Some say it’s one of &lt;a href="http://qconlondon.com/london-2009/presentation/Null+References%3A+The+Billion+Dollar+Mistake"&gt;the worst inventions in history of programming languages&lt;/a&gt;, some say it is number one cause of errors in Java programs. Anyway you look at it - &lt;a href="http://en.wikipedia.org/wiki/Pointer#The_null_pointer"&gt;null pointer&lt;/a&gt; (in all its incarnations) is a sensitive subject. I wonder why there is no song about it, there are several funny &lt;a href="http://www.daniweb.com/forums/thread43073.html"&gt;re-works of Beatles songs&lt;/a&gt; with geeky lyrics, like Unix Man (Nowhere Man, “he’s a real Unix man sitting in his Unix LAN, making all his UNIX .plans for nobody…”), Write In C (Let It Be), Yesterday (“yesterday, all those backups seemed a waste of pay…”), Something ("Something in the way it fails, defies the algorithm logic...") and a not so funny Eleanor Rigby. I’d like to write a new song, “Null” using the “Girl” tune. Only my inspiration ended after a single verse:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;If there’s anybody going to listen to my story, &lt;/div&gt;&lt;div&gt;All about the Null who brought the fall.&lt;/div&gt;&lt;div&gt;It’s a value that you want so much, it makes you sorry,&lt;/div&gt;&lt;div&gt;Still you don’t regret a single call. &lt;/div&gt;&lt;div&gt;Oh Null, Null…&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;p&gt;I also have a middle verse inspired by Smalltalk, where the equivalent of &lt;b&gt;null&lt;/b&gt; is &lt;b&gt;nil&lt;/b&gt;, a keyword that returns an object of class UndefinedObject. It has no methods, except &lt;i&gt;isNil &lt;/i&gt;and &lt;i&gt;notNil&lt;/i&gt; that return true and false respectively, so &lt;b&gt;nil&lt;/b&gt; responds to any other method invocation with “&lt;b&gt;DoesNotUnderstand:&lt;/b&gt; &amp;lt;method name&amp;gt;&lt;i&gt;&lt;method&gt;&lt;/method&gt;&lt;/i&gt;”, and in my experience, at least, pretty much equivalent to NPE in Java. Interestingly enough, though, &lt;a href="http://wiki.squeak.org/squeak/5962"&gt;Objective-C turned &lt;/a&gt;&lt;b&gt;&lt;a href="http://wiki.squeak.org/squeak/5962"&gt;nil&lt;/a&gt;&lt;/b&gt;&lt;a href="http://wiki.squeak.org/squeak/5962"&gt; into a “black hole”&lt;/a&gt; that returns self upon any invocation.&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;Nil’s a kind of null, she is not answering your calls,&lt;/div&gt;&lt;div&gt;you feel a fool (fool fool).&lt;/div&gt;&lt;div&gt;When you think the code looks good, she answers “it’s not understood”, &lt;/div&gt;&lt;div&gt;she’s cruel (cruel cruel).&lt;/div&gt;&lt;div&gt;Ah null, null…&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;From Beatles to Elvis&lt;/span&gt;&lt;/div&gt;&lt;div&gt;One situation where nulls are very annoying, is when we have a “chain” of method invocations, such as account.getOwner().getAddress().getStreet(). If any of the methods return null, we get NullPointerException from the next method invocation. I previously &lt;a href="http://sensualjava.blogspot.com/2007/11/null-safe-access-to-properties.html"&gt;suggested a solution&lt;/a&gt; to the problem, but now (due to popular demand) there is a &lt;a href="http://jroller.com/scolebourne/entry/java_7_null_ignore_invocation"&gt;proposal&lt;/a&gt; for Java 7 language enhancement, called &lt;a href="http://docs.google.com/Doc?docid=ddb3zt39_78frdf87dc&amp;amp;hl=en"&gt;The Elvis Operators&lt;/a&gt;.  One of the stronger arguments for this solution is that it is available in other languages like C# and Groovy, even if &lt;a href="http://adventuresinsoftware.com/blog/?p=293"&gt;not everybody is entirely happy with it&lt;/a&gt;. Perhaps this is subjective, but after all, programming language design is about human perception and feelings, as much as about computer capabilities. So, I admit: &lt;span class="Apple-style-span" style="font-style: italic;"&gt;I feel uneasy with this new way of method invocation.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;The Demeter &lt;/span&gt;&lt;strike&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Law&lt;/span&gt;&lt;/strike&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt; Suggestion&lt;/span&gt;&lt;/div&gt;&lt;div&gt;One of the more controversial guidelines of object-oriented programming, Demeter Law is related to “Tell Don’t Ask” and usually summarized as “only talk to your close friends”. It prohibits series of method invocations like the one described above; in fact, more than one dot in series of method invocations is disallowed (unless the chain originates in a this object’s member (?)). There’s a good description of the “The Law” in &lt;a href="http://www.pragprog.com/articles/tell-dont-ask"&gt;Pragmatic Programmers article&lt;/a&gt;; it was originally discovered and named by &lt;a href="http://www.ccs.neu.edu/groups/faculty/lieber.html"&gt;Karl Lieberherr&lt;/a&gt;, who created the &lt;a href="http://www.ccs.neu.edu/research/demeter/"&gt;Demeter Project&lt;/a&gt;  and wrote the &lt;a href="http://www.ccs.neu.edu/research/demeter/biblio/dem-book.html"&gt;book&lt;/a&gt; named “Adaptive Object-Oriented Software - The Demeter Method”. Martin Fowler &lt;a href="http://pages.citebite.com/n1f0t3t8b0kvt"&gt;demoted the Law to Suggestion&lt;/a&gt;, and in general, Demeter managed to generate a lot of controversy and debates inside both Java and Ruby communities, the debates ranging from &lt;a href="http://www.javalobby.org/java/forums/t104659.html"&gt;intellectual (almost academic) polemics&lt;/a&gt;, to flamed &lt;a href="http://pivotallabs.com/users/alex/blog/articles/273-lovely-demeter-meter-maid"&gt;battles between consulting firms over preferences in programming styles, music and hairdo&lt;/a&gt;. Yes, really. Anyway, if you believe in Demeter, our use-case for “null-safe” method invocations is flawed to begin with. But do we believe in Demeter? It took me a while to form an opinion.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;1) I do believe in “Tell, Don’t Ask” and the internal iterator (as presented in Pragmatic Programmers article) to be preferable over external iterator (&lt;a href="http://gafter.blogspot.com/2007/07/internal-versus-external-iterators.html"&gt;when applicable&lt;/a&gt;, of course). &lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;“Tell Don’t Ask” begs for closures in the language. For those who say “closures are not object-oriented”, Smalltalk not only supports closures, and with minimal syntactic overhead, but basic things like &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;if &lt;/span&gt;and &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;while &lt;/span&gt;are designed around closures and would not be possible otherwise. &lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;But "Tell Don't Ask" goes much deeper and wider. For example let's look through Demeter's eyes on service locator vs. injection: locator is wrong, because you go to a factory to get a factory to get a service. Injection is right, because you pass yourself to injector, which sets your the dependencies directly. How about ORM? How much grief is in loading strategies, because we do getContainer().getItem().getProperty(), vs. calling database.execute(query)? Food for thought.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2) Now the paper boy example – this one I do not buy. First of all, we don’t pay for things in cash these days – we give the seller our credit card. Not very secure? Maybe. But much more handy. &lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;People should generally stop obsessing around security in software, I think. At one point a highly ranked architect in the firm I worked for said “we can’t deploy any software in the browser because it is not secure”. Yes, it is not secure, it’s a problem and people are working on it. And yet, even as it is, is it secure for the jeweler store to put some jewels in the front window? Why not keep them all in the backroom safe?  Because they won’t have buyers, that’s why. What good is all the security, if you go out of business? &lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p class="MsoListParagraph"&gt;Back to paper boy, the example also does not hold if you are a large organization – the receiver of the service is not the one who authorizes the payment, and not the one who handles the payment. The supplier may wish for “direct communication” as much as he wants, but the rules of corporate procurement are quite different. Then again, it may be silly to attack the example…? Well, the thing is that I hope to show later that you can’t follow Demeter and scale, just like the example doesn’t.&lt;/p&gt;&lt;p class="MsoListParagraph"&gt;3) Now there’s “hard to mock” argument. Ok, at risk of starting a flame war here, I mean: I love unit-testing just like the next guy, and I know how useful it is, but let’s not get carried away here. &lt;/p&gt;&lt;p class="MsoListParagraph"&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Unit-testing, just like static types/compilation, or static analysis, is a means to achieve code quality, not the goal in itself. If it helps you – great, if it gets in your way – ditch it. I think the “100% test coverage” is a fallacy. Dijkstra said “tests only prove presence of bugs, never their absence”, which is even truer for unit-tests. (I heard “we have unit-tests, we don’t need QA” argument once or twice. Yeah, right.) &lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p class="MsoListParagraph"&gt;Anyway, “hard to test” may be a smell, but unless the suspicion can be substantiated – sorry, circumstantial evidence not accepted.&lt;/p&gt;&lt;/div&gt;&lt;div&gt;4) So even though I partially agree that “Demeter violation” is a symptom of a problem, the solution proposed by Demeter is, in my opinion, simply absurd. The grand huge fat mega-façade? Dots replaced with underscores? It cannot scale and it is sweeping design problems under the carpet. I mean, give me &lt;a href="http://gbracha.blogspot.com/2009/03/subsuming-packages-and-other-stories.html"&gt;hierarchies of nested objects that support subsumption&lt;/a&gt;, like &lt;a href="http://blog.3plus4.org/2009/03/08/a-taste-of-nested-classes-part-4/"&gt;Newspeak modules&lt;/a&gt; – now we are talking. But mega-façades? No thanks.&lt;/div&gt;&lt;div&gt;&lt;div&gt;So there are good things that result from minding Demeter, but not following the law per se. &lt;/div&gt;&lt;div&gt;a) For example, “don’t return a java.util.List from your API when you don’t want clients adding elements to the list” – that’s basics of any sound API design – return the minimum interface that the client needs, Josh Bloch has been saying this repeatedly. &lt;/div&gt;&lt;div&gt;b) We should consider to proxy the returned object (perhaps with our own (inner) class), and then we’ll have control over what the returned object’s methods do.&lt;/div&gt;&lt;div&gt;c) Applied to DI – “do not depend on module A just to give you access to another module B, instead depend on B directly”, is also a reasonable rule of thumb. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But let’s now go back to our beloved nulls.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Power to the method - let the declaration site decide&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Demeter or not, methods are meant to do things. I would argue that typical methods should not be assumed to be wrapping field access, or performing trivial computations. Yeah, I know we all do POJOs, which are really POCS, Plain Old  C Structs in disguise.  (And what makes them structs are frameworks that assume a dumb accessor and mutator, and freak out if they are not.) I believe that most methods should do something, so invoking them on a null target should yield an error, not some ambivalent null… So I am not too happy with changing the programming language to accommodate to behavior that should have been atypical.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now if some methods are “dumb” and have reasonable defaults (like null for property accessor in null object, or 0 for size/length of a null collection/array, or null for a null string upper case transformation), then the method implementer should decide – not the caller. And again, it’s not problem-free, but worth exploring. Somewhat similar behavior has been proposed by Jacek &lt;a href="http://codervirtue.blogspot.com/2009/03/null-safe-invocation-in-java-7.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Suppose at the method declaration we add a default clause: either &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default &amp;lt;value&amp;gt;,&lt;/span&gt; or &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default &amp;lt;expression&amp;gt;&lt;/span&gt;, or &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default &amp;lt;code-block&amp;gt;&lt;/span&gt;, with the return type of value/expression/code-block similar to method return type, and parameters and exceptions (in 2 latter cases) similar to the method’s ones. BTW &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default &lt;/span&gt;is an existing Java keyword, used in &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;switch &lt;/span&gt;statements. &lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Now examples:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;&lt;/span&gt;&lt;/div&gt;&lt;span&gt;&lt;span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;public int&lt;/span&gt; size() { &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;return this&lt;/span&gt;.size; } &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default &lt;/span&gt;0; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;public boolean &lt;/span&gt;isEmpty() { &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;return this.&lt;/span&gt;size == 0; } &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default true&lt;/span&gt;; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;public &lt;/span&gt;Person getOwner() { &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;return this&lt;/span&gt;.owner; } &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default null&lt;/span&gt;; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;public &lt;/span&gt;Iterator iterator() { &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;return &lt;/span&gt;… } &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default &lt;/span&gt;Collections.emptyList().iterator(); &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;public &lt;/span&gt;Something produce(Param1 p1, Param2 p2) &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;throws &lt;/span&gt;E1 {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   //normal method code here&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;} &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default &lt;/span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  //default calculation, similar to static method, can use p1 and p2, throw sub-type of E1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  //needs to return Something&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;} &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;The location of the “default clause” can be after method body (and if we stick to coding convention of keeping default it on the same line as the closing curly brace, I think it is preferable), but it can sit also between end of method parameter list and the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;throws &lt;/span&gt;clause, or between the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;throws &lt;/span&gt;and the method body start. I think tail location is preferable, because it reminds of the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;switch &lt;/span&gt;statement. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Another variation that increases similarity to switch may be adding a colon (&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default :&lt;/span&gt; ) and requiring return keyword, like &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default : return null;&lt;/span&gt; instead of &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default null&lt;/span&gt;. Also, the support for “defaults” can be added gradually, with only values in the first stage and more later if it proves to be successful. Also, alternative to default may be &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;case null : &lt;/span&gt;… .&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;The method would be compiled now additional synthetic static method, e.g. ___size(), with the same signature and throws clause, the synthetic method returning the “default” body provided by the user. &lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately, though, call sites are affected by such method definition and compiled to something like:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;SomeType object;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;if &lt;/span&gt;(object != &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;null&lt;/span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  object.m()&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;} &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;else &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;try &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;     SomeType.___m();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  } &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;catch &lt;/span&gt;(NoSuchMethodError e) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;throw &lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;new &lt;/span&gt;NullPointerException();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;} &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So the “default” would be calculated based on declaration type of the object, just like any static method invocation. Why catching NoSuchMethod? Well, what if SomeType class is recompiled alone, and the default clause, and with it the ___m() method, are gone? We want NPE to be thrown, not NSME. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If, on the other hand, we add the default behavior without recompiling clients, they’ll be still throwing NPEs, I think we would not want all method invocations to become complex byte-code like the one described above… If I understand Jacek’s proposal correctly, unlike me, he suggests every method invocation to go through a static method. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;It would be interesting to see to what extent JIT could optimize code like that when it learns that object is not null… could it throw away everything but object.m()? This certainly requires more investigation.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Maybe, babe, boom&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Another option would be to turn to Functional Programming for an answer. This is one of the things known in FP world for ages: &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Maybe &lt;/span&gt;in Haskell, or &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Option &lt;/span&gt;in Scala and F#. Here’s a &lt;a href="http://debasishg.blogspot.com/2008/03/maybe-scala.html"&gt;nice description by Debasish Gosh&lt;/a&gt;, and if you want to learn about Monads, &lt;a href="http://james-iry.blogspot.com/search/label/monads"&gt;James Iry’s blog&lt;/a&gt; or a Haskell book would be a good place to start. But we don’t have Monads in Java, Stephan Schmidt tried to &lt;a href="http://feeds.feedburner.com/~r/stephansblog/~3/357235228/"&gt;simulate Maybe with Iterable&lt;/a&gt;, and the result is cute, very cute even, but lacks the monadic awesomeness of flatMap, as others have pointed out. Hm, but wait, we do have a monad in Java. That’s exceptions. The naïve translation of Maybe in Java would be:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;String &lt;/span&gt;street;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;try &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  street = account.getOwner().getAddress().getStreet();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;} &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;catch &lt;/span&gt;(NullPointerException e) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  street = &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ok, it’s not so clean and pretty as pattern match, but… well, that’s Java. No, wait, smart and experienced programmers like us – we know that we shouldn’t use exceptions that way, because it is expensive! Hm, and why is it? Because &lt;a href="http://blogs.sun.com/jrose/entry/longjumps_considered_inexpensive"&gt;filling in the stack trace&lt;/a&gt;, actually, otherwise it’s &lt;a href="http://www.javaspecialists.eu/archive/Issue129.html"&gt;rather cheap&lt;/a&gt;. But we don’t need stack trace here, only… the exception is the standard NPE, we cannot subclass it and override fillInStackTrace(). Bummer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Using exceptions for control flow is &lt;a href="http://www.drmaciver.com/2009/03/exceptions-for-control-flow-considered-perfectly-acceptable-thanks-very-much/"&gt;debatable&lt;/a&gt;. I am not a proponent of this style, just for the record. I am simply exploring options… what if the JVM “magically” knew not to fill in stack trace when it’s not used? Exceptions would become cheaper and whole new programming style in Java would emerge...? &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some of the Java 7 language enhancement proposals are to do with exceptions, &lt;a href="http://tech.puredanger.com/java7/#catch"&gt;multi-catch&lt;/a&gt; for example, I am all for it BTW. Now what if we add another flavor to catch and introduce “no-instance” catch, such as:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;try &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  //…&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;} &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;catch &lt;/span&gt;(NullPointerException) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  //…&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Note that there is no e, no exception instance, no way to re-throw or print – clearly no need for a stack trace. What if JVM kept a bit-map of exception types in “no-instance” try/catch blocks on the stack, and threw these exceptions without filling in the stack trace? After all, we are guaranteed that they are caught and no “phantom” exception like this escapes to the user… these exceptions could be pooled too. Then we could say&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;String &lt;/span&gt;street;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;try &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  street = account.getOwner().getAddress().getStreet();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;} &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;catch &lt;/span&gt;(NullPointerException) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  street = &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And &lt;a href="http://www.javac.info/"&gt;if we had closures&lt;/a&gt;, we could even make it prettier. We could create a utility method like&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;public static&lt;/span&gt;&lt;span class="Apple-style-span" style=""&gt; &amp;lt;T&amp;gt; &lt;/span&gt;&lt;t&gt;T nullsafe({ =&gt; T} expression) {&lt;/t&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;return &lt;/span&gt;nullsafe(expression, &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;null&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;public static&lt;/span&gt; &lt;t&gt;&amp;lt;T&amp;gt; T nullsafe({ =&gt; T} expression, T default_value) {&lt;/t&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;try &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;return &lt;/span&gt;expression.invoke()&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  } &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;catch &lt;/span&gt;(NullPointerException) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;return &lt;/span&gt;default_value;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It would be invoked like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;String &lt;/span&gt;street = nullsafe({ =&gt; account.getOwner().getAddress().getStreet() });&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In all its glorious maybiness and with no, or little, performance overhead?! :-) But hey, I said I don’t like clients deciding on the value that the method returns… true, which is why I am not entirely happy with any of the proposals. But at least here we don’t change the language for the sake of null alone – the “exceptional” invocation is explicitly made with a catch clause or via a special library call. &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p class="MsoListParagraph"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Epilog&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoListParagraph"&gt;All this just for the sake of intellectual exercise, so don't take too seriously. :-)&lt;/p&gt;&lt;p class="MsoListParagraph"&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;Update&lt;/span&gt;: &lt;/p&gt;&lt;p class="MsoListParagraph"&gt;So why I don't like any of the solutions, not even the ones I proposed? The "default clause" is essentially another static method. It may even work for interfaces, with a slight twist. The real problem is that static cannot be overridden, unlike the method it is "attached to", so the default clause and the actual method body will not correspond, so we basically gained nothing. &lt;/p&gt;&lt;p class="MsoListParagraph"&gt;As for the instance-less exception, call me old-fashined, but I think that exceptions are for exceptional things, and this is stretching the hacks around them just one bit too far. &lt;/p&gt;&lt;p class="MsoListParagraph"&gt;So I'll stay with plain old null for now, thank you.&lt;/p&gt;&lt;p class="MsoListParagraph"&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-8473991968311947892?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/8473991968311947892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=8473991968311947892' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/8473991968311947892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/8473991968311947892'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2009/03/oh-null-null.html' title='Oh Null, Null'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-9039669399288633733</id><published>2009-01-09T17:35:00.008+02:00</published><updated>2009-01-09T23:11:43.344+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>The return of forgotten design patterns</title><content type='html'>Some design patterns are used all the time and their names are known to all - like facade, factories and proxies. Some design patterns are &lt;a href="http://tech.puredanger.com/presentations/design-patterns-reconsidered"&gt;more popular than they should be&lt;/a&gt;. But some, although rarely mentioned by their name, have been recently "rediscovered". I'm talking about &lt;a href="http://www.javaworld.com/javaworld/jw-07-2003/jw-0725-designpatterns.html"&gt;Flyweight&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Memento_pattern"&gt;Memento&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Flyweight&lt;/span&gt;&lt;br /&gt;This one basically lets us share n instances between m concurrent clients when m &gt; n. It separates "intrinistic state", the normal class members, and "extrinistic state", which is maintained via parameter passing and return values. Make your intrinistic state immutable, and you can share the same instance between multiple clients. Cool, ha? Priceless. Look at &lt;a href="http://en.wikipedia.org/wiki/Concurrent_computing#Concurrent_interaction_and_communication"&gt;message passing concurrency instead of shared memory concurrency&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt;, &lt;a href="http://martinfowler.com/bliki/Transactionless.html"&gt;transactionless architecture&lt;/a&gt;... All these treasures actually follow the same spirit as Flyweight.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Memento&lt;/span&gt;&lt;br /&gt;This pattern suggests that if you want to save your object state, you better export it in a new dedicated memento object and store the memento. Then restore your object from the memento.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/commons/1/18/Memento_design_pattern.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 444px; height: 180px;" src="http://upload.wikimedia.org/wikipedia/commons/1/18/Memento_design_pattern.png" alt="" border="0" /&gt;&lt;/a&gt;This is like serialization, only serialization didn't follow the pattern, unfortunately.&lt;br /&gt;&lt;br /&gt;Josh Bloch suggests we do it manually with so called "Serialization Proxies" - see item 78 in chapter 11 of 2nd edition of "&lt;a href="http://java.sun.com/docs/books/effective/"&gt;Effective Java&lt;/a&gt;". Here's a slide from &lt;a href="http://developers.sun.com/learning/javaoneonline/2006/coreplatform/TS-1512.pdf"&gt;JavaOne 2006 preso&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_GnOWSH314CY/SWd9rxEq8QI/AAAAAAAAAP8/UAamjxZ7T_c/s1600-h/ser_proxy.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_GnOWSH314CY/SWd9rxEq8QI/AAAAAAAAAP8/UAamjxZ7T_c/s400/ser_proxy.JPG" alt="" id="BLOGGER_PHOTO_ID_5289334478230712578" border="0" /&gt;&lt;/a&gt;The book lists more advantages of the pattern, like improved security (see item 76 - danger of hackers acquiring references to private fields using de-serialization), ability to de-serialize a different class from the originally serialized instance (RegularEnumSet and JumboEnumSet example) etc.The name "memento" isn't mentioned though.&lt;br /&gt;&lt;br /&gt;Now imagine persistence architectures actually using intermediate memento objects... instead of modifying actual objects bytecode, breaking encapsulation with access to their private fields, imposing constraints like public empty constructors and so on... Maybe we would have been better off with mementos...?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-9039669399288633733?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/9039669399288633733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=9039669399288633733' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/9039669399288633733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/9039669399288633733'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2009/01/return-of-forgotten-design-patterns.html' title='The return of forgotten design patterns'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GnOWSH314CY/SWd9rxEq8QI/AAAAAAAAAP8/UAamjxZ7T_c/s72-c/ser_proxy.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-3293901183050982055</id><published>2009-01-09T13:22:00.006+02:00</published><updated>2009-01-09T14:02:53.518+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Static types are from Mars, Dynamic types are from Venus</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/en/8/8c/VenusandMarsalbumcover.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 300px; height: 300px;" src="http://upload.wikimedia.org/wikipedia/en/8/8c/VenusandMarsalbumcover.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.paulmccartneyshop.com/mall/productpage.cfm/PMEn/163473"&gt;Venus and Mars&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;static &lt;/span&gt;- associated with logic and acting by the rules, strong, efficient, usually responsible for safety and order enforcement; but non-compromising (for better or worse), non-adaptive, weak in communication skills.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;dynamic &lt;/span&gt;- associated with beauty and elegance, light, good in communication skills, can usually be easily made to do what you want them to, change all the time and adapt to change well; but unpredictable, act on intuition rather than logic, often seen as less efficient and weaker.&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-3293901183050982055?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/3293901183050982055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=3293901183050982055' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3293901183050982055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3293901183050982055'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2009/01/static-types-are-from-mars-dynamic.html' title='Static types are from Mars, Dynamic types are from Venus'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-2508603801145452418</id><published>2009-01-07T19:10:00.026+02:00</published><updated>2009-02-15T13:52:10.972+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Types and components</title><content type='html'>Just some thoughts following a recent conversation I had. Don't we always want static types? If we can detect errors in our program, why not do it as early as possible? Sure. So when is "as early as possible"? I think the answer depends on what our program is - is it one monolithic piece or a component? &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the past monolithic software was prevalent, but today I would bet that most software is meant to be a component. Just look at open-source as it used to be before Java - you'd usually download the C source-code, change it if you need, build it all on your machine, and create one big executable. (And BTW - congratulations, you are a geek.) Cross platform Java changed the situation. Now open-source projects give you a jar to download, you put it on your classpath and you are ready to go. This lowered the bar for open-source adoption, and contributed (aside less restrictive licenses and other factors) to baby-boom of open-source frameworks and tools. Nowadays a Java developer cannot even imagine having no 3rd party jars in the classpath!&lt;br /&gt;&lt;br /&gt;Static type check validates our software component against other components in the &lt;span style="font-weight: bold;"&gt;compilation&lt;/span&gt; environment. Does it match the &lt;span style="font-weight: bold;"&gt;runtime &lt;/span&gt;environment? What about different configurations of the runtime environment - there are tests and real deployments, and various types of deployments, and any given installation environment can change over time - new components being added, other updated or removed? How do we guarantee that compile time checks still hold? The short answer is - we can't. We need dynamic type safety anyway. Now let's examine the added value and the price (yes, there is one!) of deeply static types.&lt;br /&gt;&lt;br /&gt;On code organization level, we try to reduce the dependencies to bare minimum - hide classes behind interfaces that we hope will remain more stable. The problem is that number of interfaces and factories in our application grows, while pursuing modularity we sacrifice simplicity... So maybe the problem is in the name? &lt;a href="http://whiteoak.sourceforge.net/"&gt;Some&lt;/a&gt; go as far as add support for &lt;a href="http://en.wikipedia.org/wiki/Structural_type_system"&gt;structural types&lt;/a&gt;, &lt;a href="http://debasishg.blogspot.com/2008/06/scala-to-java-smaller-inheritance.html"&gt;minimizing dependency&lt;/a&gt; to a single field/method signature (&lt;a href="http://beust.com/weblog/archives/000476.html"&gt;not a problem-free&lt;/a&gt; solution,  but there are &lt;a href="http://www.jot.fm/issues/issue_2008_01/article4/"&gt;interesting refinements&lt;/a&gt;). All this may help, but doesn't really solve the problem.&lt;br /&gt;&lt;br /&gt;Another aspect we need to deal with is building and packaging the software. Here we enter the world of dependency management, the world of "make", Ant, Maven, repositories, jar versions; if it's a large enough and complex enough software we work on, simply speaking - we enter the world of pain. I still find it strange that we haven't found a better way.&lt;br /&gt;&lt;br /&gt;As for application deployment and its problems, we'll get back to it later. But the truth is that no matter how hard we try, we can't guarantee there will be no errors when we deploy our software, so ... JVM doesn't trust us and gives us &lt;a href="http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#88597"&gt;verification&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Simply put, when class is compiled, some of its requirements from other classes are captured and encoded into the bytecode. Then JVM would check them when the class is loaded, and reject the class if they can't be met. (This is really an over-simplified description of a complex algorithm, which also takes time to execute, despite &lt;a href="http://en.wikipedia.org/wiki/Java_performance#Split_bytecode_verification"&gt;optimization efforts&lt;/a&gt; on JVM side.) So this isn't really a dynamic check, it's something in between - names in our class get linked when it is loaded. In the classic Java SE class-loading scheme, where components are basically a chain, this scheme should work. But if we want real components, ones we can add, override, replace or remove while program is running - sweet turns sour. Our interfaces and factories have names, and classes that represent them need to reside in some "common vocabulary" usually loaded by the parent classloader, because it's not only the class bytecode that matters, but also &lt;a href="http://www.bracha.org/classloaders.ps"&gt;who loaded what&lt;/a&gt;. Since we are talking actual classes, not their names, once we loaded two components, they cannot change their protocol of communication without reloading their parent, they also can't use a different version of a sub-component that the parent component has referenced.&lt;br /&gt;&lt;br /&gt;In JEE that sort of things is necessary, that's why classloading in JEE is a terrible mess, not only it does not follow any specification, but it is different in almost each and every app server (wasn't there supposed to be portability?!) If you ever used &lt;a href="http://commons.apache.org/logging"&gt;commons-logging&lt;/a&gt; in a JEE app, you probably &lt;a href="http://www.qos.ch/logging/classloader.jsp"&gt;know what I mean&lt;/a&gt;. Maybe it got fixed lately, I don't know, but the &lt;a href="http://commons.apache.org/logging/tech.html"&gt;Tech Guide&lt;/a&gt; for commons-logging is an ode to classloader frustration.&lt;br /&gt;&lt;br /&gt;Back to deployment: whenever there are some sort of dynamic components - JEE, Spring or OSGi, there is always reflection. And most of the time there's lots of XML too. It's an escape route from static types. I attended &lt;a href="http://javaedge.net/sessions.html"&gt;Alef Arendsen's session&lt;/a&gt; at JavaEdge that presented OSGi and SpringSource. I carefully watched Alef juggle between XML, source and console like a child who watches a circus magician trying to uncover his tricks. But I didn't quite figure out the magic. And that was a whole session just for HelloWorld. I know Spring folks are doing best they can, and they're smart and all... but comparing to Smalltalk, I wasn't quite impressed. As for other solutions, although  I haven't tried this out, there's &lt;a href="http://code.google.com/p/peaberry/wiki/DetailedDesign"&gt;Guice/OSGi integration&lt;/a&gt; without XML and with dynamic proxies and on-the-fly bytecode generation with ASM, but there's some overhead for the user, because it requires intermediate objects for services. So this way or the other, looks like JVM platform is holding us back.&lt;br /&gt;&lt;br /&gt;Verification is addition, not replacement of dynamic checks. So what we get is basically a triple check of correctness (javac, verifier, dynamic) but loss of flexibility - we are interfering with components runtime life-cycles. If the invocation target is resolved just in time when the call is made, nothing precludes the target component from being reloaded between calls. But with preemptive validation, we get a static dependency tree at runtime, classes wired with each other "too early" and for good, which makes reloading a component very hard (although people &lt;a href="http://www.zeroturnaround.com/presentation/"&gt;keep trying&lt;/a&gt;). The reason for "early linking" is also performance, but late binding doesn't mean that the runtime platform can't do any optimization heuristics... but they'll have to be dynamic optimizations in the style of JIT. Will &lt;a href="http://jcp.org/en/jsr/detail?id=292"&gt;invokedynamic&lt;/a&gt; bring the salvation?&lt;br /&gt;&lt;br /&gt;It seems when we are talking about multiple components, "statically typed platform" does not quite do the job. Static type check may mean a lot inside a component, but as for inter-component communication they are not only useless, but harmful. People sometimes dismiss dynamic types, because they think "it's like static types, but without static types". What they may not realize is that you are not just loosing, you are gaining something with dynamic types. You get &lt;span style="font-weight: bold;"&gt;late binding&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;meta-programming&lt;/span&gt;, and in a multi-component environment, it means a whole lot!&lt;br /&gt;&lt;br /&gt;And that's when we are talking "inside the platform" components developed in the same language. Once you work with a system that runs on a different platform or developed in a different language - our type system doesn't normally stretch across the communication boundary. The other system may not even have static types, and since we are only as strong as the weakest link, our static types don't really help us. I think every time we try to encode types into communication between systems we end up with a monster like CORBA or Web Services. But there's another (unfortunately popular) extreme of just sending a string over and hoping for the best - with no checking on our side at all. Then we are relying on the other system to stop us from doing damage, and there's no way to correctly blame the component that made an error - was it a wrong string or an unexpected change on the other side? I think that ideally type or contract checking and conversions can be done dynamically on both sides, and not as part of the protocol. This results in light and flexible data-exchanging protocols (like HTTP or ATOM) which are easier to work with and I think will win in the end. On the more theoretical level I like &lt;a href="http://www.cs.utah.edu/%7Ekathyg/interop.pdf"&gt;this model for intercommunication&lt;/a&gt; and of course there are &lt;a href="http://gbracha.blogspot.com/2008/12/unidentified-foreign-objects-ufos.html"&gt;Aliens&lt;/a&gt;, that model external system as a special object in our system.&lt;br /&gt;&lt;br /&gt;So as far as I see - components simply require a dynamic environment, they may be statically checked inside, but act as "dynamic" to the outside world. Sort of hard skeleton and soft shell. Indeed soft parts are much easier to fit together and less breakable, due to flexibility - this is used often in mechanical engineering and in nature, so &lt;span style="font-weight: bold;"&gt;why not in software?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-2508603801145452418?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/2508603801145452418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=2508603801145452418' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/2508603801145452418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/2508603801145452418'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2009/01/types-and-components.html' title='Types and components'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-5839567926894844311</id><published>2008-12-11T17:02:00.005+02:00</published><updated>2008-12-11T21:10:21.938+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>How not to implement Comparable</title><content type='html'>I have already blogged about the &lt;a href="http://sensualjava.blogspot.com/2007/11/beware-overflows-in-numeric-operations.html"&gt;danger of numeric overflows&lt;/a&gt;. I recently came across this example in Java course materials (!!!):&lt;br /&gt;&lt;pre&gt;public class Foo implements Comparable&amp;lt;Foo&amp;gt; {&lt;br /&gt;private int number;&lt;br /&gt;public int compareTo(Foo o) {&lt;br /&gt;  if (this == o) return 0;&lt;br /&gt;  return number - o.number;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;How do you think Integer.MAX_VALUE compares to negative numbers? It will appear smaller. This reminds me of even worse case we encountered in a real codebase. Look at this:&lt;br /&gt;&lt;pre&gt;public class Foo implements Comparable&amp;lt;Foo&amp;gt; {&lt;br /&gt;private long id;&lt;br /&gt;//...&lt;br /&gt;public int compareTo(Foo o) {&lt;br /&gt;  if (this == o) return 0;&lt;br /&gt;  return (int)(id - o.id);&lt;br /&gt;}&lt;br /&gt;public boolean equals(Object o) {&lt;br /&gt;  return o != null &amp;amp;&amp;amp; (o instanceOf Foo) &amp;amp;&amp;amp; compareTo((Foo)o) == 0;&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;How do you think &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;new Foo(8325671243L)&lt;/span&gt; and &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;new Foo(25505540427L)&lt;/span&gt; compare? They are equal, but I will do it ala &lt;a href="http://www.weiqigao.com/blog/tags/java/"&gt;Weiqi Gao&lt;/a&gt; and leave you to find out why... :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-5839567926894844311?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/5839567926894844311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=5839567926894844311' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5839567926894844311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5839567926894844311'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/12/how-not-to-implement-comparable.html' title='How not to implement Comparable'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-3880931836372220428</id><published>2008-12-11T16:01:00.004+02:00</published><updated>2008-12-11T16:55:26.294+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Static initializers - update</title><content type='html'>After some interesting comments to my &lt;a href="http://sensualjava.blogspot.com/2008/12/case-against-static-initializers.html"&gt;previous write-up&lt;/a&gt; I decided to make a follow-up post with some additional details.&lt;div&gt;Here is the code from &lt;a href="http://java.sun.com/docs/books/effective/"&gt;Effective Java&lt;/a&gt;:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;public class Person {&lt;br /&gt; private final Date birthDate;&lt;br /&gt; //...&lt;br /&gt; private static final Date BOOM_START;&lt;br /&gt; private static final Date BOOM_END;&lt;br /&gt;&lt;br /&gt; static {&lt;br /&gt;   Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));&lt;br /&gt;   gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);&lt;br /&gt;   BOOM_START = gmtCal.getTime();&lt;br /&gt;   gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);&lt;br /&gt;   BOOM_END = gmtCal.getTime();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean isBabyBoomer() {&lt;br /&gt;   return birthDate.compareTo(BOOM_START) &amp;gt;= 0 &amp;amp;&amp;amp;&lt;br /&gt;     birthDate.compareTo(BOOM_END) &amp;lt; 0;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;and here's how I would have changed it:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;public class BabyBoom {&lt;br /&gt; private static final BabyBoom boom = new BabyBoom();&lt;br /&gt; private Date start = null;&lt;br /&gt; private Date end = null;&lt;br /&gt;&lt;br /&gt; private BabyBoom() {}&lt;br /&gt;&lt;br /&gt; public static BabyBoom getInstance() {&lt;br /&gt;   if (boom.start == null || boom.end == null) {&lt;br /&gt;     Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));&lt;br /&gt;     gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);&lt;br /&gt;     boom.start = gmtCal.getTime();&lt;br /&gt;     gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);&lt;br /&gt;     boom.end = gmtCal.getTime();&lt;br /&gt;   }&lt;br /&gt;   return boom;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean contains(Date birthDate) {&lt;br /&gt;   return birthDate.compareTo(start) &gt;= 0 &amp;amp;&amp;amp; birthDate.compareTo(end) &amp;lt; 0;&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;public class Person {&lt;br /&gt; private final Date birthDate;&lt;br /&gt; //...&lt;br /&gt; public boolean isBabyBoomer() {&lt;br /&gt;   BabyBoom boom = BabyBoom.getInstance();&lt;br /&gt;   return boom.contains(birthDate);&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;I didn't synchronize &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;getInstance&lt;/span&gt;, because initializing the dates twice does no harm, so it's not worth the price of synchronization. However I did check that both fields are initialized before returning the object in &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;getInstance&lt;/span&gt;. &lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-3880931836372220428?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/3880931836372220428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=3880931836372220428' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3880931836372220428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3880931836372220428'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/12/static-initializers-update.html' title='Static initializers - update'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-7770655119220825201</id><published>2008-12-07T22:05:00.005+02:00</published><updated>2008-12-09T10:58:53.152+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>A case against static initializers</title><content type='html'>&lt;div&gt;"Effective Java" is an excellent book. I recently bought the 2nd edition, and it is absolutely fabulous, priceless. However after quite some time in the industry, I've learnt not to take any advice blindly. First edition was also excellent, but several of the items were revisited since then. So here's an item that I have mixed feelings about - &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;A&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;void creating unnecessary objects&lt;/span&gt;. The advice is to use static initializers for the expensive computation. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Static initializers are double-edged sword. It's like with the stock exchange in times of crisis - for a particular individual it may be a good idea to sell the stock, but the trouble is that everybody's doing it, and in the end everybody's losing big-time. Same applies to static initializers. One or two may seem harmless, but they add up and together create a big problem. The fact that static initializers &lt;strike&gt;are&lt;/strike&gt; &lt;span class="Apple-style-span" style="font-style: italic;"&gt;(edit) &lt;/span&gt;may be invoked at program start-up affects everybody and since they potentially interfere with classloading, it's &lt;strike&gt;very hard&lt;/strike&gt; &lt;span class="Apple-style-span" style="font-style: italic;"&gt;(edit)&lt;/span&gt; harder to debug them if anything goes wrong.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Here is how it usually gets out of hand: people start with initializing static members in static blocks. Map of values, sort of configuration details. That alone sounds harmless. But soon comes the time when the values in a map need to be read from a properties file, so here we got IO within static block. Uh oh, better catch these exceptions. Before you notice the whole thing turns into a &lt;a href="http://www.javapuzzlers.com/"&gt;puzzler&lt;/a&gt;. Don't believe me? Here's a real problem I had.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Server in Java, client is either applet or JNLP. On certain machines, only one of them can run. You run server first - client never comes up, no error whatsoever. You reboot and connect as client to another machine - no problem. But if you try to start up the server locally - silent death. A team in India spends months on it. In vain. The whole release is detained, escalation to senior management. The thing ends up on my desk after a ruthless blame game between teams. Long story short: it's a DirectX problem. Why the **** does the server need DirectX? Ah. What's next after reading defaults from a properties file? Reading them from the database. Oh, but it's a different process, and the database needs to be up. So we not just connect to database from initialization block, we wait for the database process to be up. Great idea. How? We follow "best coding practices" and reuse: find a poller utility somewhere in the JDK. Apparently there is a java.awt.Timer. Why not? Great idea. Apparently, a touch of one AWT class causes a bunch of other AWT classes to load, which in turn loads DirectX and OpenGL dlls. And guess what - Windows on some machines has a &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4455041"&gt;nasty bug&lt;/a&gt;, that only allows to load them once per machine, regardless of the user. And when another user tries to do it - the loading gets stuck. And our server is of course a system process, while the client belongs to the logged in user. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Since it was a last minute fix, we solved it with some JVM flags that disabled DirectX and OpenGL. The problem was not the fix, but the diagnosis. If it was part of the regular code, it would have been easy to connect with a debugger, see what call gets stuck, investigate it from there. But as it was part of start-up, people didn't know where to look. Not to mention the man-months accumulatively spent by developers who waited for the server to restart when testing. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So... what's the lesson here? &lt;a href="http://gbracha.blogspot.com/2008/02/cutting-out-static.html"&gt;Life is better without static&lt;/a&gt;, avoid it as much as you can. &lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-7770655119220825201?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/7770655119220825201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=7770655119220825201' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/7770655119220825201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/7770655119220825201'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/12/case-against-static-initializers.html' title='A case against static initializers'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-2924176068609854422</id><published>2008-12-07T14:24:00.000+02:00</published><updated>2008-12-07T14:26:21.354+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Java... tea?</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_GnOWSH314CY/STvAv85f_PI/AAAAAAAAAPk/_tCWoOEpjAg/s1600-h/green_java_tea.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 252px; height: 320px;" src="http://4.bp.blogspot.com/_GnOWSH314CY/STvAv85f_PI/AAAAAAAAAPk/_tCWoOEpjAg/s320/green_java_tea.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5277023318428351730" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-2924176068609854422?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/2924176068609854422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=2924176068609854422' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/2924176068609854422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/2924176068609854422'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/12/java-tea.html' title='Java... tea?'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GnOWSH314CY/STvAv85f_PI/AAAAAAAAAPk/_tCWoOEpjAg/s72-c/green_java_tea.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-5348683779300971646</id><published>2008-12-07T12:40:00.011+02:00</published><updated>2008-12-07T16:37:35.853+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>No clone for you!</title><content type='html'>&lt;a href="http://www.javapractices.com/home/HomeAction.do"&gt;Java Practices&lt;/a&gt; call &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Cloneable.html"&gt;Cloneable&lt;/a&gt;/&lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Object.html#clone()"&gt;Object#clone&lt;/a&gt; API &lt;a href="http://www.javapractices.com/topic/TopicAction.do?Id=71"&gt;pathalogical&lt;/a&gt; and suggest to avoid it. I have to agree. Here's my little story. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have a method that receives a certain object, which is Cloneable. Now I want to actually clone that object, so I am calling the clone method. Makes sense, no? Apparently not. My slightly outdated version of IDEA was confused, just as I was, and did not complain. But Javac was cruel and uncompromizing. No clone for you. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://3.bp.blogspot.com/_GnOWSH314CY/STutwmUbshI/AAAAAAAAAPc/pnXj-fkHie4/s320/clone_nazi.jpg" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 280px; height: 280px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5277002438826242578" /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Because Cloneable does not require a clone() method, and Object#clone() can be protected. WTF? My objects subclass different not-necessarily-cloneable classes, so they can't have a common cloneable superclass. So I'll define my own ReallyCloneable interface that has a public clone method, sounds simple enough...? Not!&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;pre&gt;public interface ReallyCloneable extends Cloneable {&lt;br /&gt;    public Object clone() _&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Now I realize there's &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/CloneNotSupportedException.html"&gt;CloneNotSupportedException&lt;/a&gt; to throw. A checked exception. I have 2 options: be a good girl, adhere to best practices and clone the signature of Object#clone, or ... not. Let's explore both options. &lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;pre&gt;public interface ReallyCloneable extends Cloneable {&lt;br /&gt;    public Object clone() throws CloneNotSupportedException;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Now all my classes (let's assume they are simple enough to contain only primitives, Strings and arrays of the above) implement ReallyCloneable and add those 3 lines:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;pre&gt;public Object clone() throws CloneNotSupportedException {&lt;br /&gt;    return super.clone();&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;But whoever clones my objects also needs to add:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;pre&gt;try {&lt;br /&gt;    //call clone&lt;br /&gt;} catch (CloneNotSupportedException e)  {&lt;br /&gt;    //handle it... how???&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Because implementing Cloneable and all the rest means that JVM will not necessarity throw CloneNotSupportedException, but as far as Javac is concerned, it still may. So no matter what, the caller needs to prepare himself for the worst. Then why bother with interfaces and all that, I ask? People say Java is verbose. I don't mind verbose, but bloated with boiler-plate to this extent?! &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The other option is &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;not to declare the exception&lt;/span&gt; in ReallyCloneable. This is possible because &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.8.3"&gt;overriding rules&lt;/a&gt; &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#308526"&gt;do not require to throw the exceptions&lt;/a&gt; of the overridden method.&lt;/div&gt;&lt;div&gt;&lt;pre&gt;public Object clone() {&lt;br /&gt;  try {&lt;br /&gt;    return super.clone();&lt;br /&gt;  } catch (CloneNotSupportedException e) {&lt;br /&gt;    //hm...? &lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Even though JLS allows it, my IDE and static analysis tools will complain. So I have to either reconfigure them or add some "escape" annotations. More typing... By now I feel like a typomaniac. And wait, I should handle the exception - I don't want to swallow it. Besides, what if someone really objects to being cloned? There is a need for a runtime exception. &lt;/div&gt;&lt;div&gt;&lt;pre&gt;public class CloneFailedException extends RuntimeException {&lt;br /&gt;public CloneFailedException() {&lt;br /&gt;super();&lt;br /&gt;}&lt;br /&gt;  public CloneFailedException(CloneNotSupportedException e) {&lt;br /&gt;    super(e);&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;and&lt;/div&gt;&lt;div&gt;&lt;pre&gt;public Object clone() {&lt;br /&gt;  try {&lt;br /&gt;    return super.clone();&lt;br /&gt;  } catch (CloneNotSupportedException e) {&lt;br /&gt;    throw new CloneFailedException(e); &lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Now at least the callers don't have to catch. But they will still have to cast, because there is no way to express a self type with Java's static types system. Sigh.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And all this why? and for what? Couldn't we just have Cloneable with a public clone and a RuntimeException to throw if we didn't want to be cloned? Simple as that? &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is yet another example of static type system's failed attempt to protect us from ourselves. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Georgia;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-5348683779300971646?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/5348683779300971646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=5348683779300971646' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5348683779300971646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5348683779300971646'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/12/no-clone-for-you.html' title='No clone for you!'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GnOWSH314CY/STutwmUbshI/AAAAAAAAAPc/pnXj-fkHie4/s72-c/clone_nazi.jpg' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-60049155000909121</id><published>2008-11-29T17:15:00.002+02:00</published><updated>2008-12-07T14:19:32.841+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='newspeak'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Brains, bucks and programming languages</title><content type='html'>&lt;div style="text-align: right;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;The title is supposed to be a paraphrase of "sex, drugs and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;rock'n'roll&lt;/span&gt;" in a geeky context.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: right;"&gt;&lt;br /&gt;&lt;/div&gt;This autumn I went to see &lt;a href="http://sensualjava.blogspot.com/2008/10/two-days-in-life.html"&gt;Paul McCartney in concert&lt;/a&gt; - a lifetime dream come true. For most people Paul McCartney is first of all an ex-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Beatle&lt;/span&gt;. Indeed, during the concert he played many classic Beatles tunes to please the audience. And the audience was very pleased. Then, he cashed in the multi-million-dollar cheque and went back to England to do what he really likes - which at this point seems to be composing &lt;a href="http://www.thefiremanmusic.com/"&gt;experimental electronic music&lt;/a&gt;.  To me it looks pretty fair. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Recently I &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;listenned&lt;/span&gt;  to &lt;a href="http://www.infoq.com/presentations/gosling-jvm-lang-summit-keynote"&gt;James Gosling's keynote&lt;/a&gt; at the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;JVM&lt;/span&gt; Language Summit. I actually enjoyed the presentation very much. One of the things he said, was something like "My dream would be to implement &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Fortran&lt;/span&gt; over &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;JVM&lt;/span&gt; ... ah, but I have a day-job".  Now, not that JVM really needs a Fortran IMO. But think about it for a second. How many people in the world can design a programming language? How many of them can design a &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;good&lt;/span&gt; programming language? And a &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;popular&lt;/span&gt; one? Java is more popular than Beatles. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Uhm&lt;/span&gt;, well... even if it's not, you get the idea.  Now what can be more important for James Gosling to do during his day job than design a programming language of his choice, I should ask his employer? What? Throwing T-shirts at &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;JavaOne&lt;/span&gt; attendants? No, really. Why is it that James Gosling can't do anything he freaking likes for the rest of his life?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think something in our business is unfair. I am not saying Microsoft model is right, I am very pro open-source and free software and all that. But I'm confused - something about it isn't right. Large IT companies make loads of money, and waste a lot of it on complete crap - I've seen this from inside. So how come &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Gilad&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Bracha&lt;/span&gt; &lt;a href="http://gbracha.blogspot.com/2008/11/we-have-good-news-and-we-have-bad-news.html"&gt;cannot find funding&lt;/a&gt; for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;Newspeak&lt;/span&gt; development? This is totally surreal!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There goes another angry post.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-60049155000909121?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/60049155000909121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=60049155000909121' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/60049155000909121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/60049155000909121'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/11/brains-bucks-and-programming-languages.html' title='Brains, bucks and programming languages'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-4927018016902947703</id><published>2008-11-29T14:25:00.015+02:00</published><updated>2008-12-08T23:12:27.302+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='newspeak'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>DSL - fuel for life</title><content type='html'>Do you feel that your programming language is too bloated? I do, and I know I am &lt;a href="http://www.cs.bgu.ac.il/~gwiener/programming/is-java-heading-for-a-fall"&gt;not alone&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;div&gt;Let's take a look at Java. You may ask - what do you mean, when you say Java? Ah, good question. There is Java, the language, as described in &lt;a href="http://java.sun.com/docs/books/jls/"&gt;the spec&lt;/a&gt;. Java the Standard. Don't you wonder where's the new edition of the book, BTW? Anyway, then there's mini-edition, enterprise edition, real-time Java... there's a huge stack of official/certified technologies (e.g. all the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;JEE&lt;/span&gt; stuff - is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;JSP&lt;/span&gt; or &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;JSF&lt;/span&gt; Java? is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;JPQL&lt;/span&gt;?), for which there are often multiple vendors. That's not all, there are all the popular open-source frameworks that don't bother getting Sun's approval, and yet they possess lion-share of the market (e.g. Eclipse, Spring). There's no chance to even keep track of all this, forget mastering. And yet, I don't feel that I have all I need. I have all that, and yet I can't write a descent program the way I'd like to, because I am missing some core features. What? Let's see - how about proper &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;modularity&lt;/span&gt;, closures, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;tuples&lt;/span&gt;, local type inference, properties... &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Java made the grade in expanding layer by layer - to the extent where it reminds me the state of the Earth in &lt;a href="http://en.wikipedia.org/wiki/WALL-E"&gt;Wall-E&lt;/a&gt;. If you haven't seen the &lt;a href="http://www.imdb.com/title/tt0910970/"&gt;movie&lt;/a&gt;, I'll just say that the Earth drowned in human-produced garbage, and the garbage made it inhabitable for anything organic. The garbage in Java makes it impossible for the core, organic features of the language to grow. In the movie, people are leaving, and robots stay back to clean up - now you make the analogy. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;img src="http://1.bp.blogspot.com/_GnOWSH314CY/STFITgz_xqI/AAAAAAAAAOw/n0xlQGRqX0M/s320/Wall_e1_small.jpg" style="cursor:pointer; cursor:hand;width: 192px; height: 200px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5274076138690299554" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As a Java programmer I really identify with Wall-E. Moving tons of garbage around, day after day, in a desperate attempt to clean up the world - something obviously impossible. And man, I'd love to be that flying-&lt;a href="http://cultofmac.com/walle-and-apple-a-match-made-in-heaven/2178"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;iPod&lt;/span&gt;-looking&lt;/a&gt; Eve from outer space. She's so strong, so modern, so clean and shiny...  And she has a mission!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;img src="http://4.bp.blogspot.com/_GnOWSH314CY/STFImAuQB5I/AAAAAAAAAO4/w6JFPLDliOM/s320/eve_small.jpg" style="cursor:pointer; cursor:hand;width: 200px; height: 200px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5274076456493778834" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If Wall-E is my Java, then my Eve is no doubt &lt;a href="http://newspeaklanguage.org/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Newspeak&lt;/span&gt;&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what does it mean in a wider sense of programming languages? I think good language should have a small core, as little redundancy as possible. And it should grow from then on. Here's Guy Steel at &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;OOPSLA&lt;/span&gt; '98:&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;embed id="VideoPlayback" src="http://video.google.com/googleplayer.swf?docid=-8860158196198824415&amp;amp;hl=en&amp;amp;fs=true" style="width:400px;height:326px" allowfullscreen="true" allowscriptaccess="always" type="application/x-shockwave-flash"&gt;&lt;/embed&gt; &lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think that the best way of growing is via internal domain specific languages, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;DSLs&lt;/span&gt;, - you don't change the core language, yet you cover more and more domains. Anders &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;Hejlsberg&lt;/span&gt; also talked about it at the recent &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;PDC&lt;/span&gt; conference - adding features as a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;DSL&lt;/span&gt;; and then, if the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;DSL&lt;/span&gt; is very successful and popular, add syntactic sugar to the core language, as they did with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;LINQ&lt;/span&gt;. I don't think that you need that latter part if your language is well suited for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;DSLs&lt;/span&gt; to begin with. So the language should have a small core &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;and&lt;/span&gt; be well suited for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;DSLs&lt;/span&gt;. Java isn't DSL-friendly. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;Scala&lt;/span&gt; is much better, e.g. the Actors library. Haskell, Ruby and of course Smalltalk are really good at it. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The last part is getting rid of garbage as you grow, and again, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;Gilad&lt;/span&gt; has an &lt;a href="http://sensualjava.blogspot.com/2008/07/software-live-and-let-die.html"&gt;idea how to do that&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;I could go on forever and ever about &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;DSLs&lt;/span&gt;, showing examples like &lt;a href="http://gbracha.blogspot.com/2007/01/parser-combinators.html"&gt;parser &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;combinators&lt;/span&gt;&lt;/a&gt;, unit-test and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;SQL&lt;/span&gt; libraries and so on. Martin Fowler &lt;a href="http://martinfowler.com/dslwip/"&gt;is writing a book&lt;/a&gt;. So, instead of boring you with repeating what's been said many times, and enumerating lots of references, I will just finish with this cutest &lt;a href="http://courses.ece.ubc.ca/571f/index.html"&gt;quote&lt;/a&gt;:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src="http://courses.ece.ubc.ca/571f/pooh-logo.jpg" style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 144px; height: 147px;" border="0" alt="" /&gt;&lt;div&gt;&lt;span times="" new="" roman=""  style="font-family:Arial,;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;DSLs&lt;/span&gt; are for making languages bear-able.&lt;/span&gt;&lt;ul&gt; &lt;span times="" new="" roman=""  style="font-family:Arial,;"&gt;    &lt;em&gt;For I am a bear of very little brain and long words confuse me.&lt;/em&gt; [&lt;a href="http://en.wikipedia.org/wiki/Winnie-the-Pooh"&gt;Milne 1926&lt;/a&gt;] &lt;/span&gt;&lt;/ul&gt; &lt;p&gt; &lt;span times="" new="" roman=""  style="font-family:Arial,;"&gt;    The premise of this subject is that computers should adapt to the ways of people, and     not the other     way around.  &lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-4927018016902947703?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/4927018016902947703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=4927018016902947703' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4927018016902947703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4927018016902947703'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/11/dsl-fuel-for-life.html' title='DSL - fuel for life'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GnOWSH314CY/STFITgz_xqI/AAAAAAAAAOw/n0xlQGRqX0M/s72-c/Wall_e1_small.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-4617132893383639797</id><published>2008-10-23T01:42:00.004+02:00</published><updated>2008-10-23T16:14:37.443+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Types and other virtues</title><content type='html'>Here's a thought. Why do Java Generics attract so much bad vibes? If we're talking about types again, gotta visit our old friends - ML, Haskell. They are doing fine, they've got it all figured out. &lt;a href="http://en.wikipedia.org/wiki/Type_inference"&gt;Hindley-Milner&lt;/a&gt; etc., they've proved themselves to be right.&lt;br /&gt;&lt;br /&gt;But them and Java, it's apples and oranges. So to bring them to the same arena with object oriented languages, let's see how are they doing on the front of extensibility? Well, there are some recent advancements, &lt;a href="http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html#htoc41"&gt;polymorphic variants&lt;/a&gt; in OCaml, &lt;a href="http://www.haskell.org/haskellwiki/Extensible_record"&gt;extensible records&lt;/a&gt; in Haskell, but it's not like the other stuff they've figured out ages ago, there's a slight hint of hesitation here.&lt;br /&gt;&lt;br /&gt;So having types and being object oriented at the same time - maybe it's just, hm, non-trivial. If Martin Odersky &lt;a href="http://www.codecommit.com/blog/scala/is-scala-not-functional-enough#comment-4162"&gt;says it's hard&lt;/a&gt; for the compiler (and he's a genius!) - then it really must be. Now look at it as a reverse Turing test - if the machine can't figure it out, how the **** are we supposed to? Which means we need an escape route. If declaring the right type is hard, we need an easy way out.&lt;br /&gt;&lt;br /&gt;Pre-generics Java didn't bother itself too much with complex static types, the trick was to fall back on the dynamic types whenever in doubt: arrays - ArrayStoreException, collections - ClassCastException. Some say it's broken. It's a hole in a fence, but it's a way out . "Oops"&lt;br /&gt;&lt;br /&gt;Then Generics came and fixed the hole in the fence. But, without realizing, they violated the status-quo, the eco-system, they stepped on a butterfly. Suddenly, the brain hurts, and the only way out is dumping all the angle brackets and jumping over the fence. It's a "No Exit"!&lt;br /&gt;&lt;br /&gt;What does Scala do? Ah! First of all Scala has a much more advanced type system to start with. But the real trick is &lt;a href="http://www.scala-lang.org/node/130"&gt;implicit&lt;/a&gt;s. If it's too hard to declare the right type, just &lt;a href="http://rickyclarkson.blogspot.com/2008/01/trivial-display-of-how-scalas-type.html"&gt;imperatively describe the conversion&lt;/a&gt;. Done deal, here's your way out. It's pretty cool, but implicits have their share of bad vibes  too. Can't live with them, can't live without them, I guess.&lt;br /&gt;&lt;br /&gt;So how about implicits for Java 7? No, actually how about Scala for Java 7? It's been &lt;a href="http://sensualjava.blogspot.com/2007/12/past-forward.html"&gt;done before&lt;/a&gt;, you know...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-4617132893383639797?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/4617132893383639797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=4617132893383639797' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4617132893383639797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4617132893383639797'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/10/types-and-other-virtues.html' title='Types and other virtues'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-8165547736052577407</id><published>2008-10-05T23:53:00.007+02:00</published><updated>2008-10-06T02:13:29.490+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>The Great Divide</title><content type='html'>What hasn't been said about static vs. dynamic types in programming languages? Read on at your own risk, because here I &lt;a href="http://sensualjava.blogspot.com/2008/06/typsy-turvy.html"&gt;go again&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;When you think of static types what comes to mind? &lt;a href="http://haskell.org/"&gt;Haskell&lt;/a&gt;? &lt;a href="http://caml.inria.fr/ocaml/"&gt;OCaml&lt;/a&gt;? &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;? Dear friend, you are better than most of us, but you have clicked the wrong URL. Peace. See you in another post...&lt;br /&gt;&lt;br /&gt;Did you say Java? Still with me? Good. Listen, now when the others have gone, just between you and me, the guys from the previous paragraph - they're on to some good stuff. Check it out, you won't regret it. But don't quit your day job, not just yet. It's a bit complicated, but did you ever witness &lt;a href="http://www.extremeprogramming.org/"&gt;extreme programming&lt;/a&gt; methodology implemented in a big corporation? No? Then picture this: &lt;a href="http://en.wikipedia.org/wiki/Elbonia"&gt;Elbonians&lt;/a&gt; take over &lt;a href="http://www.dilbert.com/"&gt;Dilbert&lt;/a&gt;'s firm and make everybody do &lt;a href="http://www.extremeprogramming.org/"&gt;XP&lt;/a&gt;. They even send &lt;a href="http://en.wikipedia.org/wiki/Pointy-Haired_Boss"&gt;pointy-haired boss&lt;/a&gt; to a &lt;a href="http://www.scrumalliance.org/view/certification"&gt;Certified Scrum Master&lt;/a&gt; course. Get the outcome? It can only end like the implementation of &lt;a href="http://en.wikipedia.org/wiki/Carl_Marx"&gt;Carl Marx&lt;/a&gt;'s ideas &lt;a href="http://en.wikipedia.org/wiki/Kolhoz"&gt;in Russian countryside&lt;/a&gt;. I am trying to say - there are ideals, and there is reality. In reality, &lt;a href="http://pab-data.blogspot.com/2008/05/haskell-academia-goes-bowling.html"&gt;Haskell programs have bugs too&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So Java, you say. How do you feel about dynamic types? Cool? Get out of here. No really, it's no fun preaching to the converted.  See you!&lt;br /&gt;&lt;br /&gt;Oh no, heaven forbid, you won't touch them with a stick. You're my guy then.  So let's rewind to Java 1.4 days, after all many Java developers still use 1.4 and many others look back at it with nostalgia. Are you one of them? Ok. So what about pre-generics collections, do you think they are statically typed? Hmmm... And what percentage of your code involves collections? So this code was not entirely statically checked. Now add all the reflection stuff...&lt;br /&gt;&lt;br /&gt;But then of course came Generics. And suddenly Java is much more complex. How do I make my code compile, gee, wildcards, captures... ?! I am trying to get something done, hello!... It's easy of course to blame Generics implementation, but if we learn something from the folks whom I kindly asked to leave in the beginning, they'll tell you that finding correct static type for every element in your program is hard. They of course think that hard is good, they are noble men with ideals, they like overcoming challenges. But you and I, we're just trying to make a living. So we curse Sun and back off to an untyped collection. Hm, maybe we're just doing the right thing? Maybe sometimes we just know that our program is correct, but the compiler demands more and more typing and wastes our time?&lt;br /&gt;&lt;br /&gt;Java 5 was all about improving type-checking. If pre-defined types were not enough, annotations came handy. Define your own and test it at compile-time or at run-time.  Did it ever happen to you that there were so many annotations, that you couldn't see the code?&lt;br /&gt;&lt;br /&gt;See, more types is not always a good thing. Unless you're very keen on intellectual challenges. James Gosling said this about Scala - functional programs will make your brain hurt, they are for calculus lovers. He's right. It's the kind of pain you feel in your muscles when you start working out, you know, that indicates they are still alive... So working out is good, but we can't afford doing it all day, ha?&lt;br /&gt;&lt;br /&gt;Maybe the appeal of plain old Java was that it's a combination of static and dynamic checks? So it's not that all dynamic is evil, maybe it's a matter of how much and where?&lt;br /&gt;&lt;br /&gt;Give dynamic types a break. Who knows, you may find eventually that they're good for some things.&lt;br /&gt;&lt;br /&gt;Peace.&lt;br /&gt;&lt;br /&gt;P.S. I've done some role playing here, just for the record. I do love Generics, even though they were hard to master. Annotations are overall very useful. Right now I don't do as much Java as I used to, and I do other fascinating languages (static and dynamic) as I, for long time, wanted to.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-8165547736052577407?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/8165547736052577407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=8165547736052577407' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/8165547736052577407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/8165547736052577407'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/10/great-divide.html' title='The Great Divide'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-6860390120029251856</id><published>2008-10-01T01:43:00.008+03:00</published><updated>2008-10-01T10:25:54.438+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='beatles'/><title type='text'>Two Days In A Life</title><content type='html'>&lt;div dir="ltr"&gt;The ban that Israel's government has put on The Beatles performance in the 60s disappointed not only Israelis, but many Jewish people who were part of The Beatles phenomena, like their legendary manager Brian Epstein. Over four decades later, Paul McCartney represented the Fab Four on stage in Park HaYarkon, Tel Aviv, and rocked the audience with a great show.&lt;br /&gt;&lt;br /&gt;&lt;div style="display: block; text-align: center; margin-right: auto; margin-left: auto;"&gt;&lt;a href="http://paulmccartney.com/scripts/imageFetch.php?src=44a58cca19cda60734cbc5abcdb3e6b9.jpg&amp;amp;w=470&amp;amp;h=264&amp;amp;sizing=crop" imageanchor="1"&gt;&lt;img src="http://paulmccartney.com/scripts/imageFetch.php?src=44a58cca19cda60734cbc5abcdb3e6b9.jpg&amp;amp;w=470&amp;amp;h=264&amp;amp;sizing=crop" border="0" height="235" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Negotiations for the concert have been tough, but after a series of rumors and denials the deal was finally set. Ticket offices were stormed on opening, 50,000 tickets were sold eventually, filling the park with fans and music lovers.&lt;br /&gt;&lt;br /&gt;Read more in this &lt;a href="http://sites.google.com/site/maccatelaviv/"&gt;illustrated account of Paul McCartney's visit to the Holy Land&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-6860390120029251856?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/6860390120029251856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=6860390120029251856' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6860390120029251856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6860390120029251856'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/10/two-days-in-life.html' title='Two Days In A Life'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-8739760553311641315</id><published>2008-09-30T23:21:00.006+03:00</published><updated>2008-10-01T01:36:16.638+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Beware of the subs</title><content type='html'>No, I don't mean these cute &lt;a href="http://www.beatles.com/core/music/yellowsubmarine/"&gt;yellow things beneath the waves&lt;/a&gt;. I am going to talk about &lt;a style="font-family: courier new;" href="http://java.sun.com/javase/6/docs/api/java/util/List.html#subList%28int,%20int%29"&gt;List#subList&lt;/a&gt; and &lt;a style="font-family: courier new;" href="http://java.sun.com/javase/6/docs/api/java/lang/String.html#substring%28int,%20int%29"&gt;String#substring&lt;/a&gt; methods in Java.&lt;br /&gt;&lt;br /&gt;Apparently many people are unaware of what exactly these methods do. Unfortunately their ignorance may lead to unpleasant consequences. So getting straight to the point: both methods &lt;span style="font-weight: bold;"&gt;do not &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;copy&lt;/span&gt; a portion of the original data, instead they create a &lt;span style="font-weight: bold;"&gt;view&lt;/span&gt;, or, in other words, a proxy to it. The important thing is that the new wrapper object holds a &lt;span style="font-weight: bold;"&gt;strong reference to the original object&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The Javadoc of &lt;a style="font-family: courier new;" href="http://java.sun.com/javase/6/docs/api/java/util/List.html#subList%28int,%20int%29"&gt;subList&lt;/a&gt; at least admits that it's a view, as for &lt;a style="font-family: courier new;" href="http://java.sun.com/javase/6/docs/api/java/lang/String.html#substring%28int,%20int%29"&gt;substring&lt;/a&gt;, the only way to find out is by looking at the source - the method redirects to this constructor:&lt;br /&gt;&lt;pre name="code" class="java"&gt;//Package private constructor which shares value array for speed.&lt;br /&gt;String(int offset, int count, char value[]) {&lt;br /&gt;  this.value = value;&lt;br /&gt;  this.offset = offset;&lt;br /&gt;  this.count = count;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;So what's the problem? Let's look at the following snippet from a real code-base:&lt;br /&gt;&lt;pre name="code" class="java"&gt;List leaky = ...; //long list of big &amp;amp; hairy objects&lt;br /&gt;leaky = leaky.subList(from, to);&lt;br /&gt;&lt;/pre&gt;Assuming that &lt;span style="font-family:georgia;"&gt;leaky&lt;/span&gt; wasn't referenced anywhere else in the code, there is no way for the programmer to access the elements that lie beyond the (from,to) range. But these bytes aint going to rehab, no, no, no - as far as JVM is concerned they are still strongly referenced. So if you really mean to extract a portion of a list (or string), and throw the rest away - &lt;span style="font-weight: bold;"&gt;copy it manually&lt;/span&gt; to a new list (or string). For example:&lt;br /&gt;&lt;pre name="code" class="java"&gt;List sneaky = ...;&lt;br /&gt;sneaky = new ArrayList(sneaky.subList(from, to));&lt;br /&gt;&lt;/pre&gt;Is there any better way a "sub" could be implemented? Well, maybe the reference to the original data could be kept weak, and only when (if) the original object is enqueued for garbage collection then the data could be copied into the "view". This would require backwards references from "original" object to "views", which would also need to be weak, so... overall this doesn't seem worth the effort, and hence avoiding leaky lists and strings shall remain the responsibility of the programmer.&lt;br /&gt;&lt;br /&gt;Speaking of subList, another nasty thing about it is that sub-list is not Serializable, nor Cloneable or anything like that, even if the original list was. And speaking of leaky things that are caused by undercover strong references - never forget non-static inner classes that refer to their enclosing instance.&lt;br /&gt;&lt;br /&gt;Take care, and keep your head above the water :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-8739760553311641315?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/8739760553311641315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=8739760553311641315' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/8739760553311641315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/8739760553311641315'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/09/beware-of-subs.html' title='Beware of the subs'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-4556652108445301153</id><published>2008-07-04T23:27:00.016+03:00</published><updated>2008-12-07T14:19:45.108+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='newspeak'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Software: Live and Let Die</title><content type='html'>This week I was lucky to attend Gilad Bracha's &lt;a href="http://www.cs.huji.ac.il/site/?i=colloquium&amp;amp;lang=en"&gt;guest lecture on Networked Serviced Programming&lt;/a&gt; at the Hebrew University. He has been &lt;a href="http://video.google.com/videoplay?docid=-5886267052339478036"&gt;talking&lt;/a&gt; about &lt;a href="http://bracha.org/objectsAsSoftwareServices.pdf"&gt;Service Objects&lt;/a&gt; for some time now, but nothing compares to hearing it live - Gilad's &lt;a href="http://www.bracha.org/oopsla05-dls-talk.pdf"&gt;presentation&lt;/a&gt; was witty and fun!&lt;br /&gt;&lt;br /&gt;So here is my interpretation and some take-aways.&lt;br /&gt;&lt;br /&gt;What's the problem with software? It is &lt;span style="font-weight: bold;"&gt;too damn complex&lt;/span&gt;. Projects crumble under their own weight. It happens to successful projects - our dearly loved Java, for example. Also look at Vista, if you dare. And it's certainly true for the monster-size projects I used to work on. Once upon a time our team took the corporate "quality improvement" policy seriously and decided to investigate what causes bugs in our multi-million lines of code project. We collected all sorts of statistics and ran all possible metrics (which was tricky 'cause some of the tools would choke on such a huge code-base) but long story short our finding was this: &lt;b&gt;the only&lt;/b&gt; metric that correlated clearly with defectiveness was LoC. It is &lt;a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html"&gt;hardly news&lt;/a&gt;, but a cure to the disease has yet to be found.&lt;br /&gt;&lt;br /&gt;There are certainly several things to be done, but what this talk focused on is getting rid of code which shouldn't be there, or in other words - dumping unused code and backwards compatibility. The way we work today - we are bound to not just specs and APIs, but to all the accidental behaviors and bugs in the previous version of our code. It seems that Gilad views code as if it was a live organism. Staying alive means being connected (and network plays a central role in his vision), but we should make way for evolution and some code should die - Gilad calls it "bit rot".&lt;br /&gt;&lt;br /&gt;So how do we turn software into a healthy living organism? According to Gilad, there are several things to be done on the technical front first.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Take advantage of the network&lt;/span&gt;: maintain a bi-directional connection with the control center - let programs pull upgrades from the net, but also send back operation statistics. This means that programming platform has to be aware of the network, and aware of the &lt;a href="http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing"&gt;fallacies of distributed computing&lt;/a&gt;. This is cloud computing utopia: Internet as a platform, browser as an OS, and &lt;a href="http://gbracha.blogspot.com/2008/04/everyone-is-talking-about-cloud.html"&gt;Javascript as the low-level programming language&lt;/a&gt; into which other languages can compile (&lt;span&gt;in a &lt;a href="http://code.google.com/webtoolkit/"&gt;GWT&lt;/a&gt; kind a way&lt;/span&gt;).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Modularity: &lt;/span&gt;it should be possible to extend and replace individual objects without interference to the whole organism. Gilad has a &lt;a href="http://www.bracha.org/jigsaw.ps"&gt;well developed theory&lt;/a&gt; about how modularity should be done in a programming language, based on principles of object-orientation using &lt;a href="http://www.bracha.org/oopsla90.ps"&gt;mix-ins&lt;/a&gt;, &lt;a href="http://dyla2007.unibe.ch/?download=dyla07-Gilad.pdf"&gt;nested classes&lt;/a&gt; and &lt;a href="http://portal.acm.org/citation.cfm?id=141936.141940"&gt;inheritance hierarchies&lt;/a&gt;; his new language, &lt;a href="http://www.bracha.org/Site/Newspeak.html"&gt;Newspeak&lt;/a&gt;, is going to implement it. &lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Explicit Dependencies &lt;/span&gt;between modules&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;- &lt;a href="http://gbracha.blogspot.com/2008/02/cutting-out-static.html"&gt;no static&lt;/a&gt;, no imports, modules are truely independent and dependency management (wiring) is performed by passing other module instances as parameters to module constructors. This allows to maintain clear boundaries between modules and flexibility in module composition.&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Frequent Updates: &lt;/span&gt;to allow the "clients" of the object APIs to deal with  changes, in addition to maintaining modularity, the changes should be made small and frequent. Call it agility, if you like. That means that we can't afford reboots, and we need to find out when the system is quiescent so that upgrade can be performed, which brings us to the next point...&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Reflection and Hot-swapping&lt;/span&gt;: objects should allow other objects to find out both static and run-time information about them without breaking the encapsulation. Objects should also allow other objects to modify them "live". Gilad and &lt;a href="http://news.squeak.org/2007/01/29/taking-the-beat-of-cadence/"&gt;his team at Cadence&lt;/a&gt; are building  the support for these features in Newspeak using &lt;a href="http://www.bracha.org/mirrors.pdf"&gt;Mirrors&lt;/a&gt;, a concept that originates in &lt;a href="http://research.sun.com/self/language.html"&gt;Self &lt;/a&gt;programming language. It's worth noting that there exist dynamically typed languages that implement hot-swapping today - &lt;a href="http://www.erlang.org/"&gt;Erlang&lt;/a&gt; being one of them. &lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Security &lt;/span&gt;is important in any distributed system, and even more so if we allow remote objects  to mess with the program. So in addition to dynamic typing and pointer safety, Gilad proposes mirrors to be guarded by &lt;a href="http://en.wikipedia.org/wiki/Capability-based_security"&gt;capability-based security&lt;/a&gt;, similar to the one in &lt;a href="http://erights.org/"&gt;E&lt;/a&gt; programming language.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Synchronization: &lt;/span&gt;many programs need to work with persistent data and it is important to keep the program and the data in-sync. Gilad proposes orthogonal synchronization, based on Smalltalk &lt;a href="http://en.wikipedia.org/wiki/System_Image"&gt;orthogonal persistence&lt;/a&gt; idea, where objects are split into transient and persistent ones by marking object tree roots accordingly. Persistent objects are upgraded whenever the corresponding part of the program is upgraded, and transient objects are  lazily recomputed. If the data is ever to outlive the service, it would be exported into some generic format, such as XML.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The most extreme and bold part of this vision is probably &lt;span style="font-weight: bold;"&gt;No Versions&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;No Releases&lt;/span&gt; - there would be only one version for every program out there. Gilad sees software becoming more of a service than a product, but in order for this to realize we'll have to overcome not just technological, but also psychological and economical barriers - we will have to change the way we develop software and the way we make money of it.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Bottom line, all this may sound too futuristic, but "&lt;a href="http://www.infoq.com/SaaS"&gt;software as a service&lt;/a&gt;" and "&lt;a href="http://www.salesforce.com/platform/"&gt;platform as a service&lt;/a&gt;" are making their way in the industry and this wave, if strong and successful enough,  may bring the significant change Gilad is predicting.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;P.S. As for the rest of us, living in the JVM world, some of the ideas ring a bell. We hope that modularity JSRs and OSGi will improve Java. Those of us who survived Ant and Maven, and felt the weight of a DI framework, will probably appreciate the amount attention Gilad is putting into software composition. It's worth noting the attempts to address hot-swapping on JVM, such as &lt;/span&gt;&lt;a style="font-style: italic;" href="http://www.zeroturnaround.com/javarebel/"&gt;JavaRebel&lt;/a&gt;&lt;span style="font-style: italic;"&gt; and &lt;/span&gt;&lt;a style="font-style: italic;" href="http://jonasboner.com/2008/06/16/erlang-style-supervisor-module-for-scala-actors/"&gt;Jonas Boner's experiments with Scala Actors and Terracotta&lt;/a&gt;&lt;span style="font-style: italic;"&gt;. &lt;/span&gt;&lt;a style="font-style: italic;" href="http://www.aosd.net/2007/program/industry/I1-ClusteringJVMUsingAOP.pdf"&gt;Terracotta server&lt;/a&gt;&lt;span style="font-style: italic;"&gt; also utilizes some ideas which (in my mind at least) look quite similar to the orthogonal synchronization scheme. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-4556652108445301153?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/4556652108445301153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=4556652108445301153' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4556652108445301153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4556652108445301153'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/07/software-live-and-let-die.html' title='Software: Live and Let Die'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-6312687797716091978</id><published>2008-06-25T15:25:00.002+03:00</published><updated>2008-12-09T08:45:27.069+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>JunkedIn</title><content type='html'>Indeed &lt;a href="http://developers.sun.com/learning/javaoneonline/j1sessn.jsp?sessn=TS-5234&amp;amp;yr=2008&amp;amp;track="&gt;LinkedIn runs on Java&lt;/a&gt;, no doubt about it:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_GnOWSH314CY/SGI5uj7-XHI/AAAAAAAAALI/I0P0cmzytN0/s1600-h/JunkedIn.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_GnOWSH314CY/SGI5uj7-XHI/AAAAAAAAALI/I0P0cmzytN0/s320/JunkedIn.JPG" alt="" id="BLOGGER_PHOTO_ID_5215794790532013170" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-6312687797716091978?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/6312687797716091978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=6312687797716091978' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6312687797716091978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6312687797716091978'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/06/junkedin.html' title='JunkedIn'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GnOWSH314CY/SGI5uj7-XHI/AAAAAAAAALI/I0P0cmzytN0/s72-c/JunkedIn.JPG' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-474858055085422067</id><published>2008-06-17T14:37:00.004+03:00</published><updated>2008-12-09T08:45:27.254+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Noble cause</title><content type='html'>&lt;a href="http://jduchess.org/"&gt;Duchess&lt;/a&gt; is an on-line community of female Java developers with members from all over the world, but currently active mainly in the Netherlands. I figured they could use some promotion, besides it's a perfect excuse to put this cute mascot on my blog:&lt;br /&gt;&lt;br /&gt;  &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://jduchess.org/"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_GnOWSH314CY/SFem0Y8A21I/AAAAAAAAALA/uwfSjO1ATP4/s320/javaduchess.png" alt="" id="BLOGGER_PHOTO_ID_5212818512682212178" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-474858055085422067?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/474858055085422067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=474858055085422067' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/474858055085422067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/474858055085422067'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/06/noble-cause.html' title='Noble cause'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GnOWSH314CY/SFem0Y8A21I/AAAAAAAAALA/uwfSjO1ATP4/s72-c/javaduchess.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-75974013656521810</id><published>2008-06-05T23:30:00.007+03:00</published><updated>2008-12-09T08:45:27.841+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Typesy Turvy</title><content type='html'>&lt;a href="http://lambda-the-ultimate.org/"&gt;Lambda The Ultimate&lt;/a&gt; feed just notified me that &lt;a href="http://lambda-the-ultimate.org/node/2828"&gt;types are considered harmful&lt;/a&gt;. Ah yes, I heard this before, so what's the news? The news is that it's not &lt;a href="http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html"&gt;Stevey&lt;/a&gt; vs. &lt;a href="http://beust.com/weblog/archives/000483.html"&gt;Cedric&lt;/a&gt; or anything like that, this is &lt;a href="http://www.cis.upenn.edu/%7Ebcpierce/"&gt;Benjamin C. Pierce&lt;/a&gt; in his own write.  Benjamin C. Pierce, from "&lt;a href="http://books.google.com/books?id=ti6zoAC9Ph8C"&gt;Types  and Programming Languages&lt;/a&gt;" and "&lt;a href="http://books.google.com/books?id=A5ic1MPTvVsC"&gt;Advanced Types and Programming Languages&lt;/a&gt;", King of ML, Lord of the Functional Programming Commonwealth, Defender of Type Systems Faith!&lt;br /&gt;&lt;br /&gt;Nice &lt;a href="http://www.cis.upenn.edu/%7Ebcpierce/papers/harmful-mfps.pdf"&gt;presentation&lt;/a&gt;, BTW. I think it's one of these situations when a big shot computer scientist is confronted with a real life problem. So you say the language is perfect for writing a compiler - good for you. How about a database application with a web front-end?&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.hazelcast.com/brave-developer.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_GnOWSH314CY/SEhUJk2TzBI/AAAAAAAAAKg/jSRHBceQEQs/s320/brave-developer.jpg" alt="" id="BLOGGER_PHOTO_ID_5208505492541000722" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;(&lt;a href="http://www.hazelcast.com/brave-developer.jpg"&gt;click to see full-size&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Mr. Language Designer, where are you in this picture?  Yes you, who designed the mousetrap which "the bug" has safely escaped from. Now it is here, so are you at least by the developer side, handing him something heavy to throw at "the bug", or are you on the bed with the rest of the crowd going "ah ah ah, what do they teach computer science graduates these days..."?&lt;br /&gt;&lt;br /&gt;One thing that impressed me during otherwise boring (let me just read you aloud the tutorial) JRuby on Rails preso I &lt;a href="http://il.sun.com/sunnews/events/2008/javaday/agenda.jsp"&gt;recently attended&lt;/a&gt; - here is a system that tries to serve the needs of the developer. Not server vendor, not language designer, not JSR politician, not some brandthirsty marketing person or buzz-oriented architect, THE DEVELOPER. I am not used to that. So all I have to say - programmers of the world, unite! Stand for your rights! We deserve better tools, because we are the ones getting the job done.&lt;br /&gt;&lt;br /&gt;Thank you for reading.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-75974013656521810?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/75974013656521810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=75974013656521810' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/75974013656521810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/75974013656521810'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/06/typsy-turvy.html' title='Typesy Turvy'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GnOWSH314CY/SEhUJk2TzBI/AAAAAAAAAKg/jSRHBceQEQs/s72-c/brave-developer.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-8710582427718094090</id><published>2008-05-15T19:17:00.004+03:00</published><updated>2008-05-15T21:58:44.226+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>In whining there is truth?</title><content type='html'>What do Java developers want? Hard to say. But here is what Java bloggers &lt;span style="font-weight: bold;"&gt;don't&lt;/span&gt; want Sun to do:&lt;br /&gt;No evolving Java syntax - no properties, no closures, etc. - fix what is already there first.&lt;br /&gt;No extending Java capabilities via annotations.&lt;br /&gt;No investing in a new JVM language (JavaFX, or JRuby in the past)&lt;br /&gt;Ok, maybe add Groovy, but don't change JVM spec.&lt;br /&gt;Hey, wait, why are key people leaving Sun? We didn't want that either!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-8710582427718094090?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/8710582427718094090/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=8710582427718094090' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/8710582427718094090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/8710582427718094090'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/05/in-whining-there-is-truth.html' title='In whining there is truth?'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-4372882089057800086</id><published>2008-05-13T15:20:00.016+03:00</published><updated>2008-12-09T11:56:05.713+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Girl Power</title><content type='html'>I have been reading recently that women are abandoning computer science, and that percentage of women in our profession is not just low, but getting lower. I'm not sure actually that the situation here is as bad as in North America, but it's certainly true that software engineering and computer science are not very popular among women. Why? To be honest, I don't have the answer.&lt;br /&gt;&lt;br /&gt;Here is what comes to mind:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Geek-ness is viewed in the society as the opposite of being attractive; this is much more important for young women, than for men. For a guy - a nice high-tech salary will provide the attraction instead.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sitting in a cube by the computer all day and doing one thing, coding, is probably not very attractive for most people, but for women especially, since most of us are better at performing a variety of tasks and interacting with people - I mean there has to be an explanation why "secretary" or "teacher" are such typical women professions.&lt;/li&gt;&lt;li&gt;Hi-tech jobs are very demanding, too demanding. For most women family life is at least as important as professional life, and usually family comes first. But there just aren't many positions you can find after getting computer science degree that allow you easily balance work and family life.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Hi-tech is for young people - look around, how many programmers you know are over 45? Why? For the same reason you don't see many women - it's hard to compete with the smart kids when you are pregnant, or haven't slept for a week, or worried about some family matter.&lt;/li&gt;&lt;li&gt;But can't we just switch roles with the husband? well, go back to first bullet, double standards of the society certainly don't make it easier on us or our partners.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;People we are surrounded with (nerdy young men mostly) are pretty anti-social creatures in the first place, even more so with species of the other sex, even more so with the ones that don't fit social stereotype.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Now suppose you survived all the obstacles, because you passionately love science and engineering. Did you watch &lt;a href="http://www.youtube.com/watch?v=CmYDgncMhXw"&gt;the knack&lt;/a&gt;? There's a grain of truth there... society became less tolerant of weirdness, and people who 100 years ago may have been referred to as crazy geniuses nowadays live "normal life" on prescribed medications. And for a girl it's even stranger to be a crazy genius then for a boy.&lt;/li&gt;&lt;li&gt;Male domination in the field - yes, it's chicken and egg problem. The field will change only if there will be enough women in it to drive the change from within and help other women. So I will devote the rest of the post to the ones who made it.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Lady Ada (Byron) Lovelace&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://en.wikipedia.org/wiki/Ada_Lovelace"&gt;&lt;img style="margin: 0px auto 10px; text-align: center; cursor: pointer;" src="http://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Ada_Lovelace_1838.jpg/225px-Ada_Lovelace_1838.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;She was more of a technical writer really, but she was a visionary.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Admiral Grace Hopper&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://en.wikipedia.org/wiki/Grace_Hopper"&gt;&lt;img style="margin: 0px auto 10px; text-align: center; cursor: pointer;" src="http://upload.wikimedia.org/wikipedia/commons/thumb/5/55/Grace_Hopper.jpg/200px-Grace_Hopper.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The inventor of COBOL and debugging.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Professor Barbara Liskov&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://en.wikipedia.org/wiki/Barbara_Liskov"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; text-align: center; cursor: pointer; width: 160px;" src="http://www.pmg.lcs.mit.edu/~liskov/images/LISKOV_crop2.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The one from the substitution principle. I chose her among several prominent computer scientist women because she was the &lt;span style="font-weight: bold;"&gt;first &lt;/span&gt;female computer science Ph.D in the US.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;SVP Jayshree Ullal&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.networkworld.com/power/2005/122605-ullal.html"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_GnOWSH314CY/SD3DN4l6L9I/AAAAAAAAAKY/oXg5jBRdqBA/s320/ullal-jayshree.jpg" alt="" id="BLOGGER_PHOTO_ID_5205531387607265234" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I originally thought to put the &lt;a href="http://www.sanfranmag.com/story/adventures-marissa"&gt;Google princess&lt;/a&gt; here, but having personally met Jayshree (she was my manager's manager's manager at one point) and impressed by her personality and professionalism (she is so clever, and yet such nice and humble person), I decided she's a better candidate to represent successful women in computer industry.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Alice, &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Dilbert's &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;workaholic colleague&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.hpcnet.org/sdsmt/SiteID=199997"&gt;&lt;img style="cursor: pointer;" src="http://www.hpcnet.org/upload/providers/168823_001127140329.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;What did she achieve exactly? Surviving in the office should not be underestimated! So I am going to honor another ex-colleague, although we never met, for providing inspiration for a character I can identify with :-)&lt;br /&gt;&lt;br /&gt;Keep coding girls!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-4372882089057800086?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/4372882089057800086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=4372882089057800086' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4372882089057800086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4372882089057800086'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/05/girl-power.html' title='Girl Power'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GnOWSH314CY/SD3DN4l6L9I/AAAAAAAAAKY/oXg5jBRdqBA/s72-c/ullal-jayshree.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-2705923703728337066</id><published>2008-05-13T11:56:00.006+03:00</published><updated>2008-12-09T08:45:28.335+02:00</updated><title type='text'>Net, Goddess of Wisdom</title><content type='html'>No, it's not a joke or some kind of wordplay.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/commons/thumb/c/c2/Neith.svg/180px-Neith.svg.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; text-align: left; cursor: pointer;" src="http://upload.wikimedia.org/wikipedia/commons/thumb/c/c2/Neith.svg/180px-Neith.svg.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Net (also &lt;a href="http://en.wikipedia.org/wiki/Neith"&gt;Neith&lt;/a&gt;) was an ancient Egyptian goddess, not very well known perhaps, unlike her Hellenistic reincarnation - &lt;a href="http://en.wikipedia.org/wiki/Athena"&gt;Athena&lt;/a&gt;. Net was a warrior goddess, just like Athena, and the goddess of weaving - "weaver" is actually the translation of her name.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_GnOWSH314CY/SClfY5hQu7I/AAAAAAAAAKQ/1qA78XmBun4/s1600-h/Athena_scaled.jpg"&gt;&lt;img style="margin: 0pt 0px 10px 10px; float: right; cursor: pointer;" src="http://3.bp.blogspot.com/_GnOWSH314CY/SClfY5hQu7I/AAAAAAAAAKQ/1qA78XmBun4/s320/Athena_scaled.jpg" alt="" id="BLOGGER_PHOTO_ID_5199792126137777074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Athena was a weaver too, according to the &lt;a href="http://en.wikipedia.org/wiki/Arachne"&gt;Arachne&lt;/a&gt; myth, and of course the goddess of wisdom.&lt;br /&gt;&lt;br /&gt;So why weaving, or net, and wisdom? Well, for several reasons. What our ancient ancestors have probably recognized is that wisdom is acquired via communication. Today we know in addition that human thinking is powered by &lt;a href="http://en.wikipedia.org/wiki/Neural_net"&gt;neural net&lt;/a&gt; in our brains. Net, yes net. We even use the same word. Inter&lt;span style="font-weight: bold;"&gt;net&lt;/span&gt;, collective intelligence... "there's nothing new under the sun" said another wise ancient man.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-2705923703728337066?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/2705923703728337066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=2705923703728337066' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/2705923703728337066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/2705923703728337066'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/05/net-goddess-of-wisdom.html' title='Net, Goddess of Wisdom'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GnOWSH314CY/SClfY5hQu7I/AAAAAAAAAKQ/1qA78XmBun4/s72-c/Athena_scaled.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-6664810038250513426</id><published>2008-04-30T16:29:00.003+03:00</published><updated>2008-05-01T11:03:51.350+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Synthetic bridge method annotations</title><content type='html'>Update regarding "&lt;a href="http://sensualjava.blogspot.com/2007/11/walls-and-bridges.html"&gt;walls and bridges&lt;/a&gt;": Sun has kindly opened an &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6695379"&gt;enhancement request&lt;/a&gt; on my behalf for the issue. Please vote if you are affected by it too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-6664810038250513426?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/6664810038250513426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=6664810038250513426' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6664810038250513426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6664810038250513426'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/04/synthetic-bridge-method-annotations.html' title='Synthetic bridge method annotations'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-7106444017730560146</id><published>2008-04-28T10:50:00.003+03:00</published><updated>2008-04-28T12:04:33.769+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='properties'/><title type='text'>Java properties links</title><content type='html'>Since I am trying to keep up to date with what's going on in "Java Properties" land, I started with &lt;a href="http://tech.puredanger.com/java7#property"&gt;Alex Miller's collection&lt;/a&gt; and have been adding things that I find either relevant or influential. Another idea I nicked from Alex was &lt;a href="http://javaproperties.tumblr.com/"&gt;to put them on Tumblog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A disclaimer: this is a personal collection, so if something looks irrelevant, it means that &lt;span style="font-weight: bold;"&gt;I think&lt;/span&gt; it is influential :-)&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;I'll be more than glad to hear suggestions for &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;more links or feeds.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-7106444017730560146?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/7106444017730560146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=7106444017730560146' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/7106444017730560146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/7106444017730560146'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/04/java-properties-links.html' title='Java properties links'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-5251959572849674315</id><published>2008-04-27T22:19:00.003+03:00</published><updated>2008-04-28T01:44:26.112+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>My OO My</title><content type='html'>No, I don't mean &lt;a href="http://en.wikipedia.org/wiki/My_Oh_My"&gt;the song&lt;/a&gt;, but it's to do with Scandinavia. &lt;a href="http://channel9.msdn.com/Showpost.aspx?postid=351659"&gt;Mads Torgersen mentioned this during interview with Joe Armstrong&lt;/a&gt; (highly recommended, there is also a &lt;a href="http://channel9.msdn.com/Showpost.aspx?postid=352136"&gt;part II&lt;/a&gt;), and later I saw another reference in a paper: apparently there is "&lt;a href="http://www.create.ucsb.edu/%7Exavier/Thesis/html/node20.html"&gt;Scandinavian school of object orientation&lt;/a&gt;", sometimes compared to "American school".&lt;br /&gt;&lt;br /&gt;Here are &lt;a href="http://ootips.org/history.html"&gt;some insights on the difference&lt;/a&gt; between the two. The point is that the former is about concepts and philosophy, and the latter is about pragmatic aspects like software reuse and organization. I am not gonna pretend that I'm smart - all I know about it comes from searching Google, so you can go &lt;a href="http://www.google.com/search?q=scandinavian+school+object+orientation"&gt;there&lt;/a&gt; and find out for yourself.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;* On a side note, since I am linking to MSDN here,  I want to say that even though my last post wasn't very favorable to Microsoft, to be fair - the company plays an important role in renaissance and democratization of functional programming (&lt;a href="http://msdn2.microsoft.com/en-us/vbasic/aa904594.aspx"&gt;LINQ&lt;/a&gt;, &lt;a href="http://research.microsoft.com/fsharp/fsharp.aspx"&gt;F#&lt;/a&gt;, &lt;a href="http://www.langnetsymposium.com/talks.asp"&gt;etc.&lt;/a&gt;), with guys like &lt;a href="http://blogs.msdn.com/madst/"&gt;Mads Torgersen&lt;/a&gt; and &lt;a href="http://research.microsoft.com/%7Eemeijer/"&gt;Erik Meijer&lt;/a&gt; largely responsible.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-5251959572849674315?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/5251959572849674315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=5251959572849674315' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5251959572849674315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5251959572849674315'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/04/my-oo-my.html' title='My OO My'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-6904363712705999830</id><published>2008-04-27T16:56:00.010+03:00</published><updated>2008-04-27T20:24:17.394+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Open the source, sesame</title><content type='html'>About a month ago a big shot from Microsoft &lt;a href="http://www.cs.huji.ac.il/%7Ecollo/Apr-02-08.html"&gt;came to speak&lt;/a&gt; at the university - looks like he's on some kind of a tour, and his mission is to convince universities to teach Windows operating system aside Unix/Linux. He waved at the audience with a free license  and tried very hard to prove that some aspects of Windows design are better than Unix, mainly because it is "newer" design and better suited for nowadays computers.&lt;br /&gt;&lt;br /&gt;Long story short, one of the things he said, was that &lt;span style="font-weight: bold;"&gt;open source is bad&lt;/span&gt;, because engineer who looks at the source of a library will design his application assuming particular implementation, which is now tightly coupled to library internals - bad. Obviously a discussion erupted - design by contract and Eiffel were thrown in the air, relation between programming language and operating systems..., but frankly all I could think of is my distant past as a VB developer and those 1000 pages "Windows *** Unleashed" books. They were written by hackers who used trial-and-error against Windows DLLs trying to make some sense of the APIs - the formal documentation was either sloppy or intentionally incorrect to misguide us, Windows application creators outside Microsoft, since we were potential competitors. Things were so different when I moved to Java. (Though my first Swing experience made me - believe it or not - miss VB, but that's another story.)&lt;br /&gt;&lt;br /&gt;Anyway, statement like this coming out of the mouth of a Microsoft employee, even if he has an impressive Unix record, was easy for me to dismiss. But here is a &lt;a href="http://www.infoq.com/interviews/dave-thomas-programming-languages-soa-and-the-web"&gt;respected Smalltalker saying&lt;/a&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;"I think people should have the source ...not to get miss quoted saying I'm against open source, but I think it's important class libraries should be viewed like caves."&lt;/blockquote&gt;(Ah, wait, he is from IBM - he can be ignored too... just kidding)&lt;br /&gt;&lt;br /&gt;I mean, seriously look at &lt;a href="http://www.jroller.com/eu/entry/a_hash_set_puzzler"&gt;this puzzler&lt;/a&gt; for example - it's pretty cool, but the solution heavily relies on a particular implementation, I would even say this is actually a hack. And sometimes a hack is necessary... or is it? Is there or will there ever be a perfect environment where we can program without hacking?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;P.S. The reference to &lt;/span&gt;&lt;a style="font-style: italic;" href="http://en.wikipedia.org/wiki/Ali_Baba"&gt;Ali Baba&lt;/a&gt;&lt;span style="font-style: italic;"&gt; tale in the title is intentional. Open source is good, very good, it's a treasure and in the world dominated by large corporations - almost a miracle. But IMO we should resist the temptation to exploit it to the last bit, because we might find ourselves locked in the cave.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-6904363712705999830?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/6904363712705999830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=6904363712705999830' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6904363712705999830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6904363712705999830'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/04/open-source-sesame.html' title='Open the source, sesame'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-5264503455558567262</id><published>2008-04-27T12:34:00.009+03:00</published><updated>2008-04-27T16:11:01.854+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='properties'/><title type='text'>Static methods as function objects</title><content type='html'>In &lt;a href="http://sensualjava.blogspot.com/2007/11/predicate-function-rule.html"&gt;one of the earlier posts&lt;/a&gt; I described a policy object created by "functional style programming" in Java. The basic idea is to make methods into Function and Predicate objects and then composite the logic from these building blocks. The problem though was that the policy implementation looked alien to Java. To re-cap: I wanted to invoke a different function based on the class of the object - classical multi-dispatch with a single argument.&lt;br /&gt;&lt;br /&gt;So inspired by extension methods idea I added a new mechanism to define properties (and functions in general) - via static methods. You define a bunch of static methods with the same name (or appropriately annotated) like this:&lt;br /&gt;&lt;pre&gt;static int size(Collection c) {&lt;br /&gt; return c.size();&lt;br /&gt;}&lt;br /&gt;static int size(Map map) {&lt;br /&gt; return map.size();&lt;br /&gt;}&lt;br /&gt;static int size(Object obj) {&lt;br /&gt; return (obj.getClass().isArray() ?&lt;br /&gt;   Array.getLength(obj) : 1);&lt;br /&gt;}&lt;/pre&gt;Now assuming I have a property declaration&lt;br /&gt;&lt;pre&gt;Property&amp;lt;Object,Integer&amp;gt; size =&lt;br /&gt; new Property&amp;lt;Object,Integer&amp;gt;(0) {};&lt;/pre&gt;The underlying implementation of the size.of(object) would be a "policy" (composite function) dispatching to one of the static methods according to run-time type of the object. So that size.of("foo") is 1, size.of(Arrays.asList("a","b","c")) is 3 and size.of(null) is 0.&lt;br /&gt;&lt;br /&gt;There are couple of issues though.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Issue #1: automatically ordering the rules. &lt;/span&gt;Now when rules are not added manually, I should be careful to test for more specific class first. The solution is to calculate a distance between two classes and always look for a best match - basically same algorithm javac uses when choosing methods at compile-time. This isn't fully unambiguous though: if class C implements 2 interfaces A and B, having different implementations of size(A) and size(B) would put me into a dilemma which one to choose for size(C).  Javac in such a case reports an error - thanks to Java being statically typed. But once I make it a run-time decision the only logical solution is to report an error at run-time. To make the problem less acute, I could add an annotation that controls ordering of the methods.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Issue #2: this is less generic&lt;/span&gt; than a general predicate-based policy - it is limited to "instanceof" predicate. One of the policies I use internally in the properties project is &lt;span style="font-style: italic;"&gt;reflectively invoke getFoo() if the class has a "getFoo" method&lt;/span&gt;. This isn't possible with static methods.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Issue #3:&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;reflection&lt;/span&gt;. It's not really a problem, but rather an enhancement I want to make: instead of using reflection I could generate the functions at compile-time with &lt;a href="http://java.sun.com/javase/6/docs/api/javax/annotation/processing/package-summary.html"&gt;APT&lt;/a&gt;, like Bruce Chapman does &lt;a href="http://weblogs.java.net/blog/brucechapman/archive/2008/03/anouncement_no.html"&gt;here&lt;/a&gt;. This is one of my next adventures, which I will hopefully describe in a future post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-5264503455558567262?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/5264503455558567262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=5264503455558567262' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5264503455558567262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5264503455558567262'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/04/static-metods-as-function-objects.html' title='Static methods as function objects'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-3928634647526848973</id><published>2008-04-26T15:43:00.003+03:00</published><updated>2009-05-22T23:14:13.285+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='beatles'/><title type='text'>Digg a pony</title><content type='html'>Here is another post with no helpful information, sorry, I meant to write a meaningful piece but I am on vacation and in fun spirits :-)&lt;br /&gt;&lt;br /&gt;Anyway, I just got reminded of something that crossed my mind before and is now more relevant than ever -  the term John Lennon invented almost 40 years ago: "bagism". It's amazing that at the time everybody laughed - a person giving an interview in a bag. You can &lt;a href="http://en.wikipedia.org/wiki/Bagism"&gt;look this up&lt;/a&gt;, or even better &lt;a href="http://youtube.com/watch?v=yNLQ5Fkdc8w"&gt;watch the video&lt;/a&gt; (fast-forward about 2 and a half minutes). Here's a short re-cap:&lt;br /&gt;&lt;blockquote&gt;"if everybody had to go in a bag for a job (interview) there would be no prejudice, you see, you'd have to judge people on their quality within, you know, we call it &lt;span style="font-style: italic;"&gt;total communication&lt;/span&gt;..."&lt;/blockquote&gt;I think this is really the web: blogging, mash-ups, syndications, and social networks, and why all this is a lot of fun - you really know nothing about the one you are talking to, except what he (she? it?) tells you.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.thebeatles.com.hk/lyrics/lyrics.asp?lyTitle=Dig+A+Pony"&gt;Dig a pony lyrics&lt;/a&gt; mention&lt;br /&gt;&lt;blockquote&gt;"penetrate any place you go" (...internet?...)&lt;br /&gt;"radiate everything you are" (...wireless?...)&lt;br /&gt;"imitate everyone you know" (...blogging? syndication?...)&lt;br /&gt;"indicate everything you see" (...search? google?...)&lt;br /&gt;"syndicate any boat you row" (...social networks?...)&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;Cheers to total communication!&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;P.S. A tribute to &lt;a href="http://en.wikipedia.org/wiki/Passover_Seder"&gt;Passover holiday&lt;/a&gt; (the reason for my vacation): there were once four boys (ארבעה בנים) - the wise and wicked one, the cute one, the quite one, and the one that can't sing... and they were &lt;a href="http://www.thebeatles.com/"&gt;fab&lt;/a&gt;.&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-3928634647526848973?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/3928634647526848973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=3928634647526848973' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3928634647526848973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3928634647526848973'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/04/digg-pony.html' title='Digg a pony'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-764629761374798629</id><published>2008-04-24T00:37:00.004+03:00</published><updated>2008-12-09T08:45:28.523+02:00</updated><title type='text'>Java and closures</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_GnOWSH314CY/SA-tDbi92YI/AAAAAAAAAKE/k_dlWuerKIM/s1600-h/java_closure.GIF"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_GnOWSH314CY/SA-tDbi92YI/AAAAAAAAAKE/k_dlWuerKIM/s400/java_closure.GIF" alt="" id="BLOGGER_PHOTO_ID_5192559169827101058" border="0" /&gt;&lt;/a&gt;My reaction to the likely postponing of closures till Java 8.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-764629761374798629?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/764629761374798629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=764629761374798629' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/764629761374798629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/764629761374798629'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/04/java-and-closures.html' title='Java and closures'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GnOWSH314CY/SA-tDbi92YI/AAAAAAAAAKE/k_dlWuerKIM/s72-c/java_closure.GIF' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-7151443114409143306</id><published>2008-02-06T22:15:00.000+02:00</published><updated>2008-02-11T00:04:44.057+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Mercurial adventure on Widows</title><content type='html'>With a friend at work we decided to check out &lt;a href="http://www.selenic.com/mercurial/wiki/"&gt;Mercurial&lt;/a&gt; as source control system. The repository was set up on a Linux box and zillion lines of code and libraries were sucked in from ClearCase, now I just had to clone it to my lap-top running Windows XP.&lt;br /&gt;&lt;br /&gt;Installed Mercurial 0.9.5 via &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/TortoiseHg"&gt;TortoiseHg&lt;/a&gt; (I am familiar with Tortoise with SVN so it was a natural choice) - very easy and straightforward so far. Issued clone command - hm, filename too long. Switching to cygwin - doesn't help.&lt;br /&gt;&lt;br /&gt;So Ok, we have pretty deep directories structure and Mercurial makes it worse because it translates everything to lower case by "escaping" capital letters - adding underscore before the letter, so "A" becomes "_a" and a single underscore becomes a double one. Why? This is to avoid problems when working with case-insensitive operating systems like Windows. Fair enough, but what do I do with these long filenames now... &lt;a href="http://mail.python.org/pipermail/python-bugs-list/2007-March/037810.html"&gt;Python bug&lt;/a&gt;? Oh, great. In the meantime the error became "file not found", but I (correctly) suspected the cause is the same.&lt;br /&gt;&lt;br /&gt;I found &lt;a href="http://www.selenic.com/mercurial/bts/issue584"&gt;this bug report&lt;/a&gt; (and &lt;a href="http://www.selenic.com/mercurial/bts/issue839"&gt;this one&lt;/a&gt;) - at least it happenned to other people, it says I can use a &lt;span style="font-style: italic;"&gt;'usestore' workaround&lt;/span&gt;. Cool, found &lt;a href="http://selenic.com/hg/rev/fe41d9a186ab"&gt;this&lt;/a&gt; - says change one of the scripts, but hey, they are compiled?! Ok, downloaded ActivePython (I admit, I never touched Python in my life) also downloaded the sources. But apparently I need a C compiler too for the full build from source - that's too much, I decided to just run Mercurial with the interpreter.&lt;br /&gt;&lt;br /&gt;Found the right script, changed it. Boom, of course extra space in indentation - until now I only heard jokes about this (besides similar experience with Fortran half a life ago). Nevermind, got it now. Still not working. I take another look at the script -  the if statement I just added was already there before! Oops, what's going on? Trying to understand the Python code - it is looking for some 'usestore' configuration option, which BTW is supposed to disable the "escaping". All I need now is to set it. Hm, how? Eventually I find out that I need to edit &amp;lt;TortoiseHg-install-dir&amp;gt;/Mercurial.ini  adding&lt;br /&gt;&lt;blockquote&gt;[format]&lt;br /&gt;usestore=False&lt;br /&gt;&lt;/blockquote&gt;(If you use plain Mercurial, not Tortoise, create Mercurial.ini under &amp;lt;mercurial-install-dir&amp;gt;)&lt;br /&gt;&lt;br /&gt;I do it and... voilà, the repository cloned!!! So bottom line - &lt;span style="font-weight: bold;"&gt;all I needed was ini file change&lt;/span&gt;. It is somewhat dangerous 'coz I still have the mixed case, but at least I have the code on my laptop. Why didn't I find it in an FAQ or tips'n'tricks or something? No idea. Hope this post helps the next person who googles for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-7151443114409143306?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/7151443114409143306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=7151443114409143306' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/7151443114409143306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/7151443114409143306'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/02/mercurial-adventure-on-widows.html' title='Mercurial adventure on Widows'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-6843361645173007624</id><published>2008-01-25T09:07:00.000+02:00</published><updated>2008-12-09T08:45:28.649+02:00</updated><title type='text'>Blonde Moment</title><content type='html'>&lt;div style="text-align: left;"&gt;&lt;a style="font-weight: bold;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.makeherup.com/2008/01/17/kirsten-dunst-looks-amazing/"&gt;&lt;img style="margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 173px;" src="http://1.bp.blogspot.com/_GnOWSH314CY/R5mMnQp44cI/AAAAAAAAAIM/Z5-CwqGSMHM/s320/kirsten_dunst_cut2.jpg" alt="" id="BLOGGER_PHOTO_ID_5159309454243062210" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Kirsten Dunst wearing Red and Sensual Java.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-6843361645173007624?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/6843361645173007624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=6843361645173007624' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6843361645173007624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6843361645173007624'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/01/blonde-moment.html' title='Blonde Moment'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GnOWSH314CY/R5mMnQp44cI/AAAAAAAAAIM/Z5-CwqGSMHM/s72-c/kirsten_dunst_cut2.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-5740756405323372687</id><published>2008-01-22T16:17:00.000+02:00</published><updated>2008-01-24T14:25:07.792+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>The taste of Java Generics</title><content type='html'>As the closure debate flames are rising, people are attacking Generics in order to attack closures. Some use it as a negative example against particular closure proposal, some try to discourage Java language changes in general and some to promote other languages.  When I read articles that start with "Generics are hard" and lead into "Generics are bad", I can't help thinking of &lt;a href="http://en.wikipedia.org/wiki/The_Fox_and_the_Grapes"&gt;the fox and the grapes&lt;/a&gt;. Yeah, they are hard. So is concurrency, NIO and many other things. So? That's why people create frameworks on top of Java.&lt;br /&gt;&lt;br /&gt;Don't get me wrong - Java Generics have faults, and they are &lt;a href="http://www.ibm.com/developerworks/java/library/j-jtp01255.html"&gt;long known&lt;/a&gt;. Here's a hit-parade of my biggest complaints, but I will also mention some solutions I have used:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1. &lt;a href="http://gafter.blogspot.com/2006/11/reified-generics-for-java.html"&gt;Erasure&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;The way to work around it is by using &lt;a href="http://java.sun.com/docs/books/tutorial/extra/generics/literals.html"&gt;type token&lt;/a&gt; or &lt;a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html"&gt;super-type token&lt;/a&gt;. As any workaround, it is &lt;a href="http://gafter.blogspot.com/2007/05/limitation-of-super-type-tokens.html"&gt;limited&lt;/a&gt;, but it can solve part of the problem - Class#cast and Class#newInstance don't issue the annoying warnings.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2. &lt;a href="http://www.artima.com/forums/flat.jsp?forum=106&amp;amp;thread=222021"&gt;Generic parameters not covariant&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;It is usually a good idea to &lt;a href="http://blog.cedarsoft.eu/2008/01/12/why-you-should-only-return-collections-with-bounded-wildcards/"&gt;use bound wildcards&lt;/a&gt; extensively.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3. No &lt;a href="http://www.artima.com/forums/flat.jsp?forum=106&amp;amp;thread=136054"&gt;lower bounds support&lt;/a&gt; (except wildcards)&lt;/span&gt;&lt;br /&gt;We can use static methods instead (ala &lt;a href="http://gafter.blogspot.com/2007/11/closures-prototype-update-and-extension.html"&gt;extensions&lt;/a&gt;) with &amp;lt;T extends Super&amp;gt; rather than &amp;lt;S super Sub&amp;gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;4. Verbosity, instead of  &lt;a href="http://freddy33.blogspot.com/2007/11/ugly-duckling-of-java.html"&gt;more aggressive type inference&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;Not much to do, hm, learn to type faster? :-)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;5. The angle brackets&lt;br /&gt;&lt;/span&gt;Yeah, I hate them most when &lt;a href="http://rickyclarkson.blogspot.com/2008/01/trivial-display-of-how-scalas-type.html"&gt;typing on blogger&lt;/a&gt;, luckily I am old enough to have been coding HTML in plain text editor a long time ago, so... back to GT and LT escapes.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;BTW Java didn't die, it has simply grown beyond its &lt;a href="http://en.wikipedia.org/wiki/Hip_%28slang%29"&gt;hipness&lt;/a&gt; age. And I am glad that it spawned even better things, such as Scala. But there is a difference between "good" and "popular". Java is popular and not that bad, other languages may be better, but not as popular. Will Scala be willing to sacrifice some of its expressive power and &lt;a href="http://rickyclarkson.blogspot.com/2008/01/in-defence-of-0l-in-scala.html"&gt;shortcuts&lt;/a&gt; (gee, stuff like that reminds me why I don't code in Perl) to become simpler to learn/read and potentially more popular? Should it? (Ruby consciously didn't and ... didn't.) We shall see.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-5740756405323372687?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/5740756405323372687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=5740756405323372687' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5740756405323372687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5740756405323372687'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/01/taste-of-java-generics.html' title='The taste of Java Generics'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-2562114104660403079</id><published>2008-01-10T12:55:00.000+02:00</published><updated>2008-01-24T14:29:20.743+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Listen To What The Man Said</title><content type='html'>Just couple of nice quotes for today: &lt;a href="http://www.odbms.org/oninnovation.html#kay"&gt;Alan Kay on Innovation&lt;/a&gt; and the not so new but still relevant &lt;a href="http://www.cs.utexas.edu/users/EWD/"&gt;Edsger W. Dijkstra transcriptions&lt;/a&gt;  - look at &lt;a href="http://www.cs.utexas.edu/users/EWD/transcriptions/EWD13xx/EWD1305.html"&gt;this Q&amp;amp;A&lt;/a&gt; for a quick feel.&lt;br /&gt;&lt;blockquote&gt;"Machine capacities now give us room galore for making a mess of it. Opportunities unlimited for fouling things up! Developing the austere intellectual discipline of keeping things sufficiently simple is in this environment a formidable challenge, both technically and educationally."&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-2562114104660403079?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/2562114104660403079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=2562114104660403079' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/2562114104660403079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/2562114104660403079'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/01/listen-to-what-man-said.html' title='Listen To What The Man Said'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-3933660838475618856</id><published>2008-01-01T13:09:00.000+02:00</published><updated>2008-01-09T21:13:36.411+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Wildcards observation</title><content type='html'>&lt;blockquote&gt;"A bug in poker is a limited form of wild card."&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-style: italic;"&gt; - &lt;a href="http://en.wikipedia.org/wiki/Bug_%28poker%29"&gt;Wikipedia&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;While looking for academic references for my properties project, I bumped into the expression problem - &lt;a href="http://homepages.inf.ed.ac.uk/wadler/papers/expression/expression.txt"&gt;the write-up by Phil Wadler&lt;/a&gt; and follow-ups by &lt;a href="http://www.daimi.au.dk/%7Emadst/ecoop04/index.html"&gt;Mads Torgersen&lt;/a&gt; and &lt;a href="http://lampwww.epfl.ch/%7Eodersky/papers/ExpressionProblem.html"&gt;Matthias Zenger/Martin Odersky&lt;/a&gt; are really fun and educative readings.&lt;br /&gt;&lt;br /&gt;This stuff caused me to re-read the &lt;a href="http://bracha.org/wildcards.pdf"&gt;the wildcards paper&lt;/a&gt; and I suddenly understood why I had this strange gut feeling about wildcard usage. Almost all learning material about Generics, including the wildcard paper itself, emphasizes the distinction between read and write methods - having a wildcard in a collection parameter prevents you from adding elements to the collection, but allows reading. This is true, but somewhat misleading. Actually, wildcard in the parameter allows us to call a method that returns the thing behind the wildcard and treat it as if the returned object is of the type of wildcard &lt;span style="font-style: italic;"&gt;bound&lt;/span&gt; (or an &lt;span style="font-family:courier new;"&gt;Object&lt;/span&gt;, if the wildcard is unbound); the wildcard prevents us, however, from calling any method that takes "the thing behind the wildcard" as a parameter. Now obviously, to add something to a collection you need to call a method that takes that something as parameter, and it is indeed prevented, but other modifications are not disallowed, e.g. &lt;span style="font-family:courier new;"&gt;clear()&lt;/span&gt; .&lt;br /&gt;&lt;br /&gt;The consequence of wildcard usage applies to any method, not just &lt;span style="font-style: italic;"&gt;"write method"&lt;/span&gt;, for example - &lt;a href="http://smallwig.blogspot.com/2007/12/why-does-setcontains-take-object-not-e.html"&gt;containment test&lt;/a&gt;. So looking at Kevin's example, it now seems to me that &lt;span style="font-family:courier new;"&gt;doSomeReading&lt;/span&gt; method shouldn't have used a wildcard if it wished to perform a safe containment test - that's the catch (or should I say, hm, capture...)&lt;br /&gt;&lt;br /&gt;Happy New Year!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-3933660838475618856?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/3933660838475618856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=3933660838475618856' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3933660838475618856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3933660838475618856'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2008/01/wildcards-observation.html' title='Wildcards observation'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-5068509139392019587</id><published>2007-12-31T16:18:00.000+02:00</published><updated>2008-12-09T08:45:28.932+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Past forward</title><content type='html'>Since my &lt;a href="http://sensualjava.blogspot.com/2007/12/back-to-future.html"&gt;previous post&lt;/a&gt; was devoted to Java history and &lt;a href="http://parleys.com/display/PARLEYS/Interview+with+Martin+Odersky+at+JavaPolis%2707?showComments=true"&gt;this interview&lt;/a&gt; with Martin Odersky recently came out, I decided to do one more short transcription related to Generics history.&lt;br /&gt;&lt;blockquote&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_GnOWSH314CY/R3nsg8rIVtI/AAAAAAAAAHc/tc6nnuliLBU/s1600-h/martin_odersky.JPG"&gt;&lt;img style="margin: 0pt 10pt 10px 0px; float: left; cursor: pointer; width: 147px; height: 224px;" src="http://3.bp.blogspot.com/_GnOWSH314CY/R3nsg8rIVtI/AAAAAAAAAHc/tc6nnuliLBU/s320/martin_odersky.JPG" alt="" id="BLOGGER_PHOTO_ID_5150407699661870802" border="0" /&gt;&lt;/a&gt;"I am an academic, actually, I'm working at the university in Switzerland. ... A long time ago I was a Ph.D. student of Nicholas Wirth, so I am in the Modula 2 operand camp... But then I drifted more and more into functional programming community, I have a good friend named Phil Wadler who is very active in the community, so he sometimes told me ... "there is this new thing, it's gonna bury functional programming, it is called Java". I wanted to find out more and he said it has garbage collection, and it runs everywhere on the Web ..., so what are you gonna do against that?!&lt;br /&gt;&lt;br /&gt;So ... we said we'll try to do a functional language on the Java platform, because the Java platform looked very exciting to us then (it was in 1995, so a long time ago). ... To find out more about what it is (I always learn best when I write a compiler) let's write a Java compiler. We had this second ever Java compiler out there after the old JavaC.&lt;br /&gt;&lt;br /&gt;Then we said - if we want to do a language it should be Java compatible, and we wrote a language called Pizza, which added stuff from functional programming to Java. We experimented a little bit with that and then Sun came and said - we like what you did, in particular the Generics, we wanna do that. Then we had a project with Gilad Bracha at Sun and we did this GJ thing, which was the Generics thing.&lt;br /&gt;&lt;br /&gt;The compiler for GJ eventually became the current JavaC compiler, Sun took that over because they decided that this compiler was more maintainable than the original. (Interviewer: "from JavaC 5 on...") From Java 1.3 already.&lt;br /&gt;&lt;br /&gt;So the compiler was in 1.3, but the Generics were disabled. In fact, the Generics were at first not that much disabled, there was a secret switch that people found out about, so there was this stealthy movement of people using Generics already in 1998 when it first came out. And then Sun pulled the plug, they said - you can't do that, so you have to re-write your compiler so that it doesn't make any Generics available. So there was a special mutilation script in the compiler which would rip it off,  so that people couldn't use it for a while, until it came back in Java 5."&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-5068509139392019587?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/5068509139392019587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=5068509139392019587' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5068509139392019587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5068509139392019587'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/12/past-forward.html' title='Past forward'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GnOWSH314CY/R3nsg8rIVtI/AAAAAAAAAHc/tc6nnuliLBU/s72-c/martin_odersky.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-5971933814078246732</id><published>2007-12-13T11:51:00.000+02:00</published><updated>2008-01-24T14:24:38.352+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Back to the future</title><content type='html'>If you look at the &lt;a href="http://www.oreilly.com/pub/a/oreilly/news/languageposter_0504.html"&gt;programming language history poster&lt;/a&gt; there's a bunch or arrows leading to Java genesis, one of which comes from Smalltalk. Ok, I heard about Smalltalk and saw some code in books. I also knew that &lt;a href="http://www.bracha.org/"&gt;Gilad Bracha&lt;/a&gt; was one of the authors of &lt;a href="http://www.strongtalk.org/history.html"&gt;Strongtalk&lt;/a&gt; (Smalltalk with static types) and later immensely contributed to Java evolution while working at Sun. I also saw references to this supposedly great language called &lt;a href="http://research.sun.com/self/language.html"&gt;Self&lt;/a&gt; in some programming language articles. But only now I see how it all linked together thanks to  &lt;a href="http://itc.conversationsnetwork.org/shows/detail3432.html"&gt;Avi Bryant's Keynote&lt;/a&gt; at RailsConf (yeah, of all places to learn about Java...) so I decided to transcribe here a small portion of this fascinating talk.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;"There's a legend that there's something inherently about Ruby that makes it hard to implement a fast VM for it, because of open classes, because of dynamic typing - there's something about meta-programming, something about Ruby that makes it hard in this day to make it run fast. And it's just not true! It was true 20 years ago -  it was a hard problem, but people solved it.&lt;br /&gt;&lt;br /&gt;This is actually from Sun site, this is a bunch of papers that collectively explain how do you make Ruby go fast. But you'll note that they're written in 1989-91, you can go and look at the URL here, they come from the &lt;a href="http://research.sun.com/self/"&gt;Self&lt;/a&gt; project. And the history is kind of interesting here, so since this is about the future and about the past, I'll give you a really brief history.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/x180/505428730/"&gt;&lt;img src="http://farm1.static.flickr.com/216/505428730_065b8b44d6.jpg?v=0"  width="167" height="250" align="right"/&gt;&lt;/a&gt;Self was a project at Sun to do Smalltalk, but even more so. Even purer object-oriented.  And it meant that they had to find ways, because they wanted to make it so object-oriented, so pure, so &lt;a href="http://en.wikipedia.org/wiki/Turtles_all_the_way_down"&gt;turtles all the way down&lt;/a&gt;,  they had to find more and more ways to make it go fast. And the technology they came up with was so interesting that they actually spawn off a start-up to try to implement new super-fast Smalltalk that was gonna be used on Wall Street. But before they got to release it, this was gonna be called Strongtalk, before they got to release it, Sun bought them back.&lt;br /&gt;&lt;br /&gt;And Sun used the technology, used the &lt;a href="http://java.sun.com/javase/technologies/hotspot/"&gt;HotSpot profiling and Just-In-Time compilation&lt;/a&gt; technology that have been developed here to build the Java VM. Which is sort of one of the great tragedies of technology, but it's true, that Java HotSpot VM in fact is what came of all of this great work of making dynamic languages go fast - of course they crippled it so that it doesn't make dynamic languages go fast anymore, but maybe &lt;a href="http://jcp.org/en/jsr/detail?id=292"&gt;that'll change&lt;/a&gt;.  One interesting footnote to this is that a lot of the engineers that were involved in that have since left Sun and are back to doing Smalltalk."&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-5971933814078246732?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/5971933814078246732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=5971933814078246732' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5971933814078246732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5971933814078246732'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/12/back-to-future.html' title='Back to the future'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-8788632787615769778</id><published>2007-12-09T22:11:00.000+02:00</published><updated>2007-12-12T00:48:26.875+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Extension methods proposal</title><content type='html'>I'd like to talk here about another Java 7 feature proposal lobbied by Google that generated lots of waves in the blog-sphere after being &lt;a href="http://gafter.blogspot.com/2007/11/closures-prototype-update-and-extension.html"&gt;revealed by Neal Gafter&lt;/a&gt;. A lot have been said (&lt;a href="http://digital-sushi.org/entry/declaration-site-extension-methods/"&gt;Peter&lt;/a&gt;, &lt;a href="http://tech.puredanger.com/2007/11/30/java7-roundup-39/"&gt;Alex&lt;/a&gt;, &lt;a href="http://www.jroller.com/scolebourne/entry/java_7_extension_methods"&gt;Stephen&lt;/a&gt;, &lt;a href="http://weblogs.java.net/blog/forax/archive/2007/11/java_7_extensio.html"&gt;Rémi&lt;/a&gt; and &lt;a href="http://www.jroller.com/jadda/entry/extension_methods_vs_method_currying"&gt;Stefan&lt;/a&gt;) so I'll add just 2 humble observations.&lt;br /&gt;&lt;br /&gt;Adding capabilities to the language vs. maintaining a safe and clear programming environment is a tough balance to keep.  I had my doubts in this particular case, and I think I tend to favor it, with one modification. I think it would be better if extension method import was different from normal static import, so the developer knows exactly what he is doing. I propose following syntax (that BTW does not require any additional keywords in Java)&lt;br /&gt;&lt;pre&gt;&lt;b&gt;import static&lt;/b&gt; java.util.Collections.sort&lt;br /&gt;  &lt;b&gt;extends&lt;/b&gt; java.util.List;&lt;/pre&gt;Compiler would then check that the first argument of &lt;span style="font-family:courier new;"&gt;sort &lt;/span&gt;is a &lt;span style="font-family:courier new;"&gt;List &lt;/span&gt;(or its super-class or super-interface) and compile &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;List list = ...;&lt;br /&gt;list.sort();&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;into&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;blockquote&gt;Collections.sort(list); &lt;/blockquote&gt;&lt;/span&gt;The main advantage of this proposal is that extension methods are imported consciously, rather than implicitly.&lt;br /&gt;&lt;br /&gt;The "importer" is also given some control over the overloading rules for the extension method - what if &lt;span style="font-family:courier new;"&gt;Collection&lt;/span&gt; has a &lt;span style="font-family:courier new;"&gt;sort&lt;/span&gt; method? what if &lt;span style="font-family:courier new;"&gt;ArrayList&lt;/span&gt; does? well, with the syntax I propose here the developer targets the method to a specific class, so overloading rules can be applied just as if the method was in that class, in this example it would overload &lt;span style="font-family:courier new;"&gt;Collection&lt;/span&gt; one, but not &lt;span style="font-family:courier new;"&gt;ArrayList&lt;/span&gt; one. It reminds me of the Ruby feature that &lt;a href="http://sensualjava.blogspot.com/2007/11/jruby-pod-cast.html"&gt;Neal Ford had mentioned&lt;/a&gt; - calling a method, and if it does not exist, executing some code piece instead. So with proper overloading rules, could imported extension method be Java alternative for &lt;span style="font-style: italic;"&gt;method missing&lt;/span&gt;? At last, there's this dark corner question "What if &lt;span style="font-family:courier new;"&gt;List&lt;/span&gt; had a &lt;span style="font-family:courier new;"&gt;sort&lt;/span&gt; method?" Personally, I think that if the class explicitly imports an extension method, it should be treated as local definition, while the method defined in &lt;span style="font-family:courier new;"&gt;List&lt;/span&gt; as inherited definition, and therefore (following the principles laid down by Gilad Bracha in one of his &lt;a href="http://dyla2007.unibe.ch/?download=dyla07-Gilad.pdf"&gt;recent papers&lt;/a&gt;) the extension method should override the one in &lt;span style="font-family:courier new;"&gt;List&lt;/span&gt;. This is somewhat similar to the infamous &lt;a href="http://blogs.sun.com/jrose/entry/scope_ambiguities_between_outer_and"&gt;"Mother May I" rule&lt;/a&gt;, but I better leave this for greater minds to solve.&lt;br /&gt;&lt;br /&gt;Another interesting aspect of extension methods in general is their behavior in case the first parameter of the method is generic. Take &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Collections.html#max%28java.util.Collection%29"&gt;&lt;span style="font-family:courier new;"&gt;Collections.max&lt;/span&gt;&lt;/a&gt; method for example. It accepts collections which element type extends &lt;span style="font-family:courier new;"&gt;&amp;lt;T extends Object &amp;amp; Comparable&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;? super T&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&amp;gt;&lt;/span&gt;. AFAIK there is no definition of extension method behavior with generics. Maybe they are not allowed, but if they were, I would expect that &lt;span style="font-family:courier new;"&gt;list.max()&lt;/span&gt; compiles only if elements of my list are compatible with the static method definition, which in this particular case means that they should be &lt;span style="font-family:courier new;"&gt;Comparable&lt;/span&gt; to each other. Now this is an &lt;span style="font-weight: bold;"&gt;enhancement of Java generics system&lt;/span&gt; - being able to add methods to classes based on their generic parameters! Wow, it's somewhat spooky, but really powerful, I can imagine a few neat things I could do with this :-) and since I am now going to spend some time dreaming, I am going to leave you to think about this...&lt;br /&gt;&lt;br /&gt;P.S. (12/12/07) Just came across a &lt;a href="http://www.codethinked.com/post/2007/12/Extension-Methods-Suck.aspx"&gt;vivid discussion&lt;/a&gt; of similar feature in .NET. First reaction - "ah, oh, I get it now, it's another one of those &lt;span style="font-style: italic;"&gt;.NET has it so we gotta have it to&lt;/span&gt;o features!". But seriously now - let's learn from their experience, the conclusions are pretty similar to what is discussed here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-8788632787615769778?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/8788632787615769778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=8788632787615769778' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/8788632787615769778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/8788632787615769778'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/12/extension-methods-proposal.html' title='Extension methods proposal'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-4430704489855952594</id><published>2007-12-05T12:47:00.000+02:00</published><updated>2007-12-11T18:42:24.229+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Faster than C</title><content type='html'>Not everyday you come across &lt;a href="http://groups.google.com/group/jvm-languages"&gt;&lt;/a&gt;an example of &lt;a href="http://groups.google.com/group/jvm-languages/browse_thread/thread/e0b10bc28f3a0a44/11b799c18e0c718b?#11b799c18e0c718b"&gt;Java program that executes faster than its C equivalent&lt;/a&gt;. Although the original code is in Scala, the speed is because of the JVM and HotSpot, and not because of the language which the program was written in. This is a good illustration of JVM strength which IMO &lt;span style="font-style: italic;"&gt;can &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;should &lt;/span&gt;be reused for other languages. (To be completely fair, gcc is not the strongest competitor among C compilers, there are optimizers that do the sort of trick that JVM did. Nevertheless, it's impressive.)&lt;br /&gt;&lt;br /&gt;Speaking of Java versus C/C++, there's an interesting debate on &lt;a href="http://lambda-the-ultimate.org/"&gt;LtU&lt;/a&gt; regarding &lt;a href="http://lambda-the-ultimate.org/node/2552"&gt;performance of GC vs. explicit memory management&lt;/a&gt;. The conclusion is not very surprising - there is a cost, but it is reasonable to pay given the other benefits of GC.   It reminds me of a discussion I had with a guy who &lt;a href="http://www28.cplan.com/cc158/session_details.jsp?isid=286118&amp;amp;ilocation_id=158-1&amp;amp;ilanguage=english"&gt;used to work&lt;/a&gt; with &lt;a href="http://java.sun.com/javase/technologies/realtime/"&gt;Java RTS&lt;/a&gt; (Real-Time Java System). I admit, when he first mentioned it, I didn't know what it was and it surely sounded weird, so I went and read a few web-pages. Java with explicit memory management.... hm? Poor Java, why would you do such a thing to it? So I asked him "Why don't you just use C or C++?" The answer was - "It's proven that programmers prefer Java and they are more productive writing Java code than C++". "All well, but shouldn't it be at least partially attributed to the fact that in normal Java we (programmers) don't need to manage the memory?" "I see your point" he smiled. That said, I admit that I know practically nothing about JME platform and how it solves real-time problems with Java. So I'm not shutting the door here - maybe I'm wrong.&lt;br /&gt;&lt;br /&gt;But I just can't help and generalize this problem, looking at where things go with JSE. I mean it's great that Java evolves, but as wonderful as Java is, it's not this one universal tool that can solve every problem in the world. If there is a need for Java-like language for real-time applications, then why can't some smart guy (at Sun &lt;a href="http://code.google.com/android/"&gt;or Google&lt;/a&gt; or wherever) create a language that does explicit memory management, but incorporates other Java advantages. &lt;span style="font-weight: bold;"&gt;Just don't call it Java, please!&lt;/span&gt; (Yeah, I know that marketing guys really want you to, but let's try to keep some dignity, fellow enginerds).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-4430704489855952594?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/4430704489855952594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=4430704489855952594' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4430704489855952594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4430704489855952594'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/12/faster-than-c.html' title='Faster than C'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-732718659020710360</id><published>2007-11-30T10:20:00.000+02:00</published><updated>2008-01-24T14:24:38.352+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>JRuby pod-cast</title><content type='html'>I almost accidentally got to hear &lt;a href="http://www.javaworld.com/podcasts/jtech/2007/112007jtech006.html"&gt;Neal Ford's interview&lt;/a&gt; about &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; this morning.&lt;br /&gt;&lt;br /&gt;Love it or hate it, &lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt; cannot be ignored. Yet the articles and blog-posts you find on Ruby vs. Java are many times so emotional and single-minded that it became a &lt;a href="http://davidrupp.blogspot.com/2007/10/last-language-war-language-trolling.html"&gt;really good joke&lt;/a&gt;. But not this one.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://nealford.com/"&gt;Neal&lt;/a&gt; starts with a bit of history, goes through Ruby comparison to Java (expressive power, meta-programming capabilities), the rising importance of JVM as a multi-language platform, comparison between JRuby and other JVM languages (&lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt;, &lt;a href="http://www.jython.org/"&gt;Jython&lt;/a&gt;, &lt;a href="http://jaskell.codehaus.org/"&gt;Jaskell&lt;/a&gt;, &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;) when to use them and how to get JRuby into your corporate development environment (the tips include - "don't say the word Ruby as long as it runs on the JVM" and "use it in test or &lt;a href="http://raven.rubyforge.org/"&gt;build&lt;/a&gt; environment first - Ruby has great advantages there and it's easier to justify a new tool for build or test than for production") and finally about his work on first commercial product developed entirely in JRuby - the agile team management suite called &lt;a href="http://studios.thoughtworks.com/mingle-project-intelligence"&gt;Mingle&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I  also liked his general comments regarding how &lt;a href="http://en.wikipedia.org/wiki/Design_Patterns"&gt;G0F design patterns&lt;/a&gt; illustrate language deficiencies, his objection to XML programming and why the concept of protective programming environment allowing to scale software development through hiring zillions of bad programmers is bankrupt.&lt;br /&gt;&lt;br /&gt;P.S. &lt;a href="http://martinfowler.com/"&gt;Martin Fowler&lt;/a&gt;, Neal's colleague at &lt;a href="http://www.thoughtworks.com/"&gt;ThoughtWorks&lt;/a&gt;, recently &lt;a href="http://martinfowler.com/bliki/GroovyOrJRuby.html"&gt;blogged about JRuby&lt;/a&gt; too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-732718659020710360?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/732718659020710360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=732718659020710360' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/732718659020710360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/732718659020710360'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/11/jruby-pod-cast.html' title='JRuby pod-cast'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-3462902963749596683</id><published>2007-11-27T19:26:00.000+02:00</published><updated>2007-12-11T18:42:24.229+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Reflection and auto-boxing</title><content type='html'>In an &lt;a href="http://sensualjava.blogspot.com/2007/11/walls-and-bridges.html"&gt;earlier post&lt;/a&gt; I discovered that the way reflection handles synthetic bridge methods is somewhat lacking. Here is another reflection issue, this time a known problem: &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6176992"&gt;6176992&lt;/a&gt; - sort of &lt;a href="http://en.wikipedia.org/wiki/Schrodingers_cat"&gt;paradox in a box&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Apparently &lt;span style="font-family:courier new;"&gt;Class#isAssignableFrom&lt;/span&gt; does not handle auto-boxing so if you have a method that returns a boolean,  &lt;span style="font-family:courier new;"&gt;Boolean.class.isAssignableFrom(method.getReturnType())&lt;/span&gt;  will evaluate to &lt;span style="font-family:courier new;"&gt;false&lt;/span&gt;. I played with it a bit further, and if you have a method that takes an &lt;span style="font-family:courier new;"&gt;int,&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;MyClass.class.getMethod(methodName, Integer.class)&lt;/span&gt; yields &lt;span style="font-family:courier new;"&gt;NoSuchMethodException&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I expected these API's to return a non-primitive class because &lt;span style="font-family:courier new;"&gt;Method#invoke&lt;/span&gt; accepts only &lt;span style="font-family:courier new;"&gt;Object&lt;/span&gt;s and translates them internally, and it worked long before auto-boxing feature was added to Java. However, after giving this more thought, I decided that it's unfair to complain that the API's return exact types, also a primitive type does not extend or inherit its boxed counterpart and Javadoc &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Class.html#isAssignableFrom%28java.lang.Class%29"&gt;describes the behavior&lt;/a&gt; of &lt;span style="font-family:courier new;"&gt;isAssignableFrom &lt;/span&gt;impeccably - the method supports &lt;span style="font-style: italic;"&gt;widening reference conversion&lt;/span&gt; only (chapter 5.1.5 in the &lt;a href="http://www.amazon.com/Java-TM-Language-Specification-3rd/dp/0321246780"&gt;3rd edition of &lt;span style="font-weight: bold;"&gt;Java Language Specification&lt;/span&gt;&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Nevertheless, &lt;span style="font-weight: bold;"&gt;Java Language Specification&lt;/span&gt; also defines &lt;span style="font-style: italic;"&gt;widening primitive conversion&lt;/span&gt; (chapter 5.1.2) and (un)boxing (in 5.1.7 and 5.1.8) and I think it is fair to ask for a utility method that tests the compatibility of 2 classes that represent primitive types and a utility for boxing and un-boxing of classes. So what I'm really asking for is a &lt;span style="font-family:courier new;"&gt;java.lang.reflect.Primitive&lt;/span&gt; class, that provides some static utilities just like &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/reflect/Array.html"&gt;&lt;span style="font-family:courier new;"&gt;java.lang.reflect.Array&lt;/span&gt;&lt;/a&gt; does.&lt;br /&gt;&lt;br /&gt;Until then, I am going to create my own utility for boxing/un-boxing - a &lt;span style="font-family:courier new;"&gt;&lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html"&gt;Function&lt;/a&gt;&amp;lt;Class,Class&amp;gt;&lt;/span&gt; of course :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-3462902963749596683?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/3462902963749596683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=3462902963749596683' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3462902963749596683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3462902963749596683'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/11/reflection-and-auto-boxing.html' title='Reflection and auto-boxing'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-9191683679571524239</id><published>2007-11-22T20:57:00.000+02:00</published><updated>2008-01-24T14:27:40.967+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='properties'/><title type='text'>Properties, static and yet dynamic</title><content type='html'>I think it's time to share some more of &lt;a href="http://sensualjava.blogspot.com/2007/11/properties-for-java.html"&gt;my Java properties ideas&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Property is a &lt;a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html"&gt;super-type-token&lt;/a&gt; and the definition looks like this:&lt;br /&gt;&lt;pre&gt;public static final Property&amp;lt;Person,String&amp;gt; name =&lt;br /&gt;            new Property&amp;lt;Person,String&amp;gt; ("name") {};&lt;/pre&gt;So I've taken the property out of its usual habitat - the object it applies to, and let it be defined in any class! One prominent flexibility is the ability to add properties to an existing class by loading a new class.&lt;br /&gt;&lt;br /&gt;How is the value associated with a particular object instance? A property should be assigned a "definition", which is in essence a &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html"&gt;Function&lt;/a&gt; that retrieves the value from a given object, by using reflection for example. The definition can be changed on the fly, and user of the property needs not be concerned.&lt;br /&gt;&lt;br /&gt;That's all very nice, but reflection is not enough if we add properties on the fly. There are 2 ways of dealing with it. The more obvious one is having a Map or an array within the object where the values can be stored. This of course means that the object class is in advance "prepared" to have dynamic properties.&lt;br /&gt;&lt;br /&gt;Another way is rather shocking at first glance... to me it was, anyway. Traditionally the object stores a property-&gt;value map. But why can't we have the &lt;span style="font-weight: bold;"&gt;property store an object-&gt;value map&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;!?&lt;/span&gt; When I read about &lt;a href="http://www.infoq.com/news/2007/09/row-vs-column-dbs"&gt;column-oriented databases&lt;/a&gt;, I realized it's not as crazy as it first looks. All I needed was WeakIdentityHashMap, unfortunately &lt;a href="http://blogs.azulsystems.com/cliff/2007/08/why-weakhashmap.html"&gt;JDK does not have one&lt;/a&gt;, but&lt;a href="http://code.google.com/p/google-collections/"&gt; google-collections&lt;/a&gt; do - the &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ReferenceMap.html"&gt;ReferenceMap&lt;/a&gt;. Also cloning and serialization need special hooks, but it's not too much hassle.&lt;br /&gt;&lt;br /&gt;I have 4 types of properties for now, Property that only allows read access, UpdatableProperty that supports read and write, and their multi-value counterparts: IterableProperty and CollectionProperty. This list can of course be extended. Any property can have a default value, and updatable property can have a list of value constraints. I have a library of definitions - plain function, reflected, mapped, ones using internal and external map like I described above and of course more can be added.&lt;br /&gt;&lt;br /&gt;Last but not least - all properties that apply to a certain class of objects are tracked, so there's an API which I can query for applicable properties for a given class. It would collect properties of all super-classes and super-interfaces - note that property can be defined for an interface and in an interface (being a &lt;span style="font-family:courier new;"&gt;final static&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;That's it for tonight. To be continued...&lt;br /&gt;&lt;br /&gt;P.S. &lt;a href="http://www.pc.co.il/Index.asp?CategoryID=82&amp;amp;ArticleID=649"&gt;JavaEdge&lt;/a&gt; was really great, thanks &lt;a href="http://www.alphacsp.com/WhoWeAre.jsp"&gt;Alpha folks&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-9191683679571524239?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/9191683679571524239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=9191683679571524239' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/9191683679571524239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/9191683679571524239'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/11/properties-static-and-yet-dynamic.html' title='Properties, static and yet dynamic'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-1579993436540134694</id><published>2007-11-19T08:33:00.000+02:00</published><updated>2007-11-19T08:37:48.565+02:00</updated><title type='text'>Software proletariat</title><content type='html'>Don't miss out &lt;a href="http://www.dilbert.com/comics/dilbert/archive/images/dilbert200711195248.jpg"&gt;today's Dilbert&lt;/a&gt; on &lt;a href="http://en.wikipedia.org/wiki/The_Lower_Depths"&gt;the lower depths&lt;/a&gt; of our profession.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-1579993436540134694?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/1579993436540134694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=1579993436540134694' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/1579993436540134694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/1579993436540134694'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/11/software-proletariat.html' title='Software proletariat'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-3926348761177795281</id><published>2007-11-18T19:41:00.000+02:00</published><updated>2008-01-24T14:27:40.968+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='properties'/><title type='text'>Predicate + Function = Rule</title><content type='html'>Another enhancement on top of &lt;a href="http://code.google.com/p/google-collections/"&gt;google-collections&lt;/a&gt; that I want to share with you.&lt;br /&gt;&lt;br /&gt;In essence, rule is condition and action. So I will use &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicate.html"&gt;Predicate&lt;/a&gt; as a condition and &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html"&gt;Function&lt;/a&gt; as an action. The composite function then consists of list of rules, for the first predicate that evaluates  to true, it will invoke the corresponding function. If none of the predicates are matched - default function will be invoked. &lt;a href="http://docs.google.com/View?docID=d35w57w_3gxhjgw&amp;amp;revision=_latest"&gt;Here&lt;/a&gt; is the source code, if you want more details.&lt;br /&gt;&lt;br /&gt;For example, here is how I define a function "size" of an arbitrary object:&lt;br /&gt;&lt;pre&gt;Function&amp;lt;Object, Integer&amp;gt; size = new Rules&amp;lt;Object,Integer&amp;gt;().&lt;br /&gt;addRule(isNull(), constant(0)).&lt;br /&gt;addRule(&lt;br /&gt;or(&lt;br /&gt; instanceOf(Collection.class),&lt;br /&gt; instanceOf(Map.class)),&lt;br /&gt;self().reflect("size").cast(Integer.class)).&lt;br /&gt;addRule(&lt;br /&gt;asPredicate(self().reflect("getClass").&lt;br /&gt;           reflect("isArray").cast(Boolean.class)),&lt;br /&gt;self().reflect(Array.class, "getLength").cast(Integer.class)).&lt;br /&gt;setDefault(constant(1));&lt;br /&gt;&lt;/pre&gt;If you read &lt;a href="http://sensualjava.blogspot.com/2007/11/null-safe-access-to-properties.html"&gt;my earlier post&lt;/a&gt;, you already know about the &lt;a href="http://docs.google.com/View?docID=d35w57w_0fc5tk2&amp;amp;revision=_latest"&gt;FunctionChain&lt;/a&gt;, this is where I statically import &lt;span style="font-family:courier new;"&gt;self() &lt;/span&gt;from. The &lt;span style="font-family:courier new;"&gt;reflect() &lt;/span&gt;function transfers Object to Object by invoking a parameterless method with given name on the current object, or passes current object to a single-parameter method of another object (or class for static methods). The &lt;span style="font-family:courier new;"&gt;cast() &lt;/span&gt;method performs a cast to given class. The &lt;span style="font-family:courier new;"&gt;instanceOf() &lt;/span&gt;function is a shortcut to &lt;span style="font-family:courier new;"&gt;ClassPredicate which &lt;/span&gt;returns true if the class it holds is assignable from a given class. I also assume statically imported &lt;a style="font-family: courier new;" href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicates.html#or%28com.google.common.base.Predicate...%29"&gt;or&lt;/a&gt; and &lt;a style="font-family: courier new;" href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicates.html#isNull%28%29"&gt;isNull&lt;/a&gt; &lt;a style="font-family: courier new;" href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicates.html"&gt;Predicates&lt;/a&gt; and &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Functions.html#constant%28E%29"&gt;&lt;span style="font-family:courier new;"&gt;Functions.constant&lt;/span&gt;&lt;/a&gt;. (I could replace &lt;span style="font-family:courier new;"&gt;reflect &lt;/span&gt;function calls with a special size and length functions, but I think it's enough to illustrate the idea as it is.)&lt;br /&gt;&lt;br /&gt;The same segment in "normal" coding would look something like that:&lt;br /&gt;&lt;pre&gt;if (object == null) {&lt;br /&gt; return 0;&lt;br /&gt;} else if (object instanceof Collection) {&lt;br /&gt; return ((Collection)object).size(); {&lt;br /&gt;} else if (object instanceof Map) {&lt;br /&gt; return ((Map)object).size(); {&lt;br /&gt;} else if (object.getClass().isArray()) {&lt;br /&gt; return Array.getLength(object);&lt;br /&gt;} else {&lt;br /&gt; return 1;&lt;br /&gt;}&lt;/pre&gt;I don't pretend one is better than the other, but it's interesting enough, I think, and sometimes useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-3926348761177795281?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/3926348761177795281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=3926348761177795281' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3926348761177795281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3926348761177795281'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/11/predicate-function-rule.html' title='Predicate + Function = Rule'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-3560590913316488713</id><published>2007-11-18T19:24:00.000+02:00</published><updated>2008-01-24T14:29:20.744+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Modularity - outside in</title><content type='html'>It is probably a pretty obvious thing, and yet some developers and software architects manage to overlook this.&lt;br /&gt;&lt;br /&gt;When refactoring a project under the flag of "better modularity" one needs to start with northbound, southbound and other external interfaces - remove the coupling between the "big boxes" in the system, and only then go inside each box and improve its architecture. Otherwise we'll find ourselves redoing huge amounts of code over and over. Just moving your middle tier code base to JEE does not solve the problem... it is like adding meat balls to &lt;a href="http://en.wikipedia.org/wiki/Spaghetti_code"&gt;spaghetti&lt;/a&gt;, while what you really want is &lt;a href="http://en.wikipedia.org/wiki/Lasagna_code"&gt;lasagna&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Just a thought.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-3560590913316488713?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/3560590913316488713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=3560590913316488713' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3560590913316488713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/3560590913316488713'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/11/modularity-outside-in.html' title='Modularity - outside in'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-4892090436632631367</id><published>2007-11-14T16:25:00.000+02:00</published><updated>2007-12-11T18:42:24.230+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Walls and bridges</title><content type='html'>Last time I &lt;a href="http://sensualjava.blogspot.com/2007/11/null-safe-access-to-properties.html"&gt;told you&lt;/a&gt; about the &lt;a href="http://docs.google.com/View?docID=d35w57w_0fc5tk2&amp;amp;revision=_latest"&gt;FunctionChain&lt;/a&gt; utility I wrote on top of &lt;a href="http://code.google.com/p/google-collections/"&gt;google-collections&lt;/a&gt;. But I discovered a very strange problem, so I have posted a &lt;a href="http://docs.google.com/View?revision=_latest&amp;amp;docid=d35w57w_2gbvjk6&amp;amp;hl=en"&gt;fixed version&lt;/a&gt; and I'd like to tell you about the problem, since I learned a lot while dealing with it.&lt;br /&gt;&lt;br /&gt;I got a &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html"&gt;Function&lt;/a&gt; instance and I want to find out whether its &lt;span style="font-family:courier new;"&gt;apply&lt;/span&gt; method accepts nulls. In order to do that, I need to check the existence of &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Nullable.html"&gt;@Nullable&lt;/a&gt; annotation on the first parameter of the &lt;span style="font-family:courier new;"&gt;apply&lt;/span&gt; method. The annotation's retention policy is run-time, so the task sounds pretty trivial, right? Wrong!&lt;br /&gt;&lt;br /&gt;How do I get hold of the &lt;span style="font-family:courier new;"&gt;apply&lt;/span&gt; method? At first I thought &lt;span style="font-family:courier new;"&gt;function.getClass().getMethod("apply", Object.class)&lt;/span&gt; should do the job, you know, because of erasure. And indeed a method is always returned, only it was sometimes missing the annotations. This was driving me crazy, until I looked at all the methods of &lt;span style="font-family:courier new;"&gt;function &lt;/span&gt;using reflection. Guess what - there are sometimes multiple &lt;span style="font-family:courier new;"&gt;apply &lt;/span&gt;methods. How could it be - it's an anonymous inner class implementing the &lt;span style="font-family:courier new;"&gt;Function&lt;/span&gt; interface alone...? And then the flashback hit me - right, synthetic &lt;a href="http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#What%20is%20a%20bridge%20method?"&gt;bridge methods&lt;/a&gt;! If I defined my function to transform &lt;span style="font-family:courier new;"&gt;Integer&lt;/span&gt; to &lt;span style="font-family:courier new;"&gt;String&lt;/span&gt;, there would be a &lt;span style="font-family:courier new;"&gt;String apply(Integer)&lt;/span&gt; method in addition to &lt;span style="font-family:courier new;"&gt;Object apply(Object)&lt;/span&gt;. And if I defined my function to transform an &lt;span style="font-family:courier new;"&gt;Object &lt;/span&gt;to &lt;span style="font-family:courier new;"&gt;Class &lt;/span&gt;(equivalent of &lt;span style="font-family:courier new;"&gt;Object.getClass()&lt;/span&gt;) then I got 2 apply methods taking &lt;span style="font-family:courier new;"&gt;Object&lt;/span&gt;, one returns an &lt;span style="font-family:courier new;"&gt;Object &lt;/span&gt;and the other one a &lt;span style="font-family:courier new;"&gt;Class&lt;/span&gt;.  Unbelievable,  ha?!&lt;br /&gt;&lt;br /&gt;Another thing worth noting, is that the annotation is present only on the original method, not on the bridge method. I have browsed the web and found 2 references to similar problem &lt;a href="http://groups.csail.mit.edu/pag/jsr308/java-annotation-design.html"&gt;here&lt;/a&gt; and &lt;a href="http://blog.interface21.com/main/2007/01/16/a-bridge-too-far/"&gt;here&lt;/a&gt;. Both Michael Ernst and Rob Harrop think that not copying annotations to bridge method is a &lt;span style="font-family:courier new;"&gt;javac &lt;/span&gt;bug, but &lt;a href="http://bugs.sun.com/"&gt;Sun Bug Database&lt;/a&gt; has no trace, so I'm going to submit one.&lt;br /&gt;&lt;br /&gt;Ok, at least I knew now what's going on, but how do I find out the right method? I decided that the only way of doing it is figuring out the first parameter in the &lt;span style="font-family:courier new;"&gt;Function&lt;/span&gt; generic definition. I used Neal Gafter's &lt;a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html"&gt;super-type-tokens trick&lt;/a&gt; with some minor enhancements - array support and ability to process arbitrary number of parameters. It allows me to find out the classes that substitute generic parameter definitions, and once I get the first one - it's the &lt;span style="font-family:courier new;"&gt;apply &lt;/span&gt;method parameter class, so I'll use it to look up the method. The &lt;span style="font-family:courier new;"&gt;apply &lt;/span&gt;method return type should not be a problem, because according to &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getMethod%28java.lang.String,%20java.lang.Class...%29"&gt;getMethod JavaDoc&lt;/a&gt; the method with a more specific return type will be found (and I can't imagine how there can be more than two methods with same parameter in our case).&lt;br /&gt;&lt;br /&gt;I had to change Neal's code a bit, because while he's using &lt;span style="font-family:courier new;"&gt;getClass().getGenericSuperclass() &lt;/span&gt;I had to use &lt;span style="font-family:courier new;"&gt;getClass().getGenericInterfaces()&lt;/span&gt; and to find the one representing Function. I noticed that interfaces need to be manually collected from all super-classes, because each class would only return the ones it explicitly implements, and (usually) not the ones that the super-class implements. Bummer... To add insult to injury - there may be several implemented &lt;span style="font-family:courier new;"&gt;Type&lt;/span&gt;s that represent a &lt;span style="font-family:courier new;"&gt;Function&lt;/span&gt; - for example if the parent implements &lt;span style="font-family:courier new;"&gt;Function&amp;lt;T,String&amp;gt;&lt;/span&gt; and child implements &lt;span style="font-family:courier new;"&gt;Function&amp;lt;Integer,String&amp;gt;&lt;/span&gt;, those would be 2 different types, and I, of course, am looking for the most specific one. &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/LinkedHashSet.html"&gt;LinkedHashSet&lt;/a&gt; did the job. Phew.&lt;br /&gt;&lt;br /&gt;You can look at the source code &lt;a href="http://docs.google.com/View?revision=_latest&amp;amp;docid=d35w57w_2gbvjk6&amp;amp;hl=en"&gt;here&lt;/a&gt;, let me know what you think. All in all, it turned out to be much harder than I originally expected, and I am wondering if &lt;a href="http://groups.google.com/group/google-collections-dev"&gt;google-collection folks&lt;/a&gt; would be willing to add similar functionality to their package... after all run-time retention of &lt;span style="font-family:courier new;"&gt;@Nullable&lt;/span&gt; is useless without it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-4892090436632631367?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/4892090436632631367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=4892090436632631367' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4892090436632631367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/4892090436632631367'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/11/walls-and-bridges.html' title='Walls and bridges'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-5694685287955072758</id><published>2007-11-07T16:46:00.000+02:00</published><updated>2008-01-24T14:27:40.968+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='properties'/><title type='text'>Null-safe access to properties</title><content type='html'>First I am going to show a nice side-effect of using properties with &lt;a href="http://code.google.com/p/google-collections/"&gt;google-collections&lt;/a&gt; interface &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html"&gt;Function&lt;/a&gt;. Like many others I am annoyed to write code of the style&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Bar getBarOfThing(Thing thing) {&lt;br /&gt;  Bar bar = null;&lt;br /&gt;  if (thing != null) {&lt;br /&gt;    Foo foo = thing.getFoo();&lt;br /&gt;    if (foo != null) {&lt;br /&gt;      bar = foo.getBar()&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  return bar;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;All the null checks make it unreadable. And heaven forbid I forget one null test... BOOM! NPE! It's much nicer in SQL, for example, where everything's a bag, no results - no problem, join it with whatever you want, you'll just get an empty bag.&lt;br /&gt;&lt;br /&gt;Now imagine that&lt;br /&gt;&lt;pre&gt;foo = new Function&amp;lt;Thing,Foo&amp;gt;() {&lt;br /&gt;  public Foo apply(Thing from) {&lt;br /&gt;    return from.getFoo();&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt; and&lt;br /&gt;&lt;pre&gt;bar = Function&amp;lt;Foo,Bar&amp;gt;() {&lt;br /&gt;  public Bar apply(Foo from) {&lt;br /&gt;    return from.getBar();&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Luckily google-collections have defined a &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Nullable.html"&gt;@Nullable&lt;/a&gt; annotation and I am going to use it to differentiate between functions that can gracefully handle null (e.g. return some default value) and the ones that don't. Now I'm going to define a &lt;a href="http://docs.google.com/View?docID=d35w57w_0fc5tk2&amp;amp;revision=_latest"&gt;FunctionChain&lt;/a&gt; class, that provides me a &lt;a href="http://martinfowler.com/bliki/FluentInterface.html"&gt;fluent interface&lt;/a&gt; to chain the functions:&lt;br /&gt;&lt;pre&gt;  FunctionChain&amp;lt;Thing,Bar&amp;gt; chain =&lt;br /&gt;FunctionChain.&amp;lt;Thing&amp;gt;self().function(foo).function(bar); &lt;/pre&gt;Which I can safely apply to any Thing, including null&lt;br /&gt;&lt;pre&gt;  assertTrue(chain.applyTo(null) == null);&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-5694685287955072758?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/5694685287955072758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=5694685287955072758' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5694685287955072758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/5694685287955072758'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/11/null-safe-access-to-properties.html' title='Null-safe access to properties'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-1224739180055423112</id><published>2007-11-06T16:07:00.000+02:00</published><updated>2008-01-24T14:27:40.969+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='properties'/><title type='text'>Properties for Java</title><content type='html'>The need for better support for properties in Java has been raised many times and in several contexts, and I am definitely not going to repeat the reasoning here. It used to be on the list of features proposed for Java 7, and &lt;a href="http://weblogs.java.net/blog/forax/archive/2007/05/java_property_d.html"&gt;here&lt;/a&gt;'s the last time I read about it on &lt;a href="http://weblogs.java.net/blog/forax/"&gt;Rémi Forax's blog&lt;/a&gt; (quite a while ago). Fred &lt;a href="http://freddy33.blogspot.com/2007/11/abstract-enum-ricky-carlson-way.html"&gt;recently blogged&lt;/a&gt; about another way of addressing the problem via abstract Enums. There were several other interesting proposals, and the main trends are summarized very nicely by &lt;span class="entry-author-name"&gt;Stephen Colebourne&lt;/span&gt; &lt;a href="http://www.jroller.com/scolebourne/entry/java_7_properties_terminology"&gt;here&lt;/a&gt;. Stephen is also the one who &lt;a href="http://www.jroller.com/scolebourne/entry/java_7_property_objects"&gt;first blogged&lt;/a&gt; about bean-independent property object and wrote a reference implementation - &lt;a href="http://joda-beans.sourceforge.net"&gt;Joda Beans&lt;/a&gt; project. I had started developing similar ideas in parallel, and since I have now reached a stage of a nice working prototype, this is what I hope to describe in the upcoming posts.&lt;br /&gt;&lt;br /&gt;First of all, I chose the bean-independent property approach (although it was before Stephen coined it that), because I think the real added value in properties is being able to refer to the property regardless of any particular object instance. Another big design decision is to avoid changing Java compiler, unlike Fred and Rémi. I mean it's a very interesting exercise to play with javac and I am really grateful that Sun made it possible, but... IMO that's the last resort to solve the problem. I mean, even in the best case where the enhancement is accepted by Sun, the earliest time when it will work in an official Java version is Java 7, which is still very far away. And using a home-made javac in production environment is just not very realistic, I mean imagine justifying it to your boss (or customer). I also tried to stay away from bytecode or source generation, and managed well so far, although I might need to use it in the future in order to improve verbosity and safety of my solution.&lt;br /&gt;&lt;br /&gt;So here is what I managed to do: no compiler changes, fully type-safe properties, some null-safety built in (ideas similar to what Stephen blogged &lt;a href="http://www.jroller.com/scolebourne/entry/java_7_null_ignore_invocation"&gt;here&lt;/a&gt;), the properties can have annotations and can be referred to in annotations, they can be applied to existing Java Beans via reflection and they expose their own meta-data via reflection. In addition to all that some Ruby-esque adding/modifying properties on the fly is supported. The last, but not least, is that I have been using &lt;a href="http://code.google.com/p/google-collections/"&gt;google-collections&lt;/a&gt; quite a lot in this project so there's  very nice inter-operation, for example Property implements &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/package-summary.html"&gt;com.google.common.base.Function&lt;/a&gt; and &lt;a href="http://blogs.warwick.ac.uk/chrismay/entry/writing_functional_java"&gt;writing pseudo-functional code in Java using google-collections&lt;/a&gt; and &lt;a href="http://stephan.reposita.org/archives/2007/10/17/creating-a-fluent-interface-for-google-collections/"&gt;fluent interfaces&lt;/a&gt; has been discussed quite a lot recently.&lt;br /&gt;&lt;br /&gt;So this is the blog-post number 0, sort of preface, that hopefully will keep you interested enough to come back and read the blog. To be continued...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-1224739180055423112?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/1224739180055423112/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=1224739180055423112' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/1224739180055423112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/1224739180055423112'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/11/properties-for-java.html' title='Properties for Java'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-1941565442029778354</id><published>2007-11-03T21:34:00.000+02:00</published><updated>2008-01-24T14:25:58.650+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Functional programming for the JVM</title><content type='html'>&lt;p&gt;Dear Java, my good old friend, there is something I need to tell you. You've been my only one for over 10 years,  but now I have trouble staying faithful. It's not you, it's me. And no, I am not moving out, not just yet, because I can't afford to leave all your stuff behind.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;But you don't satisfy all my needs anymore!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I know you are trying, dear, and good people try to help you - here &lt;a href="http://www.gafter.com/%7Eneal"&gt;Neal Gafter&lt;/a&gt; is working hard to give you &lt;a href="http://gafter.blogspot.com/2007/01/definition-of-closures.html"&gt;closure&lt;/a&gt; support, Ricky Clarkson, a true &lt;a href="http://martinfowler.com/bliki/AlphaGeek.html"&gt;alpha-geek&lt;/a&gt; who &lt;a href="http://rickyclarkson.blogspot.com/2007/10/life-in-old-java-yet-closures-prototype.html"&gt;played&lt;/a&gt; with the  &lt;a href="http://gafter.blogspot.com/2007/10/java-closures-first-prototype.html"&gt;first prototype&lt;/a&gt; of &lt;a href="http://www.javac.info/"&gt;Neal's work&lt;/a&gt;, has &lt;a href="http://rickyclarkson.blogspot.com/"&gt;blogged the results&lt;/a&gt;. But, sorry love, I can't wait until the &lt;a href="http://tech.puredanger.com/java7"&gt;big makeover in Java 7&lt;/a&gt;. What do you expect me to do with all these &lt;a href="http://www.robert-tolksdorf.de/vmlanguages.html"&gt;JVM languages&lt;/a&gt; around? These languages inter-operate (well, to certain extent) with your libraries, so I can enjoy all the usual stuff but I can also be more expressive. Here is an example of &lt;a href="http://martinfowler.com/bliki/JRubyVelocity.html"&gt;hooking up JRuby with Velocity&lt;/a&gt; and another one of &lt;a href="http://chasethedevil.blogspot.com/2007/09/fast-web-development-with-scala.html"&gt;writing servlets in Scala under Tomcat&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;You wanna know who they are? Among the young ones, &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; deserves to be mentioned first, alongside &lt;a href="http://jruby.codehaus.org/"&gt;Ruby&lt;/a&gt;, &lt;a href="http://www.mozilla.org/rhino/"&gt;JavaScript&lt;/a&gt; and &lt;a href="http://www.jython.org/Project/index.html"&gt;Python&lt;/a&gt; to name just &lt;a href="http://groups.google.com/group/jvm-languages"&gt;a few&lt;/a&gt;. Classic ones include several Lisp dialects  (e.g. &lt;a href="http://clojure.sourceforge.net/"&gt;Clojure&lt;/a&gt; and &lt;a href="http://armedbear.org/abcl.html"&gt;Common Lisp&lt;/a&gt;), &lt;a href="http://www.gnu.org/software/kawa/"&gt;Scheme&lt;/a&gt; and &lt;a href="http://ocamljava.x9c.fr/index.html"&gt;OCaml&lt;/a&gt; implemented over the JVM as well. Either there is a compiler that produces bytecode, or there's a JVM scripting engine, and sometimes both. I hope one day to make a deeper study and produce a proper comparison table, maybe then you'll understand.&lt;br /&gt;&lt;/p&gt;You think that closures alone aren't good enough reason to have a little flirt on the side with another language? Hmm, consider the fact that "the other language" may offer me hot-swapping of classes, mix-ins, better modularity, pattern matching, better concurrency model and dynamic typing support ... who can blame me for being tempted.&lt;br /&gt;&lt;br /&gt;Still loving you, yours truly but... not entirely.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-1941565442029778354?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/1941565442029778354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=1941565442029778354' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/1941565442029778354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/1941565442029778354'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/11/functional-programming-for-jvm.html' title='Functional programming for the JVM'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-1659373978736505961</id><published>2007-11-01T13:59:00.000+02:00</published><updated>2007-11-09T11:47:51.901+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Beware: Overflows in numeric operations</title><content type='html'>Well, isn't it amazing how huge can be the problems caused by a simple little code piece? Have a look at &lt;a href="http://www.javapuzzlers.com/"&gt;Java Puzzlers&lt;/a&gt; - there are plenty of examples. What is important to understand is that it's no fiction nor Neal and Josh perverted minds. It's out there in the software we use and the one we produce. Want proof? &lt;a href="http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html"&gt;Nearly All Binary Searches and Mergesorts are Broken&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Here is the story of what happened to me. The code was written by a colleague, and at some point became my responsibility. I didn't notice anything wrong when first reviewing it, but later on I had to fix the problems. Now have a look:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Node implements Comparable {&lt;br /&gt;  private long _id;&lt;br /&gt;  &lt;br /&gt;  public Node() {&lt;br /&gt;    _id = IdGenerator.getNewId();&lt;br /&gt;  }&lt;br /&gt;  public Node(long id) {&lt;br /&gt;    _id = id;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public boolean equals(Object obj) {&lt;br /&gt;    return compareTo(obj) == 0;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public int hashCode() {&lt;br /&gt;    return (int)(_id ^ (_id &gt;&gt; 32));&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public int compareTo(Object obj) {&lt;br /&gt;    if (obj == null) {&lt;br /&gt;      return -1;&lt;br /&gt;    }&lt;br /&gt;    if (obj instanceof Node) {&lt;br /&gt;      Node tmp = (Node) obj;&lt;br /&gt;      return (int)(_id - tmp._id);&lt;br /&gt;    }&lt;br /&gt;    return -1;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Looks innocent, right? Why would then new Node(12884902889L).equals(new Node(4294968297L)) be true?! Ah, because 12884902889-4294968297=8589934592=2^33 and when cast to int, 2^33 is of course 0. Bellisimo!&lt;br /&gt;&lt;br /&gt;But hey, here's one even worse. IdGenerator generates long Ids from 2 integers -  persistent &lt;i&gt;high&lt;/i&gt; and in-memory &lt;i&gt;low&lt;/i&gt;, low being incremented all the time and high only when MAX_VALUE of ids have been given out or when the process restarts. So far so good. Look at this function then:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public synchronized long getNewAndReserve(int interval) &lt;br /&gt;                    throws IdGeneratorException &lt;br /&gt;{&lt;br /&gt;  long value;&lt;br /&gt;  if (low + interval &gt;= MAX_VALUE) {&lt;br /&gt;    high = getNewHighValue();&lt;br /&gt;    low = 0;&lt;br /&gt;  }&lt;br /&gt;  value = getNewId(high, low);&lt;br /&gt;  low += interval;&lt;br /&gt;  return value;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;MAX_VALUE is BTW Integer.MAX_VALUE. Now think puzzlers... YES! a sum of 2 integers is an integer, it can NEVER exceed a MAX_VALUE, it overflows to a negative number! The fix for this is to change the condition to (low &gt;= MAX_VALUE - interval) and to add an assertion that (interval &gt; 0).&lt;br /&gt;&lt;br /&gt;All this makes you think whether high-level programming language like Java should help you avoid this kind of problems...? But that's worth of another post sometime. In the meantime, look after your numbers, folks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-1659373978736505961?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/1659373978736505961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=1659373978736505961' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/1659373978736505961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/1659373978736505961'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/11/beware-overflows-in-numeric-operations.html' title='Beware: Overflows in numeric operations'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8866592669665585195.post-6900533973094831574</id><published>2007-10-12T12:16:00.000+02:00</published><updated>2007-10-12T15:33:49.882+02:00</updated><title type='text'>Why is this blog named this way?</title><content type='html'>Because of my &lt;a href="http://java.sun.com/"&gt;main occupation&lt;/a&gt; and &lt;a href="http://www2.lancome.com/_int/_en/catalog/product_color.aspx?prdcode=196019&amp;amp;CategoryCode=AXEMakeup%5EF1_Lips%5EF2_Lip_Lipsticks%5EF3_Lip_Lip_Satiny&amp;amp;"&gt;lipstick colour&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8866592669665585195-6900533973094831574?l=sensualjava.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sensualjava.blogspot.com/feeds/6900533973094831574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8866592669665585195&amp;postID=6900533973094831574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6900533973094831574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8866592669665585195/posts/default/6900533973094831574'/><link rel='alternate' type='text/html' href='http://sensualjava.blogspot.com/2007/10/why-is-this-blog-named-this-way.html' title='Why is this blog named this way?'/><author><name>Yardena</name><uri>http://www.blogger.com/profile/15649241856669571499</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://bp0.blogger.com/_GnOWSH314CY/R1ldVRk0eII/AAAAAAAAAFg/njzlPYVynf4/S220/alice1.jpg'/></author><thr:total>0</thr:total></entry></feed>
