I wanted a way to look at the structure of the ant file before I did open-heart surgery on it. Google led me to ant2dot and GraphViz (with a very nice version for Mac OS X and the iPhone).
It's a very neat way to quickly get a handle on the dependencies in your ant file and it's certainly helped me figure out how to reorganize things.
My only complaint would be that it doesn't understand the ant-contrib foreach task which has a target attribute and therefore creates a dependency so such children appear as orphans.
I figured I'd blog this in case anyone else finds it useful!
No, XP is nothing new, it's just become increasingly popular as more people try it and find benefit in its practices.
Over the last three or four years I've been adopting a variety of Agile Methods on projects to see whether they help with some of the typical problems we all run into these days: tight deadlines, vague and changing requirements, poor estimates, lack of visibility into progress. I've been pretty pleased with the results. Agile Methods aren't a panacea: being agile doesn't make you a better developer (or project manager) overnight but it does help give you a better handle on the status of a project, it lets you maintain measurable forward movement, the focus on testing increases your confidence in "completion" as well as providing a safety net while you're making improvements in the code structure.
So perhaps before dismissing XP and Agile as "some new fad", you might make it one of your resolutions for 2010 to try these decade(s) old approaches?
BTW, some of those other "new fads" that you think are challenging the CF establishment... you know, new fangled stuff like Ruby and Python? Just remember those languages pre-date CFML! Happy New Year! :)
Once again the XP mailing list has provided a good read with a link to large-scale research at Microsoft into the effectiveness of certain software practices. As the researcher points out, the vast scale and diversity of Microsoft's software development ecosystem allows for some in-depth analysis that compares different approaches on similar teams.
The article is worth reading all the way through and shouldn't really contain any surprises but there are a couple of things I wanted to pull out and highlight.
William Pietri posted a link to a page about his team's project room that I think makes interesting reading, particularly for folks who are skeptical about XP.
He goes into enough detail of the XP process for folks to get a real feel of how his project runs without getting bogged down in theory.
I'll be interested to hear what non-XP people think of such a work environment?
I've left comments on a few of the blog posts but several people have asked me to go into a bit more depth about my thoughts on this issue (since I'm one of the people sometimes accused of "pushing" OO and insisting it's the "right" way to do things).
He talks through six major issues and then summarizes in positive and negative bullet points. It's not a perfect list but I agree with most of it. When I'm hiring, I look for someone who is passionate, programs in their spare time, works on personal side-projects, learns additional technologies "for fun". I want someone who has "strong opinions, weakly held" (which is a toned down version of what is presented on that blog post). Similarly, I hear alarm bells when I am interviewing a developer who views programming as "just a job", only learns new technologies when the company sends them on training courses and only knows one set of technologies. I'm less concerned (than the blog's author) about someone who started programming "late" in life.
As folks who've been interviewed by me know, I don't "quiz" people or set them "clever" tests. I get them talking about their work and their projects. I want to hear passion, I want to hear about problems and how they solved them - and how they dealt with managers (or peers) who didn't see eye to eye with them on solutions.
Are your criteria different?
"Scientific and Engineering Programming in C++" was a landmark book that introduced powerful techniques based on templates. When we (ANSI Standards Committee) were trying to redefine the language rules around name lookup as regards the friend keyword, we were forced to preserve the examples in that book because they had passed into common usage, even though we really wanted to restrict how the friend keyword worked. We did, eventually, come up with suitable rules.
Watching "Chuck" tonight (we recorded it from Monday) brought that whole committee experience back to life for me!
As someone building a social networking website, I know what he means and, whilst "maybe" was part of our earlier design, when we launch, you will only be able to say "yes" or "no" to an event. Zeldman says:
How can you know what "maybe" means? In the context of a web service, you can't.
He also rails against five-star ratings since those have an implicit "maybe" (three stars) that tells you very little.
Thoughts?
Of course, as those folks who've struggled with Model-Glue: Unity (or Rails or any other framework) know only too well, it's not quite that simple!
So why do some people struggle when others find these frameworks so easy and so productive? The answer is blindlingly obvious, unfortunately, but it isn't an answer most people want to hear.
Sammy Larbi asks "is Rails easy?" and points to Venkat's blog entry "Can your cat code my Rails App?". The answer to both of these might seem obvious. The answer to the second question is clearly "no". The answer to the first question is, unfortunately, "it depends".
As Venkat says:
I asked why she thought developing with Ruby/Rails is so darn simple. She said she had seen a demo of a fully working app being created within minutes without much effort or code.
The videos are, of course, somewhat misleading because they show what someone can do once they already know the framework really well. It's the same reason that experienced OO developers find OO so liberating and productive: they already know OO really well!
Venkat compares C++ and Java, saying the latter is more productive with the following caveat: "I doubt anyone would say that Java makes an ignorant programmer more productive. You did have to take the time to learn the details of the language, the platform, and the API."
The point behind all this is that there really is no silver bullet. Using a framework doesn't automatically make you more productive from day one. You have to learn how to really use your tools and sometimes that learning process is non-trivial to the point of seeming endless (and being a lot of hard work!).
I post this because I got into a somewhat heated discussion at CFUNITED a few years back with someone who thought OO was dumb because they'd tried to use it and it made a mess of their application. I said that it takes time and effort to learn OO in order to be able to apply it properly. They got offended, thinking I was telling them they were too stupid to learn OO. I've repeatedly said: this stuff is hard. I started doing OO in January 1992 and I'm still learning. OO has mostly become second nature to me now but that doesn't preclude me from learning new techniques - often from people with less OO experience - that help make me more productive.
So don't think that Rails is going to turn everyone into super-productive programmers overnight - most people coming to Rails already have a fair bit of Java and OO experience so pick up the concepts easily and, once they've learned the Ruby and Rails specifics, they can be more productive than they were in Java.
It's the same principle that applies when you learn a new framework in ColdFusion. It may seem strange at first and may look like extra work but once you understand most of the specifics, you can be much more productive. Just be prepared for a learning curve.
You can build AIR applications easily with Flex using the beta of Flex Builder 3 but you can also build AIR applications with HTML.
You need the AIR SDK (again, from Adobe Labs) and a text editor (and access to the command line to run the adl and adt SDK programs to run and package AIR applications respectively).
Of course that might be a bit more work than you want to do. In which case, install Aptana - either standalone or as a plugin for Eclipse / Flex Builder - and then install the AIR plugin for Aptana. Now you simply create a new "Adobe AIR" project, fill out the application information wizard, select your JavaScript libraries (it assumes you are building an AJAX application) and off you go!
Surprisingly, this is my first exposure to jUnit. Yeah, I know, I'm such a big fan of cfcUnit, how can I never have used jUnit? Anyway, I write my TestFoo.java class with its setUp() and tearDown() methods and start writing testMyMethod() methods. Then it occurs to me: how do I run this? I'm so used to the browser-based runner for cfcUnit that I'd never thought about the Java equivalent.
Out of curiosity, I right-clicked in the editor panel displaying the test case and there, in the Run As... submenu: JUnit Test. Wow! Really? Could it be that simple? Yup! Up pops a JUnit view in the bottom panel running my tests and showing a red failure bar and list of failed tests. Perfect!
Well, of course my tests failed - I just wrote the tests. Next I'll write the code.
As is so often the case, Eclipse continues to surprise me in pleasant ways! Now, where's the cfcUnit plugin?
I love HackNot but it generally takes a very black and white view on things. Andrew, who is essentially taking over my old team, is a proponent of dynamic languages (as am I) and he feels that HackNot's analysis is thin, to say the least. I'm a big proponent of dynamic languages and have to agree with Andrew that HackNot's arguments are often specious in this particular scenario.
It still makes good reading tho' - just substitute "ColdFusion" for "Ruby"...
Scott Hanselman has a wonderful post about trying to rewrite a perfectly good Boo library in C#. Classic NIH / RTW. And he paid for it - but at least he had the sense in the end to reuse the other person's wheel.
Last time I messed with Haskell, I chose the nhc98 compiler because it was easily available for the PowerPC Mac. When Haskell had cropped up in discussions with not one, but two ColdFusion developers this week, I figured I'd install it on my new Intel Mac. Except nhc98 is not available as a binary distribution for the Intel Mac. Easy, I thought, download the source and build it myself. The build failed. The notes suggest using the ulimit command to remove the file-size limitation on the shell. OK. The build still failed. The notes say if you can't solve it with ulimit, use another Haskell compiler to help bootstrap the build.
Try as I might, I couldn't find an existing Intel Mac binary of any Haskell compiler. But there's an IRC channel listed on the Haskell web site. #haskell on freenode.net. I figured that #coldfusion is so helpful that I might as well try the #haskell channel... There were nearly 300 people in there! And, guess what? They were very happy to help me for several hours. First, they pointed me at an Intel Mac build of ghc (the Glasgow Haskell Compiler) which, incidentally, was contributed by a member of the Haskell community (i.e., built from source and submitted back). I installed it and it worked just fine. So far so good.
Then I installed hmake and hi (hmake interactive) which are build and shell tools for using Haskell compilers. I ran into problems with a library dependency. Again, the IRC channel folks were very helpful. Following their instructions, I removed the (obsolete) dependency and successfully built and installed the two hmake tools. Yay!
Then I went back to nhc98, determined to build that from source. I ran into several more dependency problems. Back to the IRC channel. Similar advice (nhc98 is old and the dependencies aren't needed when using newer compilers to bootstrap it). I finally got it built but, unfortunately, every file it generated just crashed. By this point, the IRC folks were wondering why I was bothering since nhc98 has really reached a dead-end. They pointed out that ghc has an interactive tool (ghci) anyway. So I admitted defeat and starting playing with ghci...
Some of the tutorials on the web features code that didn't work. A quick check in with the IRC channel and I learn that Haskell 98 had a flat namespace for libraries but since then the standard library ("Prelude") has been reorganized into a hierarchy of packages. We discussed some of the slight differences between Haskell 98 (per the tutorials I was trying to follow) and "modern" Haskell and I kept on learning.
One of the interesting things about the channel is that members are constantly swapping code fragments and experimenting amongst themselves with ways to solve problems. Very collaborative!
So, once again, I'll suggest to the curious among you to check out Haskell.
I'd also ask you to think about the difference between the #coldfusion channel on DAL.net and the #haskell channel on freenode.net. #coldfusion has 20-30 members most of the time and occasionally gets as high as 50. For the most part it is banter about everyday life but folks will rally and focus if someone comes on asking a ColdFusion question. #haskell has 270-300 members and discussion is mostly about Haskell. We're all so very passionate about ColdFusion and we like helping newbies. Why are so few CFers on IRC compared to Haskell developers?
Now, I know my readership is mostly about creating dynamic websites but I suspect many of you are also happy to create high-quality, standards-compliant static HTML websites at a reasonable price.
If that's within your business purview, I can hook you up with a community of cat breeders / exhibitors who would love a new website based on CSS and clean HTML for a reasonable price.
Email me via the contact page with links to your portfolio and I'll connect you with clients!
This post hits a nerve for me because as a senior software architect for most of the last decade, I've often found myself in situations where I've ended up quite distant from the code. And I don't like that much. I don't want to just write code but I do find writing code to be both very therapeutic as well as a good way to experiment with some of my ideas and evolve better practices.
I realized recently that, although I created the engineering team that rebuilt macromedia.com (now adobe.com) using ColdFusion and Flash, I hardly wrote any of the code on that site! The RSS feeds on LiveDocs are powered by code that is based on an initial prototype I built but that's about it, in terms of live code. I wrote quite a bit of back end infrastructure code for our ERP integration project (lots of XML processing and JMS messaging). That was a while ago.
My new team is smaller and is trying to be more agile in style so architects write code too. It's really good to roll up my sleeves and write code again - it's really helped me confirm some of my architectural ideas about what we're building (both good ideas and bad ideas!).
BTW, this lack of coding at work is what fuels my contributions to open source projects outside work, such as Fusebox 5!
I haven't watched the preso yet but I'm using SVN / Trac day-in, day-out to manage Fusebox 5 so I wanted to get the word out...
A few people point out that they sometimes sketch out code by writing pseudo-code in comments and then writing the real code, which can leave the code in the situation that Kay describes. I've done that too sometimes so I sympathize - but I generally replace a pseudo-code comment by real code, not write the code below the comment.
Anyway, it made me go back over some of my code to see what sort of comments I put in real code. The answer is: "very few". I was actually surprised at how sparse my commenting style is. The code is readable (in my opinion!) because it uses carefully named variables and methods so the code mostly reads like English phrases and sentences. I also generally keep each line of code pretty simple, breaking complex operations into multiple lines where possible.
We all have different styles, of course, but bear in mind that the main audience of your code is probably not going to be you in the future.
And here's an example of some real code I wrote with what I consider a good comment:
some validation on formats:
- should be at least 3 characters
- should be at least two alphabetic
- optionally followed by - and two or three alphabetic
- optionally followed by _ and at least 3 alphabetic
--->
<cfif len(outputSalesOrg) gte 3 and
REFind("^[A-Z]{2,}(-[A-Z]{2,3})?(_[A-Z]{3,})?$",outputSalesOrg) eq 1>
<!--- it's probably valid --->
<cfelse>
<cfset raiseException("INVALID","Unknown sales organization (#arguments.inputSalesOrg#) encountered",arguments.filename) />
</cfif>
Feel free to comment here or over on Kay's blog (to keep the thread in one place, if you want).
Rich draws a parallel with designers and the designs they create - and how easy they are to learn. I want to draw a parallel with object-oriented design / programming. All the time you have to actively focus on it and think hard about the problems, it's difficult. Over time, you gain expertise and a comfort level - as the lessons learned move into long-term memory and things become more natural. In other words, you know you've reached a level of expertise with certain concepts when you find yourself applying them almost subsconciously, without thinking too much about it.
That doesn't make it any easier to learn OO, but it should give you a way to measure when you become effective at applying OO. Mind you, you might find it easier to learn if you try not to over-think how to design your solution - let it flow. If it's "wrong", you'll figure it out later and will have learned a practical lesson but more likely you'll just refactor your solution to be a better fit for your problem space over time.
And listening to an iPod while you program? Yeah, works for me...
I just want to know your thoughts on this question... Which is the best Framework you think to adapt? (Fusebox or Mach II)Even assuming they mean "adopt", it's certainly not a straightforward question. I'd recommend folks download my frameworks comparison presentation and take a look at the accompanying sample application code. This covers Fusebox, Mach II and Model-Glue and gives pros and cons for each framework as well as some broad recommendations based on your skillset and the type of application you want to build. The sample code has nine variants of a single application, showing various flavors of Fusebox, Mach II, Model-Glue, Tartan and ColdSpring in various combinations.
I'm currently running around CFUGs with a talk about "Objects & Persistence" that briefly covers four of the ORM frameworks that have appeared lately: Arf!, objectBreeze, Transfer and Reactor. I'll soon also be giving a talk about factories and covering ColdSpring. Both of those talks will be accompanied by more variants of more applications.
However, I get the impression that some of the people asking me this question want me to specifically recommend a framework or a combination of frameworks for them so they don't have to digest the presentation and code. The short answer is that there is no "One True Answer™".
Here's part of another email - which has a lot more background the question - but here's how the question was phrased:
Anyway, I'm looking for some guidance with frameworks. I am involved in a project that I know could benefit from using a framework. I just don't know which one would be best. The more I read, the more confused I get. I think I've narrowed it down to Fusebox or a Model-Glue / ColdSpring / Reactor set up. I really like the MVC concept, but am new to that as well, so I'm not sure if it would be easier to go with something that forces the implementation or trying to implement Fusebox in an MVC pattern.This person has done their research and understands some of the tradeoffs involved which is great as far as I'm concerned. I sympathize with this part "The more I read, the more confused I get." - it's not a simple choice. They will get a long, detailed response - as soon as I find time. The other email shown above will get a short recommendation to read my presentation and look at the sample code.
The point of this (somewhat long) blog entry is that if you want me to offer advice on the choice of frameworks, I'm more than happy to do so - but the quality of the answer you get will be directly proportional to the amount of information you provide me with (and the amount of "homework" you show you've done).
And yes, I do have a personal preference - if there is no overwhelming reason to use a different specific framework combination. Just remember that what works for me might not necessarily work for you. What is my personal preference? Don't read too much into someone's personal preferences...
Why the change of heart? Well, with all the OO ColdFusion I've written, I must admit that I haven't really missed interfaces. At first I did, but then I started to use type="any" or type="WEB-INF.cftags.component" and that is actually more powerful. How can a "weaker" type be more powerful? Simply because you can pass any object that is able to respond to the necessary methods - those objects don't need to be part of a rigid single-inheritance tree!
I'm not the only person who thinks this way... Michael Smith just interviewed Hal Helms about his talk at CFUNITED 2006 and here's a little clip from that:
Michael Smith: So, you're going to argue that Adobe should add interfaces to ColdFusion?Hal's talk is about "duck typing" which is only really possible in languages that have dynamic type systems (where a variable's type is determined at runtime based on its contents).Hal Helms: No! What good would that do us developers in the trenches who face these problems right now? Besides, that's exactly the wrong solution. The reason that C# and Java need interfaces is that they are statically typed -- that is, data types get determined prior to run time. But ColdFusion doesn't suffer from this restriction: it's dynamically typed. What we need is to embrace the fact that ColdFusion *is* dynamically typed. And we haven't even started to talk about mixins! There are all kinds of new possibilities!
Smalltalk programmers are used to this, as are Ruby programmers and others. With all the enthusiasm around Ruby these days, ColdFusion programmers might do well to embrace some of Ruby's strengths which are also ColdFusion's strengths - including dynamic typing.
Some years ago I was chatting with Scott Meyers (author of "Effective C++" etc) and he felt there are three broad classes of programmers: public, protected and private. Private programmers write operating systems and frameworks and other sorts of "black box" software. Sometimes they mentor teams of other programmers. Protected programmers understand APIs and frameworks and help drive projects (some protected programmers also write frameworks). Successful projects have at least one protected programmer mentoring the others. Public programmers build applications. They use frameworks and libraries but they don't usually understand exactly how those things work, just that they do work, and they rely on the protected (and private) programmers to help them design systems and get things working.
Going back to Meilir's seven stages, the private programmers are the masters and researchers; protected programmers are the journeymen and maybe some of the practitioners; public programmers are practitioners and apprentices (and occasionally some exposed programmers).
Meilir's J-curve is an important issue to consider - as folks advance from apprentice to practitioner they experience a drop in productivity as they take on all that new information and assimilate it. Meilir notes this can take between six and eighteen months and that moving on to the next stage (journeyman) can take another eighteen to thirty-six months. Don't underestimate the time this progression takes! I've encountered people who think they can just pick up a new technique (like OO) and be productive immediately - and who got quite angry with me when I suggested otherwise. As Meilir says, in general the shortest time from a seminar to full productivity with that technique is about two years.
Most of all I want you to read the article and take heart that learning new techniques really does take time. It doesn't mean you're stupid just because you don't get OO in a few weeks - you should expect proficiency to take a good while. My early OO efforts were pretty horrible, looking back... (hmm, looking back to 1992 when I started to learn OO!). Also remember that the seven stages apply to each individual technique or skill so there is always more to learn as new techniques appear and new skill opportunities are offered.
He explains hyperthreading in a recent post as an answer to a question based on a misunderstanding about how HT works... but what's really interesting is the note in the comments about how certain applications run slower with HT enabled and then an explanation of why that may happen.
A related point crops up in my "Enterprise Integration with ColdFusion" talk (from MAX) where I make the point that robust systems need to be able to save "invalid" data.
In other words, the validity of data depends on the context. For application robustness, you actually need to be able to accept - and store - any data, even if your business rules consider it "invalid". It's 'valid enough' to store it but not necessarily 'valid enough' to be used by the business logic.
I haven't really been able to articulate that point very well to some people. However, now I can point you at this excellent post by Martin Fowler on contextual validation.
What he said!
Tony Arnold's Rolling with Ruby on Rails on Mac OS X Tiger is a great place to start. He offers an installer package that fixes the pre-installed Ruby and adds Rails etc. Caveat: if you have CFMX 7.0.1 installed, your httpd.conf file probably has some LoadModule directives after the AddModule directive block - move those LoadModule directives up to the end of the main LoadModule block before running the RoR installer!
Then he says to update your rubygems - make sure you switch to GCC 3.3 before doing this!
sudo gem update
Then you can run through his test application example and it should just work. Pay particular attention to the chgrp and chmod commands he specifies and the directives in Apache to tie it all together.
At that point, you'll probably want to walk through the two part ONLamp Rolling with Ruby on Rails article: Part 1, Part 2.
Now, I love Apache but I'll accept that it has some, er, "quirks"... My favorite slide is the one that talks about the powerful mod_rewrite:
I probably don't need to say anything more than just "mod_rewrite". But I will."Voodoo" and "... flexibility of sendmail"
The docs practically scream "GO AWAY!"
Joe thinks courses would get more intake if they offered a "more up to date" / "real world" set of languages for computer science. Jared sort of agrees, suggesting some sort of application development course.
I disagree with both of them (and most of the commenters on both blogs)! However, someone called Jeff commented on Joe's entry and I do agree with him:
I don't think the language of use is important; I think teaching the concepts should be the primary thing in any cirriculumn. Computer science concepts haven't changed much in the past 20 years. Languages have, but you can apply the concepts to any languages.Exactly! The important stuff behind Comp Sci is about basic concepts and algorithms and a general understanding of how systems work. We're still running software on a Von Neumann architecture so all of this stuff still applies. You do need to learn about memory and pointers and data structures because those are the basics of programming.
Honestly, I doubt that the incoming students are going to be able to examine the curriculum and determine its usefulness (or not). I've known a lot of people who were thrown at a dozen languages in their college career, but never learned how to code.Also agree! Computer science courses are not intended to churn out "programmers" - they're meant to turn out people who understand how to solve problems and how to reason about programming. Those are the building blocks of being a good programmer.
In college, I learned on Pascal (they switched to Java the year after I Graduated). Pascal was designed solely for the purpose of teaching programming concepts. I realize my experience is in the minority, but I wouldn't trade it for anything.I too learned Pascal, not for the syntax or applicability of the language but for the concepts and algorithms. I learned a bunch of other languages in my spare time to tackle the real world stuff.
I think there are two problems here:
One is that people think they can somehow skip over the fundamentals and fast track to becoming really good programmers. I've met a few who are completely self-taught but they're very, very rare. Most of the really good programmers do have a computer science background (even if they went back and did night school to learn it).
The other problem is that people think academic institutions are supposed to create turn-key workers. Only experience can do that to be honest. Academia should help people hone their learning skills - it should not just teach a "trade".
Remember: unskilled jobs are easy to outsource - and that includes basic programming skills. Software design, architecture and problem solving are much harder to outsource. Academia is - and should be - about the higher level skills.
Designing and developing test harnesses and test case code can be every bit as challenging - and rewarding - as designing and developing the product itself. Some of the challenges include:
- figuring out how to automate as much as possible, not only of the actual test case execution but also of the result verification and regression
- figuring out how to create negative test cases - to test and verify error cases - that run automatically and accurately
- figuring out the edge cases in the spec, the boundary conditions, the possible off-by-one errors
So, as a developer, take some time to think about life on the other side of the looking glass. Think about test cases. Think about how you would plan all those test cases. Think about automating those tests.
Oh, and he has a knock at exceptions again. I'm in two minds about his comments there. He's right about how exceptions can made code paths hard to identify but I think the benefits of exception handling outweigh the additional burden of having to think about possible exception when you read code. Exceptions let you move error handling out of the 'main flow' of code - making the normal cases easier to read - and also helps you collect all your error handling in closely related chunks of code at appropriate tiers in your application. But it's certainly very easy to write bad exception code!
I couldn't resist changing the color scheme when I aded some rounded corners. You can get the old colors back by adding ?style=red to the URL.
In between the morning sessions, I bumped into Reg Charney, contributing editor for Linux Journal and an old friend from the C++ committee days. We caught up on life during the break and, after the event-driven architecture talk, we had a chance to continue our discussions over lunch. Not surprisingly, we talked about open source as well as life in the Bay Area (Reg and his wife are in the process of moving back to Toronto).
It's been a very interesting conference - lots of ideas floating around my head about new things to try in ColdFusion, things to review in the coding guidelines, new areas of technology to explore. With the sessions being 90 rather than 60 minutes, speakers get a chance to go into much more depth and cover the edge cases - that makes the talks more rewarding but sometimes harder to follow. But then good conferences should be a challenge!
She talked about the goals of security (authentication - who are you? - confidentiality - encryption; integrity - signatures; reliability - preventing replay and DoS attacks). After that somewhat gentle introduction, she worked through an example (Hello World, of course) and added increasing levels of security to it, looking at the issues and benefits of each step, as well as explaining which a combination of all these techniques is actually required. Very impressive.
The XML behind all of these standards is monster scary stuff! Michele worked with VS.NET which I must grudgingly admit hides much of the complexity and auto-generates a lot of the machinery (although she still had to hand-edit a few bits of XML and insert some fairly verbose C# code into her examples as she went).
Increasing security generally adds some degree of bloat to the messages so there's a tradeoff: performance versus security. Key management becomes important pretty quickly as you work with more clients (to manage all their public keys). There are also hardware options for managing "nonce" (a per-message key with an expiry timestamp to prevent reply attacks etc).
A very comprehensive and impressive talk - much better than I expected!
He started out by explaining what a call stack provides: Continuation (return), Context (local vars) and Coordination (synchronized execution). This means one at a time sequential execution, in a determined order, on a single machine.
If you want concurrency (and scalability), you need to move away from the simple call stack model. He looked at threads but said they are hard to work with and fussy - lots of low-level housekeeping code. The Java 5 standard library adds a Future generic / template for simplified concurrency programming model. It has an isDone() and a get() method - isDone() tests whether the thread is finished, get() blocks until the result is available so it is a join operation. He showed more of the Java 5 library framework and it uses the Command and Executor patterns, just like Kevlin's generic C++ concurrency library. In fact, much of this section of Gregor's talk mirrored Kevlin's, despite the C++ / Java difference.
He noted that even with this easier programming model, it is still related to the call stack architecture: it has the same command and control scheme with a primary execution thread and explicit synchronizatio etc.
At this point he introduced his Event-Driven Architecture which, to be honest, looked a lot like JMS with publishers and subscribers and queues - except that it all operates locally under control of Java's threading model.
Because of his specific approach, that are several downsides: type safety is reduced (he relies on reflection to some extent, looping over the inheritance tree and using try/catch to find event matches) so testing is more important; dependencies are critical and can be hard to visualize.
One truism of systems like this is that loosely coupled systems are harder to diagnose and debug, no matter what techniques you use to implement them.
Overall it was an interesting little technique but it seemed rather fragile. However, between this and Kevlin's talks, I'm getting some good ideas for how to build an easy to use concurrency framework around CFMX 7's event gateway mechanism!
Once again Scott mentioned that the data community missed out on a whole lot of software engineering - although we also need to recognize that they have a lot of value to add to projects with their database knowledge. The trick is to harness that by having developers learn some data techniques and having DBAs learn some development techniques and then working together closely in an agile manner.
He offered up some references: the Database Refactoring website; his "Agile Database Techniques" book; an essay on database refactoring.
He said that refactoring a database is harder than refactoring code because of coupling (many systems accessing the same database), lack of encapsulation (it's all 'just data'), lack of tools etc.
Classic commentL: "SQL is the root of all evil!" - meaning that having raw SQL embedded in your code is a sure way to prevent agile database development. Hide the SQL - use Data Access Objects at a minimum, use persistence frameworks if they are up to the job, use encapsulation. Don't let applications have raw access to the data.
Then he ran through a number of specific refactorings (replacing / renaming a column, merging columns, replacing one-to-many relationships with an associative table, introducing a surrogate key). In each case, the key elements are:
- maintain the current and modified schema elements side-by-side for a while so applications can gradually cut over
- add stored procedures to maintain integrity between the old and new schema elements
He touched on environments, saying developers need a database for experimenting with schema changes as well as a regular shared database. At Macromedia, we have a crash'n'burn instance for developers to play with as well as a shared 'dev' instance (and then we have several QA databases, an integration / load test database and finally production).
Another thing he emphasized was unit testing for databases - something almost no one in the audience was doing. A couple of references: DB Unit, UTPLSQL for Oracle.
It's not a product. It's just a cool name for an old technique.
Google turns up a bunch of tutorial stuff on using XmlHttpRequest which is the core of this.
Rob Rohan built Neuromancer a while back that is effectively an implementation of this.
Update: Rob's site URL changed (corrected above) and he has blogged some examples of how to use Neuromancer to do the "AJAX technique".
Scott's talk was another information-packed session and, like Kevlin, he's a very engaging speaker.
Both talks gave me plenty of food for thought and I'll try to distil some of the recommendations down to apply them to ColdFusion.
Over lunch I got to chat with Kevlin some more - it was good to see him again as the last time I saw him was at my wedding (well, one of them).
Darin increased my enthusiasm for Eclipse and made me feel guilty for my lack of active involvement to date at the actual coding level of CFEclipse and Fusebox CFE!
I had planned to attend another Mike Rosen SOA talk but popped into the end of Dan Saks' C++ operator overloading talk and, since I haven't seen Dan to chat to for about six years, we ended spending the next two hours catching up on our lives and the state of C++ and Java. He mostly works in the embedded C++ arena these days and he's also the track coordinator for the SD conferences.
Then it was time for a "Fireside Chat with Joel Spolsky". If you don't read Joel on software then you're missing out on a lot of insight (and humor). One of the SD staff prompted him with questions and he talked about his time at Microsoft (adding VBA to Excel), his thoughts on interviews, software maturity, methodologies and magic - and a number of other topics. He's a very savvy IT veteran and funny to boot. I'm looking forward to his CFUNITED keynote!
He emphasized that OO model and data model are usually different (and should be!!). It's not a one-to-one mapping between database columns and object attributes. Not all columns appear in an object model and not all object attributes appear in a database. However, objects may need to maintain "shadow information" above and beyond their real data in order to be persistable - typically key information and update timestamps.
He highlighted a number of critical issues that object developers need to consider including: referential integrity - sets of related records require inserts / updates to occur in a specific order or they require transactions (or both!); sequencing is an issue (e.g., line items on an order typically have a sequence number in the database but may be represented by an ordered collection in memory - inserts and deletes are key operations).
When dealing with legacy data, consider adding views to simplify the legacy schema in order to make mappings easier. Also consider schema wrapper objects (data access layer mappings) so that you can refactor the legacy schema later without changing (most of) your application.
He also mentioned that lazy initialization of data is a good technique - only load the data you need for the current operation. This speaks to using data gateways for aggregate data and not creating arrays of objects for everything - just create an object when you need to drill down into that data.
At the end, someone asked him about Hibernate. He likes it, but it has a one-to-one mapping between tables and classes which is very restrictive (and not optimal in most cases). He noted that is being addressed in a future version tho'.
A very interesting talk with some challenging ideas.
Takeaway: don't slavishly write DAOs that correspond one-to-one to your database tables - think about your object model independently and do what's best for that while keeping an eye on the physical persistence model.
He ran through some basic threading concepts and outlined what he calls four levels of thread safety:
- threadbare - safe only in a single-threaded program: typically uses a lot of unencapsulated shared data / resources
- exclusive - safe as long as threads are independent and the data / resource is guaranteed to be used by only one thread at a time
- requested - explicit locking
- transparent - safe regardless of threading
He emphasized that not all programs need to aspire to the fourth level of safety - sometimes 'requested' is the best you can do (and sometimes that's all you need!). A lot of code out there is only at the second (or even the first) level...
He made some broad recommendations that are worth noting:
- If you have a container class, don't code locking strategies directly into it (it's restrictive and makes it harder to use / reuse).
- Construction and execution should be separate. Never start running a thread / process in the constructor: construct it and then, when it is needed, execute it.
- Inheritance vs. delegation - he showed a delegation model that used Command and Executor patterns and noted that this has looser coupling than the apparently simpler inheritance model but it also has more parts. Apparent simplicity doesn't always translate to maintainability or usability.
He started his talk looking at the basic C model for threading and noted that it was all based on functions and that a thread (function) returned a result which could be used by the parent process. Access to a result is often lost in higher abstractions, such as most C++ thread libraries. The thinking seems to be that you just need the thread to run, you don't really need it to return anything. However, we often do need the result and so we end up programming around the result-less model with complex joining / marshaling code.
The generic model he proposed uses functional objects (objects that look like functions, with operator() defined to perform execute / join operations). If you don't have operator overloading, you need an explicit execute() or call() method to simulate this - but it is a very powerful technique!
He deliberately decouples the logic of threads (functions) from the threading model itself so that you can unit test with simple mock objects in the absence of threading! Nice!
Finally he touched on locking, noting that it was an orthogonal subject and can (and usually should) be designed independently of your threading model. That was a very interesting insight.
Not sure how much of this might be applicable to ColdFusion but it's given me lots of ideas for experimenting with some framework code around the Asynchronous CFML Gateway that CFMX 7 provides!
I planned to attend Alan Shalloway's Pattern Oriented Design session but after the first five minutes it was clear this would be an introductory talk rather than anything in-depth. So I used the time to tour the exhibit hall. It was a bit of a trip down memory lane finding XVT still in business (cross-platform application development toolkit), as well as old competitors Parasoft and McCabe & Associates (competitors to Programming Research, where I used to work in the early 90's). I also spent some time chatting to the Recursion Software folks who bought up Voyager, JGL and the C++ ToolKit - products created by ObjectSpace, whose interview I walked out of in the 90's (after they'd flown me from London to Dallas!). Looked at SourceForge Enterprise Edition - I didn't even know they had a version other than their hosted version! IBM Rational had a booth but no one seemed to want to talk to me (not that I'm a Rational fan). Overall it seemed to be a bit of a poor showing in terms of exhibitors.
I originally planned to stay for Joel Spolsky's "fireside chat" but since that was over an hour away at that point and I'd exhausted the exhibits, I decided to head home for the day.
More Bruce Eckel, this time talking about why weak typing doesn't have to mean you lose robustness. He compares Python to Java and uses automated test suites as an argument against the rigid static typing of Java (OK, that's an over-simplification but I hope you get my drift). It's an interesting position - and it follows on from the checked / unchecked exception discussion.
I always used to be a big fan of static typing and enhanced static checking - Dutch software studies in the 80's and 90's showed that static checking (source code analysis) was generally eight times more effective at finding bugs than dynamic checking (test suites). It was that sort of logic that probably led the developers of Java to favor checked exceptions.
Testing has moved on tho' and now, with approaches like Test-Driven Development, we have to some extent embraced the importance of testing and we've gotten better at automating it.
I'm still a little nervous about the shift from static checking to dynamic checking but on the other hand I love the productivity that weakly typed languages bring (Python, ColdFusion etc).
Just remember that when you call for stricter type checking in a language...
Update: following more links and Google results, I turned up this article by an old friend, Alan Griffiths that runs along the same lines as Bruce's article. Alan used to write for Overload, the C++ journal I edited for a few years (he may still do so?).
He went through a number of different "smells" and listed several attributes that each of those smells have (e.g., bloated, exposed, duplicated). Smells have names like "Speculative Generality" (making code unnecessarily flexible or generic), "Inappropriate Intimacy" (where two classes are too tightly coupled), "Feature Envy" (where one class keeps calling methods on, and operating on the data of, another class) etc.
Some notable comments were:
- In Test-Driven Development, the names of the tests should seed the documentation of the code - since good tests ought to reveal what the code does
- A dumb data holder class can often be refactored - either to include behavior from elsewhere (making it a real class) or to move the data elsewhere (making it unnecessary)
He showed several code fragments and asked the audience to identify the "smells" for each so it was a very interactive (and entertaining) session. He mostly left the solutions - the refactorings - as an exercise for the audience. Very worthwhile!
Right now I'd better pay attention to Mike Rosen who is explaining SOA.
Update: check out Josh's refactoring website.
Eric's blog is one of only a few Microsoft blogs that I read regularly. He writes some great stuff (although I wish he wouldn't use purple text).
Quite a few of my former ANSI standards committee colleagues are there as speakers: Dave Abrahams, Chuck Allison, Kevlin Henney, Rex Jaeschke, Dan Saks, Alex Stepanov, Herb Sutter. Other well known names include: Scott Ambler, Scott Bain (behind the NetObjectives UML series I recently blogged), Bruce Eckel ("Thinking in..."), Allen Holub ("Getters and Setters are Evil"), Stan Lippman, Stephen Mellor, Scott Meyers, Ted Neward, Randal Schwartz, Alan Shalloway, Joel Spolsky, Gerald Weinberg, Rebecca Wirfs-Brock.
Anticipation for Hani (Bile Blog) to write a scathing stream of vitriol about how Prevayler represents everything that is wrong with the Java open source movement. I love reading Hani's rants but he seems to have been on holiday for the last two weeks, which is very disappointing.
In the end, I wasn't disappointed: Mike Spille stepped up to the plate to rip into Prevayler. Mike also seems to have been on holiday for a while with no posts to his Pyrasun Blog since early December.
Hani's message is sometimes lost in his (very humorous) ranting but Mike tends to stay much more focused and really pulls out some key issues when he has something to rant about.
Reading Mike's blog entry - and the Prevayler material itself - really does make you wonder about some of these Java projects. It is open source itself or is it just Java? What causes these cult-like, fringe projects to get such high-profile coverage? And why so many of them?
These are smart folks and they can't figure out how to add optional static typing without breaking things. Guido's article goes on to look at a few of the issues and even he admits to being groping in the dark on some of them. Even the humble greatest common denominator function is a thorny hotbed of issues!
Back when I used to write source code analysis tools, I used to take a lot of flak for a couple of warnings the tools produced about "optimized" loop code (in C / C++ where people think rolling operations into a single line with the ++ operations makes things faster). After receiving several complaints from users, I sat down and benchmarked the generated machine code for a variety of platforms, both with and without compiler optimization enabled, for the code my tool complained about and the code my tool suggested you write instead. In every single case bar one, the simple, recommended code was as fast or even faster than the compressed code that most users thought was faster. Only on one platform, with compiler optimization enabled, was the simpler code slower. I put the results in the next release of the product manual and users stopped complaining.
Sometimes, the obvious is wrong. And in most cases the benefits of low-level optimization are so minor that they just aren't worth the effort.
Like it or not, knowing OO principles may help you get a job over someone who doesn't. Web development has grown up.
I think that's a bit weird but I can sympathize - we had a party to celebrate BroadVision's eCommerce software being removed from our website and replacing it with freshly-minted ColdFusion and Flash code!
I don't think you always need to move back from expert in language X to beginner in language Y - it all depends on whether your skills are based on the language or based on the larger skill of programming. I was also an Assembler and COBOL programmer back in the day but I could also program in C (and several other languages) so each change of job and each change of technology for me was always built on top of my prior experience - as I added C++ and then Java and then ColdFusion to my toolset.
The key here is programming ability and I think that means being multi-lingual and keeping up to date with what the industry is doing on the leading edge (learning about patterns, AOP, SOA, MDA etc and picking up the best practices contained therein).
There's nothing wrong with being a ColdFusion programmer but you owe it to yourself to learn other skills too, not to change technology but to get better jobs that pay more and still let you leverage your favorite technology. In other words, don't be just a programmer...
Migration paths are very important for programmers. If they feel they don't have a reasonable migration path for their skills, they will consider changing their core skills instead of simply upgrading them. Microsoft is taking a big gamble on .NET because for both VB and ASP, the .NET versions are in many ways radically different - more of a reskill than an upgrade. They're gambling that developers using Microsoft technologies are prepared to reskill - still using Microsoft technologies - rather than stay put (with older MS technologies) or changing completely to non-MS technologies.
A few recent notes I've seen on blogs indicate that there are likely five times as many Java developers than C# developers out there which is an interesting data point (and the trends don't look like changing that ratio in the near future).
Some of these issues were known irritants back when I was on the committee that we just didn't have time or resources to address.
It's good to see more information appearing about developing for .NET on non-Windows platforms. It'll be interesting to see how Mono and Portable.NET do.
Anyway, what have I got for my efforts? Stunningly simple yet extremely comprehensive CVS integration. Wow! The Navigator View shows CVS versions and whether files are up to date or not. The context menu on files offers a very rich set of CVS-related commands and the Text Compare (between versions) is very slick too.
In E4X, you can now specify XML literals that create fully-formed navigable XML structures behind the scenes, and you can traverse these structures using notation similar to XPath, with dots used instead of slashes:
var over27inEng = empdoc..employee.(department.@id == 500 && age > 27);This will return all
employee nodes (like //employee in XPath) which have: - a
departmentchild with anidattribute equal to 500 and - an age
childwith a value greater than 27
I look forward to seeing E4X support appearing in various implementations of languages based on ECMAScript!
Note: TeraTech are also offering a one-day Mach II training course from Hal Helms to give developers a fasttrack way to learn Mach II. At just $349, this sounds like a bargain to me - and it's the Monday after Fusebox 2004 so you can easily combine the two events for very little additional outlay!
No developer with a day job has time to keep up with all the new development tools coming out of Redmond, if only because there are too many dang employees at Microsoft making development tools!There's a deeper undercurrent in that quote that affects us all - well, all us 'developers' - we like to develop solutions to problems that we perceive and not all of those perceived problems are real problems in the world at large. Why do so many of us want to consistently recreate the wheel? Because doing so is 'cool' and 'fun', for the most part. Why do so many of us write our own blogging software or whatever the flavor of the month is? We're developing solutions for ourselves, a lot of the time, without looking at what 'the client' really wants (whoever the client happens to be). I find it interesting that underlying Joel's analysis and commentary is essentially that same accusation laid at Microsoft's door: they got a bit too wrapped up in cool technology.
And then, of course, there's Mono. Someone recently asked me what I thought the impact of Mono would be. Hmm, well, I don't think Mono is going to kill Windows / Microsoft / Java / Sun / whatever. I think that it will provide a way for a large number of open source developers that dislike Microsoft to develop software using Microsoft (sorry, "ECMA standard") technology (.NET / C#) with less guilt and less discomfort. But since I don't see it running "MS Word for .NET" any time soon I don't see it actually 'going' anywhere in particular. Even if the extended Mono community build complete new GUI shells etc on top of it, I don't see those apps making headway on Windows .NET systems (too much competition from Microsoft itself - even assuming Windows .NET systems gain enough market share!). And if the Mono community's apps don't get take up on Windows .NET systems, that leaves Linux which, whilst it is a definite threat to Microsoft, isn't going to suddenly accelerate in uptake just because Mono is around. In my opinion. After all, if Microsoft fails due to the failure of Longhorn / .NET then Mono isn't going to be very popular either... So why not use Java?
/opt/local in case you are wondering). All I had to do to get up and running was to add /opt/local/bin to my path environment variable and I was writing my first C# program ("Hello World" of course). After my experiences with the SSCLI on Jaguar, I was amazed at the speed of Mono's compiler and runtime! Now I guess I can get on with learning C# although I don't really know what I'll use it for...
I also wanted to play with ASP.NET so I downloaded XSP and mod_mono (for Apache) but the XSP server process doesn't seem to run properly on Mac OS X yet unfortunately. I may spend some time fiddling with the source code to see if I can isolate the problems. The mono-devel list already helped me to get mod_mono to build correctly but I'm guessing that not too many Mono developers are using Macs right now.
- Safari. I started with an early beta and I've loved it ever since. It's fast, feature-rich and so well integrated with the operating system.
- Borland's Together Control Center - in my opinion the best Java design and development environment ever created. Even at $6k per seat (which it was when we bought it several years ago) it's great value!
- Dreamweaver MX 2004 - a powerful, sophisticated code editor and HTML tool with FTP, SFTP and a myriad shortcut tools.
- SQL Grinder - the best $49 I ever spent on shareware! An intuitive tool for manipulating databases.
- MacCVS GUI - a powerful CVS UI, although it doesn't allow the "-b" option on diff. The fish icon is cute :)
- MySQL - OK, I agree with Mats on this one!
- Fire - http://fire.sourceforge.net/ - the Mac equivalent of Trillian.
- Eclipse - promising IDE... might be worth using in a few years once they get the performance and the functionality sorted... :)
- MacLorem - a great utility for generating gibberish to populate web pages while you are developing
- OmniGraffle - a wonderfully intuitive graphics program
- OpenOffice - we don't need no stinking Microsoft Office!
- Virtual PC - a necessary evil... It works really well and, frankly, it's more reliable than native Windows on Intel
- Watson - a whole bunch of amazingly useful utilities in a simple UI
- Macromedia Contribute - the easiest way to manage random websites
- NetNewsWire - the best Mac RSS feed reader
- iCal - the simplest, best calendar application
- Mozilla Firefox - the best "second" browser (I just upgraded from Firebird)
There is no one true way that works for all people, all teams or all projects. This is true of all the "ologies" we deal with in the software industry. The trick is knowing which parts of which "ology" will work for you and your team and adopt them accordingly (and in an informed manner).
Like Mr Ed, I have misgivings about a number of things many XP people seem to think - the agile manifesto (quoted in the comments on Hacknot) has led many XPers to completely undervalue process, tools, documentation, contracts and plans to the point of viewing them as unimportant. They are important in the bigger picture - XP is very programmer-focused and while that may get software built faster, it doesn't mean you get a good maintenance proposition. I'm not convinced that YAGNI, KISS and "embrace change" are a good basis for a system that will be easy to maintain and enhance in the future (they're often good for the micro-problem but the macro-problem needs more forethought and more care, in my opinion).
Alan Richmond shared a link to this wonderfully insane article recently on the Mach II mailing list: Hello World in Patterns. The sheer ingenuity of the author has to be admired in combining so many patterns to create something so complex just to say "Hello World!". That article doesn't have a great of substance, it's true, and it is a very extreme edge case, however it links to this rather excellent discussion: Design Patterns Considered Harmful. I think the best quote from that discussion is "A master will no longer use patterns except where they would occur naturally. After all, this is really what patterns are - the natural solution to the problem that have repeatedly arisen even before they were written."


