Home

Advertisement

Back on 2005 I wrote about an practical use of what Fowler describes as "Human Interface" operations.

Yesterday I was unit testing some code of my work and I started with a top down approach regarding the way I wanted to write the testing code.

Basically I wanted to have a collection of Command objects that would change my input instances (to a Rule Engine) so I could mix and match easily different updates to trigger different rules, at each unit test (lines 9-10).

I also wanted to make several requests to the Rule engine, before validate the results, since a lot of rules are just fired after other ones being fired on previous invocations (lines 12-13).

But what I wanted the most was to easily express the way I would get results from different iterations (using ranges); and summarize elements and apply operations on the resulting sets of data (lines 15-17).

01:public class TerminalModelTest extends CommandTests
02:{
03:    @Test
04:    public void execute()
05:    {
06:        Transaction t = new Transaction();
07:        t.setAuthorizationDate(new Date());
08:
09:        TransactionUpdateCommand mcc = new SetMccRamdomCommand(5001);
10:        TransactionUpdateCommand codePosPDV = new SetTerminalCodePosPDV("xxxxxx12");
11:        
12:        RuleServiceInvoker commands = new RuleServiceInvoker();
13:        CommandsResultSet results = commands.run(t, 10, mcc, codePosPDV);
14:
15:        assertTrue(results.iteration(0, 4).intProfileVar(3).incrementedEachTime(1));
16:        assertEquals(0, results.iteration(5).intProfileVar(3));
17:        assertTrue(results.iteration(6, 10).intProfileVar(3).incrementedEachTime(1));
18:    }
19:}

To better understand the assertions above one must know that some arrays of integers, double, Dates are sent back and forth to the Rule Engine, inside the engine the end user sees those array slots as proper named structured data, but at this level, where we poor developers reside they are just arrays, and the class that holds them all is the one called 'Profile', so now I can say that I wanted in the line 17:

  • Extract the results from the iterations (or requests) 6 to 10;
  • From those iterations work only with the integer array of values, specifically the ones on the position 3;
  • Check if the difference between each one of those are of 1;

All those methods in place I could start with their implementation, and bellow is the result (with the omission of some unrelated code ;):

Here is the code to run the commands upon the input instances and an special mention to the inner private class 'LocalReturn' just because java does not have tuples or return statements with multiple values (of course one can always return an array, but it's not that beautiful).

public class RuleServiceInvoker
{
    CommandsResultSet run(Transaction t, int times, Command... commands)
    {
        CommandsResultSet results = new CommandsResultSet();
        for (int i = 0; i < times; i++) {
            ...
            for (TransactionUpdateCommand command : commands) {
                command.execute(t);
            }

            input.setTransaction(t);
            LocalReturn ruleServiceReturn = invokeAndKeep[OmittedName2]Variables(input);
            results.add(ruleServiceReturn.output);
            ...
        }
        return results;
    }
    ...
    private class LocalReturn {
        [OmittedName1]Input input;
        [OmittedName1]Output output;
        public LocalReturn([OmittedName1]Input input, [OmittedName1]Output output) {
            this.input = input;
            this.output = output;
        }
    }
}

Bellow the 3 container classes, so I could work exactly with the data I needed for each assertion:

public class CommandsResultSet
{
    private List<ComandsOutputIteration> iterations = new LinkedList<ComandsOutputIteration>();

    public ComandsOutputIterationSet iteration(int start, int end)
    {
        ComandsOutputIterationSet set = new ComandsOutputIterationSet();
        for (int i = start; i < end; i++) {
            set.add(iterations.get(i));
        }
        return set;
    }

    public ComandsOutputIteration iteration(int idx)
    {
        return iterations.get(idx);
    }

    public void add([OmittedName1]Output output) {
        iterations.add(new ComandsOutputIteration(output));
    }
}

public class ComandsOutputIterationSet
{
    private List<ComandsOutputIteration> iterations = new LinkedList<ComandsOutputIteration>();

    public IntProfileVarSet intProfileVar(int idx)
    {
        IntProfileVarSet set = new IntProfileVarSet();
        for (ComandsOutputIteration it : iterations) {
            set.add(it.intProfileVar(idx));
        }
        return set;
    }

    public void add(ComandsOutputIteration iteration) { iterations.add(iteration); }
}

public class ComandsOutputIteration  
{
    private [OmittedName1]Output output;

    public ComandsOutputIteration([OmittedName1]Output output) {
        this.output = output;
    }

    public int intProfileVar(int idx) {
        return output.get[OmittedName2]ProfileVariables().getIntegerValues()[idx];
    }
}
Here an interesting spot where I could use a bit of recursion, at the 'diff' method:
public class IntProfileVarSet
{
    private List<Integer> ints = new LinkedList<Integer>();

    public boolean incrementedEachTime(int diff) {
        if (ints.size() < 2) {
            throw new RuntimeException("Less than 2 elements! No increment can be verified!");
        }
        return diff(0, 1, diff);
    }

    private boolean diff(int current, int next, int diff) {
        if (ints.get(next) - ints.get(current) == diff) {
            return next + 1 == ints.size() ? true : diff(next, next + 1, diff);
        }
        return false;
    }

    public void add(int intProfileVar) { ints.add(intProfileVar); }
}

This top down approach to design certain operation is most pleasant since you already start exactly where you want to get in the end :-)

