JazzScheme "feels" familiar to both CL programmers and Scheme programmers (although it is neither) as it incorporates features from multiple languages. In addition, it currently supports a mixture of object systems. For people coming from a Java background, there is an object system that looks very similar to the Java one; however, JazzScheme also supports a more CLOS-like object system as well and a programmer can mix-and-match the approaches.
Although JazzScheme is currently a Win32-only product, it was recently open-sourced and Guillaume is porting it to Linux and Mac OS X by re-writing the Win32-specific C++ core in Scheme (currently, Gambit ) and using the Cairo graphics library (for graphical rendering). In addition, he is transitioning JazzScheme from a proprietary lisp dialect to actually being an R5RS-compliant Scheme.
Jedi is the IDE used to develop JazzScheme code (although it also currently supports Scheme, CL, C++, and Java as well) and is the largest non-commercial application developed in JazzScheme. It has a look and feel similar to Eclipse but with influences from Emacs, MCL, and the Lisp Machine. It was fun to see how you could dynamically introspect/debug/change UI components of the editor while you were editing code in the editor! Once the multi-platform port has been completed, Jedi should provide a nice alternative for Scheme or CL programmers who don't want to use Emacs.
Guillaume plans to have the cross-platform version of JazzScheme/Jedi available (as an early beta) in the beginning of 2008. It will be interesting to see how this develops and I'll definitely be following his progress. If you're interested in learning more about JazzScheme, you can browse the JazzScheme web site, download the Win32 version of the code, and join the
Joe O’Brien and I will be hosting the Test-Driven Developement in Rails Pragmatic Studio in Columbus.
Test Driven Developement in Rails
Mark your calendars. It is official! Joe O’Brien and I will be teaching a new Pragmatic Studio: Test Driven Development in Rails . The first offering of this studio will be in Columbus on October 17th through the 19th.
To quote from the web site :
In this Studio, you’ll learn how to do test-driven development by actually doing it. We’ll teach you how to get started with a solid foundation of testing practices, and then quickly build on those with advanced techniques and tools. You’ll experience a powerful synergy between testing and design that helps you write better software, faster!
If you ever wanted to improve your testing skills in Ruby and Rails, then this wil be the place for you. I’m really excited about this opportunity. I hope to see a lot of you there.
Here's what Amazon's best sellers page looked like today. LiSP even managed to beat out Harry Potter!
Or, alternatively, maybe the tastes of the book-buying public are improving! ;-)
Can older people be great entrepreneurs?
Marc Andreesen has a
great post
on this age-old question. In part I, he's digging through the data. Some of his observations are powerful and worth summarizing:
"Generally, productivity -- output -- rises rapidly from the start of a career to a peak and then declines gradually until retirement.
This peak in productivity varies by field, from the late 20s to the early 50s, for reasons that are field-specific.
Precocity, longevity, and output rate are linked. "Those who are precocious also tend to display longevity, and both precocity and longevity are positively associated with high output rates per age unit." High producers produce highly, systematically, over time.
The odds of a hit versus a miss do not increase over time. The periods of one's career with the most hits will also have the most misses. So maximizing quantity -- taking more swings at the bat -- is much higher payoff than trying to improve one's batting average.
Intelligence, at least as measured by metrics such as IQ, is largely irrelevant."
I went through an evolution of sorts on this topic.
I started with a variation of the Beard Hypothesis (enthusiasm decreases with age but experience increases, and there's an optimum cross-over point). This is the easiest viewpoint as you get older and look back at some of your earlier crazier ideas, but notice that that older crowd is very risk-averse. Douglas Adams had a great take on it:
- "everything that’s already in the world when you’re born is just normal;
- anything that gets invented between then and before you turn thirty is incredibly exciting and creative and with any luck you can make a career out of it;
- anything that gets invented after you’re thirty is against the natural order of things and the beginning of the end of civilisation as we know it until it’s been around for about ten years when it gradually turns out to be alright really.
- Apply this list to movies, rock music, word processors and mobile phones to work out how old you are."
I then moved on to Dean Simonton's observations, beautifully covered in Marc's article. My thinking was driven by books like "The Black Swan," "Fooled by Randomness," DeVany's analysis of Hollywood Economics and Home-Run Hitting, and a casual observation of how Evolution creates things (massive trial and error). Basically, the number of swings at bat, poems attempted, paintings painted, etc. determine the success rate. The more you try, the more you learn, the faster you iterate, the better you get, and the more chances that you have of being productive. Your outcome scales more with the number of bets than the...
As displays increase in size and prices drop, more and more users will end up with relatively large displays by default . Nobody buys 15 or 17 inch displays any more; soon, it won't make financial sense to buy a display smaller than 20 inches. Eventually, if this trend continues, everyone will have 30-inch displays on their desktops. This is clearly a good thing. You can never have enough display space. But there is one unintended consequence of large displays.
One of the advantages of small monitors, ironically, is that because they're small, they nudge users into a simpler, windowless method of working . Instead of wasting time sizing, moving, and z-ordering windows, users only need to deal with one maximized window at a time. They can flip between maximized applications in much the same way they change channels on the television. But once your display gets to 1600 x 1200 or beyond, this easy one-app-per-display model isn't feasible any more. Dan recently ran into this problem when he upgraded to a 30" LCD :
Users of 30-inch monitors face the terrible, terrible problem of how to effectively use all of that space. You don't often want to maximise a folder or document window on a screen this big; either you'll end up with a lot of white space and important program buttons separated by a vast expanse of nothing , or you'll get lines of text 300 or more characters long, which are difficult to read .
That's the large display paradox . Having all that space can make you less productive due to all the window manipulation excise you have to deal with to make effective use of it.
Personally, I'm a card-carrying member of the prestigious three monitor club , which means I'm one step ahead of Dan. At least until he doubles or triples down :
Although my displays are only 20 inches in size, I have three of them . Maximizing a window to a 20 inch, 1600 x 1200 display area is a reasonable thing to do most of the time. I also use UltraMon , which gives me the indispensible ability to drag maximized windows between monitors . I'm constantly grabbing maximized windows and "throwing" them from monitor to monitor, ala
Summary:
[[Category:Blog]]
[[Category:Blog entries by date|07.08.07]]
[[Category:Year, 2007]]
[[Category:Agile software development]]
[[Category:Project management]]
[[Category:Increments]]
[[Category:Iterations]]
==Blog: August 7, 2007 ==
I've noticed people lately yet again getting wrapped around the axle of "''incremental''" development versus "''iterative''" development. RUP and the OMG didn't help matters any by calling everything ''iterations'' and ''iterative development''. They're different, have to managed differently, have to be thought of differently. It happens that most project teams do both at the same time, usually without thinking about it. Then someone starts thinking about it, gets clever, and does one without the other. Bad things ensue.
=== Incremental development defined ===
From [[Using VW staging to clarify spiral development#Incremental_development_defined|"Using VW staging to clarify spiral development"]]:
: By "incremental development", I specifically mean a
:: '''staging and scheduling strategy''' in which the various parts of the system are developed at different times or rates, and integrated as they are completed.
: It neither implies, requires nor precludes iterative development or waterfall development - both of those are rework strategies. The alternative to incremental development is to develop the entire system with a "big bang" integration.
''Incremental'' development helps you improve your '''process.''' Each time around the process, you get to change and improve your work habits.
=== Iterative development defined ===
From [[Using VW staging to clarify spiral development#Iterative_development_defined|"Using VW staging to clarify spiral development"]]:
: By "iterative development", I specifically wish to mean a
:: '''rework scheduling strategy''' in which time is set aside to revise and improve parts of the system.
: It does not presuppose incremental development, but works very well with it. As shown in the figures, the difference is that an increment may actually ship, whereas an iteration is examined for modification.
''Iterative'' development helps you improve your '''product.''' Each time around the process you get to change and improve the product itself (and maybe some of your work habits)
----
These definitions were written back in 1992, when they were still separate terms and people wanted to know their meanings. Then, as above, RUP and the OMG people mushed the two together and we've been having trouble ever since.
Those definitions are still pretty good, 15 years later. Sit on them, hatch them, think about what it means to do them separately and together. Think about how your project strategies might vary as...
It started with me forgetting my laptop bag at home . Then I had to work with an attorney on some things. He's a nice guy, and does a good job, but you know, it's not what I'd really like to spend my day doing.
Then in the middle of the afternoon, I hung up the phone and checked my email. About 50 messages from Samba telling me that processes with various PIDs had crashed unexpectedly. Uh-oh. I think we still have some 80ish people using that.
About a minute later, a coworker says, "John, I've been bad." "Is that why I just got 50 emails from Samba?" "No. Well, yes. Well, maybe. I don't know."
It turned out he was working on a restore from tape that, out of necessity, grabbed more data than he needed. He meant to type
rm -r ./var
but typed
rm -r /var
instead. Oops. He hit Ctrl-C halfway through, so /var was still there enough to send email but not enough for Samba (or, apparently, NFS) to work.
As he dashed off to pull yesterday's tapes from offsite storage, I prepared the restore and made a plan. We hadn't installed any software since yesterday, so I restored var to a temporary location, took the server down into single-user mode, overwrote the /var that still existed, and rebooted the Xen instance in question. Everything back to normal. Except, that is, for the potentially dozens of users that will require assistance running SCANPST.EXE because their Outlook PST, being the fragile heap of garbage that it is, will have somehow been corrupted by this little incident.
So, what did we learn from this?
- Deleting /var was probably the least annoying outage I've had to deal with yet. Certainly less nerve-wracking than the time I was working on a live, powered-up server and my wedding ring shorted out something on a circuit board. I didn't know if that thing would just reboot or if we'd be down for hours waiting for parts...
- It was really nice knowing what was going on, rather than trying to find that bit out
- One coworker commented, "if he had to delete part of an operating system, at least it wasn't Windows. We wouldn't have recovered in 15 minutes if it was." True.
- Bacula is great.
- Backups are great, even if you don't use Bacula to make them.
- I dislike programs that take server load from 0.3 to 9.5 just telling you that there's something wrong with the server.
What to do? I could just work without headphones. I'd be fine, but you know, I've got standards here. My job involves working with computers, so I ought to be able to come up with a workaround, right?
So lesse... what do I have? One binaural (mono sound, but speakers for each hear) telephone headset. One Polycom SIP phone, connected to our corporate Asterisk system. One workstation with sound capabilities. One installation of Asterisk on this workstation for testing purposes. And, a pre-existing path from the corporate system to the workstation system for testing Asterisk. (Very handy that, and used a lot when we were doing active Asterisk work.)
So in less then five minutes I had music going via my telephone headset. Lo-fi, and not noise-dampening like the Etymotics, but I enjoyed it for the simple fact that it was being played *over the phone* at no cost to anyone. My desk phone supports multiple "lines", so I still could place and receive calls just fine.
Should anyone care to look, they'd find a 5-hour call from me to myself deep in the Asterisk logs. My own workstation logs will show that I put myself on hold for 5 hours (since I used Asterik's music-on-hold feature to play my own selections).
IP telephony is fun. So is Asterisk.
The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures. Yet the program construct, unlike the poet's words, is real in the sense that it moves and works, producing visible outputs separate from the construct itself. It prints results, draws pictures, produces sounds, moves arms. The magic of myth and legend has come true in our time. One types the correct incantation on a keyboard, and a display screen comes to life, showing things that never were nor could be. ... The computer resembles the magic of legend in this respect, too. If one character, one pause, of the incantation is not strictly in proper form, the magic doesn't work. Human beings are not accustomed to being perfect, an few areas of human activity demand it. Adjusting to the requirement for perfection is, I think, the most difficult part of learning to program.-Frederick P. Brooks, "The Mythical Man-Month: Essays on Software Engineering, Anniversary Edition (2nd Edition)"
Here is a sample " To over take other automobile companies and to reach at the helm, Toyota had devised a comprehensive action plan which included the Toyota Production System. " .
"reach at the helm"? WTF? You expect me to believe Roy writes or speaks like that?
I can only conclude that some half baked journalist essentially made up the article and attributed it to Roy.
Thoughtworks is an excellent company, with many world class writers in its ranks and this kind of ghostwriting goes against everything Thoughtworks stands for. And if the editors at the magazine must have someone pretending to be Roy, they magazine ought to get someone who understands how to write English well.
It amazes me that people whose profession is all about writing well don't know the rudiments of the language in which they write.
In the spirit of Jennifer Tidwell's excellent Designing Interfaces book , there are a few great catalogs of data visualization emerging online.
Start with the oft-cited Periodic Table of Visualization Methods .
There's another excellent collection at Data Visualization: Modern Approaches .
If you're looking for visualization with a less practical, more web-oriented bent, a colleague recently discovered the FWA: Favourite Web Awards site. That's where we found the Uniqlock "clock" , and the giant rickshaw pointer .
At any rate, if you're a student of Tufte like I am, you might find it helpful to review a sample of what visualizations and techniques are possible (or even advisable) before plowing ahead on your next "Rich Internet Application" .
| [advertisement] PhotoDrop.com makes it simple to create and share online photo albums. Upload your full resolution pictures via the web site or with the free Photo DropZone utility, and you're done. No fees. No storage limits. It's the fastest and easiest way to share photos and create albums . |
To understand just what is being asked for here, first observe that a standard pair of dice throws a 2 exactly 1/36 of the time, a 3 exactly 2/36 of the time, and so forth:
| 2 | 1/36 |
| 3 | 2/36 |
| 4 | 3/36 |
| 5 | 4/36 |
| 6 | 5/36 |
| 7 | 6/36 |
| 8 | 5/36 |
| 9 | 4/36 |
| 10 | 3/36 |
| 11 | 2/36 |
| 12 | 1/36 |
The standard dice have faces numbered 1, 2, 3, 4, 5, and 6. It should be clear that if one die had {0,1,2,3,4,5} instead, and the other had {2,3,4,5,6,7}, then the probabilities would be exactly the same. Similarly you could subtract 3.7 from every face of one die, giving it labels {-2.7, -1.7, -0.7, 0.3, 1.3, 2.3}, and if you added the 3.7 to every face of the other die, giving labels {4.7, 5.7, 6.7, 7.7, 8.7, 9.7}, you'd still have the same chance of getting any particular total. For example, there are still exactly 2 ways out of 36 possible rolls to get the total 3: you can roll -2.7 + 5.7, or you can roll -1.7 + 4.7. But the question is to find a nontrivial relabeling.
Like many combinatorial problems, this one is best solved with generating functions. Suppose we represent a die as a polynomial. If the polynomial is Σ a i x i , it represents a die that has a i chances to produce the value i . A standard die is x 6 + x 5 + x 4 + x 3 + x 2 + x , with one chance to produce each integer from 1 to 6. (We can deal with probabilities instead of "chances" by requiring that Σ a i = 1, but it comes to pretty much the same thing.)
The reason it's useful to adopt this representation is that rolling the dice together corresponds to multiplication of the polynomials. Rolling two dice together, we multiply ( x 6 + x 5 + x 4 + x 3 + x 2 + x ) by itself and get P ( x ) = x 12 + 2 x 11 ...
(0,0,0)And you can see at a glance whether two vertices share an edge (they are the same in two of their three components) or are opposite (they differ in all three components).
(0,0,1)
(0,1,0)
(0,1,1)
(1,0,0)
(1,0,1)
(1,1,0)
(1,1,1)
Last week I was reading the Wikipedia article about the computer game "Hunt the Wumpus" , which I played as a small child. For the Guitar Hero / WoW generation I should explain Wumpus briefly.
The object of "Wumpus" is to kill the Wumpus, which hides in a network of twenty caves arranged in a dodecahedron. Each cave is thus connected to three others. On your turn, you may move to an adjacent cave or shoot a crooked arrow. The arrow can pass through up to five connected caves, and if it enters the room where the Wumpus is, it kills him and you win. Two of the caves contain bottomless pits; to enter these is death. Two of the caves contain giant bats, which will drop you into another cave at random; if it contains a pit, too bad. If you are in a cave adjacent to a pit, you can feel a draft; if you are adjacent to bats, you can hear them. If you are adjacent to the Wumpus, you can smell him. If you enter the Wumpus's cave, he eats you. If you shoot an arrow that fails to kill him, he wakes up and moves to an adjacent cave; if he enters you cave, he eats you. You have five arrows.
I did not learn until much later that the caves are connected in a dodecahedron; indeed, at the time I probably didn't know what a dodecahedron was. The twenty caves were numbered, so that cave 1 was connected to 2, 5, and 8. This necessitated a map, because otherwise it was too hard to remember which room was connected to which.
Or did it? If the map had been a cube, the eight rooms could have been named 000, 001, 010, etc., and then it would have been trivial to remember: 011 is connected to 111, 001, and 010, obviously, and you can see it at a glance. It's even easy to compute all the paths between two vertices: the paths from 011 to 000 are 011–010–000 and 011–001–000; if you want to allow longer paths you can easily come up with 011–111–110–100–000 for example.
And similarly, the Wumpus source code contains a table that records which caves are connected to which, and consults this table in many places. If the caves had been arranged in a cube, no table would have been required. Or if one was wanted, it could have been generated algorithmically.
So I got to wondering last week if there was an analogous nomenclature for the vertices of a dodecahedron that would have obviated the Wumpus map and the table in the source code.
I came up with a very clever proof that there was none,...
[ more ... ]
That go me thinking about the problem in general. For some reason I've been trying to construct a die whose faces come up with probabilities 1/21, 2/21, 3/21, 4/21, 5/21, and 6/21 respectively.
Unless there is a clever insight I haven't had, I think this will be rather difficult to do explicitly. (Approximation methods will probably work fairly easily though, I think.) I started by trying to make a hexahedron with faces that had areas 1, 2, 3, 4, 5, 6, and even this has so far evaded me. This will not be sufficient to solve the problem, because the probability that the hexahedron will land on face F is not proportional to the area of F , but rather to the solid angle subtended by F from the hexahedron's center of gravity.
Anyway, I got interested in the idea of making a hexahedron whose faces had areas 1..6. First I tried just taking a bunch of simple shapes (right triangles and the like) of the appropriate sizes and fitting them together geometrically; so far that hasn't worked. So then I thought maybe I could get what I wanted by taking a tetrahedron or a disphenoid or some such and truncating a couple of the corners.
As Polya says, if you can't solve the problem, you should try solving a simpler problem of the same sort, so I decided to see if it was possible to take a regular tetrahedron and chop off one vertex so that the resulting pentahedron had faces with areas 1, 2, 3, 4, 5. The regular tetrahedron is quite tractable, geometrically, because you can put its vertices at (0,0,0), (0,1,1), (1,0,1), and (1,1,0), and then a plane that chops off the (0,0,0) vertex cuts the three apical edges at points (0, a , a ), ( b ,0, b ), and ( c , c ,0), for some 0 ≤ a , b , c ≤ 1. The chopped-off areas of the three faces are simply ab √3/4, bc √3/4, ca √3/4, and the un-chopped base has area √3/4, so if we want the three chopped faces to have areas of 2/5, 3/5 and 4/5 times √3/4, respectively, we must have ab = 3/5, bc = 2/5, and ca = 1/5, and we can solve for a , b , c . (We want the new top face to have area 1/5 · √3/4, but that will have to take care of itself, since it is also determined by a , b , and c .) Unfortunately, solving these equations gives b = √6/√5, which is geometrically impossible. We might fantasize that there might be some alternate solution, say with the three chopped faces having areas of 1/5, 2/5 and 4/5 times √3/4, and the top face being 3/5 · √3/4...
If you really do want just the math articles for some reason, you can subscribe to the feeds at http://blog.plover.com/math/index.rss or http://blog.plover.com/math/index.atom . I've been generating these sub-feed files since the blog began, and I know nobody uses them. But perhaps someone would like to.
Similarly, there are sub-feeds for other subsections of the blog, for example "physics". Most of these topic areas receive many fewer updates than does the "math" section:
| 64 | math |
| 16 | lang |
| 14 | physics |
| 14 | oops |
| 14 | linogram |
| 14 | book |
| 14 | prog |
| 10 | bio |
| 7 | lang/etym |
| 6 | meta |
Personally I feel that the eclecticism of the blog is one of its attractions, and I gather that a lot of other people do too, but perhaps not everyone agrees.
Summary:
[[Category:Blog]]
[[Category:Blog entries by date|07.08.05]]
[[Category:Year, 2007]]
[[Category:Agile software development]]
[[Category:Requirements]]
====Blog: August 5, 2007 ====
I just started noticing an interesting trend --- more people are writing real "stories" to anchor their requirements (on agile projects).
This is a nice trend away from XP's "user stories" (misnamed because they generally contain no ''story'', just a feature or ability.)
The people writing these new types of stories don't care what XP calls or called it's <whatever-they-are>. They simply have decided to write stories describing a real person doing a real thing with the system, stories that have a beginning, a middle, an end, stories with steps in them, with concrete details.
Other people have done this in the past and given them names. HCI folks call them "concrete scenarios"; I had to call them "usage narratives" because XP had taken the more appropriate name "user story".
The new wave of people ignore all that and simply write stories.
Here's the type of thing:
----
: Fred the facilities manager creates an order using the system. The system notifies Rick the review manager, who reviews the order using the system and OKs it.
: Lee, the loading dock worker, puts it onto a truck, marking it accordingly in the system.
: When the truck gets to the receiving dock, Liz the loader at that location fills in needed paperwork, eventually also marking in the system that the item has arrived. . . .
----
You get the idea.
In some official lingo, this is a ''concrete scenario'' of a ''kite-level use case''. However, repeating myself, people writing these things often just call them "stories".
Try it - I think you'll like it.
(p.s. the Eclipse Jazz project also uses these stories - I'm trying to get one to post.)
----
<center>
[[People still trump process|<< previous blog entry]]
|
[[???|no next blog entry >>]]
</center>
Ha. I'm just kidding.
The demand for a politics reddit has been great, and the political news has been bountiful, so here you go. We hope that a politics reddit will allow our politically inclined users to focus their submissions on a more targeted audience.
In other news...
The new version of reddit is inches away from getting online. We had hoped to get it online last week for you all to test and to play with, but things always seem to be more complicated in practice. We'll keep crunching and get things cruising as soon as we can.
Take it easy, redditors.
Going through some old code, I found this obfuscated python poem I wrote five years ago:
cruel_python, what_have_i_done
='evil.append(list(eachone))',
"awful code is so much fun"
if 'i am smart': 'it just might run'
"it's so much worse than 'hello world'"
"these next three lines look just like perl!"
'while(<>){chomp;s/perl/python;print}';oranges='fruit';
bad="'enitlavo ruoy knird'=gsm;gsm labolgxgsm tnirp";
empty="";global eachone;evil=[];
'but a secret here is in your reach'
apples=oranges, "eachone=each"
def do(task="do what i ask"):
global eachone; exec task
"and just in case you're not perplexed,"
worse,now = (bad.split('x'),"!")
for each in worse:
exec apples[1]
if each in worse:
do(cruel_python)
worse = evil; "evil".split().reverse()
[each.reverse() for each in worse]
"and now we've reached the final verse";
map(do, map(empty.join, worse))
I originally posted this as a cryptogam on comp.lang.python, after my previous cryptogram was cracked after only half an hour.
Turns out, even with garbage code like this, python's syntax and whitespace made it trivial to crack the simple cipher.
The last meeting was focussed, for instance, on the difficulties of transitioning from the habits instilled from working in India's "Silicon Valley" to those needed for doing world class work, particularly in research/scientific software, the price one needs to pay and the metrics of progress. While that was a fascinating discussion, what struck me then was how lucky I am to know people who are unwilling to accept the status quo and exert themselves to become the best they can be.
This extends beyond the attendees of our end of month meetings. I just got back from lunch with another friend I haven't met in a while. I am amazed at how much she has learned in the intervening period and how many different areas of improvement she has targeted for the future. Indian society has the nasty habit of grinding down women who want to excel in any field, so that will be an interesting career to watch. If she ever starts a company, I will be the first to invest in it.
On reflection, I realize that I subconsciously rank people by (a) their potential to excel and (b)the ratio of actual achievement to potential achievement. I pay attention proportional to how high I think they score on these parameters and so I end up ignoring people who, in my subjective opinion, have low scores on both parameters.
I am not very sure that is the "right" way to judge people or decide who to befriend (I guess I am an unconscious "elitist") but it results in my knowing people who strive to excel. And given the caliber of some of my friends, I effectively end up knowing people who'll change the world.
A standard part of my development kit is Microsoft's Visual Studio . Here's what I have to install to get a current, complete version of Visual Studio 2005 on a new PC:
- Visual Studio 2005 Team Suite Edition
- Visual Studio Team Explorer (Team Foundation Client)
- Visual Studio 2005 Service Pack 1
- Visual Studio 2005 Service Pack 1 Update for Windows Vista
- SQL Server 2005 Express Service Pack 2
- Visual Studio 2005 Team Edition for Database Professionals
- Visual Studio 2005 Team Edition for Database Professionals Service Pack 1
Note that this is only a partial list; it doesn't include any of the other Visual Studio add-ons you might need to code against newer Microsoft technologies, such as ASP.NET AJAX , WF , or .NET 3.0 .
What's wrong with this picture?
I appreciate that some of these products were released out of order, which is partially why the install is so convoluted. But if one of the disadvantages of open-source software is "configuring the stack" , I'm having a hard time seeing how Microsoft's commercial stack is any easier to configure than the alternative open source stacks these days . Either the open source stuff has gotten a lot more streamlined and mature, or the Microsoft stuff is somehow devolving into complexity. I'm not sure which it is, exactly, but the argument that choosing a commercial development stack saves you time rings more and more hollow over time.
As the old adage goes, Linux is only free if your time is worthless *. But apparently your time can be worthless even if you've paid for the privilege.
* attributed to Jamie Zawinski .
| [advertisement] TransferBigFiles.com allows you to send huge files (up to 1GB) to anyone without worrying about email attachment limits. Send via the Web site or download the DropZone utility for even more functionality. Its fast, easy, and totally free! Transfer big files now . |
Summary:
[[Category:Articles]]
[[Category:Software development]]
[[Category:Articles by date|2007.08.03]]
[[Category:Year, 2007]]
<center>
[[Collaboration: the dance of contribution|
<< previous article]]
|
[[???|
next article >>]]
</center>
'''Alistair Cockburn''', Humans and Technology, [mailto:arc@acm.org]
Humans and Technology Technical Report ''HaT TR 2007.02'', Aug. 05, 2007. © Alistair Cockburn
''Give your users two chances to review and revise each software feature before you consider the feature basically "done". Here's how to schedule, plan and track it.''
== The problem ==
Ever since writing [[Are iterations hazardous to your project?]] I have been bothered that the current agile practice doesn't seem to think it important that the users get to see what's being built and change or steer it. Iteration lengths are so short that the programmers barely have time to program up the basics before the end of the iteration – there's certainly not enough time for the users to show up and say, "No, actually, that's not what I had in mind" or "No, actually, that doesn't work very well for me."
I heard one XP "customer" ask others in the product management or "customer" role, "Is it just me, or do you also have to ''get it right'' the first time? On our project, if I request a change, they tell me that story will go back to the back of the queue or the project timeline will be delayed. As a result, I have to get it right the first time. ... Isn't this against the very spirit of agile development?"
This person is right on all counts – that does happen, and it is against the very spirit of agile development.
In [[Just-in-time_methodology_construction#Methodology_Families|Crystal Orange]], we had a policy rule, "there are two user viewings per release".
That is, within the normal cost of developing some feature or use case for the user community, they had two chances to see '''real''' code (not just a UI mockup) and change their minds about what they were requesting. Since that was for a fixed-price project, the project manager stipulated an additional rule – on the first viewing, they could change anything, but on the second viewing, they could only correct mistakes.
I took this as basic user rights – of course they should get a chance to see it and correct it before it would ever be considered "''done''"!
It seems as though I was fairly alone in believing this. Over the years, programmers have become so focused on "getting the user story ''done'' and geting velocity credit for it" that they started considering user changes as an unnecessary cost. ("We could get this software out much faster if only the users...
My class in the fall is called “User-generated”, and it looks, among other things, at the tension surrounding that phrase, and in particular its existence as an external and anxiety-ridden label, by traditional media companies, for the way that advertising can be put next to material not created by Trained Professionals™.
All right-thinking individuals (by which I basically mean Anil Dash and Heather Champ ) hate that phrase. Now my friend Kio Stark * has come up with what seems like a nice, and more anthropologically correct version: Indigenous Content (which is to say “Created by the natives for themselves.”)
* ObKio: Best. Tagset. Evar.
Before I go, there are a few tasks that I need to accomplish. The most important one is implementing conjoining jamo behavior so that Korean will work properly in Unicode. (Korean will take a huge amount of room in memory, which I'll describe soon in another post.) Additionally, I have to finish Unicode collation and fix some problems with
pull-elem
, which will probably require huge changes in
extra/xml/xml.factor
. Those last two things might have to wait until October, but the first one is essential because there are people waiting for Unicode support, and strings of UTF-8 which Factor thinks are ISO 8859-1 won't cut it. I hope proper Unicode handling, including 8- and 32-bit strings, are made a part of Factor .90, or at the latest .91.
If I have any readers (or if there are any other Factorers) in the Northfield area, or just the Minnesota area (besides Doug), please contact me.
This is a fun example of using FlexMock
Andrew Sweeney Asks:
Andrew Sweeney emailed me with the following question:
I am currently working on a ruby project in which I think flexmock would be a good fit for unit testing. I have read the documentation and gone over the examples however fail to wrap my head around how to apply flexmock to my own app. I was hoping that you could give me some guidence and get me started or point me in the right direction.
You can find his original source code here .
I thought his problem was interesting enough to write it up as an example of using FlexMock. Andrew and his mentor, Bil Kleb gave permission for me to reproduce the code in my blog. The F3D Queue class is part of a Computational Fluid Dynamics project ( http://fun3d.larc.nasa.gov ) at NASA .
Quick Code Review
The F3D Queue class is small, so there’s not a lot of code we need to wade through. We see it uses a second class named AutoF3D, but the only clues we have to what AutoF3D might do are the four method calls on the “job” object in the run method.
It looks like the main interface to the queue object is the add_to_queue method. There is a thread started that pulls jobs (i.e. AutoF3D objects) from the queue and processes them in turn. There is some server delays built into the system. I presume that Computational Fluid Dynamics is, ummm, computationally complex and the delays are just there to make sure the workload does eat up all the CPU time on the server.
Starting Testing
When writing new code, I always like to approach it in a Test-First manner. Because I won’t write solution code without a test that forces me to write it, I have a high confidence that the code is will covered with tests.
Unfortunately, dealing with legacy code means that the code is already written and the test-first approach won’t work. That’s ok, I have a little trick that I use. Just comment out the bodies of all the methods in the class you are about to test. Then write the tests that force you to uncomment the code. Just uncomment only enought to get the tests to pass, don’t uncomment anything you don’t have to. You have enough tests when all the code has been uncommented. The technique is almost as good as doing real test-first.
The Commented Out Version
Here's an interesting thought question from Mike Stall: what's worse than crashing?
Mike provides the following list of crash scenarios, in order from best to worst:
- Application works as expected and never crashes.
- Application crashes due to rare bugs that nobody notices or cares about.
- Application crashes due to a commonly encountered bug.
- Application deadlocks and stops responding due to a common bug.
- Application crashes long after the original bug.
- Application causes data loss and/or corruption.
Mike points out that there's a natural tension between...
- failing immediately when your program encounters a problem, eg "fail fast"
- attempting to recover from the failure state and proceed normally
The philosophy behind "fail fast" is best explained in Jim Shore's article (pdf).
Some people recommend making your software robust by working around problems automatically. This results in the software "failing slowly." The program continues working right after an error but fails in strange ways later on. A system that fails fast does exactly the opposite: when a problem occurs, it fails immediately and visibly. Failing fast is a nonintuitive technique: "failing immediately and visibly" sounds like it would make your software more fragile, but it actually makes it more robust. Bugs are easier to find and fix, so fewer go into production.
Fail fast is reasonable advice-- if you're a developer. What could possibly be easier than calling everything to a screeching halt the minute you get a byte of data you don't like? Computers are spectacularly unforgiving, so it's only natural for developers to reflect that masochism directly back on users.
But from the user's perspective, failing fast isn't helpful. To them, it's just another meaningless error dialog preventing them from getting their work done. The best software never pesters users with meaningless, trivial errors-- it's more considerate than that . Unfortunately, attempting to help the user by fixing the error could make things worse by leading to subtle and catastrophic failures down the road. As you work your way down Mike's list, the pain grows exponentially. For both developers and users. Troubleshooting #5 is a brutal death march, and by the time you get to #6-- you've lost or corrupted user data-- you'll be lucky to have any users left to fix bugs for.
What's interesting to me is that...