Thursday, March 27, 2008
Adventuress Crew
I spent a Saturday on board in training, which included a sail around the bay.
The next day was the first public sail of the season. Since my family is a member of Sound Experience, we got to come on for free. We set up the bicycle train & all 5 of us rode down. The twins explored the cabins, including standing on my shoulders to peek out the focsle hatch. They eventually fell asleep as the trip was coming to an end - great timing! Reid got to look at plankton in a Microscope.
Monday I took Reid to his homeschooler's gymnastics class. It's held in the post office building, of all places, which is a fancy, century-old structure perched up high over the bay. From there I got to watch Adventuress sail around while he was in class.
Monday night I looked at Adventuress' schedule and saw that there wouldn't be many opportunities for me to volunteer, so I better get with it. They sail from a variety of ports, but only a handful of trips are from Port Townsend. They do day sails for a few hours, as well as 3-7-day trips, but I don't think I can fairly leave the family overnight.
First chance was Tuesday. So I showed up at the docks Tuesday morning, and they said they'd put me to work. It turns out that the group that was coming out was a homeschooling group, some of which had been at the gym class the day before. Funny.
Next chance was a public sail on Saturday, but we were out of town for a birthday party.
Easter Sunday we planned to do an egg hunt, but it was rainy, so we had a small event in our living room. Then I headed down to the docks for a public sail that afternoon. It was a pleasant sail, with enough wind to get us going, but not enough to make it "interesting". That is, until we were putting the sails away. We were training to furl the enormous mainsail, when a squall hit, and winds climbed to about 25mph. We could barely get the main under control, and it was suddenly cold, dark, and rainy to boot. When we were back at the docks, the weather cleared up, and we did what we could to make the boat neat -- shipshape.
Monday was the last day sail I can do for a while. It started off well for me. As soon as I stepped on board, I got to climb on top of the main gaff to downrig some extra lines they had placed up there for the wind. I enjoy the feeling of being able to climb; something I used to think I couldn't do. The participants were school kids, mostly 8th graders, who had come all the way from Yakima. It was quite a full ship, with 45 kids + 2 adults + crew. When we were headed back to the docks, I got to take the "small boat ride", zooming along in a little inflatable dingy, to be dockside when adventuress came in. Weee! When we were furling the staysail, we all sang "lean on me". There's a lot of music on Adventuress, and I love singing, but I'm not used to doing it with any kind of audience. Maybe in time... At the end of the day, I said my thanks and good-byes to the crew, and they responded quite heartily.
Wednesday there was a postcard from Adventuress, signed by many of the crew & staff, saying thanks.
I love the fact that we both feel indebted to each other. I am grateful for my chance to go sailing, to learn so much more about sailing in general, and this boat in particular, to see this beautiful ship in action, and to give others (passengers) the chance to get on the water, as well. I know that Adventuress & Sound Experience benefit as well: they got my help, and I know that organizations like this also feed on the energy that volunteers bring. Mutual indebtedness is the basis of a strong community. Bring it on.
At the beginning of May they'll be back in PT for a day; I hope I get to go out with them again then. After that, it's September, around the Wooden Boat Festival.
Monday, February 25, 2008
Adventuress maintainance