*The [OmittedNameX]s where placed to protect the Business of this client.

Java.has("closures"); //yet, too verbose

  • May. 21st, 2009 at 9:50 PM

The code bellow shows how Java annonynous inner classes are just static typed closures, with all verbosity but also all behaviour needed :-)

1:import java.util.LinkedList;
2:
3:public class VerboseClosures {
4:    public static void main(String[] args) {
5:        MyList langs = new MyList();
6:        langs.add("Java");
7:        langs.add("Scala");
8:        langs.add("Ruby");
9:
10:        final String msg = "Got ya";
11:        langs.each(new HandleAll() {
12:            public void handle(String s) {
13:                System.out.println(msg + ": [" + s + "]");
14:            }
15:        });
16:    }
17:}
18:
19:class MyList extends LinkedList<String> {
20:    void each(HandleAll handler) {
21:        for (String s : this) {
22:            handler.handle(s);
23:        }
24:    }
25:}
26:
27:interface HandleAll { void handle(String s); }

Back on 2004, Fowler said about closures:

So the first crucial point about closures is that they are a block of code plus the bindings to the environment they came from. This is the formal thing that sets closures apart from function pointers and similar techniques.(Java's anonymous inner classes can access locals - but only if they are final.)

As we can see on lines 10 and 13 our method being sent to the each operation is capable of accessing a local variable (marked as final though). Of course, closures should be much more easy to manually write, that's half of their strengh.

This is again, just to exemplify the concept, even so, anonymous inner classes are extremely handy in the absence of "normal" closures backed up by good syntax sugar.

(*) Extending LinkedList is not encourage, but this is just to make the example simpler

(**) In favour of Java I can say that free IDEs like Eclipse can generate all this verbose code with a few keystrokes (and programmers are more than used to that with their editors, hehe). Hence, leaving us the the best of both worlds, closures but still all the good side of static typing, like safe automated refactorings. And the chances you to be using already a IDE for Java development are rocket high...

(***) Closures are much more pleasant with proper syntax sugar, there's no way do deni it.

Java.has("duck typing"); //yet, too verbose

  • May. 21st, 2009 at 8:52 PM

I'm sure I'm not the first to blog this but let's go: This simple example shows how we can have the Duck Typing effect using reflection on the Java platform:

1:import static java.lang.System.out;
2:
3:public class VerboseButStillDuckTyping
4:{
5:    public static void main(String[] args) throws Exception
6:    {
7:        quack(new WoodDuck());
8:        quack(new Object());
9:    }
10:
11:    static void quack(Object obj) throws Exception
12:    {
13:        Duck.class.getMethod("quack", null).invoke(obj, null);
14:    }
15:}
16:
17:interface Duck { void quack(); }
18:
19:class WoodDuck implements Duck
20:{
21:    public void quack() { out.println("Quaaack!"); }
22:}

Above we are invoking the quack method on two references, one that has the needed implementation and the other which does not have. As expected the second invocation raises an runtime error, as with any dynamic language :-)

