Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Friday, July 23, 2010

Watch Directory For Changes in Groovy

One must-have feature in any modern web stack is the ability to automatically restart/refresh the development server when you edit the source code. It is critical for developer workflow that the feedback loop be as tight as possible. Here source code refers to actual class definitions, templates (JSPs, GSPs, haml files, etc...), static content (javascript, css, images), AND configuration (I'm looking at you, struts.xml).

All web frameworks which do not support automatic updating of all content during development shall hereafter be referred to as "Legacy Web Frameworks". Is your shop using them?

Justin Voss and I have been hard at work on a web micro-framework called Ratpack (inspired by Ruby's Sinatra). Lest it become a Legacy Web Framework right out of the gate, we've implemented basic auto-reloading right away. Feel free to grab this for other uses, as it works independently.

groovy runapp.groovy app/myapp.groovy app

The script app/myapp.groovy will be killed and re-run when any content in the app directory changes.

Since Ratpack uses Jetty, there are probably better solutions. Feedback is welcome.



The NIO.2 Filesystem in JDK7 will make this sort of thing much easier.

Sunday, May 9, 2010

Haml For Grails

Writing a Grails app? Find out why so many Rubyists swear by Haml for writing views.




Interested parties have created JHaml, a Java implementation of Haml, and a corresponding Grails plugin. (Patches welcome!)

To try it out, just grab the plugin:
grails install-plugin haml
Then add this bean definition to your grails-app/conf/spring/resources.groovy.


Now, you have the option of writing views (with the .haml extension) that will be automatically rendered to GSPs.

Learn more in the Haml tutorial.

Official Grails Plugin Page

Monday, January 12, 2009

Beyond web.xml

Another day paying the bills in Eclipse...
public class HelloWorldServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().println("Hello World!");
}
}

So you've just written yourself a spiffy little servlet and you want to test it out. That's when it hits you... there is a long and arduous road ahead. You've got to remember how to deploy a War (how does that Ant script go again?). You need to configure Tomcat (Or wait 20 minutes for Weblogic to start). Then you need to write that dreaded web.xml file. This is a barren wasteland, riddled with fire and ash and dust. The very air you breathe is a poisonous fume. Not with ten thousand men could you do this. Tis folly!

Dag-nabbit! You aren't writing a big fancy industrial strength web app. All you want to do is run your little servlet in a local web browser and get on with your life! Jiminy Cricket, it's times like this that can turn a developer to Rails.

So what are you going to do? Bite the bullet and muddle through it all for the umpteenth time? Give up and write a command line app? Recall that the three chief virtues of a programmer are: Laziness, Impatience, and Hubris. Where there is a will, there is a way.

Grab yourself a Jetty jar and throw one of these in your app:
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;

public class EmbeddedServletRunner {
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
Context root = new Context(server,"/",Context.SESSIONS);
root.addServlet(new ServletHolder(new HelloWorldServlet()), "/hello");
server.start();
}
}
Run it. Point your browser to http://localhost:8080/hello and you're good to go.

Thursday, April 10, 2008

Subsequences With BGGA Closures

Just a quick followup on Returning '(()) Considered Difficult. I just rewrote the "subsequences of length n" exercise yet again (surprise, surprise), this time using the Java BGGA prototype by Neal Gafter et al. I really like being able to abstract away the accumulation loop.
import static com.cadrlife.ListUtils.*;
...
private static <T> List<List<T>> subn(int n, List<T> list) {
if (n == 0) {
return Collections.<List<T>>singletonList(new ArrayList<T>());
}
if (list.isEmpty()) {
return new ArrayList<List<T>>();
}
T first = list.get(0);
List<T> rest = list.subList(1, list.size());
return addAll(collect(subn(n-1, rest), {List<T> sub => push(first, sub)}),
subn(n, rest));
}

A word on syntax: Some people have come down on the {=>} closure syntax but I wonder if they have actually used it. This was my first time using BGGA; everything compiled and worked on the first try. I can't say the same about trying to simulate closures with anonymous Transformer classes using the Apache Commons CollectionUtils version of collect.

Just in case you don't have com.cadrlife.ListUtils in your classpath, here are the obvious definitions of collect, addAll, and push.
package com.cadrlife.ListUtils;
...
public static <A,B> List<B> collect(List<A> list, {A => B} function) {
List<B> result = new ArrayList<B>();
for (A element : list) {
result.add(function.invoke(element));
}
return result;
}
public static <T> List<T> push(T el, List<T> list) {
list.add(0, el);
return list;
}

public static <T> List<T> addAll(List<T> a, List<T> b) {
a.addAll(b);
return a;
}

FunctionalJ: Steve points out that the last bit could be done this way, using the Java library FunctionalJ.
DynReflect reflect = new JdkDynReflect();
Function1 pushFirstElem = reflect.staticFunction(
AnnotatedSequencer.class, "push").f2().bind(first(list));
return addAll(map(pushFirstElem, subn(n - 1, tail(list))),
subn(n, tail(list)));
Be forewarned that using reflection to simulate first-order functions in this way will sacrifice compile-time verification.