Thursday, February 21, 2008
The end of the world as we know it
First and foremost, I am aware of the environmental crisis: climate change, desertification, coral bleaching, tree death, topsoil erosion, habitat destruction, irreversible loss of biodiversity, toxic and radioactive waste, the PCBs in every living cell, the vast swaths of disappearing rainforests, the dead rivers, lakes and seas, the slag heaps and quarry pits, the living world reduced to profit and pavement.
I am aware of Peak Oil and the dependency of all aspects of our economic infrastructure and food supply on fossil fuels. And I realize that no conventionally-recognized alternative energy source can possibly hope to replace oil and gas any time soon.
Monday, February 18, 2008
Dear Diary
--
-Jay
Monday, February 11, 2008
Tuesday, January 22, 2008
Port Townsend construction irony
Thursday, January 10, 2008
Signs of Port Townsend: Getting to the library
Today we walked to the library for a story time event for toddlers. We put the twins in the double stroller for the trip there. When we arrived, we saw 3 strollers already parked outside. I think that's a good sign.
On the way home, Zephyr refused to ride in the stroller. As he walked, he stopped at each puddle, observed the relationship between the reflection and the real objects, dropped a rock in & observed the corruption of the image, then picked up the rock and walked on. He had a fantastic time. When he got home, he was cold & wet, but 15 minutes later he was warm & asleep.
Thursday, December 13, 2007
Biking the wrong way
First, I didn't have internet access working in the new house, so I couldn't look up bus info, and couldn't remember it well.
Second, I wasn't paying attention to the clock.
Third, I rode my bike on the wrong path. Here's what I could have done:
View Larger Map
(Assume I cut across that sharp left turn that Google Maps won't let me do, because it thinks this is for a car.)
But I turned left too early, and meandered around for a while. Here's what I did instead:
View Larger Map
That's 7.5 miles. I'm pretty impressed with myself, considering how long it has been since I was in shape, and how, with the move & everything, the last couple months have been little exercise and a gain of 10 pounds.
And then, after the bus ride, I rode the bike up the big hill to the house.
And then, I put the babies in the stroller, and walked to the grocery store to get dinner for the family.
I'm feeling proud of myself, and very hopefull for my future exercise.
Saturday, December 08, 2007
An attempt at an immutable Queue
Eric said he will write about an immutable queue implementation. I really like the way the immutable stack turned out, essentially using references between Stack<> objects to implement a linked list, but I couldn't figure out a similarly elegant way to do the same thing for Queue. Maybe people who are more clever will come up with something better, but I just had each Queue<> object contain a list of references to elements.
I wrote once in C# 2.0, using an array to store the elements. The code would be cleaner if I used a List<>, but then I would be harder to verify immutability.
class Queue<T> : IQueue<T>
{
public static readonly IQueue<T> Empty = new Queue<T>(new T[] { });
readonly T[] elements;
Queue(T[] elements)
{
this.elements = elements;
}
public bool IsEmpty { get { return this.elements.Length == 0; } }
public T Peek() { return this.elements[0]; }
public IQueue<T> Remove()
{
T[] newElements = new T[this.elements.Length - 1];
Array.Copy(this.elements, 1, newElements, 0, newElements.Length);
return new Queue<T>(newElements);
}
public IQueue<T> Add(T value)
{
T[] newElements = new T[this.elements.Length + 1];
Array.Copy(this.elements, newElements, this.elements.Length);
newElements[newElements.Length - 1] = value;
return new Queue<T>(newElements);
}
public IEnumerator<T> GetEnumerator()
{
for (IQueue<T> Queue = this; !Queue.IsEmpty; Queue = Queue.Remove())
yield return Queue.Peek();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
}
Then I rewrote using C# 3.0, taking advantage of the rich support for sequences. The code is much simpler, but I think that's basically because the IEnumerable extension methods do pretty much what I did in my first attempt. But I'll take it. J
class Queue2<T> : IQueue<T>
{
readonly IEnumerable<T> elements;
public static IQueue<T> Empty = new Queue2<T>(new T[] { });
Queue2(IEnumerable<T> elements)
{
this.elements = elements;
}
IQueue<T> IQueue<T>.Add(T value)
{
return new Queue2<T>(this.elements.Concat(new T[] { value }));
}
IQueue<T> IQueue<T>.Remove()
{
return new Queue2<T>(this.elements.Skip(1));
}
T IQueue<T>.Peek()
{
return this.elements.First();
}
bool IQueue<T>.IsEmpty
{
get
{
return this.elements.Count() == 0;
}
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return this.elements.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.elements.GetEnumerator();
}
}
Saturday, November 24, 2007
Immutable data class generator: it lives!
Well, it works. You invoke like this:
. .\Library.DataClass.ps1
class MyClass {
field ([string]) S
field ([int]) I
} > MyClass.cs
And then you can write:
MyClass mc = new MyClass.Builder().SetS("xxx").ToMyClass();
MyClass mc2 = new MyClass.Builder(mc).SetS("yyy").ToMyClass();
And the output looks like:
internal partial class MyClass
{
public readonly System.String S;
public readonly System.Int32 I;
public MyClass(string S, int I)
{
this.S = S;
this.I = I;
}
public class Builder
{
public string S;
public int I;
public Builder()
{
}
public Builder(MyClass value)
{
this.S = value.S;
this.I = value.I;
}
public virtual MyClass ToMyClass()
{
return new MyClass(this.S, this.I);
}
public virtual Builder SetS(string value)
{
this.S = value;
return this;
}
public virtual Builder SetI(int value)
{
this.I = value;
return this;
}
}
}
The main issue is that the ToMyClass and Set* methods are virtual. I think I may be hitting a bug in PowerShell, but I'm still researching it. For now, this will have to do.
Here's the implementation of Library.DataClass.ps1:
function Class
{
param (
[String] $name,
[ScriptBlock] $memberScriptBlock
)
$class = New-Object System.CodeDom.CodeTypeDeclaration $name
$class.TypeAttributes = [System.Reflection.TypeAttributes]::NotPublic
$class.IsPartial = $true
$constructor = New-Object System.CodeDom.CodeConstructor
$constructor.Attributes = [System.CodeDom.MemberAttributes]::Public
$class.Members.Add( $constructor ) | Out-Null
$builderClass = New-Object System.CodeDom.CodeTypeDeclaration "Builder"
$class.Members.Add( $builderClass ) | Out-Null
$builderConstructor = New-Object System.CodeDom.CodeConstructor
$builderConstructor.Attributes = [System.CodeDom.MemberAttributes]::Public
$builderClass.Members.Add( $builderConstructor ) | Out-Null
$builderConstructor2 = New-Object System.CodeDom.CodeConstructor
$builderConstructor2.Attributes = [System.CodeDom.MemberAttributes]::Public
$builderConstructor2.Parameters.Add(
(New-Object System.CodeDom.CodeParameterDeclarationExpression( $name, "value" ))
) | Out-Null
$builderClass.Members.Add( $builderConstructor2 ) | Out-Null
$realizeMethod = New-Object System.CodeDom.CodeMemberMethod
$realizeMethod.Attributes = [System.CodeDom.MemberAttributes]::Public
$realizeMethod.Name = "To$name"
$realizeMethod.ReturnType = $name
$ctorExpression = New-Object System.CodeDom.CodeObjectCreateExpression
$ctorExpression.CreateType = New-Object System.CodeDom.CodeTypeReference($name)
$realizeMethod.Statements.Add(
(New-Object System.CodeDom.CodeMethodReturnStatement(
$ctorExpression
))
) | Out-Null
$builderClass.Members.Add( $realizeMethod ) | Out-Null
# return a hash of the CodeDom objects related to
# this field
function field
{
param (
[Type] $type,
[String] $name
)
@{
type = $type
name = $name
readonlyFieldDeclaration = $(
# CodeDom doesn't support 'readonly' fields.
# See http://blogs.msdn.com/bclteam/archive/2005/03/16/396915.aspx
# $field = New-Object System.CodeDom.CodeMemberField($type, $name)
# $field.Attributes = [System.CodeDom.MemberAttributes]::Public
# $field
New-Object System.CodeDom.CodeSnippetTypeMember("`tpublic readonly $type $name;`n")
)
fieldDeclaration = $(
$field = New-Object System.CodeDom.CodeMemberField($type, $name)
$field.Attributes = [System.CodeDom.MemberAttributes]::Public
$field
)
parameter = New-Object System.CodeDom.CodeParameterDeclarationExpression($type, $name)
fieldReference = New-Object System.CodeDom.CodeFieldReferenceExpression(
(New-Object System.CodeDom.CodeThisReferenceExpression),
$name
)
parameterReference = New-Object System.CodeDom.CodeVariableReferenceExpression $name
setMethodName = "Set$name"
}
}
& $memberScriptBlock | foreach {
$class.Members.Add( $_.readonlyFieldDeclaration )
$constructor.Parameters.Add( $_.parameter )
$constructor.Statements.Add(
$(New-Object System.CodeDom.CodeAssignStatement( $_.fieldReference, $_.parameterReference ))
)
$builderConstructor2.Statements.Add(
(New-Object System.CodeDom.CodeAssignStatement(
$_.fieldReference,
(New-Object System.CodeDom.CodeFieldReferenceExpression(
(New-Object System.CodeDom.CodeVariableReferenceExpression "value"),
$_.name
))
))
)
$builderClass.Members.Add( $_.fieldDeclaration ) | Out-Null
$setMethod = New-Object System.CodeDom.CodeMemberMethod
$setMethod.Name = $_.setMethodName
$setMethod.ReturnType = $builderClass.Name
# This should be Public,Final, but that fails for me. Possible PowerShell bug?
$setMethod.Attributes = [System.CodeDom.MemberAttributes] "Public"
$setMethod.Statements.Add(
(New-Object System.CodeDom.CodeAssignStatement(
$_.fieldReference,
(New-Object System.CodeDom.CodeVariableReferenceExpression ("value"))
))
)
$setMethod.Statements.Add(
(New-Object System.CodeDom.CodeMethodReturnStatement(
(New-Object System.CodeDom.CodeThisReferenceExpression)
))
)
$setMethod.Parameters.Add(
(New-Object System.CodeDom.CodeParameterDeclarationExpression( $_.type, "value" ))
)
$builderClass.Members.Add( $setMethod )
$ctorExpression.Parameters.Add( $_.fieldReference )
} | Out-Null
$csharpCodeProvider = New-Object Microsoft.CSharp.CSharpCodeProvider
$sw = New-Object System.IO.StringWriter
$codeGeneratorOptions = New-Object System.CodeDom.Compiler.CodeGeneratorOptions
$codeGeneratorOptions.BracingStyle = "C"
$codeGeneratorOptions.BlankLinesBetweenMembers = $false
$csharpCodeProvider.GenerateCodeFromType( $class, $sw, $codeGeneratorOptions )
$sw.ToString()
}
PowerShell DSLs: Using hashtables and scriptblocks together
Previously I presented the use of hashtables and scriptblocks as DSL input formats. You can also convert between them, with processing in between. I tried that out, and I think the result is interesting enough to post. Again, here is the input:
class MyClass {
field ([string]) S
}
The previous code would use the 'field' function to manipulate the class object as appropriate:
function field
{
param (
[Type] $type,
[String] $name
)
# add the field declaration
$field = New-Object System.CodeDom.CodeMemberField($type, $name)
$field.Attributes = [System.CodeDom.MemberAttributes]::Public
$class.Members.Add( $field )
# add the ctor parameter
$ctorParameter = New-Object System.CodeDom.CodeParameterDeclarationExpression($type, $name)
$constructor.Parameters.Add($ctorParameter)
# add the ctor initializer
$fieldReference = New-Object System.CodeDom.CodeFieldReferenceExpression(
(New-Object System.CodeDom.CodeThisReferenceExpression),
$name
)
$ctorInitializer = New-Object System.CodeDom.CodeAssignStatement(
$fieldReference,
(New-Object System.CodeDom.CodeVariableReferenceExpression $name)
)
$constructor.Statements.Add( $ctorInitializer )
}
& $memberScriptBlock | Out-Null
But another idea is to have the 'field' function produce a collection of CodeDom objects that can be assembled later.
# return a hash of the CodeDom objects related to
# this field
function field
{
param (
[Type] $type,
[String] $name
)
@{
fieldDeclaration = $(
$field = New-Object System.CodeDom.CodeMemberField($type, $name)
$field.Attributes = [System.CodeDom.MemberAttributes]::Public
$field
)
parameter = New-Object System.CodeDom.CodeParameterDeclarationExpression($type, $name)
fieldReference = New-Object System.CodeDom.CodeFieldReferenceExpression(
(New-Object System.CodeDom.CodeThisReferenceExpression),
$name
)
parameterReference = New-Object System.CodeDom.CodeVariableReferenceExpression $name
}
}
& $memberScriptBlock | foreach {
$class.Members.Add( $_.fieldDeclaration )
$constructor.Parameters.Add( $_.parameter )
$constructor.Statements.Add(
$(New-Object System.CodeDom.CodeAssignStatement( $_.fieldReference, $_.parameterReference ))
)
} | Out-Null
I suspect that the latter model is a little better because it separates concerns. Consider if I were to add other statements to my language, such as 'property'. The 'foreach' at the end could probably be written in a way that works for both fields and properties. However, the hashtable is slightly concerning, because it's not typed – if I get the key names wrong somewhere, I'm screwed.
I find that I'm spending quite a lot of time on this, but it's important that I find a way to create DSLs quickly. I figured that right now I'm just learning the techniques, and then if I master them, then I can do it more quickly when the time comes.
Friday, November 23, 2007
Immutable data class generator: Skeleton implementation
I've made a little progress on my PowerShell DSL for data classes, and figured it's a good time to show it off.
Here's the input format at this point:
class MyClass {
field ([string]) S
}
(I'm using the ScriptBlock approach.) I generally like the syntax, except for the need to add parentheses around the type. The alternative is to use a fully-qualified string:
class MyClass {
field System.String S
}
I'm not sure which is better, but I'm going with the first one for now, because it allows a more specific type than string.
The basis of the implementation is to write methods named 'class' and 'field'. 'class' is simple; here's an excerpt of the important bits:
$class = New-Object System.CodeDom.CodeTypeDeclaration $name
$class.TypeAttributes = [System.Reflection.TypeAttributes]::NotPublic
$class.IsPartial = $true
$constructor = New-Object System.CodeDom.CodeConstructor
$class.Members.Add( $constructor ) Out-Null
$class
The implementation of 'field' could go in several different ways. For now, I've written it to manipulate the class as appropriate, e.g.:
$field = New-Object System.CodeDom.CodeMemberField($type, $name)
$class.Members.Add( $field )
$ctorParameter = New-Object System.CodeDom.CodeParameterDeclarationExpression($type, $name)
$constructor.Parameters.Add($ctorParameter)
$fieldReference = New-Object System.CodeDom.CodeFieldReferenceExpression(
(New-Object System.CodeDom.CodeThisReferenceExpression),
$name
)
$ctorInitializer = New-Object System.CodeDom.CodeAssignStatement(
$fieldReference,
(New-Object System.CodeDom.CodeVariableReferenceExpression $name)
)
$constructor.Statements.Add( $ctorInitializer )
(I'd like to attach the full script, but I don't see a way to do that in blogspot). It generates this output:
internal partial class MyClass
{
public string S;
private MyClass(string S)
{
this.S = S;
}
}
EDIT: See PowerShell DSLs: Using hashtables and scriptblocks together for a different view of this code.
Immutable data class generator
I'm working on a DSL implementation for defining "data classes" with certain properties in C# (see http://blogs.gotdotnet.com/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx for an example of the output).
Table of Contents
- Goals
- Skeleton implementation
- ???
PowerShell DSLs: Script block input
As an alternative to using a hashtable for input, you can use a script block. Here's a script-block-way of doing the same thing as before:
class MyClass -accessibilty:public {
member string S
}
and here's one of many ways of handling it
function class {
param (
[String] $name = $( throw
"name is required" ),
[String] $accessibilty,
[ScriptBlock] $memberScriptBlock = $( throw
"member script block is require" )
)
" $accessibilty class $name {"
& $memberScriptBlock % { " public $($_.declaration)" }
" }"
}
function member {
param (
[String] $type = $( throw
"type is required" ),
[String] $name = $( throw
"name is required" )
)
@{
declaration = "$type $name;"
}
}
What's happening here is that the first word on any line becomes a function, and the remaining words are parameters to that function. So, you're now creating an "internal DSL" in PowerShell. This lets you work in a more idoimatic PowerShell manner.
PowerShell DSLs: Hash table input
@{
kind = 'class'
name = 'MyClass'
accessibilty = 'public'
members = @{
type = 'string'
name = 'S'
}
}
How do you consume this input? Here's an example. (Note that the code generation side is not the focal point here -- the way that we interpet the input is what matters.)
if ($input.kind = 'class') {
" $($input.accessibilty) class $($input.name) {"
$input.members | foreach {
" public $($_.type) $($_.name);"
}
" }"
}
Which generates this output:
public class MyClass {
public System.String S;
}
This approach seems most effective when you need to express a lot of attributes on a single element. The downside is that the input seems a bit verbose and unnatural in some cases.
PowerShell DSLs
I have only 3 examples of PowerShell DSLs to work from, and I don't see any guidance in this area, so I figured I'd write about what I find.
Table of Contents
- Prior art
- Why PowerShell?
- Custom invocation w/ a library
- DSL tool invocation
- Hash table input
- Script block input
- Using hashtables and scriptblocks together
Warning: technical content ahead
Friday, November 09, 2007
Reid's Journal Entry: Making Apple Crisp
J: How many oranges did you use?
R: Zero oranges. It only takes apples and a few other ingredients, which are kind of like spices. Butter,
J: Oranges?
R: No... I mean, yes
J: What else?
R: Weeds. Then we milk and cereal. This is going to be so funny! Don't write that.
J: After you mixed it up, what did you do?
R: I baked it for 2000 hours. What zee doh.
J: How did it taste?
R: It's not ready for that part yet. We added 2000 drops of stevia in. Time for what it tasted like. It tasted like... stevia. Of course it would.
Friday, October 19, 2007
A new adventure
Today I announced broadly that I'm leaving Microsoft.
I sent 3 emails. Two went to the discussion groups of tools that I own, to announce the change of ownership of these tools. Strictly for business reasons, but then the news started flowing, and I was starting to get questions. So I sent out the third - to basically every person I've worked with in the last 11 years.
What's next?I'm going to be a stay-at-home dad. The twins are 20 months old. Reid is 6. We want to homeschool Reid, and eventually the twins.
Living off savings will require that we spend a lot less. We currently live 1.9 miles from Microsoft campus, which is a damn expensive place to be. With me not working there, it doesn't make sense to live here, so we're moving away.
We've picked Port Townsend as our new home. It's such a cool city. 8000 people. 25mph speed limits. Hopefully we can bike & walk just about everywhere.
It's also a good choice because I love old, wooden boats, and PT has plenty of them. But that's for the future - right now, our attention will be on the family. Catching up on rest, taking good care of ourselves, being together.
I'm trying to leave Microsoft on good terms, and that includes trying to wrap things up on my current project so that it will succeed when I'm gone.
There's also a lot of work to do to get the house ready, purge our stuff some more, find a new home, pack, and move. Whew!