Of course this is just a proof of the concept and not what should be a regular practice on development with the Java language. This is just to remember that people very often does not proper recognize the dynamic features of the Java runtime environment.

Martin Odersky says on this interview that types can be really annoying for small scripts but for the other case, big systems (real production systems) the refactoring that it allows and the reliability of your code are a fair (or small) price to pay:
They are probably less important when programming in the small. Types can be in a spectrum from incredibly useful to extremely annoying. Typically the annoying parts are type definitions that are redundant, which require you to do a lot of (finger) typing. The useful parts are, of course, when types save you from errors, when types give you useful program documentation, when types act as a safety net for safe refactoring.
I could not agree more, if I'm doing a 50~100 lines script I'm probably not using a full IDE and the Java anonymous inner class full syntax will not be generated by my jEdit (or any other text editor), so a friendly idiom for closures are really a differential.

At the same time I'll not need to maintain this script for months or years, or might never read it again, hence the possibility of powerful automated refactoring (that for instance IntelliJ of Eclipse provide) are not a need, like they are and we already take them for granted on regular systems that we deploy to hundreds/thousands of users.

Automated refactorings are the open gates to the easy and encouraged evolution of software code, and statically declared types are their very foundation.

The Simplicity Pattern

  • May. 20th, 2009 at 6:01 PM

{title updated}

I was talking to Miguel about the advantages and disadvantages of the CGI way of making web apps, and had in mind the yearly years of it and how alternative solutions like Java Servets proposed a much more sophisticated way to handle the emerging web application needs. Then I stumble upon a @voidspace's blog entry: Is CGI dead? and the argument of simplicity (as I remember Miguel rightfully pointed this also) was put on the table and I don't disagree at all with it. And interesting is to notice that even Java Servlets simplicity (although not as simple as the CGI protocol is) made it the very foundation of several other famous frameworks, which in the end do a lot of the dirty work that software developers used to have.

It's always the tradeoff: with a very simple (but elegant) solution you easy it's adoption, and on its solid base several other layers of software can be built, providing each one more features to the components that will lay on top.


The funniest version of the History of Programming Languages, just one small piece bellow:
1970 - Guy Steele and Gerald Sussman create Scheme. Their work leads to a series of "Lambda the Ultimate" papers culminating in "Lambda the Ultimate Kitchen Utensil." This paper becomes the basis for a long running, but ultimately unsuccessful run of late night infomercials. Lambdas are relegated to relative obscurity until Java makes them popular by not having them.
And the best:
1987 - Larry Wall falls asleep and hits Larry Wall's forehead on the keyboard. Upon waking Larry Wall decides that the string of characters on Larry Wall's monitor isn't random but an example program in a programming language that God wants His prophet, Larry Wall, to design. Perl is born.

:D

JVM.scale(Ruby.app)

  • Nov. 14th, 2008 at 8:27 AM
Could the Java Platform be the a major helper in order to help Ruby apps to scale more easily?
Ruby and JRuby still generate a lot of enthusiasm. More and more Ruby programmers are looking at JRuby as their Ruby projects mature — when they move into heavier loads, larger systems, more cores, more processors. Most significantly, as Ruby development branches out into larger enterprises where deployment on Java servers is important, JRuby is seen as the solution.
A less obvious advantage to JRuby is that it may already be a better Ruby implementation. Certainly that's where it's headed — faster, better use of memory, better use of resources. Many Ruby programmers are starting to see these advantages.
So, people are beginning to understand that whether it's based on Java or the standard implementation, JRuby is better at handling resources, better at taking advantage of multi-core processors, and so on. This is the impetus for people to try JRuby, and to stay with it once they've tried it.
It's really sad that most people simply ignore the fact that the Java Virtual Machine supports multiple language for so many years now.

