| //TheArts/ImprovisationsVol1 | Fri Jun 12 2009 10:27 PM GMT | I'm having a 'private beta' of a new solo piano album I'm considering releasing through these here internets. The contents are much more of a modern classical (i.e. whacked out) sort than other stuff I've done. In particular, I'm looking for sound engineering feedback, but any thoughtful ears will do.
If you think you have the patience to put up with this pretentious nonsense, email me.
| | | | | | //ComputersAndTechnology/MakingBadProgrammersCare | Fri May 22 2009 05:59 PM GMT |
[updates at the end of the page]
BruceEckel blogged this:
On the other hand, the WBC summit was really about psychology: why do programmers write poor code and don't seem to care about it, and what can we do to convince them to write better code and to care? At best, we succeeded in enumerating the problems that we had seen, so compared to the other summits we reached no conclusions. But perhaps the struggle was the important thing, and like Weinberg's PSL company simulation, we all needed to have these ideas inserted so we could struggle with them over the ensuing years.
I had a similar conversation with PragDave once. He related an incident with a programmer at a client that seemed 100% on board with unit testing, and then never actually did it. They'd go round and round, discussing doing it, and then it never happening.
Rick Kitts would like a "developer psychology book" (I'm quoting a comment he posted to his own article, not directly linked here...). Sounds like he wants one for the business people, too.
Luke Hohmann says:
Forcing a given team to adopt an approach that they don't believe in ... is a certain recipe for failure.
How do we change their beliefs?
Alistair Cockburn throws a log on the fire of despair:
Somewhere in here is the point I'm trying to make.
* One point is that there really are a bunch of good techniques and behaviors out there, and there are people who use them effectively. * One point is that most people don't know of such techniques and can't use them. * One point is that Oh So Very Many People don't have the motivation and energy either to research and learn the techniques, or to apply them. With the very many disastrous results that we see. * One final point is that the last point limits our hopes of eventual success, whether with agile, with lean, with project management, product management, testing, architecture, etc etc etc. As long as the multitudes can't be bothered, it doesn't matter what great techniques some of us know.
So, in this sense, I'm done with the "60% projects fail, 60% features don't get used" attack (or defense).
Those failures can be ascribed to lack of caring. That has no known antidote.
As Bruce says, this is about psychology and ethics and morals. This is about the spirit and the soul.
This TED talk by Dan Ariely ("Our Buggy Moral Code") I think has some interesting parallels to some of the agile practices to increase the amount of accountability in a group. Dan doesn't use the word accountability, but it's what kept coming to my mind throughout the talk.
see FaithAndBusiness.
| | | | | | //ComputersAndTechnology/AlmostBarelyWorking | Fri May 22 2009 04:50 PM GMT |
Dave Stagner submitted this great post on the pragprog mailing list that I think relates to CompletenessAndMaturity:
Software hovers around the line between barely works and almost works.
This has nothing to do with technology. It's human nature. Given the resources (time, skills, tools) needed to write software that more than barely works, almost everyone from the lowliest hacker to the biggest megacorporation will choose instead to write more software, or more complex software. New functionality is added or new ideas pursued until the software degenerates from "barely works" to "almost works". At this point, either the effort is made to get the software back up to the barely works state, or it just gets worse until it is abandoned.
I think this is an important point in the SoftwareAppreciation category as well. I'd wager most not-very-technical managers of tech would not see something working as 'barely working', only to be surprised when the problems in the future crop up (see also TendingSoftware).
| | | | | | //ComputersAndTechnology/OnManaging | Thu Apr 16 2009 04:16 PM GMT |
Some thoughts (that need better organization) after listening to 2 Radio Lab podcasts: "Choice" - talking about the magic number 7 (+/- 2) and the experiment with cake and fruit, and "The Obama Effect, Perhaps" [podcast only], talking about the distraction of stereotypes in performance:
DO NOT DISTRACT your technical people. They have a multitude of decisions to make throughout the day in terms of quality (better code organization, testing considerations, etc) which WILL COST OR SAVE YOU MONEY down the road.
Schedule pressures, multitasking, anything that will offer a technical person a conscious or subconscious reason to just move on with less than their best is bad business.
Of course, this whole point is irrelevant to you if you think too much that developing software is BDUF and Mindless (Monkey?) Coding At Back (MCAB).
This looks like it could relate, though not exactly sure how. (HT/RT: @marick)
In one study, college students were given one of two menus. One menu featured French fries, chicken nuggets and a baked potato; the other included those same items as well as a salad. The French fries, widely perceived as the least healthful option, were three times [33% of all subjects vs. 10%] as popular with students selecting from the menu that had the salad as they were with the other group.
| | | | | | //ComputersAndTechnology/ShiftingAbstractions | Mon Mar 30 2009 06:44 PM GMT |
Read LeakyAbstractions if you're not familiar with that concept.
If you have a difficult time grasping how changes in abstraction layers can bite a schedule in the arse, here's an example from a team I worked on:
The prior version of a handheld application the team was working on knew how to trigger the camera on the device to capture an image. No big deal.
Then a newer model of the device was selected by management to be deployed to end users and the technical team eventually got one of the new devices to try the software with. When they did, they discovered the application could no longer trigger the camera on the new device. Why? The device manufacturer had decided to change the interface (the key abstraction here) to the camera, and utilize a new API provided by the manufacturer of the OS.
Unfortunately, this all went down during a stressful time of the project and apparently some executives complained that the technical team should have known about this change in the device and accounted for the day and a half they lost to figuring out how to accommodate this unforeseen change.
The technical team was initially proud of the fact they'd been thrown such a curve ball and had still hit the ball. Any complaints may have quickly stomped out that fire by having an unreasonable expectation for being able to predict the future.
The problem is it's way too easy to use hindsight to connect the dots and think they should have been connected. Reality is things take time to get to. On reflection, the technical team couldn't get the new device any faster, because the newness of the device had restricted inventory and the manufacturer was delayed in getting the team the device.
Go read EmergentAngst for another take on 'shouldas'.
| | | | | | //ComputersAndTechnology/ComputersAreNotPeople | Mon Mar 30 2009 04:45 PM GMT |
Elisabeth Hendrickson's post prompted me to flesh this one out.
People are very good at learning, adapting and intuiting. Computers are great at performing repetitive tasks with precision and speed. Vice-versa -- not so much.
This is a big problem when translating from a people process to a robot one, because often times people don't understand what they do to the level of detail a computer needs.
This is not the same thing as "people don't know how to do their job." People succeed in their work all the time. The distinction is they do a portion of it unconsciously.
To demonstrate, grab a smart-ass (a 12 yr old boy will do just fine). Now, instruct them how to tie their shoelaces, and make sure the smart-ass takes all of your instructions literally. Within less than a minute, I predict you'll be ready to smack your assistant.
To make matters worse, most business processes that the software under development is trying to emulate are spread across multiple people, all who are unaware of some of the details that they effortlessly perform every day.
This is why I agree with agilists who promote getting working software into the hands of end-users as quickly and as frequently as possible, to flush out all of the unconscious bits.
P.S. This doesn't even touch the fact that new software tools may enable end users to discover new ways for them to do their work. You certainly can't automate a process that hasn't even been thought of yet.
P.P.S. An example of this from my own work history: Company A had a tool to allow client managers to author surveys that an army of field reps could use on a handheld to gather information from the front lines for said client. Company B also had a tool like this. Company A agreed to take on Company's B business, and it was my job to create a new survey building tool to accommodate the needs of both. In the process, Company A gained some new functionality. There was no great way to specify how this new functionality should work, however, because it turned out Company B didn't actually have this functionality previously, they just thought it would be cool to have. So, how do you invent a new tool the end-users have never had before? Interactively.
But this is bad news for the bean counters: there's no great way to know what that's going to cost ahead of time. Best way to manage that budget: interactively.
| | | | | | //ComputersAndTechnology/TddEfficiency | Tue Mar 03 2009 05:38 PM GMT |
From Brett Bim:
Microsoft Research has put out a paper with data that shows implementing TDD ... decreases your pre-release defects by 40-90%.
Paper is here. InfoQ's take:
The pre-release defect density of the four products, measured as defects per thousand lines of code, decreased between 40% and 90% relative to the projects that did not use TDD. The teams' management reported subjectively a 15–35% increase in initial development time for the teams using TDD, though the teams agreed that this was offset by reduced maintenance costs.
| | | | | | //ComputersAndTechnology/ProgrammingAsTheoryBuilding | Fri Feb 20 2009 06:29 PM GMT |
see DevelopmentAnalogies
testrus tweets about a paper written by Jason Catena discussing "Programming as Theory Building", an article written by Peter Naur, reprinted in Alistair Cockburn's Agile Software Development:
Naur makes the argument that the act of developing software has mistakenly been taken as an act-of-production—production of “a program and certain other texts.” He cites several examples of empirical data inconsistent with the production model of development; including, the fact that documentation of arbitrary completeness and exactitude does little, if anything, to convey an understanding of a program to those not involved in its original creation.
Theory building, `a la Naur, is the individual and collective effort to: understand the world; understand how the software is shaped by the world and how it will integrate with that world; understand the essence of the software and how best to articulate (code) that essence; and understand if you have gotten the first three understandings right.
The observable activities associated with theory building include telling a lot of stories, exploring ideas, trying things to see if they work, testing your understanding, populating your physical space with evocative reminders of your understanding, and doing these things iteratively in increasingly comprehensive increments. Looks a lot like an agile environment, but bears little resemblance to a production environment.
testrus also shot me a link to an article by Dave West that references Naur's work as well.
see also ComputersAreNotPeople
| | | | | | //ComputersAndTechnology/JavaScriptMethods | Fri Feb 13 2009 07:44 PM GMT |
Being the hipster that I am, I'm just now getting around in 2009 to doing some work in JavaScript. To help me get up to speed, I begged the twitter-verse for help and my friend Glenn Vanderburg came to the rescue. He gave me a little personal tutorial on methods and namespace issues via IM, and when I asked if I could paste it here, he said, "Anything for you, Mr. Fowler."
Glenn's written about his own n00by-ness with JavaScript here, an extract from some of his NFJS talks.
I guess my immediate n00b concerns: 1) I'm going to have a few methods all acting on some data, so I don't want 5 global methods all passing around the same data through params and 2) I've seen people do namespace tricks to keep from defining anything in the global space methods, but I don't know what those are or what is best.
OK. JavaScript supports "classes", kinda. It uses functions to do double-duty as constructors, and if you intend to use a function as a constructor, conventionally you would give it an uppercase name.
function Point(x, y) { this.x = x; this.y = y; } var p1 = new Point(3,4);
Then to add methods, you do this:
Point.prototype.distance = function(otherPoint) { whatever(); }
Now you can say
p1.distance(p2);
The constructor (Point) is a function, but a function is just an instance of class "Function", so it's an object that has its own properties. 'prototype' is one of them.
So it's normal to define them outside the constructor, then?
Yes, that's normal. If you do that, then every instance shares the same methods. If you do it in the constructor, each instance gets its own (identical) copy of all the methods. That's not a big deal if you're only going to create one instance, which is pretty common, and it does have the advantage that the methods defined in the constructor share access to the parameters of the constructor and local vars defined in the constructor, which gives you a kind of "private" instance variable (Crockford writes about that). But typically you don't need that way. The JavaScript way is public everywhere, and in the context of a web page that works pretty well.
So back to my example of adding methods ...
Point.prototype.distance = function(otherPoint) { ... };
Since Point is just an object, and so is its prototype, you can do this also:
Point.prototype = { distance: function(otherPoint) { ... }; };
replacing the entire prototype with a new object that has all of your methods defined in it. Some people like that because it's less noisy and gives you one set of braces between which you can find all of the methods of Point.
Ok. So if i did that a 2nd time, it'd blow away the prior methods, not append them.
Yes, precisely.
So then, others have defined methods like Object.extend so that you can say:
Point.prototype.extend( { distance: function(otherPoint) { ... }, });
Extend copies all the properties from the passed object into the target object, so you don't actually replace the prototype, you just add a batch of new properties and values to it.
[You can also add methods to an object's prototype this way:
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g,""); }
]
The cool thing about the way the prototype works, whether you use it the 'normal' way or using extend, is if you start with this:
Point p1 = new Point(3,4); Point p2 = new Point(4,5);
and then, later, you do this:
Point.prototype.translate = function(otherPoint) { this.x += otherPoint.x; this.y += otherPoint.y; };
Now p1 and p2 both support translate(), even though you defined the method after you created the instances, because method lookup is completely dynamic.
This is similar to Ruby, no? If I append a method to the String class, all existing string instances get that method, too.
Yes. But in JavaScript, if you replace the prototype after you've created instances ... you've effectively created two classes. All of the previously created points are members of the first class, and new ones are members of the new one.
When you say "new Point(3,4)" the new point object gets created, and then its __parent__ property (which is where method lookups happen ... it's like the internal class pointer in Ruby) gets set based on the current value of Point.prototype.
Now, on to namespaces.
There's no such thing as a namespace. Just global variables, local variables, and objects. Sometimes people define a "namespace" by wrapping everything in a big anonymous function and using local vars:
(function() { var a, b, c; function foo(){ a = 3 } function bar(){ alert(a); } foo(); bar(); } )();
and there are times when that's appropriate. But usually people define one global variable, set it to an object, and use properties of that object as their namespace:
FooBar = { foo: function() { this.a = 3 }, bar: function() { alert(this.a); } };
That's what jQuery does: it only sets two variables in the local scope (jQuery and $) and they both contain the same object, which has a bunch of properties that are the jQuery functions and global state.
Ok. I think that broke parts of my brain.
Sorry about your brain. :-) JavaScript will do that.
Well, thanks a ton for the impromptu tutorial, this was very helpful.
You're welcome.
| | | | | | //ComputersAndTechnology/JoelOnSolid | Mon Feb 02 2009 05:34 PM GMT |
Joel's comments on SOLID Principles.
My knee-jerk reaction:
I think Joel is over-reacting to what he heard. I would need to listen to the Hanselman podcast first to know for sure, but at least in my practice of SOLID, I frequently do not code things out to letter of the law in obedience to SOLID, but I will make note of where I smell a violation with code comments, so when I come back through there later, I can know that if I need to enhance what's going on there, I'm going to need to revisit the design so I don't continue on in the path of the violation and have to suffer that fate.
I'm hearing Joel preach YAGNI and I think Uncle Bob would agree.
Uncle Bob's POV.
| | | | | | //ComputersAndTechnology/DiskUsageForWindows | Mon Jan 19 2009 08:23 PM GMT |
cLabs Disk Usage for Windows (clduw)[1] is a utility I wrote in Delphi[2] a number of years ago for finding where all your disk space has gone. I still use it fairly regularly (though there are many alternatives out there these days) and have just put up with its cruftiness: mainly, that it doesn't background thread the disk scanning so the thing just hangs there.
After being pinged this week by a user (howdy Olav!) who was rightly complaining about another bit of cruftiness (improper sorting of Int64 data), I decided to get off my duff.
I haven't released anything formal yet, but the latest build can be found here: http://clabs.org/dl/clduw. Check it out and click the email link there on the right if you have any feedback.
What's been done so far (build 57):
- fixed the sorting bug on really big numbers - added background threading of disk scanning, with regular update of UI as it searches - when the list view has focus, the Enter key no longer triggers the Refresh button but instead will drill down into the selected directory in the list - backspace shortcut key for going up a directory - default sort order is now disk space used, descending - added File | Open... option to browse to a directory to scan - additional keyboard shortcuts for existing functions (e.g. Ctrl+E to explorer the current folder) - A new "Maximize Height" view option. Maximizing the whole form is still an option, but having such a huge gap of white space between the directory name column and the other columns is not very usable, so now you can just maximize the height (F11 shortcut) to get as much of the list visible without losing the proximity of the column data. - If there's an error message from Windows trying to scan a folder, its message is now displayed next to the folder's name.
[1] Sheesh, I bet that page looked old in 1996. Could I have weaker layout skills?
[2] Alas, poor Delphi. You served me well in years past, but you're just too constricting a language and IDE to work in these days compared to Java/Eclipse and C#/VisualStudio/R#. (Granted, I'm still only using the free 2006 Turbo edition (is there a later free version?)). Adding threading was a bit too much work compared to these other languages.
| | | | |
|
|