Lisp/Ruby style symbols
Chris Nicholson-Sauls
ibisbasenji at gmail.com
Sun Aug 5 11:11:53 PDT 2007
Alex wrote:
> I've been writing a lot of Ruby code lately, and I've really began to appreciate the convenience of certain features (dynamic typing, flexible metaprogramming, etc). Obviously a lot of these features simply cannot be implemented in D (or would have a very awkward style of implementation), but one little thing that I've found to be very useful are the Lisp style symbols. For those unfamiliar, it is a concept similar to enumerations, except that instead of having a defined range of values, you simple declare a variable ands set it equal to :name_of_symbol. This flexibility less code has to be written (no type declaration) and IMHO would make for a nice addition to D. I'd imagine we could allow something like the following:
> sym my_var = :foo;
> auto my_var2 = :bar;
>
> any thoughts? or more importantly, any chance of this actually making it in?
While I also enjoy and make extensive use of this in Ruby, I really
don't see it making its way into D at all. In face, you can technically
use an invariant string to the same effect. Prior to D/2.0 (and still,
for now) I've used a class to achieve similar effect. Here it is off
the top of my head.
final class Symbol {
public static class MismatchException : Exception {
private this (char[] msg) {
super("Symbol type cannot be compared with other types");
}
}
private static Symbol[char[]] pool ;
public static Symbol opCall (char[] str) {
Symbol result ;
if (auto ptr = str in pool) {
result = *ptr;
}
else {
auto copy = str.dup;
pool[copy] = result = new Symbol(copy);
}
return result;
}
private char[] value ;
private this (char[] value) {
this.value = value;
}
public bool opEquals (Object other)
in {
assert((cast(Symbol) other) !is null);
}
body {
if (auto sym = cast(Symbol) other) {
return sym is this;
}
else {
// for release code
throw new MismatchException;
}
}
version (Tango) {
public char[] toUtf8 () {
return value.dup;
}
alias toUtf8 toString;
}
else {
public char[] toString () {
return value.dup;
}
}
} // end class Symbol
I did mention that's off-top-o'-head, yes? So it might have some small
issue. Remember that even in Ruby Symbol is a class which works in a
similar fashion to this, except that it also associates a numeric id
with each symbol, which I haven't bothered doing here.
Again, for D/2.0:
typedef invariant(char)[] symbol ;
Not technically the same, I suppose, as you lose the "this string exists
exactly once" aspect. For that, I think you'd have to modify the above
class to use invariant typing in place of the .dup'ing.
If D were to get a symbol type of some sort, I don't think the :foo
syntax would work well. ColdC also has symbols, using the 'foo syntax,
which also doesn't suit D at all, as it ambiguates with [w|d]char
literals. @foo maybe? Hm. \@foo even. Bah, not worth worrying about.
-- Chris Nicholson-Sauls
More information about the Digitalmars-d
mailing list