The Java VM is multi language since its conception, as its runs above the called Java bytecodes which is the needed layer of indirection between it's languages and the VM, with the compilers the actors needed to fill in the gap.

Many years before now we could play with so many languages that compiled to the JVM. I hope JRuby and JPython communities keep up with their great work a take advantage of such mature and sophisticated JVMs we have (available for free) nowadays!

A Maven/common/myth

  • Oct. 22nd, 2008 at 7:33 AM
A maven (also mavin) is a trusted expert in a particular field, who seeks to pass knowledge on to others.
Yesterday I read an interesting post from the Maven Diaries about a common Maven myth regarding his famous directory structure:
The directory structure used by a Maven project has never been fixed. There are defaults, yes, but they can all be overridden. I have had many clients over the years that have had existing structures that needed to be preserved for various policy reasons, or projects that had lives spanning many branches into the past where changing the directory structure would have made merging a nightmare. The defaults are easy to change at a project, or organizational level. That the structure is fixed in Maven is a myth.
Jason van Zyl also talks about the advantages of using a folder structure as an standard, a how maven made success promoting it, but also points that the default structure alone is not a good reason to use Maven. The also depicts some of the advantages Maven can provide like:
  • Help to quickly onboard new developers;
  • Find resources for your build and release team;
  • Reach a standard in your department, or your organization;
  • Integrate with disparate parts of your organization;
  • Incorporate third party libraries;
And does a very honest statement:
Maven has many flaws, but it is very usable by a large number of groups. Maven is also not static. Not many people know that .NET and C toolchains have been created for Maven, or that with a few new implementations of internal components that Maven can build OSGi components directly from manifest information (look Mom, no POM!), or that you can write Maven plugins in Groovy, Ruby, or Ant script. Many of these things are unknown because the Maven project has admittedly been terrible at documenting these attributes and features. This is a failure at the Maven community level that we are trying address.

It's not only sad that Maven has so many strengths and also such a huge flaw like the lack of good documentation, and I can tell this is true for at least the past 3 of 4 years, when I first looked at Maven 2 site in order to start using it. In 2006 I started again using it at a company I worked for, the same poor docs were there and seems that this situation is still the same on 2008. Or perhaps as a person who's not so aware of the last advances in the project I'm having a unfair view of it?

[Update] According to Brian Fox, the new book "Maven: The Definitive Guide" authored by some fellows of Sonatype is the new documentation improvement the Maven docs needed :) 

Tags:

A peek at Java::Google Knols

  • Sep. 19th, 2008 at 1:54 PM
Inspired by the last appearance of the Google Knol on /. (Wikipedia like service) I checked one more time for Java related articles on their base. I found this Java SE 7 knol, nothing that impressive but interesting, worth a look :) On the oficial release of Google Knol there were yet no articles talking about Java.

The ./ article talks about the difficulty people find citing Wikipedia articles as a source due to it's highly dynamic nature and the viral aspect of the GNU Free Documentation License:
I've been suggesting for some time that Wikipedia, or some fork of Wikipedia, should allow users to "sign off" on a version of an article, and then lock that article against future edits until the signer had approved them. The signing off would allow people to cite a Wikipedia article as a source that had been vetted by at least one person (with confidence in the source depending on that person's credentials). The signer's identity (and sometimes, their credentials) could be confirmed using several methods, such as verifying an .edu e-mail address. Users could still submit edits, but they would have to be approved by the article verifier. Different users could sign off on different versions of the same article, and readers would still have the option of viewing the latest version of an article, with all of its unmoderated edits (which is what you're looking at on Wikipedia most of the time).
...
And therein lies the logical incompatibility between the GFDL and the CC-BY publishing options currently allowed by Knol. If you copy GFDL-licensed content from Wikipedia, you are agreeing that for any copies or derivative works that you create, you will not only permit other users to remix them, but that you will require those other users to agree to the same terms for the remixed works that they publish. If you published such content on Knol under the CC-BY option, you would be granting the reader permission to incorporate the work into their own derivative work which they could then publish under an All Rights Reserved license.

