I've been using the maven-googletoolkit2-plugin from http://code.google.com/p/gwt-maven/ for a few weeks and I today I needed to add GWT to another maven2 project. Since I last looked maven-googletoolkit2-plugin has moved on. The build defect I noticed last time I used it has gone and the plugins can be directly downloaded from a repository so you don't have to build them yourself, but the whole thing has become more complex and now seems to depend on tomcat (from looking at the source). This wasn't going to work for me as I'm using jetty.
So, I went with calling the GWTCompiler from an ant build.xml file and then using the maven-antrun-plugin to call the correct target in the build.xml file. Here's the plugin entry from the pom file. I'm passing into the build.xml the properties it needs. Most interesting are gwt.devJar, which is set in the profiles section of the pom to gwt-dev-mac or gwt-dev-windows depending on the platform, and pluginClasspath, which gives access to the classpath used by the plugin, including the maven-artifact-ant classes, and which you'll see used in build.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions><execution>
<id>CreateAdditonalArtifacts</id>
<phase>process-classes</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<property name="pluginClasspath"
refid="maven.plugin.classpath" />
<property name="gwt.devJar" value="${gwt.devJar}"/>
<property name="gwt.module"
value="com.zanthan.example.Example"/>
<ant antfile="${basedir}/build.xml">
<target name="CompileGWTSources" />
</ant>
</tasks>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact-ant</artifactId>
<version>2.0.4</version>
</dependency>
<!-- can't add gwt-dev jars here because doing so breaks the ant
task above, instead they are in build.xml -->
</dependencies>
</plugin>
The relevant pieces of build.xml are shown below. I'm using the dependencies ant task provided by maven-artifact-ant and made available via the typedef using the pluginClasspath property to get access to the gwt-user and gwt-dev jars directly from the repository. Then using the java task it's very easy to call the compiler.
<typedef uri="urn:maven-artifact-ant" classpath="${pluginClasspath}"
name="dependencies"
classname="org.apache.maven.artifact.ant.DependenciesTask">
</typedef>
<target name="CompileGWTSources">
<artifact:dependencies filesetId="gwtDev.classpath">
<dependency groupId="com.google.gwt" artifactId="${gwt.devJar}"
version="1.3.1"/>
<dependency groupId="com.google.gwt" artifactId="gwt-user"
version="1.3.1"/>
</artifact:dependencies>
<java fork="true" classname="com.google.gwt.dev.GWTCompiler">
<jvmarg value="-XstartOnFirstThread"/>
<arg value="-out"/>
<arg value="src/main/webapp/scr"/>
<arg value="-gen"/>
<arg value="target"/>
<arg value="${gwt.module}"/>
<classpath>
<pathelement location="src/main/gwt"/>
<pathelement path="${pluginClasspath}"/>
<fileset refid="gwtDev.classpath"/>
</classpath>
</java>
</target>
Overall a simpler solution that the maven-googletoolkit2-plugin one.
Some notes on using the maven-googletoolkit2-plugin. Download the code for the plugin from the project's subversion repository. I used the command svn checkout http://gw-maven.googlecode.com/svn/trunk/ gwt-maven. You only need to build the maven-googlewebtoolkit2-support module. However, it won't build as is because it has a dependency that it doesn't need on maven-googlewebtoolkit-support and when you try and build the whole project there is a error. com.thoughtworks.qdox.parser.ParseException: syntax error @[47,64] in file:.../com/totsp/mavenplugin/gwt/support/beans/Bean.java Easy enouth to fix though, just delete the dependency from the pom and then mvn install will put the plugin in your local repository.
Next you have to configure the plugin in your pom. The plugin depends on the gwt-user and gwt-dev jars so you have to install these to your local repository using mvn install:install-file. For example
mvn install:install-file -Dfile=gwt-user.jar -DartifactId=gwt-user -DgeneratePom=true -DgroupId=com.google.gwt -Dpackaging=jar -Dversion=1.3
The plugin configuration itself should look something like.
<plugin>
<groupId>com.totsp.gwt.maven</groupId>
<artifactId>maven-googlewebtoolkit2-plugin</artifactId>
<configuration>
<googleWebToolkitOutputDirectory>${basedir}/src/main/webapp</googleWebToolkitOutputDirectory>
<googleWebToolkitCompileTarget>com.google.gwt.sample.hello.Hello</googleWebToolkitCompileTarget>
<sourceDirectories>
<param>${basedir}/src/main/java</param>
</sourceDirectories>
</configuration>
<dependencies>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev-mac</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
</plugin>
The googleWebToolkitOutputDirectory is where the generated code is placed. This is changed from the default value to fit with a standard maven directory layout. googleWebToolkitCompileTarget is the module to compile and sourceDirectories specifies where to look for the source code.
Finally, to execute the gwt compiler you use mvn googlewebtoolkit2:compile
Surprisingly interesting. The presentation linked to from the post is good. The problems discussed are related to why Materialized Query Tables in DB2, Materialized Views in Oracle, and Indexed Views in MS SQL Server have the restrictions on the view operations that they do. The Weird World of Bi-Directional Programming | Lambda the Ultimate
A great list, linked to by many other people :) Bokardo » 7 Reasons Why Web Apps Fail
I've updated my version of maci so that it keeps track of your ten highest scores.
In order to learn a little bit, and I mean a little bit, about programming using Java and Cocoa on Mac OS X, I've written a version of the MaciGame. It's available as a disk image, maci.dmg, is licensed under the GPL, and so includes source code. I still need to improve the application icon and add a way to keep track of high scores. Pretty good game though.
I know I probably should have found this earlier but I'd like to recommend the venkman JavaScript debugging extension for mozilla/firefox. I downloaded version 0.9.85 from the venkman development pageand it worked just beautifully.
This describes how we find part of the answer to this question at work. First you need to know that we use perforce for source control and bugzilla for defect tracking. Each time we make a build for QA the build process labels the source code using the p4 label and p4 labelsync commands. So what we need to do is to find what changed between two labels and translate that into what bugs were fixed.
Perforce and bugzilla are linked using p4dti so that each bug in bugzilla becomes a job in perforce and changes to the status of the job are propogated to changes to the status of the bug. Therefore, if we know what jobs were fixed between two builds we know which bugs were closed.
Based on information from this perforce technical note I devised the following procedure.
First find the highest numbered changelist in each label. This can be done using the command p4 changes -m 1 //path/to/release/...@label for each label.
Now find all the changes that apply to the release between the two release found in the first step. p4 changes //path/to/release/...@change1,@change2
Finally, find for each change which jobs it fixes and these jobs are the bugzilla changes that we're after. p4 fixes -c changeNumber
All of this can be incorporated into a little shell script that returns the result we're after. I've put the script on the next page because the lines don't wrap well. The last line does the following, finds all of the changes, uses cut to extract just the change numbers, uses xargs to call p4 fixes for each change, uses cut to extract the perforce job names returned, and finally uses sort to order the result and remove any duplicates.
get_change_number() {
release=$1
build=$2
CHANGE=`p4 changes -m1 //path/to/releases/$release/...@$build | cut -f 2 -d ' '`
}
if [ $# -ne 3 ]
then
echo "Usage: changes.sh "
exit 1
fi
RELEASE=$1
FROM_BUILD=$2
TO_BUILD=$3
get_change_number $RELEASE $FROM_BUILD
change1=$CHANGE
get_change_number $RELEASE $TO_BUILD
change2=$CHANGE
p4 changes //path/to/releases/$RELEASE/...@$change1,@$change2 | cut -f 2 -d ' ' | xargs -n 1 p4 fixes -c | cut -f 1 -d ' ' | sort -u
Sometimes there is a better way, and sometimes you even have to resort to perl, but for some quick bulk editing jobs sed is just excellent. Today I was faced with a bunch of xml files defining screen layouts. They contained references to properties using elements such as <property name="Foo"... and <propertyMember name="Bar".... Unfortunately all of the names were with an initial uppercase letter while the correct Java convention is initial lowercase for property names and this was stopping the property change listener hooking up correctly. So, how to make the necessary change easily?
Using the gnu version of sed it can be done in one line to edit all the xml files in a directory, and keep backups, as shown below.
sed --in-place=".bak" --expression='s/<property\(Member\)\? name="\([A-Z]\)/<property\1 name="\l\2/g' *.xml
Even though I had to download gnu sed and compile and install it on my box (Mac OS X) this was still much faster than any other solution. The actual script executes like lightning, you hit enter and it's already finished, amazing.
As part of the build process I've been trying to validate some xml files against an xml schema using the xmlvalidate ant task. The problem is that the xmlvalidate task won't validate more than one file at a time, as bug 32791 shows. Unfortunately ant doesn't provide any built in looping constructs so I downloaded the ant-contrib project from sourceforge and was able to use the foreach task it provides with no problems.
<foreach target="validateOneFile" param="file_to_validate"
inheritall="true">
<path>
<fileset dir="${standard.xml.dir}/gui/forms/">
<include name="*.xml"/>
</fileset>
</path>
</foreach>
Why is it that scheme isn't more popular? Why is it even necessary to invent languages like Ruby, Python or Perl? Or, why do people invent these languages instead of adding the features they want to an existing language? Is some of it just not invented here syndrome? Why did Python become popular when Perl already existed and why Ruby when there was both Python and Perl? Why is Java going to have a scripting language called Groovy when there are already other scripting languages, not least of which JavaScript and Jython, available? Sure, Groovy has closures but then so does JScheme.
No answers, just questions.
I've just posted the latest version of XSLTXT. This improves the conversion from xsltxt to xsl. I've been using it at work of some fairly complex and large (~1k lines) stylesheets with no problems. I've also added an xslTransfrom option to the command line so you can use xsltxt to just transform xml using regular xsl stylesheets if you want to.
Kimbly has a post about Code Inertia talking about how the programmers in her shop write large amounts of code, with much copy and paste, to solve problems that could be solved more compactly. She's interested in trying to change this. To which I say:
What about the old reward and punishment routine? I'd say that it's very unlikely that the programmers will change their behavior on their own. The way they work now is fine by them, I'd go so far as to say that the way they work now is being rewarded. Producing a lot of code is probably regarded as a sign of being a code stud. Kimbly's comments imply that it might be. Are the people who write more lines looked up to, are stats maintained about how many lines each person wrote? If lines of code per programmer is tracked, even if no formal reward is associated with it, then I suggest stopping. Instead track something associated with the behavior you want to promote. One thing would be to track number of tests created and have some target for number of tests per lines of code, the more code written the more tests required. Unfortunately it's very difficult to directly measure the thing you want to promote, code reuse.
Another angle is to make it easier to do the right thing. If you use Java then IntelliJ IDEA or Eclipse with their refactoring support make it easier to reuse than to copy and paste. Instead of copying the code for a method from one subclass to another it's easier to automatically move the method to the superclass.
One suggestion, that of introducing XP, might work, but not if you continue to track lines of code per programmer. It's a way of adding a set of rewards and punishments that favour a particular style of development. I'd take a good look at the programming culture in your shop and see how it could be tweaked so that reuse becomes seen, and rewarded, as more important and valuable than lines of code.
Testing software is like cooking popcorn is a microwave. With popcorn you set the timer for five minutes but it's time to stop when popping slows to 2-3 seconds between pops. With software you can estimate how long testing is going to take based on your past experience, and the amount of code to test, but the only way to know for sure when the software's done is watch for when the interval between finding bugs goes up beyond some limit you set.
Good article from Gamasutra explaining why you should fix your bugs as you go and start tracking them early in the development cycle. Gamasutra - Resource Guide - "Production Testing and Bug Tracking"
Last week at work we had to demonstrate in a proof of concept single signon integration with Netegrity's product SiteMinder. As usual this involved us in installing, configuration and interfacing to software we'd never worked with before. When this happens we have to rely on the manuals.
The problem in this situation is that the manuals are not designed around the task we're trying to complete. Instead of a detailed and thorough explanation of all the possible options and the way to select the correct one in each situation, which is what a manual should provide for more normal uses, what we need is an explanation of how to get something up and running quickly in a simple situation. There's just not enough time, unfortunately, to understand everything in detail. We need a good conceptual model for the software and how-to style configuration information for the simplest possible working setup.
I imagine the actual readership for such a thing would be fairly limited for most software. For something like, for example, SiteMinder or a Portal product though, there must be a fair number of people who have to perform integration as third parties, not just install or setup for end users.
We did get it all working in the end though. Turned out to be pretty easy really, at least for the simple configuration I went with. Fortunately the design of our security system just required adding an addition SiteMinder specific module and modifying the configuration files. The whole thing could be shipped as a drop-in jar file.
On the Joel on Software forum there was a thread called Code that writes code. In it I mentioned the technique I like of generating base classes and overriding them to add user written code. This means you don't have to manage files containing both generated and hand written stuff with all the problems when you want to regenerate. Turns out there's a name for this pattern, the Generation Gap.
Interesting little article. Design and Research. One remark though. I'm not convinced that an interactive toplevel is a huge win in software development. I'd prefer a decent refactoring editor/browser any day.
From TheInquirer a report of a report. Large firms hold off Web services because of security fears Pretty much matches what I've seen, lots of talk and RFQ check boxes but no real action.
I have linux on my machine at work and here at home. When I work from home I have a couple of options. Remote XWindows over ssh, which is pretty slow, or a local copy of the sources to work on. The best way I've found to get a local copy is to use rsync to replicate my source directory from work to home. The alternative is to use CVS to update a home copy of the code. Not only is rsync faster it also lets me work on stuff I haven't checked in yet. Because I'm syncing with my own copy of the sources I don't have to worry about overwriting other people's changes and I can either check in the code by logging in to work with ssh or just wait and do it the next day.
On TheServerSide there's an article about Model Driven Architecture, TheServerSide.com - MDA from a Developer's Perspective. This includes 10 Myths about Code Generation. I spent several years working for a company whose product relied on code generation, and we use quite a bit of it at work now so I have some thoughts myself about this issue.
In particular I don't agree with myth 7. I'll just use XML/XSLT and be done with it. The explanation for why this is a myth makes the assumption that you will be modifying the generated code and have to merge these changes in with any later regeneration. In my opinion this is the result of using a flawed pattern for generated code.
I believe the correct pattern is to never modify the generated code. Clearly you'll never be able to generate code that provides 100% of the functionality you need. The question is where to add the extra functionality. Instead of adding it by editing the generated code, add it by subclassing the generated code and overriding and adding methods where needed. When you have control over the framework and it is designed with this approach in mind the end result are much better than can be achieved with don't touch the code colored blue techniques you see in NetBeans, VisualStudio.NET and similar tools.
We use this scheme very successfully at work with our own XSLT based code generation system. Using XSLT really is an advantage over proprietary tools with their own little languages, each of which will have its own little bugs, with their lack of full access to the template source, and with their vendor lock in. The biggest remaining problem with code generation really remains for the programmers writing the templates. This is the fact that you're dealing with two control flows, the one of the templates used to generate the code, and the one of the code being generated.
As a sort of learning exercise I think I might have a go at porting XSLTXT to C#. This will have to be more than just a straight translation of code as the .NET apis for reading XML are different from the Java ones. In .NET Microsoft has implemented a pull type api. An application program makes calls to the parser to retrieve the next node they are interested in. Java uses SAX and application programs use listeners to handle events issued by the parser. The claim is that a pull api is easier for application programmers to handle. This may be true but I think it's going to be harder to write an XSLTXT parser to support a pull api as now I'll have to handle the state of the parse rather than letting the application do that.
Microsoft has only recently "gotten religion" where software patterns are concerned. Their patterns & practices site is recent, as is any formal interest in or promotion of patterns within the company. They were late to recognize the importance of software patterns, especially among corporate and Java developers, just as they were late to see the importance of the internet. However, as with the internet, though they are at the back of the field at the moment you can expect to see them running faster than anyone else and they'll soon catch up. I imagine they may well recruit some pattern heavy hitters to add credibility to their offerings. Eventually we'll probably even see people who think that Microsoft invented the whole concept!
In the meantime though, to have their most public .NET (and anti-Java) effort held up as an exmaple of how not to do things, as this article, PetShop.NET: An Anti-Pattern Architecture does, must be embarassing. It's an interesting look at the patterns used in Microsoft's PetShop.NET implementation. The issues have been raised before, in particular by Clinton Begin in discussing his JPetStore implementation, but it's good to see it as the main focus of an article. Though PetShop.NET performs better than the original EJB PetStore it may weaken Microsoft's overall argument in the end because of the poor design it demonstrates.
Via Lambda The Ultimate comes this commentary Impressions of the International Lisp conference ILC2002 from Oleg Kiselyov. Excellent stuff, including such gems as I learned that Kent Pittman is an angry man --- and interesting observations on Google and programming in general.
For the past week and a half at work we've been putting together a point release of our software. This involves taking stuff that was going to be in the next release and stuffing it into the current one so that it can be delivered to a customer. Ok, not the best plan for how to go about things but that's the way it is.
The fun part has been fixing lots of little bugs and tweaking the UI. It's very satisfying to be able to knock off five or six or more issues in a day and see an improvement in the software. Having a close deadline and having to work under time pressure can be motivating. Everyone pitches in even more than normal and things really move forward. It's only when it drags on for weeks or months and becomes the company's normal way of operating that it's a problem. After a couple of weeks you need to slow down, step back and refactor, and make sure the code's still in a good state. I've certainly seen some stuff in the UI code that could benefit from some cleanup when we have the time.
In the past few days I've started to mess around with Python (2.2.1) a bit and I'm increasingly impressed. Perhaps it's not as elegant, I think, as scheme but it's a whole lot better than perl. Good library/module support for easily doing the sorts of things, like parsing xml and sending/serving HTTP, that are needed to build some classes of interesting apps these days. Very similar to Java but faster to write. My only quible so far would be with the GUI. I've used tk pretty extensively in the past, both from tcl and scheme, and I don't think it's as good as Swing. On the other hand it's certainly my choice for the P in LAMP.
From Gamasutra comes The Analyst Primer. Though directed specifically at the games industry I think it's a pretty good overview of the whole industry analyst scene and how it works.
On Friday it was announced that HP was going to bundle WebLogic with its UX11i server. BEA and Hewlett-Packard Team Up Against IBM. The article says this will be extended to all of HP's platforms in the future.
On Monday HP announces that it's going to join with Microsoft to promote .NET. Microsoft, HP Promote .NET Strategy. I suppose you're allowed to wager on both horses but I always thought only the bookies won in those cases. On the other hand, I suppose HP does have to hedge its bets so that they come out of the J2EE vs .NET "war" ok whoever "wins".
Wow. Editorial coverage for Linux in The New York Times. The New Challenge to Microsoft is a pro Linux piece touting the benefits to consumers and governments of wider Linux adoption.
Gamasutra has another article worth reading, "Keeping Up with the Sims". It's about the problems of managing the production of the enormous amount of content when producing expansion packs for the Sims. Eletronic Arts outsources the production of sprite art for the Sims to New Pencil. It's interesting to read how they deal with the production of a vast number of images that all have to fit in with the style of the Sims game.
The Symbolics Lisp Machine Museum has, among other interesting things, this paper looking at why Symbolics Inc. failed. It uses heterogeneous engineering as a model to structure the analysis. Interesting. Crossing the Chasm also looks like a pretty good model for what went wrong, but perhaps one with less prescriptive benefits.
A quote: It turns out that technology is only useful if the environment is engineered to find it useful. I think Sun has been pretty successful here wrt Java. They've worked pretty hard to support the perception that Java is the solution to people's problems. Beyond a certain point this becomes a self fulfiling prophecy, people use the product to solve problems, hence it is a solution to problems.
Today Joel Spolsky is talking about performing daily builds of software. He recommends a product called FinalBuilder for a special price of $199. Looking at the FinalBuilder website it seems to be a product like Ant with a nice GUI, but targeted towards building software for windows.
What does the existence of such a product say about Windows software development? Hard to say really but it does make me think about what sort of open source community Windows developers have access to.
When I write Java there are a lot of different projects I can borrow resources from, does a similar ecosystem exist if I'm writing MFC code? Building a supportive community around a language is important for its adoption and growth. For Java, open source projects like Jakarta and many others have helped a great deal. Will a community develop around .NET, or does the whole attitude of Microsoft mean it never will? I don't mean that MS will actively prevent it, but is the feeling that you have to pay to play on windows so ingrained that people just won't share?
Interesting post on The Joel on Software Forum - CityDesk and swf. Talks about designing for expert users as well as for novices. How to integrate these two concerns is an interesting topic and I think it's discussed well in chapter 11 of Programming as if people mattered by Nathaniel S. Borenstein. The Amazon reviews are a bit unfair, some of the examples may appear dated but the underlying principles are timeless.
I especially like the advice to listen to your users but ignore what they say. It's suggested that you consider them like a class of three-year-olds. If they're all crying for a cookie you don't necessarily give them a cookie, but you might want to prepare them a nourishing lunch to address their real needs.
This paper introduces the Guide pattern. It's an extension to the more well known Visitor pattern which separates the action to be taken on the objects in a structure, for example the nodes in a tree, from the actual structure of the objects. The guide pattern goes further and also splits out the navigation. This lets you separate the three concerns, how the objects are related, how the objects should be navigated, and what should be done to each object, into independently reusable components.
A 1986 essay by Fred Books, of The Mythical Man Month fame called No Silver Bullet: talks about the impossibility of finding a Silver Bullet to solve the problems of producing software.
Quote: I believe the hard part of building software to be the specification, design, and testing of this conceptual construct, not the labor of representing it and testing the fidelity of the representation. If this is true, building software will always be hard. There is inherently no silver bullet.
Apparently this provoked many rebuttals when it was published but of course Brooks was right. Since 1986 no silver bullet has appeared. This IEEE Software: From the Editor column of 1999 claims that great progress has been made. Personally I'm not so confident.
I found this in a discussion on LtU. Towards the end of the thread this post is especially interesting. We should be paying more attention to how a language supports team development and how it encourages a community to form around it.
I've always found development war stories interesting. Sometimes they're also informative. I think you probably know the sort of things I mean. Tales of projects that went well, production disasters leading to phone calls in the middle of the night, companies where arms on chairs were status symbols, and so on and on. When told well they present useful lessons in an easily digested form.
One of the best sites I've found for this is Gamasutra. It's a game deveopers site that needs a free registration. The postmortem features can be just fascinating. Generally they use the format of "Introduction", "What went right" and "What went wrong", with right and wrong each being five points. It's interesting to see the same lessons popping up in different projects. Items such as under estimating work, managing content and programming workflow, and the importance of finding or building the right tools, . Lots of these apply to the more mundane sort of programming that I do for a living, and its fun to read about the rest. For example I've never worked on a project where choosing the right voice actor and building a character around their image was one of the things that made the development process successful.
From Lemonodor comes a link to "Design Patterns" Aren't by M-J. Dominus a Perl person.
The book he seems to base his argument around is Design Patterns: Elements of Reusable Object-Oriented Software otherwise known as GoF (Gang of Four). This was published October 1994 as the result of work over a number of years. Perl was first released in 1987 as version 1.0. Version 5.0, which introduced objects to the Perl world, came out in 1994 as well.
I think the place where M.J. Dominus goes wrong is in treating the the book is a series of C++ code samples to cut and paste into programs. Bashing design patterns because the Iterator pattern can be, to some extent, expressed using foreach statement in perl is ridiculous. Of course the simple things can be done that way, and picking the simplest pattern in the book makes it trivial to show how. What about the Observer, or Visitor patterns, what about Model-View-Controller? Does Perl have statements for these as well? Can you write mvc $foo $bar $baz->{'fruit'}; and have Perl "do the right thing"? Of course not.
As you start to look at higher level patterns like Acceptor-Connector it's clearer and clearer that they are shorthand ways to describe and name common situations so that programmers and designers can catalogue and pass on their knowledge. Just as carpenters call a particular joint a dovetail rather than describe it's detailed configuration every time, so programmers and designers use Observer as shorthand for a common configuration of components and assignment of responsibilities. Even if the language you're using provides facilities like scheme's excellent macro system you still should know that the Observer pattern is a useful way to organise responsibilites for some situations.
To end in the style in which the slides are written, what sort of person knows so little about Design Patterns as to put forward these arguments, yet feels themselves qualified to present on the topic? On the other hand seeing that on slide 6 Mr. Dominus expresses his opinion that the C++ macro system blows goat dick I think I can make a pretty guess about what sort of person he is.
The Perl community seems to attract this. Sometimes it looks like cleverness and trickiness in coding is valued over intelligence and clarity. Not just in coding though, look at the first Perl Artistic License. The GNU organization says "We cannot say that this is a free software license because it is too vague; some passages are too clever for their own good, and their meaning is not clear."
Over on kuro5hin there's an interesting article on a new AntiPattern. The Death Sprint is the result of a missapplied and badly implemented XP development process. As opposed to the more well known Death March, where nothing is ever released, though development goes on endlessly, the Death Sprint has frequent releases of code. However, over time the quality of the releases, and the quality of the underlying code base, gets worse and worse. The team is going faster than they can support, tripping over their own feet. With no time to refactor existing code before adding new features, or to consider their design, quality goes downhill, and each new feature becomes harder and harder to implement and introduces more and more bugs.
The cure is threefold. First pause to implement unit tests for existing features and make sure they all pass. Secondly refactor the existing code to make it cleaner and easier to modify in the future, checking with the unit tests at each stage so that bugs aren't introduced. Thirdly, and finally, keep the unit test disipline and add some design so that quality remains high in the future.
On sweetcode, which is a great place for finding the more offbeat and interesting software projects, I found XSH, the "XML Editing Shell". This is a perl module that uses the metaphor of a file system with directories to represent an XML document with elements. It provides a shell for traversing and manipulating the file system using commands analogous to the unix shell commands. For example, cd is used to change the current context to different elements with the argument being the xpath to the target element; ls is used to list the current context. Of course commands are also provided to add new elements and attributes, and even to apply style sheets. I suggest reading the article at xml.com first for an overview.
I've always been interested in systems that attempt to use an existing conceptual model from one domain in another domain. If done successfully it makes it easier for new users to understand and learn the system as they are able to apply knowledge from the domain they already know to the new tool. The danger is that any conceptual mismatch between the old known model and the model of the system being learnt can prove very jarring.
Just after I first posted this I realised how easy it would be to implement something like this is scheme or lisp. The read-eval-print loop is already built in. All that would be needed is to implement the cd, ls etc. commands as scheme/lisp functions and it would work. Using Oleg's scheme xml tools as a basis I could imagine even me knocking this together.
On Lambda the Ultimate this morning was a posting discussing Larry Wall's latest Perl language design statements, this time about regular expressions. As usual Ehud Lamm had interesting things to say not just about the proposal but also about the meta issue of language design.
Meanwhile, at the same time, over on the other side of town, on slashdot, the latest perl musings were also being discussed. When I got to this discussion it had about 4 posts rated at +3 or above, and they were all rated funny. Clearly no serious discussion was taking place yet. I would have liked to see some posts about people's experience with perl, the perl 6 efforts, alternatives to perl, in fact anything but more funny remarks. I thought maybe I could try and get a discussion started. A lofty and presumptuous goal. A provocative post title looked like a good way to attract attention and get people talking, so I posted Perl's had its day - It's become like COBOL.
I think this is a defensible argument. Certainly I would say that Perl has had its day. I don't think it will again be the defacto choice for scripting or cgi programming the way it once was. It used to dominate the space it is in, it's less dominant now with the rise of python and ruby for scripting and php for cgi work; I don't think it will get its dominance back. It will still be used but some of this use will be because of legacy perl code that must be maintained or extended instead of rewritten. The rest will be for quick scripts that must be written and the writer happens to knows perl, the situation I find myself in from time to time. In some ways this is similar to COBOL, legacy use and legacy users.
Actually some of the resulting discussion was interesting, though not perhaps as interesting as I had hoped. What was more interesting to me was the history of the moderation done to the post and the light it threw for me on the slashdot groupthink that occurs. The post started off at +2 climbed to +4 (interesting) where upon it must have attracted attention as it was hit with flamebait and troll to end up at +2 (troll). Then it started to go up again and it currently sits at +3 (interesting) having had 11 moderation points used on it. Result as of now:
Moderation Totals: Flamebait=2, Troll=1, Insightful=1, Interesting=4, Overrated=2, Underrated=1, Total=11.
A quick look at the moderation of other posts in the threads and it seems like they generally get a small number of points, maybe 1 to 3, all in the same direction. There is also a really strong tendency for moderators to use offtopic to force threads to stay rigidly on topic when a bit of drift would make for a much more interesting discussion. Ah well, it was fun.
Paul Graham says in his most recent piece Succinctness is Power "It seems to me that succinctness is what programming languages are for." Actually, it seems to me that what programming languages are for is to enable us to explore and clearly express what we mean, realise that meaning as an executing program, and understand and change what we mean later without having to start from scratch. John Wiseman said in response to one of Mr. Grahams earlier pieces "I place a lot of value on Graham's thoughts on lisp because he's not a fanatic". I'm afraid his recent writings are starting to tend, in my opinion, in that direction. This isn't necessarily a bad thing though, after all, without RMS we wouldn't be where we are now.
More interesting stuff from Paul Graham. In this article he advances the view that the Lisp family of languages are superior to other programming languages. I actually believe this, even though I write Java for a living. However, the meta-question is, why aren't Lisp style languages more popular now than they currently are? And the answer can't be, "the best solution doesn't always win" as that is no explanation at all. Paul talks about this towards the end of the article but no complete explanation emerges.
Quotes include and reading at runtime enables programs to communicate using s-expressions, an idea recently reinvented as XML.
and the very cynical Because, you know, when it comes down to it, the pointy-haired boss doesn't mind if his company gets their ass kicked, so long as no one can prove it's his fault. The safest plan for him personally is to stick close to the center of the herd.
Within large organizations, the phrase used to describe this approach is "industry best practice." Its purpose is to shield the pointy-haired boss from responsibility: if he chooses something that is "industry best practice," and the company loses, he can't be blamed. He didn't choose, the industry did.
Found courtesy of lemonodor
Over in the discussion area at Joel on Software, where the level of trolling has recently been rising, I read this very interesting thread on getting started with UML. Worth taking a look at.
Martin Fowler has put on the web an early draft of what looks like an interesting book, Enterprise Application Architecture. Once I've had a chance to read it I'll post my impressions.
Ootips provides an interesting and useful collection of tips for object oriented architecture, design, and programming.
Not that I agree with all of the stuff. For example the section on static type checking doesn't address "modern" type systems and the type inference mechanisms in languages like Haskell, O'Caml, and ML. With these you get the benefits of static typing without the verbosity. You don't need to declare the types of all variables, and the language can and will infer undeclared types based on the types required by the variable's usage. The downside is that the type system is more complex and is currently harder to understand than the simpler models of, for example, Java and C#.
At this point in time I think that the static typing vs dynamic typing discussion is starting to heat up again after some years when less attention was paid to it in non academic circles. Personally I like languages with higher order functions and static type systems, but I also really like scheme, which is dynamically typed. This post and the thread it's part of seems to show I'm not the only one.
Extracted from a discussion at Lambda the Utlimate here is a list of myths about programming languages. I've reordered them slightly. It's an interesting list really, many Slashdot threads about programming languages devolve into rants by people defending one or other of these myths.
From the comp.lang.ml FAQ "ML (which stands for Meta-Language) is a family of advanced programming languages with [usually] functional control structures, strict semantics, a strict polymorphic type system, and parametrized modules." It's an interesting set of languages especially if you're used to Scheme with its dynamic type system or languages like Java with its OOP style. Using higher order functions (often abbreviated to hof in newsgroup postings) can take some getting used to.
I acutally started out by learning (at least partially) Haskell. Fascinating, even monads made sense after a while. However, I found it just too purely functional for the sorts of problems I like to try and solve, which are generally not along the line of how to encode and evaluate financial instruments using a domain specific language. I felt I needed something more like ML. From my little knowledge the two most popular "dialects" are Standard ML of New Jersey and OCaml and I settled on Standard ML, at least to start with. My efforts to learn it are currently being greatly helped by a recently published book book which helpfully uses largish chunks of code so you can see how to structure things for real. There is no real substitute for reading and writing code when you're learning a language.
Browsers that understand HTTP 1.1 can understand compressed data, this can reduce the bandwidth your site consumes by 75% . The HTTP 1.1 standard defines the Accept-Encoding header that lets a browser tell a server the various ways in which data transmitted to it can be encoded. One of the possibilities is gzip. I've sort of known this in the back of my mind for a while but today I actually got round to using it.
This article provides a overview of the whole subject and is written by the author of the mod_gzip module for Apache that I'm using on this site. I found it easy to instally mod_gzip both on Apache on this linux box and on Apache on a win2k box at work. It did take a little poking around but the needed information is in the FAQ.
For the main page of the site I'm getting around 60% compression and for the article pages around 75% compression. This is good for me as I'm quite prepared to trade a small increase CPU usage for a descrease in bandwidth consumption.
The impetus for this investigation was a performance problem encountered at work. Our current release version of our application has pages that are a bit larger than they should be. In the next release we've made quite a few changes to reduce their size. This is combined with a client that has a network connection that's a bit smaller that we would prefer to produce an overloaded connection. One of the things we can do is to serve compressed data and this is what we're doing. Fortunately we have a couple of choices, the mod_gzip and possibly mod_proxy approach for Apache customers and an IIS method for those who use Microsoft. Personally I think the Apache approach is easier to configure because you can do it by editing a configuration file instead of having to issue commands from the command prompt.
You know how they say If the only tool you have is a hammer everything looks like a nail, well this is an example of how to use a hammer as a screwdriver. Of course it would all be much easier if you had a screwdriver in the first place but that didn't stop the writer of this code. Section one is entitled Functional composition, curried functions, partial applications and lambda expressions. and this is done in XSLT so watch out. Via LtU.
What's the most important factor when learning a different computer language? I'd say it's whether or not you have an application for the language that you can use to motivate you. For languages like perl or python that's fairly easy as there is always some scripting to do that's not been done yet.
For languages that are not "scripting" languages it's sometimes harder to come up with something that's worth doing. This probably accounts for the million and one "frameworks" that you see on SoureForge. In some ways it's much easier to write a framework to write web applications than it is to think of a web application you want or need to write. To go off on a tangent I think that the best "frameworks" often emerge from a project that needed a framework to build something else that was their main focus. At least that way there is some discipline about what gets included and what doesn't.
At the moment I'm trying to learn Standard ML. The problem is coming up with something that I want to write in Standard ML. One of the reasons I write things like xsltxt in java in my "spare" time is that I write java at work so there is often some problem that would be fun to explore but which can't be done at work.
Ah well, back to the search for a problem domain.
In the development I do at work the most basic and common operation is looking through existing code to fix bugs or add enhancements. I suspect this is true for most commercial Java development whether you're looking through code you or someone in your team wrote or through xerces or xalan or jdom or some other package. Here's where there is the potential language feature conflict though. Brief to write and "more than one way" will help early adoption for a language but may conflict with easy to read and understand, which is what I want when faced with 250k lines to maintain. (of course the usual whipping boy here is perl, so I'll point my finger that way also)
I decided that my emacs minor mode for assisting with java editing deserved wider circulation so I set it up as a project on savannah :) The project is called jxminor and the code is available via cvs or as a tar download.
I'm not anticipating a great demand for this code, after all how many people edit java with emacs these days, but I don't think that's the point really. jxminor is very useful to me and maybe someone else would like it as well.
It would be interesting to know how many people use emacs and how many other IDEs for java editing. I've not noticed any features in the IDEs that people use at work that are must haves and the extensibility of emacs is a big plus for me. Also, surprising as it is to people who remember the complaints about the size of emacs, it is a lean mean editing machine compared to the bloatware that is a "modern" IDE. Programs that are so large that you can either run the IDE or run the program you're developing seem a bit too big for me.
Ah, now there's a phrase to conjure with (found in a slashdot post). I think there really is a set of language features that this environment requires, or at least that makes developing in this environment easier. Some languages target this environment and some, such as arc, deliberately don't.
Is there a way to make these environments more productive. I've heard of the studies that show great variation (10 times?) in programmer productivity, which seems to indicate you're better off with one star than five or six ordinary mortals. Fred Brooks, in "The Mythical Man-Month" proposed the surgical team model where one truly expert programmer is supported by others in different roles.
Is this how programming has to be done? Is it like playing a musical instrument where you can probably teach most people how to do it but few will be really great? Is an orchestra a good model? What do you do with all the people who play third chair violin? How do you deal with the "everyone needs to learn to program" ideas? Is it even true that everyone needs to learn to program? After all not everyone could repair a car but most people could drive one.
Do we need different languages for just these reasons? Some languages that are safe and fitted for the mixed-ability team and others that take the "With great power comes great responsibility" approach. Or, is it possible to build one language where you can choose to loosen the restrictions or tighten them depending on the situation? In which case how do different sections of code with different restrictions interact etc. etc.?
Obviously I have no answers, only questions.
Paul Graham has just made available online his book On Lisp for download. Reading the first few chapters and other articles from his site again makes me think that much of XP is a way to try to bring the benefits of the lisp/scheme development process to java.
Obviously it's not as simple as a one to one correspondence between the two systems. The biggest difference I think comes from the XP focus on what might be called the corporate or enterprise sort of development project while On Lisp and Paul Graham's writings, though certainly commercial, relate to a different environment. (I'm trying to think of a couple of word characterization but I'm drawing a blank right now).
On the other hand the similarities between the design approaches are striking, and you could apply the enterprise techniques to the lisp approach quite easily, while there are things about the lisp approach that require lisp and don't translate well to a java based XP system.
The development technique On Lisp describes as Interactive Programming (Sec. 3.4) where functions are constructed bottom up towards an initial design with constant testing, refactoring and integration into the whole is very similar to XP. But I think the difference is that Java does not as easily support the most powerful part of the lisp style, the simultaneous construction of the application and the language extensions and abstractions that support it. In lisp you build the language in which you finally write the program so that when you get to the writing the program you have a syntax and semantics that match the problem domain.
In java you have no macros, can not extend the java syntax in the same way you can the syntax of lisp, and it's nowhere near as convenient to pass functions around and operate on them (and I'm not even considering the amazing stuff that Haskell makes easy). I find I end up with wordier and less "elegant" solutions than I would in lisp or scheme. Code that you could abstract out into a macro or closure in scheme ends up requiring a separate system to generate it from xml specifications using an xslt template system. (yes, I've done this)
Where java does shine is in it's excellent libraries that you can bolt together very easily to produce an application. It also has the mindshare advantage for enterprise development, especially with the J2EE APIs.
I need to think about these issues some more but the more java I write the more I miss the things that can be done in scheme.
First notice of On Lisp availability courtsey of lemonodor and Lambda the Ultimates, both well worth reading.
Many, if not most, open source Java software projects use Ant instead of make as their build tool. When Ant was first introduced it offered only a subset of the features of make, and even now it is still behind in some areas. So, how come it took off so dramatically? Perhaps "The Innovator's Dilemma" by Clayton M. Christensen offers some useful insight.
Personal experience. I've actually constructed a complete build system for a commercial Java project using make and then turned round and redone the whole thing using Ant because it made some Java specific tasks so much easier on Windows platforms. I hope that this lets me comment on both systems from the basis of at least some experience.
The Dilemma. The Innovator's Dilemma identifies three key concepts that help to explain why and how an existing successful "product", such as make, can be rapidly replaced by a newcomer that initially has far fewer features. These are
Disruptive technology. To quote from the book "Disruptive technologies bring to market a very different value proposition than had been available previously. Generally, disruptive technologies underperform established products in mainstream markets. But they have other features that a few fringe (and generally new) customers value."
This is clearly the case with Ant where I would point to the ease with which Java compilation can be done, the simplicity of building war and ear files and the lack of additional software needed to run on Windows platforms as some of the more disruptive values. Though Ant lacks features that make has, such as being able to dynamically generate rules by pattern matching, it is so simple to get Ant to do something when you are working on a Java project that you can get started much sooner than if you have to use make. Anyone can put together a simple Ant build.xml file to compile some code they have written because they already have most of the knowledge and software they need. Getting make set up to do the same thing may well include installing cygwin if you are working on Windows, and learing the syntax of make files.
Feature set.Because of the rapid rate of progess and the general ease with which features can be added any software product rapidy acquires far more features than customers need or are willing to pay for. In the context of make or Ant the currency of the payment is the time taken to understand either product and work out how to accomplish the task you have. Once a disruptive product reaches a certain level of "feature completeness" users will swap from the existing product to the new one at a dramatic rate as they trade some features they currently don't use for some ease of use or other benefit they want.
I would say that because make has so many more features, and to a great extent so much more capability, it is a more difficult product to get started with. For many projects Ant provides enough functionality even though it does not provide the same amount as make. Even if both continue to add features at the same rate the features that make adds will necessarily be of use to a smaller number of non make users, (those people who have a build problem but can't use make as it doesn't have some feature X) as most needs are already addressed by make. However, those features added to Ant will satisify a larger number of non Ant users as there are more of them.
Clearly existing projects are "locked in", at least to some extent, to their existing build system, but as new projects start they pick they can pick something new to use. If people don't already understand make, or are intimidated by it then they will start with something else if they can, and Ant picks up another user.
Investing. For open source products the investment being made is the time and effort people put into developing the product, including developing addons and surrounding infrastructure.
I think the hint here is that existing projects will seldom spawn their disruptive replacements. People working on an existing project have too much invested too easily throw it all overboard for a less functional alternative. You do see projects embarking on major rewrites, but almost always to provide a more functional, better architected solution, not to provide a simpler alternative that satisfies fewer of their "customers" than the current system.
Future. As Ant adds more features and becomes more complex will it be possible for it to remain easy to pick up and work with or will it start to approach make, leaving an opportunity for another replacement? A more "global" question, is it possible to design a system from the startbodybe a disruptive technology and so take over a market in that way.