Archive for Java

The Little Guy

I said at the end of my sort-of review of Effective Java that a few things bugged me while reading it, not about the book, but about Java itself. These aren’t totally well-formed in my head, so I’m going to try to write them down in an attempt to get them to make sense. This may or may not work. Stay with me here.

I’m going to flick through the book to refresh my memory of stuff, so my thoughts will roughly follow the same order as the book, if you want to follow along.

Ah, here we go. A recommendation from chapter 2 (and the first itemised piece of advice in the book).

Item 1: Consider static factory methods instead of constructors

The gist of this is that constructors have some drawbacks. To name a few: they don’t have descriptive names; they always create a new object, where you might want to reuse an existing one; and they’re forced to return an object of that class, where you might want to use a subclass. Wrapping it in a static factory method gives you control over these things, and by making the constructor private or protected you can make the factory method the primary way for an API user to get a new object.

So, good advice. But there’s a little guy in the back of my head (you know the guy) who starts whispering little subversive things at points like this. He’s always yammering on about something, so it’s usually easy to ignore him, and I wasn’t really listening to him when I was only up to chapter 2… but by the time I was halfway through the book he’d said sensible things enough times in a row that I sort of started paying attention. Anyway, here’s what he said here:

Shouldn’t a language feature called a constructor support the ways that someone might want to construct an object? Why are we being advised to work around it?

Now, look, there are plenty flaws in that argument – the advice is that you consider using it where appropriate, not that constructors are always bad; and nowhere is it written that a language feature has to be usable from anywhere in its raw form for it to be useful. So the little guy hasn’t scored any points yet.

But keep this in mind. Later on (if I stay interested enough in the topic to keep writing about it) we’ll come back to why the little guy’s point was deeper than I realised at the time.

Okay, moving on. The next Item is about using an intermediate builder object when there are a lot of constructor parameters, especially if some of them are optional. There’s a comment in this section that I want to quote because it sort of sums up what my poorly-structured rant is about, albeit bluntly, and from a slightly different direction.

The Builder pattern simulates named optional parameters as found in Ada and Python.

And, I’ll add, most Lisp dialects, C#, Scala and, of all things, Visual Basic. Oh, and recent versions of Fortran. (Cheers to Rosetta Code. Also: there are recent versions of Fortran?) I’m not arguing with Bloch here – it’s good advice for writing Java – but if you have to write boilerplate to simulate what other languages give you for free, it might be a hint that the programmer is doing work that really lies in the bailiwick of the compiler.

I’ve clocked slightly more hours writing Java than Python, but the Python hours are more recent. Reading this made me think about closing the book and swearing allegiance to Python. (Apart from the performance problems and lack of type safety. Oh, and I wasn’t reading it with the intent of converting. I was just trying to stay up to date. Seriously. Guido, I’d never leave you.)

I’ll leave it there – only two Items into the book – but to give you an idea of where the rant is heading, here’s a short talk by Rob Pike about Go.

Leave a Comment

*pop*

…is the sound my head made when reading this post about lazy error handling in Java. You see, functional programming and Java are completely disjoint sets of neurons in my head. Seeing Java code formatted like Lisp and doing lazy evaluation… requires some rerouting.

And when the post finished with:

But there’s more to come, as Thrower has higher aspirations still. It’s not just a functor. It’s a monad.

Okay, look, I followed a link into the middle of this. I really should start somewhere earlier. I wonder if there’s a Lambda Calculus for Dummies?

Or The Complete Idiot’s Guide to Forcing Programming Methodologies into Languages that Go Out of their Way Not to Support Them?

Leave a Comment

Sudoku speedup

Previous version: 10 hours.

With the latest improvement: 33 seconds.

1         9   15 5 12   3        
    2   3     7   1     10   13  
    13 7           14 11   9      
16 12   8     2         7     3  
13       11 10 3   2           14  
  4         7   12              
14 5     15     9   7     4     6
        12     16 4     6   11 10 13
15   14     8       9 16 2   12 7  
    1 5 6     13     15   2      
10 9       11     13 8 14     4   16
      16     9 14   10       13 5  
      6 5     8   2            
  13       2   12 15 5       1 11  
8 1   3                 15   2  
      9   15     11   7 13 5      

Leave a Comment

4×4 Sudoku

The Java sudoku solver is coming along nicely. There are still a few obvious things missing; in particular there’s a simple strategy that should speed up solving quite a bit. (Which I won’t try to explain here.)

After that’s done, there’s a plan in the back of my mind to make it multi-threaded, or possibly even distributed. I’m not sure about the best place to split it up yet… For solving a puzzle that’s known to have one solution, or towards the end of generating a puzzle where only a few of the branches are valid, splitting up the brute force tasks should be fairly useful; but for choosing a value for the first cell of an empty puzzle, every branch has a valid solution, so having multiple threads exploring all of them is pointless. The most profitable time to split up the task would be early enough that the available branches are deep, and will take a while for each of the threads to explore; but late enough that only one of them is expected to be valid.

The interesting question is whether it’s possible to recognise that point.

Anyway, here’s a result from the current version. The 4×4 (er, 16×16) puzzle below took just over ten hours to generate.