Trying to keep up with the best practices

  • May. 12th, 2008 at 8:57 PM

I'm always checking the new version of the Netbeans IDE, besides the fact still think Eclipse is the best free IDE available nowadays.

One of the things I first check (since the versions pre 5.x) are the available Wizards and mostly the web application and Swing ones, in search of live examples of the best practices applied to the frameworks or libraries in use.

I've always been a fan of the user interface toolkit of the Java Platform, a great part of it is what we know as the Java Swing. But it was not before a critical moment in my career in the year of 2005 that I finally decided to do experiments with it. From this personal initiative my Text Adventures Suite project was born (Hosted at the Google Code). Nevertheless the main focus of that project at that time was to get an running implementation ASAP, the swing best practices had to wait (The full context of this project would require a post of its own).

When I manage to give TAS some hours of my free time, between adding new features and refactorings I try to look again, and more closely, at the best practices of the tools involved, and Swing itself is by far the most used library.

In the last days, the Wizards of the version 6.0.1 of Netbeans brought to my attention the Swing Application Framework.

The main aspects of it are depicted bellow:
  • Application lifecyle, notably GUI startup and shutdown;
  • Support for managing and loading resources, like strings, formatted messages, images, colors, fonts, and other types common to desktop applications;
  • Support for defining, managing, and binding Actions, including Actions that run asynchronously (in the "background");
  • Persistent session state: support for automatically and selectively saving GUI state from one run of an application to the next;
  • Performing Background Tasks.
