www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Lisp/Ruby style symbols

reply Alex <CppCoder gmail.com> writes:
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?
Aug 05 2007
parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
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
Aug 05 2007