Saturday, March 29, 2008

Returning '(()) Considered Difficult

Suppose you want a function to find all subsequences of a list with a certain length. For instance, the subsequences of (1...5) with length 2 are as follows.
(1 2) (1 3) (1 4) (1 5)
(2 3) (2 4) (2 5)
(3 4) (3 5)
(4 5)
This is not a red-herring example cooked up just to make Java look bad. This actually came up at work! I did something along these lines. Yuck.
private static <T> List<List<T>> subn(int n, List<T> li) {
List<List<T>> ret = new ArrayList<List<T>>();
if (n == 0) {
ret.add(new ArrayList<T>());
return ret;
}
if (li.isEmpty()) {
return ret;
}
T x = li.get(0);
List<T> xs = li.subList(1, li.size());
for (List<T> sub : subn(n-1, xs)) {
sub.add(0, x);
ret.add(sub);
}
ret.addAll(subn(n, xs));
return ret;
}
However, that was not the way my thoughts originally took shape. I think in Lisp.
(def subn (n li)
(if (is 0 n) '(())
(no li) '()
(join (map [cons (car li) _] (subn (- n 1) (cdr li)))
(subn n (cdr li)))))
Then I moved it to Haskell for greater clarity.
subn 0 _      = [[]]
subn _ [] = []
subn n (x:xs) = map (x:) (subn (n-1) xs) ++ subn n xs
With great pain, I converted those three lines of Haskell into the ugly splatter of Java you saw above. Later on, I started playing around with Scala and gradually compacted the Java into something strikingly similar to its Haskell ancestor.
def subn[T](n: int, li : List[T]) : List[List[T]] = (n,li) match {
case (0,_) => List(Nil)
case (_,Nil) => Nil
case (_,x::xs) => (subn(n-1, xs) map (x :: _)) ::: subn(n, xs)
}
The title of today's post refers to the inordinate amount of trouble it is to simply return "The list containing the empty list" in Java. I tried such monstrosities as these:
Collections.singletonList(Collections.EMPTY_LIST) // List<List>
Arrays.asList(Collections.emptyList()) // List<List<Object>>
Collections.singletonList(new ArrayList<T>()) // List<ArrayList<T>>
Collections.singletonList((List<T>)new ArrayList<T>()) // List<List<T>>
The last option does give the correct type, but it causes a compiler warning and is not much less cumbersome than the naive approach, i.e.:
List<List<T>> ret = new ArrayList<List<T>>();
ret.add(new ArrayList<T>());
return ret;
So here's a challenge for you Java developers out there. What would you change about the admittedly sloppy Java code at the beginning of this post? I'm issuing an all points bulletin to the refactoring mavericks (Mike, James), the simple-design visionaries (Steve), and the speed-freak optimizers (Dan). I wouldn't even mind seeing a C# version (Ethan), or an improvement on the Haskell (Eric).

Incidentally, I know some people think recursion is hard to read. I'd love to see an iterative solution as well.

P.S. I realize that the comment boxes don't hold code blocks very well. Feel free to link to a solution.


Updates:
Based on your input, I am now happy to give three different ways of returning '(()) in one line. I am only including ways that would work in the context I gave (i.e. the inner list must be mutable). The last is my favorite because the others cause compiler warnings.
return Arrays.<List<T>>asList(new ArrayList<T>());
// Type safety : A generic array of ArrayList is created for a varargs parameter

return new ArrayList<List<T>>() {{add(new ArrayList<T>());}};
// The serializable class does not declare a static final serialVersionUID...
// Ricky points out that this is an "Eclipse warning".

return Collections.<List<T>>singletonList(new ArrayList<T>());
// No warnings :)
Eric has blessed us with a version in Factor (not to be confused with my aversion to Factor). He also added a Haskell version using list comprehensions to achieve better laziness properties.

Meanwhile, back in Javaland, Dan suggested using SortedSet, particularly the subSet method. This seems to be a dead end in this case, but is certainly a useful corner of the Collection hierarchy.

After briefly attaining List Enlightenment, Thomas produced an implementation in Java with no recursion. Aside from being much longer and totally opaque, it also has worse performance charactoristics. It essentially produces every subsequence and then filters by length, similar to the Haskell one-liner suggested in the comments.

Wednesday, February 6, 2008

Is Java the new COBOL? No.

I'll bash Java as much as the next guy, but when people start to throw around the 'C' word, that's where I draw the line. Being compared to COBOL is kind of like being compared to Hitler. As Dijkstra said in 1975:
The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offence.
Would anyone say the same about Java with a strait face?

The Perils of Java Schools offers some of the harshest criticism of Java to receive widespread attention. What's the chief complaint? Java is too easy! I'm serious. Joel actually asserts that Java is not difficult enough for a college curriculum. He argues that C++, with its pointer-juggling headaches, is much better at weeding out lesser minds.

This is such a bizarre thing to say that I hardly know where to start.

First off, I went to MST (formerly UMR) where our CS department uses C++ and we're damn proud of it. Therefore, it is with a heavy heart that I admit the following: Yes, Java is easier, but that's not a bug, it's a feature! Making programming easier is a Good Thing.