But it is still just a prototype :(
The intended audience for this snapshot is experienced Swing developers with a moderately high tolerance for pain.
Finally, it's important to note that it is also largely inspired on the JSRs:

An introduction article can be found here.

With some lucky I can make the proper updates and make my huge GUI classes less complex, and in the meantime, remove some of the business logic of it (yeah, bad karma points to my score ;)

swing logo

My beanshell indenter, alpha version

  • May. 9th, 2008 at 12:59 AM
Just finished the first alpha version of my beanshell source code indenter for the TAS!
It can transform code like this:
   1:          print("Hello world");
   2:    if(player.someAttribute == "someValue") { if(true) {a++;} doFirst();
   3:     doIt();
   4:            for ( Object typedElement: foo )   {
   5:        print( typedElement );}
   6:        
   7:                  print("Hi Duke!");
   8:
   9: } else {
  10:     doThat(); if(false) {run(a); b--;}}
Into this:
   1:print("Hello world");
   2:if(player.someAttribute == "someValue") {
   3:    if(true) {
   4:        a++;
   5:    }
   6:    doFirst();
   7:    doIt();
   8:    for ( Object typedElement: foo ) {
   9:        print( typedElement );
  10:    }
  11:    
  12:    print("Hi Duke!");
  13:    
  14:}
  15:else {
  16:    doThat();
  17:    if(false) {
  18:        run(a);
  19:        b--;
  20:    }
  21:}
  22:
Here is the hackish code (forgive the quality of it, it had less than a couple of hours of my attention so far):
   1:/**
   2: * Created by Bruno Patini Furtado [http://bpfurtado.livejournal.com]
   3: * Created on 08/05/2008 21:50:46
   4: */
   5:package net.bpfurtado.bsh.indenter;
   6:
   7:import static net.bpfurtado.commons.io.FileUtils.linesOf;
   8:
   9:import java.io.File;
  10:import java.util.regex.Matcher;
  11:import java.util.regex.Pattern;
  12:
  13:public class Indenter
  14:{
  15:    private int level;
  16:
  17:    public String indent(File file)
  18:    {
  19:        StringBuilder buffer = new StringBuilder();
  20:        for (String line : linesOf(file)) {
  21:            buffer.append(indent(line));
  22:        }
  23:        return buffer.toString();
  24:    }
  25:
  26:    private String indent(String origLine)
  27:    {
  28:        StringBuilder lines = new StringBuilder();
  29:
  30:        origLine = origLine.trim();
  31:        Matcher regexMatcher = Pattern.compile("([\\{\\};])").matcher(origLine);
  32:
  33:        String line = null;
  34:        boolean found = regexMatcher.find();
  35:        if (!found) {
  36:            line = tabs(level) + origLine;
  37:            lines.append(line + "\n");
  38:            lines.toString();
  39:        }
  40:
  41:        int lastIdx = 0;
  42:        while (found) {
  43:            int idx = -1;
  44:            String sign = regexMatcher.group(0);
  45:            if (sign.equals("{")) {
  46:                this.level++;
  47:                idx = regexMatcher.start();
  48:                line = tabs(level - 1) + origLine.substring(lastIdx, idx).trim() + " " + sign + "\n";
  49:                lines.append(line);
  50:                lastIdx = idx + 1;
  51:            } else if (sign.equals("}")) {
  52:                idx = regexMatcher.start();
  53:                String lineCore = origLine.substring(lastIdx, idx).trim();
  54:                if (lineCore.length() > 0) {
  55:                    line = tabs(level) + lineCore + "\n";
  56:                    lines.append(line);
  57:                }
  58:
  59:                this.level--;
  60:                lines.append(tabs(level) + sign + "\n");
  61:                lastIdx = idx + 1;
  62:            } else {
  63:                idx = regexMatcher.start() + 1;
  64:                line = tabs(level) + origLine.substring(lastIdx, idx).trim() + "\n";
  65:                lines.append(line);
  66:                lastIdx = idx;
  67:            }
  68:            found = regexMatcher.find();
  69:        }
  70:        return lines.toString();
  71:    }
  72:
  73:    private static String tabs(int n)
  74:    {
  75:        StringBuilder b = new StringBuilder();
  76:        for (int i = 0; i < n; i++) {
  77:            b.append("    ");
  78:        }
  79:        return b.toString();
  80:    }
  81:}

Horstmann Interview at SDN: Java Community

  • Mar. 16th, 2008 at 6:40 PM
A very interesting point of view of Cay Horstmann published on his interview at SDN:
Horstmann: When I compare blogs about C# and Java technology, I'm struck by the differences in tone. Many C# bloggers talk about the latest goodie that came from the heavens at Redmond and how they might use it. But the Java technology bloggers write about why something is no good and needs to be improved. Now it could be that C# is such a wonderful creation that no one needs to complain. But I don't think so. If it were, more people would use it by choice. Instead, I think that the Java community has a culture of healthy whining.

We have both the will and the means to improve things and do not passively accept what is handed to us. We don't wait for Sun or someone else to fix what doesn't work. We tinker in a thousand projects and build improved libraries, frameworks, and even new languages. The open sourcing of the Java platform will enable it to be viable for years to come.

The strong and active community behind Java has always being one of its fundamental strengths.

Tags:

Jeremy Ellison makes a strong argument talking about his game implemented in Lisp. More precisely Corman Common Lisp used as glue to several game related APIs:
Before you dismiss my game project as a toy, let me build a little credibility with you. I am using Gamebryo, which is a pretty popular graphics solution for AAA games and Korean MMOs, Chipmunk 2D physics, Flash 9 for my UI, and fmod for sound. All these packages are wrapped and exposed to my Lisp environment.
That's a response to a terrible rant made to Java by Steve Yegge.
He also puts a great emphasis on LISP macro mechanism, which IMHO is the very soul of the LISP way of programming.
And in the middle of it all he talks about the game industry prejudice against modern languages, dynamic and with Virtual Machines:
The video game industry is waking up to the idea that multicore programming is hard, particularly hard in C++, and that C++ is not efficient for rapid prototyping in terms of programmer effort. This is occurring at the same time that Microsoft and Sun are beating their drums and promoting two VM based languages that are better than C++, where better is defined as easier to program in the host language with only a small performance loss. Both C# and Java are subsets of C++ that are cleaner, and with additional features to make it easier to write code that is self inspecting.

In summary, the text is short, clear, informative and he makes good points in favour of LISP, such a polemic language.

This is probably one of a few posts on which I'll comment several passages of a polemic Steve Yegge post titled Code's Worst Enemy.

He starts complaining about how huge is the code base of one of his projects and how the Java programming language is the sole guilty actor in this play, or should I say a Farce instead of a regular play?
The bad thing that happened to me is that I wrote a beautiful game in an ugly language, and the result was lovely on the outside and quite horrific internally.
His work is beautiful, the ugly character here could never be his design techniques which led to a 500K maintenance nightmare (according to his very own words) but no one less than the horrendous Java programming language.

But, let's start with some of the things that caught my attention, Yegge starts with one dangerous contradiction:
The average industry programmer today would not find much wrong with my code base, aside from the missing unit tests (which I now regret) that would, alas, double the size of my game's already massive 500,000-line code base. So the main thing they would find wrong with it is, viewed in a certain way, that it's not big enough. If I'd done things perfectly, according to today's fashions, I'd be even worse off than I am now.
Wow, first he regrets not using Unit Tests, which according to his words would double the size of his code base and would lead him to a worse maintenance problem than the one he has created so far!

I mean... we've struck gold here... how can someone be so wrong about such a good development practice? On thing is saying you regret not having used the technique, another one is to held it responsible for the very opposite effect it is suppose to have!

Unit tests are angels when you have a huge code base and you need to make changes to that code, it will rapidly light noisy red lights to guide you directly to the bugs you have created in the last hours or minutes of work! If done correctly and diligently of course.

It cannot be considered an increase on the code base of your system, because it's not part of your system, it just tests the system!

Automated Tests are all about warning you as fast as possible about new bugs and telling you precisely where they manifest themselves.

But Yegge tries to clarify his point:
Some people will surely miss my point, so I'll clarify: I think unit testing is great. In fact I think it's critical, and I vastly regret not having unit tests for my game. My point is that I wrote the game the way most experienced programmers would tell you to write that kind of system, and it's now an appallingly unmanageable code base.
That is certainly a very strong argument if you know what sarcasm is... You can't blame the creator of such a huge mass on unmanageable code because... every experienced programmer would do the same! (according to Yegge, of course...)

But he continues...
If I'd done the "right thing" with unit tests, it would be twice appalling! The apparent paradox here is crucial to understanding why I hold my minority belief about code base size.

Well, that's indeed a paradox, a paradox of someone who could not get yet what automated tests are all about.

Josh Bloch talks about GWT

  • Jan. 16th, 2008 at 10:53 PM
I've just watched this interview with Josh Bloch on Voices that Matter.
Some interesting points Josh points that I took note were: (just a rough copy and paste of my notes)
  • C safe type system is nowhere near robust and fast as you can do with Java;
  • When you talk about Java you talk about the Platform. I've personally insisted on this so many times...;
  • Why use the Java Platform:
    1. Everybody knows, research popular;
    2. Rich ecosystem tools (talks about Eclipse but not Netbeans);
    3. Libraries good and stable;
    4. Safe well designed language;
    5. Great books;
  • Design patterns: Static factory vs. Builder patter;
  • Concerns about better Concurrency API and tools, since nowadays we have in a more popular fashion multiple CPUs power;
  • Java Thread APIs where great for the last years but not anymore;
  • All Java performance improvements since its first version; 50x faster from JDK 1.0 until now;
  • Stealing merge sort algorithms from the Python API;
  • The joy of the FindBugs tool;
  • JUnit and testing and concurrent applications, how this successful API does not fit into the concurrent scenarios;
  • First thing understand the requirements, before building your software;
  • Java and the OLPC;
  • The Java URL implementation of equals and hashcode is totally broken! Never use it on Maps!!! (FindBugs detects it!);

Java Strings 101 and criticism

  • Dec. 10th, 2007 at 7:58 AM
I was very disappointed to see the code bellow in the blog of Erik Sink, one guy I really respect.

String a = new String("foo");
String b = new String("foo");
if (a == b)
{
      // this will never happen
}

The complaint ,which I can understand to some extent, is that this kind of comparison in Java does not compare the actual Strings but the pointers of the two objects.

What I dislike here is that the special way Java treats its Strings is very well documented and present in every introductory material:
http://java.sun.com/docs/books/tutorial/java/data/strings.html
Note: The String class is immutable, so that once it is created a String object cannot be changed. The String class has a number of methods, some of which will be discussed below, that appear to modify strings. Since strings are immutable, what these methods really do is create and return a new string that contains the result of the operation.
And didn't the usual simple quotation marks syntax was not used? I can think in the need of the String constructor if I have for instance an array of bytes, otherwise why not simply use the most common String syntax?

I would not call Java not intuitive because in most cases the == operator works as expected, although I don't like using it never, I always rely on the equals (because it works in all cases). And what was not intuitive was the usage of the new operator to initialize new Strings.

That said, Erik does not make a rant on Java based on that and I'm always looking forward his new posts, he is a great software developer and has a huge experience in the battle field, ages bigger than my small incursions into this fascinating world of software development :-)

Tags:

A powerful java wiki

  • Nov. 23rd, 2007 at 6:37 AM
From TSS with my highlights:
XWiki is a generic wiki platform allowing the development of collaborative applications. It's developed in Java under the open source LGPL license.

The XWiki platform allows for rapid application development by providing common runtime services such as Rights Management, Page Rendering, Transparent Storage, Page Manipulation (edit, delete, rename, view), Versioning, Authentication, Macros, Scripting (Velocity and Groovy) and more. These services are available as APIs in Java, XML/RPC and GWT. The Java APIs can be used either in Java Plugins or directly from within wiki pages using the Velocity and Groovy scripting languages.
I've been using the Wikispaces in a personal project at SourceForge. It's rather simple but good enough, my only complain is that the service is too slow on SF.

wikispaces logoxwiki logo

Android OS and Eclipse

  • Nov. 12th, 2007 at 9:56 PM
A nice and short video of how to develop a small Android Java application using Eclipse. It shows all your contacts and dials the preferred phone number of the selected one.

My friend Frank Sands sent me the post from the engadget.



google android logo

Posted by kdawson on Saturday November 10, @12:43PM
from the one-can-hope dept.
An anonymous reader writes "With the first anniversary of open-source Java coming up November 13, a Sun official believes the project could bear a fruit much sought-after in the Java community: a Java port to the Apple iPhone. Apple has not released a version of Java capable of running on the popular device. But Sun's Terrence Barr, technical evangelist for the Java mobile and embedded community, believes Apple's plans to release an SDK for iPhone in early 2008 may result in the open-source phoneME version of Java ME winding up on iPhone."
I shall arise the same, though changed

That's how the Platform Lead for Java SE, Danny Coward, describes the process of incorporating new features in the next major releases of the Java language.

He compares good design principles making us recognize instantaneously different classic car brands even they having changed so much in the last decades. He considers that a good set of core principles are always respected in the new releases of these products and I agree with him.

Have you ever wondered why some cars are instantly recognizable? Seen a new BMW in the last 25 years without twin headlamps? Wondered how an SUV can still look like it's a Porsche? How a Corvette can still convey "Corvette" after over 50 die-hard years?
He says the new Java language features must evolve following its core principles and I personally like this idea.

These are other good points from the article I'd like to highlight:
Innovation for established products is arguably more difficult: You have customers who already like your product who you want to keep.
we need to scan the horizon for ... non-disruptive innovations that have widespread useful consequences

And finally he wisely states: Reading is more important than writing and One language, with the same meaning everywhere.

As much as I liked the article there are some new features he puts under the light that makes me worry, they are:
  • Closures, Block Constructs, Method References;
  • Operator Overloading;

I really don't think these features should use the classic Java language as a home as I can live pretty well with the static nature of anonymous inner classes and I love to know that [] will be always used on arrays and my plus sign will always add numbers/Strings without my need to investigate it.

Eadem Mutata Resurgo

Latest Month

November 2009
S M T W T F S
1234567
891011121314
15161718192021
22232425262728
2930     

Tags

Syndicate

RSS Atom
Powered by LiveJournal.com
Designed by Tiffany Chow