6             2   15     16   11  
  2   4   3 8 12   5            
5 16 11     13 4           1   14  
  8 13           14           9 4
      14     1     7   3   4 6  
12 13 7       6 15         2   8 9
3       16 12     10     13       7
9           13 5       16   1    
  7   11         8   3       2  
13     16 8         10 1 7 4 3   6
  6           11     9 2       1
    8 1   5               13    
  15     14   3 16 2   5   12      
          2     4              
14     12   7 9 1     16   11   13  
2                 11       5 1 3

Comments (2)

Java Sudoku

Ever since SudokuBan (bit rot guilt guilt), a sudoku solver has sort of been my one-step-beyond-”Hello world” program for new languages. Although Java isn’t exactly a new language for me, the re-familiarising process is more or less the same; so I kicked off a sudoku solver in Java. And just a few minutes ago I sort of got it trivially working.

By “sort of” and “trivially” I mean that I’ve tested its ability to solve an empty grid. That is, given an empty 3×3 (or more correctly 9×9) sudoku grid, it can fill it with numbers that would be a valid solution. It doesn’t do randomness yet, so the solution it finds is by some definition the “first” valid sudoku (adding randomness is the first step to generating new puzzles). In principle it should be able to solve existing puzzles, but I haven’t tried it yet. In fact I don’t think the class has enough exposed to be able to fill in the puzzle’s starting cells. Hmm.

The Mercurial repository is public if anyone would like to follow along, or copy my copious mistakes.

Incidentally, the “first” sudoku looks like this:

+---+---+---+
|123|456|789|
|456|789|123|
|789|123|456|
+---+---+---+
|231|674|895|
|875|912|364|
|694|538|217|
+---+---+---+
|317|265|948|
|542|897|631|
|968|341|572|
+---+---+---+

Leave a Comment

Encapsulation vs Security

Here’s my ten-word review of Joshua Bloch’s Effective Java: If You Write Java, You Need To Read This Book.

I wanted to say that up front, because I’m about to talk at great length about one of its shortcomings, which would give the impression, purely by wordcount, that I don’t think it’s a good book. This is just a reflection of how many more words it takes to explain a negative point than a positive one. The book is irrefutably useful and you should read it (if you write Java).

To give the issue a bit of context, here’s a fact that I was only dimly aware of before doing some mid-reading research:

If you get the security settings right, the Java Virtual Machine guarantees access control.

If you declare a field private, and you’re running a trusted JVM, and the security manager is set to disallow JNI and changing accessibility through reflection and a handful of other things, then you can run untrusted third-party code in the same process and even pass those objects to the untrusted code and it will never be able to get at the private field.

This is such a big deal that I don’t understand why it isn’t a bigger deal. It’d be impossible to make this kind of claim in a natively compiled language, because you can always pointer-arithmetic your way to the private data. Python makes only the vaguest of gestures in the direction of information hiding, and certainly doesn’t guarantee it. Maybe C# and the rest of the .NET family make some guarantees, I’m not sure (although whether you’d trust Microsoft to get the security right is a different story (but then, the same question should be asked of Sun Oracle)).

Here’s the issue though. This means that access control in Java actually has two different (although overlapping) purposes: encapsulation, and security. And they’re not the same thing.

Encapsulation is about reducing the complexity and increasing the abstraction of classes by hiding their implementation. Security is about stopping people from seeing or changing data that they shouldn’t be able to. Security is for protecting users from malicious programmers; encapsulation is for protecting programmers from themselves.

Security at this level isn’t always possible. If you’re writing a library for other people to use in a JVM that they control, you can’t expect to hide anything from them – they can turn the security manager way down, or change your bytecode, or run a modified JVM. (At university we had an assignment that involved black-box testing of algorithms that we were given as obfuscated JARs. I worked out that you could peek at some of the internals by rebuilding the Java standard libraries with String declared non-final, and passing in a subclass with some instrumentation added. And no, I didn’t actually do it.)

Most times that someone compromises their own system, they can only do damage to themselves. Of course, you probably still want to make your library as tight as possible so that it isn’t a security hole for other code that it interacts with. The point is that it can be dangerous, or at least an unnecessary programming burden, to rely on language guarantees for security if you’re not always going to have control of the platform.

On the other side, encapsulation isn’t always desirable. Well, maybe it is. There’s heated debate about this. Some people (many of them Java devotees) argue that programmers will find and use every available undocumented feature, and anything you inadvertently expose will doom you to support it forever. Others (e.g. a high proportion of Python fans) say that an API is as much a social contract as a technical one, and that if someone wants to work around an interface that doesn’t meet their needs then, well, we’re all adults, and they’re welcome to do so as long as they accept the consequences if the implementation changes.

The point is that encapsulation and security are different requirements. Making a field private because it’s an implementation detail is one decision; making a field private because using it would open a security hole is a very different decision. If you try to squeeze the concepts into one then at some point you’re going to make a poor decision. And now we get to my one (and minor) gripe with Effective Java: it doesn’t do enough to distinguish between them.

