My favorite font for programming. Use a black background for vibrant colors.
In this color scheme I use an off-white (not full intensity) rather than pure white, otherwise the white text seems brighter than everything else. Interestingly, this font is typically bundled with Linux, but IMO it looks significantly better in Windows.
Friday, September 26, 2008
Friday, September 12, 2008
Symbols in .NET
I'm a big fan of Ruby's "symbols". Symbols are sort of like strings or enums, but different. Their syntax is an identifier with a colon in front, e.g. :Foo. See here for details.
I love using symbols in place of enums, because if they are implemented properly, comparing two symbols is as fast as comparing two integers (enums). Enums have the problem of non-extensibility; library B can't define new values for an enum in library A. Meanwhile, anybody can define a new symbol at any time.
Via Loyc I would like to add symbol support to C# and boo, but Loyc is a long way off as long as I have nobody to help me. In the meantime, see here for my current implementation of Symbols in C#.
To simulate enums using Symbols in C#, I just define a static class full of Symbols. For example:
I love using symbols in place of enums, because if they are implemented properly, comparing two symbols is as fast as comparing two integers (enums). Enums have the problem of non-extensibility; library B can't define new values for an enum in library A. Meanwhile, anybody can define a new symbol at any time.
Via Loyc I would like to add symbol support to C# and boo, but Loyc is a long way off as long as I have nobody to help me. In the meantime, see here for my current implementation of Symbols in C#.
To simulate enums using Symbols in C#, I just define a static class full of Symbols. For example:
public static class Tokens {Enjoy!
static public readonly Symbol WS = Symbol.Get("WS"); // whitespace
static public readonly Symbol NEWLINE = Symbol.Get("NEWLINE");
static public readonly Symbol ID = Symbol.Get("ID"); // identifier
static public readonly Symbol PUNC = Symbol.Get("PUNC");
static public readonly Symbol EOS = Symbol.Get("EOS");
static public readonly Symbol ML_COMMENT = Symbol.Get("ML_COMMENT");
static public readonly Symbol SL_COMMENT = Symbol.Get("SL_COMMENT");
...
}
Simulating covariant return types in C#
For several years, Microsoft engineers have refused to add support for covariant return types, a trivially simple feature that should have been in the CLR from the beginning.
Suppose you want to write a Clone() method that returns a copy of the current object. Naturally you want to write the following, but it is illegal:
Since you are implementing an interface, you can use this workaround that uses explicit interface implementation:
The above workaround is okay for implementing an interface, but what if you are writing a class hierarchy, and you want a Clone() method that is virtual but has the appropriate return type?
Oops, the workaround that you use for interfaces is illegal for class inheritance. There is still a solution, though:
That's right. You need six Clone() methods. The last method is virtual in case you want to make a class derived from ComplexNode, e.g. VeryComplexNode:
Without covariant return types, you have to to define an additional virtual function for each additional derived class.
Suppose you want to write a Clone() method that returns a copy of the current object. Naturally you want to write the following, but it is illegal:
class MyStuff : ICloneable {
public MyStuff Clone() { ... }
}
Since you are implementing an interface, you can use this workaround that uses explicit interface implementation:
class MyStuff : ICloneable {
public MyStuff Clone() { ... }
object ICloneable.Clone() { return Clone(); }
}
The above workaround is okay for implementing an interface, but what if you are writing a class hierarchy, and you want a Clone() method that is virtual but has the appropriate return type?
class BaseNode : ICloneable
{
object ICloneable.Clone() { return Clone(); }
public virtual BaseNode Clone() { ... }
}
class ComplexNode : BaseNode
{
override BaseNode BaseNode.Clone() { return Clone(); } // Error!
public ComplexNode Clone() { ... }
}
Oops, the workaround that you use for interfaces is illegal for class inheritance. There is still a solution, though:
class BaseNode : ICloneable
{
object ICloneable.Clone() { return Clone(); }
public BaseNode Clone() { BaseNode c; Clone(out c); return c; }
protected virtual void Clone(out BaseNode clone) { ... }
}
class ComplexNode : BaseNode
{
public new ComplexNode Clone() { ComplexNode c; Clone(out c); return c; }
protected override void Clone(out BaseNode clone) { clone = Clone(); }
protected virtual void Clone(out ComplexNode clone) { ... }
}
That's right. You need six Clone() methods. The last method is virtual in case you want to make a class derived from ComplexNode, e.g. VeryComplexNode:
class VeryComplexNode : ComplexNode
{
public new VeryComplexNode Clone() { VeryComplexNode c; Clone(out c); return c; }
protected override void Clone(out BaseNode clone) { clone = Clone(); }
protected override void Clone(out ComplexNode clone) { clone = Clone(); }
protected virtual void Clone(out VeryComplexNode clone) { ... }
}
Without covariant return types, you have to to define an additional virtual function for each additional derived class.
Subscribe to:
Posts (Atom)