Second, there actually exist C++ programmers who don't understand recursion. Sad but true. It's even possible (albeit rare) to make it through my school's pointer minefield without being able to recurs your way out of a wet paper bag. Joel is just plain wrong to assume that there is a single "part of the brain" whose purpose is to grok pointers and recursion. Pointers and recursion are not the same. At all.

I'll grant that someone who only knows Java is unlikely to understand pointers, but how bad is that really? Pointers don't help you think in higher levels of abstraction. They exist for the sole purpose of getting in your way. Other respectable languages without pointers include: Lisp, Python, Haskell, Ocaml, and Scala.

Recursion is a completely different matter. Java and C++ both support recursion equally well (or equally poorly). If you don't understand recursion, you don't really understand functions/methods. Period.

Let's assume for the moment that I'm done picking on Joel Spolsky. His real point is that schools should not water down their curriculum, and I absolutely agree. Self-respecting CS departments should fight to keep data structures, operating systems, language design, and graph theory. They should also continue to require calculus. This all has nothing to do with our petty programming language feuds. Despite what we C++ elitists would have you believe, C++ is not an academic language. It is a vocational one. Universities teach C++ because employers want that skill, not because they think it builds character.

Still, in all of his anti-Java rhetoric, Joel never (AFAIK) compared Java to COBOL. That would be hitting below the belt.

What makes me rush to Java's defense all of the sudden? Mostly it's because I'm at home sick with a cold... but here is an equally good reason.
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO-WORLD.
PROCEDURE DIVISION.
MAIN.
DISPLAY 'Hello World'.
STOP RUN.
I can not and will not compare Java to that. Let's look at another example, just to drive it home.
x = y * 2;       // C, C++, Java
$x = $y * 2; # Perl
X = Y * 2 ! Fortran
(set! x (* y 2)) ; Scheme
(= x (* y 2)) ; Arc
These are all fairly reasonable ways to multiply y by 2 and store the result in x. How does it look in COBOL?
MULTIPLY 2 BY Y GIVING X.
I can't even look at that without cringing. COBOL was a horrifically misguided attempt to blend pseudo-code with pseudo-English. Being a "business-oriented language", COBOL had syntax designed to appeal to the managers of 1960. Java was an effort to simplify and enhance C++, designed to appeal to the programmers of 1995.

So remember: Java just kinda sucks. COBOL really really really really sucks. If COBOL were an ice cream flavor, it would be pralines and arsenic. If COBOL were the only programming language I could use, I would leave the field.

Friday, February 1, 2008

The Functional Programming Apologist

There do exist legitimate criticisms of functional programming (FP) concepts, just as there are reasonable criticisms of imperative style, procedural style, prolog-esk logic/constraint programming, and even our precious object-orientation. Still, as you might expect, the vast majority of the tomatoes hurled in the general direction of the FP community are totally absurd. Here are a couple actual comments from various blogs. I am not giving the sources for obvious reasons, but you could probably find them in Google.
Imperative languages represent the straight line from point A to point B. They reflect the true nature of the beast. If you had to slay a dragon, would you try to convince another dragon to fight for you, or would you grab a damn weapon?
Yes, as a matter of fact, I WOULD get another dragon to fight for me. It's called abstraction! This is why we have programming languages in the first place, even though machine code "reflects the true nature of the beast". Does your CPU know what object orientation is? Unless you do all your structure and flow control using GOTO, you are NOT reflecting the true nature of your beloved beast. Sorry to break the news.

Here's another real gem. I see this sort of thing all the time.
Closures in today's world are a "language geek" feature. Unless done extremely carefully and in a way that supports the various skill levels of developers, they end up being unusable and unsupportable by anything less than computer language savants. In their inherent obscurity and complexity, "language geek" style closures are about as anti-Java as you can get.
First off thanks for calling me a geek, I really didn't get enough of that growing up interested in computers. Imagine a time when Java didn't have generics. In other words, imagine Java 1 through 4. Java 5 generics evolved from the type classes in Haskell — a fringe fancy-pants FP academic language if there ever was one. Some people (possibly the same ones) were saying:
Generics in today's world are a "language geek" feature. Unless done extremely carefully and in a way that supports the various skill levels of developers, they end up being unusable and unsupportable by anything less than computer language savants. In their inherent obscurity and complexity, "language geek" style generics are about as anti-Java as you can get.
I think I've made my point.

But wait! Maybe I've been wrong all these years! Maybe generics and even anonymous inner classes are perfect additions to Java, but closures would be stepping way over the line. After all, they are an FP concept and Java is OO. That's like the Hatfields and the McCoys and the two would never mix. Could that really be the case?

Let's see what James Gosling, the inventer of Java, said about it just yesterday:
There has been a lot of chatter about the closures proposal penned by Neal Gafter. And, in particular, whether or not I support it. I absolutely do. Java feels alive, not stuck in some chisel marks on stone tablets. Closures were left out of Java initially more because of time pressures than anything else. Closures, as a concept, are tried and true - well past the days of being PhD topics.
And don't even ask me what Guy Steele would say about it!