Some of Bloch’s points (e.g. Item 10: Always override toString) are clearly about programmer-friendly abstractions. Other points (Item 76: Write readObject methods defensively) are clearly about security – no programmer would (or could, reliably) exploit it just to get around API restrictions. In one place (Item 39: Make defensive copies when needed) he mentions that a particular security measure has a big enough performance hit that it can be valid to leave it open, if it’s in an environment where misuse will only hurt the (mis)user. But in other places it’s not so clear exactly what kind of advice he’s giving, which could lead readers to apply the advice in the wrong way.

Part of this might be that Bloch is writing from the perspective of someone who worked on the Java platform APIs, which sit in the part of the Venn diagram where encapsulation and security do overlap: they’re widely used, so any leaky implementation details are guaranteed to become a compatibility issue; and they’re the basis for every other API (even a trivial class extends Object) and available to malicious code even on a trusted JVM, which effectively makes them part of the platform’s security guarantee. And I suppose you could argue (indeed, he says something similar to this in the introduction) that you don’t always know where your code will end up, so aiming for as much encapsulecurity as possible isn’t a bad thing.

And frankly that’s a pretty good argument. Which is why you still need to read this book.

(A few other things bugged me while reading it, but most of them were directed at Java rather than the book itself. There might still be another post or two in this topic.)

Comments (19)

Editing comfort

Emacs is on my long list of things that I love in theory, but in practice have only the most tenuous of grips on. (See also: Go, wine tasting, Fourier analysis. Also, I know I ended a sentence with a preposition. Suck it up.)

So – and I say this with all love and in spite of my new year’s resolution – Eclipse with Counterclockwise? So much easier to use than Emacs with SLIME. Almost certainly less powerful, but for the purposes of learning a language, I do not care.

Comments (539)

Closures in Java (as opposed to Clojure, which… nevermind)

Last time I worked with Java was before my Lisp days (or at least various attempts to get into Lisp), so I’m looking at it again now with a different context. So when I came across this use of an anonymous class in Effective Java (comments removed for brevity – bad practice shut up shut up):

static List<Integer> intArrayAsList(final int[] a) {
    if (a == null)
        throw new NullPointerException();

    return new AbstractList<Integer>() {
        public Integer get(int i) {
            return a[i];
        }

        @Override public Integer set(int i, Integer val) {
            int oldVal = a[i];
            a[i] = val;
            return oldVal;
        }

        public int size() {
            return a.length;
        }
    };
}

…my first thought was “waaaitaminute… Java has closures?

Now, it took a while for my memory of these things to come back, and a bit of searching to fill in the gaps… it turns out Java doesn’t quite do closures (it doesn’t work with non-final variables because it actually copies them behind the scenes), and at any rate there’s still the whole anonymous class mess instead of first-class functions (which I’ve always found annoying).

Then, it turns out that there’s a proposal to get first-class functions and lambda expressions in Java. And not from some random functional programming fanboy, but taken seriously by Sun and at one point planned for inclusion in Java 7 (it’s now deferred to Java 8).

All of this makes me wonder though… How does Clojure implement closures? Does it have some roundabout way of doing it that could mess up performance in opaque ways? Or is the JVM really that much more flexible than the Java language lets on? Or is Clojure a completely degenerate Lisp dialect?

Apparently I’ve got more reading to do.

Leave a Comment

Perlin noise applet

Here, have some Perlin noise.

Drag to rotate and change the rate of bubblyness.

This is just some random stuff that I’ve been messing with to get back into the swing (pun intended?) of Java. The code is embarrassingly ugly so I’m not going to put it up it in its current state.

(Note: Java 6 update 21 doesn’t play nicely with something in a non-obvious way.)

(Note 2: In fact it seems to be not working on a wide variety of machines. There could be multiple issues here. Hmm.)

(Note 3: Possibly it just needs a newer version of Java than I’m using at work. I’m starting to re-discover my old impression that OpenGL in applets is more trouble than it’s worth.)

(Note 4: You know what, I’m sick of this asking for security permissions and whatnot every time the front page loads. The applet is moved below the fold. Continue at your own risk.)

» Continue reading “Perlin noise applet”

Leave a Comment

Java and whatnot

It’s been about six years now since the last time I had a job that involved writing Java. Since then I’ve pulled it out occasionally for toy projects, but that role has been taken over lately by Python (although not for anything heavily numerical).

In the last couple of weeks I’ve started playing around with it again, for a confluence (pun partially intended) of minor reasons:

  • Android. When I got my HTC Hero last year, I’d always planned to dabble in app development, but never got around to it. Now that Tina has a Samsung Galaxy S (a genuinely awe-inspiring phone, by the way), it’s become interesting again; that, and I actually have an idea for a project (more on that later).
  • When I started looking into Lisp, I read a bit about Clojure, a Lisp dialect that compiles to the JVM. At the time, it seemed like a bit of a fringe project, albeit a cool one. Now that I’ve gone through the Common Lisp thing and concluded that its biggest problem is the available compilers, a more modern take on a well-supported platform with solid standard libraries is starting to sound appealling.
  • Other stuff that I won’t talk about yet. Ssshhhh!!!

Leave a Comment