I just cut my own hair! It was so incredibly easy! I'd snipped at little bits with scissors before, or cleaned up around my ears, but this time I got out the clippers and really did it. #2 all around the sides and back, then I cleaned up the top and front with scissors. Wow! I can't believe I have ever paid $80 for a haircut, ever. This may not be as perfect as the cuts I get for $35-50, but it's certainly as good as a $12-30 cut. Of course, I can't quite see the back... If you see me in person, you have my express permission to tell me if the back looks bad.
how to bring a powerbook g4 to its knees
My powerbook has finally gotten so incredibly slow that I'm resorting to using my linux box as a client. Here's the trick: I'm burning a purchased ten-hour unabridged audible book to audio cd, for personal use. I think the audible DRM policy must only allow this because it's such a fucking pain. I'm on disc 4 of what will probably be 10 or 12, and my mac has been unusable for most of the last hour. I can type into my text editor, but it's like closing my eyes, because the text doesn't appear for at least 30 seconds after I type it. Oh, well, they're only comments.
I'm really enjoying having a few non-stress days to explore and code in Open Laszlo. It's a fast, fun platform for prototyping, and I love that I can just post my work and almost anyone anywhere can see it, pow, with nothing more than Flash 7. It's the total opposite of working with C++ and OpenGL on a custom virtual reality hardware installation. "Sure, I'd love to show you my work, just come to Providence, Rhode Island." Heh. Nope, much easier now.
The question still remains: do I spend some time this week getting up on the learning curve with Objective-C/Cocoa/XCode, or do I leave all my eggs in the OpenLaszlo basket? All things come to an end, eventually, and when my association with Laszlo ends, I don't want to have to go back to C# and .NET, or (heavens no!) middleware.
roundrectbutton, and the purpose of styles
I've been sort of disliking OpenLaszlo styles since I started using CSS. The <style> tag says "Be greenish!" which is a cool effect, but not much use when I'm trying to match a particular customer's brand, or artist comps. CSS lets me specify exact colors; the <style> tag lets me suggest approximate colors.
But something changed my mind. Yesterday, Oliver Steele contributed a roundrect class to OpenLaszlo. Until then, without a designer and art assets, we had to prototype with plain old rectangular views. The roundrect class inspired a button based on it, roundrectbutton, which I've just checked in to the dev branch, in the incubator. I was trying to make it a well-behavd basecomponent subclass, so I made it handle _applyStyle
, so now it's tintable. This makes me happy in a silly sunday morning wannabe designer kind of way.
In the example below, the roundrect buttons are mine; the other widgets are built-in OpenLaszlo components.
Semi-Transparent Text in Open Laszlo
Due to a limitation in the Flash player, device text can only be visible or invisible; any non-zero opacity values for text will be drawn as opacity=1. "Device text" means text drawn by the Flash player using the client operating system's underlying font technology. Device text is inexpensive both in runtime cost and download cost; it uses the font already present on the client machine, so no font description needs to be downloaded. However, device fonts are handled slightly differently on different operating systems; the font dimensions may not be the same across runtimes, and some OS's may not even have fonts you expect. (Notably, most linux machines lack Verdana.)
Embedded fonts are more flexible, but they cost more, in runtime and download size. The OpenLaszlo platform ships with several TrueType fonts, which can be found in lps/fonts
. Specify a font for embedding by using the font tag:<font name="timmons" src="timmonstb.ttf" />
This includes the timmons TrueType font in the swf built from your lzx code. If you're counting bytes (and you should be) just that one font adds 58624 of 'em to your download. Ouch. If you're design-focused, embedded fonts are worth it for two reasons: one, you can be sure they will look the same on every flash runtime, and two, they can be rendered semi-opaque.
There are two workarounds, both of which increase the download size:
- Turn the text into an image; render it as an image with dynamic opacity. This is a huge pain to maintain.
- Use embedded fonts.
The difference between embedded and device fonts has been bothering me for a while, so I put together a little example. It constrains the opacity of various text objects to the value of a slider.
Here's the app:
Here's the code:
<canvas width="600" >
<font name="Arioso" src="ariosor.ttf">
</font>
<font name="timmons" src="timmonsb.ttf"/><view name="inset" x="20" y="20">
<simplelayout axis="y" spacing="10" /><view name="controls" layout="axis:y; spacing:30" width="100%" height="140" >
<text multiline="true" x="10" width="${parent.width-20}" >
This slider controls the opacity of each of the text objects below, as
well as the right half of the rectangle at the bottom of the canvas.
Opacity varies from 0 (slider=0) to 1 (slider=100).
The text using embedded fonts (timmons and arioso) can have fractional
opacity; the text using device fonts can only be visible or invisible.
</text>
<slider id="gSlider" minvalue="0" maxvalue="100" value="50" x="10" width="${parent.width-20}" />
</view><view height="130">
<simplelayout axis="y" spacing="10" />
<text id="gText" height="24" font="timmons" fontsize="18" opacity="${gSlider.value/100}">
some text in timmons (an embedded font)
</text><text height="24" font="Arioso" fontsize="18" opacity="${gSlider.value/100}">
some text in arioso (an embedded font)
</text><text height="24" font="Verdana" fontsize="18" opacity="${gSlider.value/100}">
some text in verdana (a device font)
</text><text height="24" font="Sans" fontsize="18" opacity="${gSlider.value/100}">
some text in Sans (a device font)
</text>
</view><view width="200" height="100" layout="axis:x">
<view bgcolor="black" width="100" height="100" opacity="1" />
<view bgcolor="black" width="100" height="100" opacity="${gSlider.value/100}" />
</view></view>
don't want to stop coding
I don't want to stop coding. It's past 11 on sunday night; I'm meeting a co-worker for coffee at 9 am to make sure I get out of bed at a reasonable time... The reasonable course of action would be to stop coding and get ready for bed. But! I have five open P2's, and code freeze is tomorrow at noon... That's not really the reason. The reason I still want to code is because there are things that are broken that I can fix.
There are runtime warnings that come from platform code, ie, OpenLaszlo. Changing the platform has more process than changing the application, so I want to get these taken care of tonight. The other runtime warnings, I know Scott will give me a hard time about... and rightfully so. Warnings are a sign that something is not entirely right. I want things to be entirely right!
Isn't it strange, though, that it's six times harder to make changes to the non-revenue-generating product (OpenLaszlo) than it is to make changes to the revenue-generating product (laszlomail)?
So, are we back to the "I write code to meet external demands" point of view? No. I write code, I am now writing code, because I want to make it better. Because I don't want to see those 1-pixel errors on the live site. I write code because I'd rather sleep less tonight and have a better product tomorrow, then sleep enough tonight and have a bunch of 1-pixel errors tomorrow.
gratitude
Can I mention again how happy I am with this life? I woke up in soft blankets with friendly cats, made breakfast, cleaned the bathroom, worked on some code... I walked in the rain over to the grocery store, listening to NPR on my iPod nano (thank you, marshall!) and bought groceries... Then walked home, again in the rain, but dry in my fleece and shell... Once home, I started a load of laundry and put away the groceries. Now I've just closed a P1, I'm working on a feature I've been wanting to add for months, and I'm safe and warm.
This is what I wanted. This is what I've been trying to create for myself.
The word of the month is gratitude. Thank you, world. Thank you, village. Thank you, old and new friends, for helping me get here.
big nerd ranch
Bret was telling me today that he's thinking about taking a class on LAMP, which reminded me of the geek cruises and the Big Nerd Ranch. Now I badly, badly want to go to the five-day objective-C and Cocoa class at the Big Nerd Ranch. While my employer would probably pick up some educational expenses, I don't think they'd be into paying $5k for me to learn the skills for my next job. Don't get me wrong here; I love working at Laszlo Systems and I've got no plans to go anywhere else. But there usually is a next job, sooner or later, and I want to write mac software. Just as soon as I master lzx, photoshop, and settle down to a single text editor.
UC Berkeley Extension doesn't seem to have really LAMP-specific courses, although this one on XML & Web Services sounds good.
As a clueful client-side geek who can sort of scramble by on the server-side, how can I best help a brilliant friend learn what he wants to know about internet architectures?
anderson cooper
I am worried that Anderson Cooper will be killed in Iraq.
productivity vs life
Yesterday was a very productive day for me. I wrote the first half of a chapter on animation for a book on OpenLaszlo, along with working examples, then I refactored my laszlo finite state machine to something closer to generalizable. (It needs to be ready to handle the passage of time as a first-class event.) I didn't fix any laszlomail bugs, but I did sleep until past noon. Here's the thing: I didn't go to a birthday party for a friend of mine. When it got to be time to go, I felt, "I want to keep working!" ...so I did. So maybe this is how those wildly productive people manage to be wildly productive: by choosing work over a social life.
Waking up this morning, lazily, slowly, I realized this part of my life is luxurious. I have a weekend day and I can do whatever I want. I don't have much disposable cash, but in some ways that makes my weekends easier; back in the 90s dot-com days, I spent large parts of my weekends shopping, or doing dinner at a nice restaurant, and a movie, or snowboarding, or whatever. That kind of wanton spending isn't an option for me right now, so it's easier to choose to work.
But again: work for me is joy. Writing a chapter on animation in Open Laszlo is immensely enjoyable: this is cool technology that produces tasty user interface effects, and I'm excited to help people learn how to do it.
The real world is still here, though; today I have to tear myself away from the computer long enough to go grocery shopping. Grocery shopping supports coding, by providing the nutrients I need to keep coding, without disrupting my process to go out and find food.
Someday my life will be different from this; someday my life will include a life-partner and maybe kids and more commitments to external organizations and a regular yoga class and sunday-morning-waffles with my circle of friends... That will be then. For now, I am enjoying this life. I'm free, and I'm doing the work I've always wanted to do.
experimenting with amazon associates
I'm experimenting with Amazon Associates, to see how it looks and feels to have click-thru recommendations in my blog. My blog readers are precious, and I don't want to waste your screen space or attention with google adwords. If I post a link in my blog, it's a link to something that I care about, and something that I think deserves a couple hundred pixels. Plus, I get a kickback of some small fraction of your purchase price. So, here we go:
Unix Power Tools is the best book on unix/linux that I've ever read. It's 1200 pages of little tiny superpowerful unix tricks. I bought this book twice (maybe gave the first one to my brother?) and it's worth buying over and over and over. It's the best parts of the best O'Reilly books. These little articles present just one thing, and you will learn something valuable even if all you read is that one thing. Knowing how to use "ls -ltr | tail -10" has probably saved me many hours of poking around, and "find . -name" is crucial for navigating deep source trees.
Let me know what you think of having these little ads.
primetime camp
Whoever thought of this, I love you: William Shatner and James Spader are a couple on Boston Legal -- a primetime show on ABC. This is so incrediby superfantastic.
careful prep for a code review
Yesterday and today, I think I stumbled upon a good structure for getting several simultaneous high priority bugs approved for checkin together. Think of the changes as orthogonal; make a new changelist for each bug you're fixing. For each changelist, make sure that it fixes the bug. Then do diffs on your files against the most recently checked in files. For each line of diff, look for fixme's and todo's. Can you clean up some bad spacing or improve a comment? Once you're proud of every line you've touched, build and run one more time. If all is well, ask for a reviewer. Then it's straightforward: "To fix this bug xxx, I made these changes in widgviewsnow.lzx." You can present the change with confidence, because you know what you've done and why. Those are fast, fun code reviews; resolving half-dozen P1 bugs in the space of a few hours.
But before all of that comes the real work of finding and fixing the bugs. Lately it's been working for me to do serious coding from hoome at strange hours. When I'm in the office, I'm available for communication and interaction, but I can't generally count on getting much real focused work done at work, lately. Thus: code hard evenings and weekends. Present focused checkins for review. Be available to work with other team members. Surreptitiously borrow team members windows machines in order to install Firefox 1.5 and trillian and openoffice and cygwin.
chocolate economy, cats, etc
Expensive chocolates are significantly more expensive than regular chocolates.
This post by Wil Shipley just keeps making me laugh. Days and days of laughter from this:
"It is well-known, of course, that cats can die to death from not eating for six hours. Or, in this case, from having to eat the kibble bits left on the bottom of the bowl."
When reading this I actually freaked out for a minute, thinking, oh no, have I killed my cats by only feeding them once a day? ...despite the fact that my cats are in fact rather roly-poly. Goes to show how powerful the feline's mind control forces have become.
maximize each iteration
This post by Ron Jeffries caught my eye a few days ago: maximize each iteration. Over the last six months, my team has released a build to a customer at least once every two weeks, often more frequently. When I first started in this world, I was told, frequent checkins are good. At Brown, I would make a little tiny change, check it in, repeat over and over. Yes, I broke the build frequently, and my colleagues and I did not understand eachother's code at all. Here at Laszlo Systems, every checkin requires a peer code review. This is fantastic for code quality, but as usual there's a quality for time trade-off. In choosing the granularity at which to do checkins, I am starting to consider some of the hidden costs:
- The author needs to synchronize their tree, resolve any conflicts, and do some version of a fly-through/smoke-test.
- The author and the reviewer have to do the review at the same time, which means the author will some small-chunk time waiting for an available reviewer.
- After the review, the reviewer and the author will both have to re-establish their cognitive state.
- The other members of the team will have to update to get each checkin, and pay their integration tax. Each integration has a flat fee in addition to the per-line-of-code-change cost.
It's worth it. An ivy league education is essentially a long series of having really smart, experienced, knowledgeable people review one's work and suggest how to improve it. Even if it didn't improve software quality, the code reviews would be worth the time for the sheer educational value.
Ideas for how to improve the value of each code review:
- Do reviews in coordinated pairs. If we both wait until we're ready for a review, we only pay the stop/start cost once for two reviews.
- Take the right size bites. The XP metric is something like a day of work or less, I think; right now I'm feeling like two or three days would be better for my team's process. I need to stray farther from the trunk to maximize the value of each of my reviews. I think XP calls this courage.
- A lot of my checkins are (just) changing assets and constants. I should combine many low-risk changes into a single checkin.
Any other suggestions on how to maximize each iteration?
Here's a live demo of the OpenLaszlo Rich Text Editor, which is part of the Laszlo Mail application. (If this were an academic paper, I'd have been thinking for weeks about the order of author names. In this case, I'll just let the team lead do the talking.) A specification of the user interface and api is available on the wiki.
The platform version of the editor supports a more stable subset of the formatting operations available in Laszlo Mail. Paragraph formatting in the flash runtime is challenging; character formatting is simpler.
better at starting than finishing
I'm better at starting things than finishing them. This week has provided another round of interesting ideas from the fascinating people I work with, but now it's time for me to be a mature programmer, and finish one of my side projects. I want to be like Oliver Steele, who created packagemapper.com over Thanksgiving. Or Don Hopkins, whose site has a ton of little projects that work. Or, heck, Wil Shipley, the creator of Delicious Library and a major contributor to the incredible Omni Group products. (Sorry, Wil, I don't know exactly how to describe your role at Omni; hope I'm not selling you short.)
My last few years of working on software has all been very isolated and obscure. If I wanted to show anyone anything, they had to either come to my lab, or for some projects I could bring my demo machine with me and demo it live. The projects have been either demo-ware or essentialy theatre. With the Open Laszlo platform, I can finally make rich smooth tasty applications that other people can use from the comfort of their own homes. Now I need to add the fit-and-finish step to my process. One standalone rich text editor, coming right up...
no programming after 9 pm
I have a rule which I've been forgetting lately: no programming after 9 pm. This is my equivalent of the extreme programming 40 hours a week rule. I'm old enough and secure enough to admit that I'm useless as a coder after seven pm. I can still do decent pixel tweaking and whatnot for a bunch of hours after that, but if I haven't found a bug by seven pm, I'm not going to find it that night.
Some of my co-workers at Laszlo work insane amounts (fer instance, Scott Evans' domain name is antisleep.com) and I've been trying to be like them... even turning up at work before 9 am a few times! but no. I need eight hours of sleep a night; I really truly do. Stopping programming by 9 pm is one of the best ways for me to maintain my happiness and well-being, not to mention my code quality.
In my world, schedules matter on the order of days and weeks, not hours and minutes. If our process is running at light-speed, it takes minimum a day for a code change to go from "it works on my machine" to "it's live." At a more normal speed, we do weekly or semi-weekly builds. So, reminder to self: go to sleep! Now! And eat a sandwich!
over-caffeinated, or, the hazards of being friendly with java juice employees
Today I went on an afternoon fructose run, and treated myself to a matcha shot. That's powdered green tea in one or two ounces of fresh orange juice. One shot is supposed to be 75 mg, two shots is 150. I am a caffeine lightweight, so I usually get just one shot and drink half of it. I think this is one of the tastiest low-sugar ways to self-medicate with caffeine; I can't stand the sucralose/aspartame/red #5/natural and artificial flavors "energy drinks." I've indulged in this treat enough to make friends with one of the employees at the Jamba near the office, and today I think she must have given me a free double, or triple, or something, because it's seven hours later and I'm still rather caffeinated. Er, thank you? I think?
so that's where my disk space is going: insidious backups
Yesterday, I downloaded Xcode 2.2. This is a 933 mb download, and installs to even bigger than that. I let it install overnight, and I woke up to a message that my startup disk is almost full. Drat!. This is still my three-year-old titanium ibook, with a 30 gb hard drive. I went looking for stuff to cleanup, but I'd cleaned my desktop a few days ago, pruned unused source trees, deleted unused applications... so where is all my disk space going? I found a directory named Backups on the root dir of my drive. Looking inside, it contains "Home Folder Full Backup" from September 22, 2005, and 11.6 gigs of incremental backups for every day since then. Ouch! Ouch! Ouch! I'm using a third of my disk space backing up files to the same disk that contains them... so when my hard drive fails, these 11 gigs of backups are going to be useless.
I'm not stupid, and I've been burnt before, so hell yes I have backups. I backup to cd once a month; my source code and mail are backed up by my employer and gmail, and I periodically drop a snapshot on a remote server. My powerbook has had so many hardware problems in the last year that I don't rely on anything being there tomorrow that was there today. These incremental backups are quite possibly the least useful data I've ever stored on any media anywhere.
I'm a paying member of .mac and I use Backup 3, which comes with .mac, and comes configured with a sensible backup plan. When I was setting up with Backup 3, I think I made some decision like "I'm going to be very cautious and do lots of backups, more than the standard apple recommendations!" Apparently I didn't think that one through completely.
I implore each of my readers: backup to alternate, write-once media, with error checking, stored offsite. If not regularly, just do it now. Today.
I'm starting my work today backing up to cd, starting with purchased music and then going through the really crucial stuff, Quicken and email and pictures and notes. Want to take bets on how much longer my powerbook will last?
a free day for coding!
It's the friday after thanksgiving and have three days to do whatever I want! I want to code. The question is, what should I code? I could dive into a fairly bad set of Laszlo Mail bugs; I've got seven P1's blocking the next milestone. I could learn Ruby on Rails, although I don't have a project I want to implement with it, so let's rule that out. I could return to my Delicious Library laszlo application. I could look at some OpenLaszlo platform issues. I could work on a book chapter I've committed to writing for an early january deadline. I could go back to my skunkworks project that will dramatically improve Laszlo Mail usability.
How to choose? I want to do something that will be fun to do and that will give me that happy coding feeling. (Code is my favorite mood-altering experience, in case that wasn't clear already.) The P1 bugs and platform performance issues sort of fill me with dread. The skunkworks usability project, though, that's exciting. When I demonstrated a prototype a few weeks ago, people were really excited about it. Probably traditional software engineering values would say, quality before features, contractually-required features before strategic features before just cool features... but I say, bah! It's my three days, and I know I'll be spending the rest of November and December on quality and contractually-required features. So, I'm going to dive into the fun usability project, and get back to the bugs saturday or sunday.