www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - identof || toIdent - feature suggestion / question

reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Would it be hard to add a construct to D that would convert a 
compile-time string to an identifier ?

E.g.

int identof("foo");
// would be equivalent to:
int foo;
// and
identof("int") foo;
// and
identof("int") identof("foo");


It would allow programmatic data structure construction through 
templates. It would also be useful while converting C macros like:

#define myMacro(foo) _whatever##foo
...
int myMacro(A);
_whateverA = 1;

which could then become

template myMacro(T, char[] n) {
	T identof("_whatever" ~ n);
}
...
mixin myMacro!(int, "A");
_whateverA = 1;


It wouldn't have to work exactly this way, but such functionality would 
boost D's template powers :) One could create templates that parse 
strings and create complex data structures based on them. For instance, 
I currently have code that look like this:

mixin Input!(`in`)
	.field!(int, `num`)
	.field!(int, `num2`)
.end input;

It's instantiated in a class with which it automatically registers 
itself, provides type info and iteration over its fields, registers some 
functions that are called from the class ctor, etc.
It also creates a struct that resembles

struct Data {
	int num;
	int num2;
	// one more field here
}

with one single difference... its fields must be accessed thru templates:

input.Data d;
d.f!(`num`) = 5;
// etc

instead of simply

input.Data d;
d.num = 5;
// etc


The 'identof' could fix the gap and make it pretty seamless. Then it 
could be taken one step further:

mixin Input!(`
	in {
		int num;
		int num2;
	}
`) input;


Comments ? Suggestions ?


-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
Jul 01 2006
next sibling parent Frank Benoit <keinfarbton nospam.xyz> writes:
 Comments ? Suggestions ?

I think it is much too dangerous. This will make it much more difficult to have code refactoring tools like the one in eclipse. This will also decrease the code readability. Everything you write can go into somewhere, make funky strings and change types as needed. I think the right place to do such things is a separate code generator, not the template mechanism. Everytime I thought I can make funky things with template, I came back to the point where I think "make it without, templates are hell". Error messages with 2k character identifiers, exploding link time, ... They are good and necessary for typesafe containers and library code base on user supplied types. But I don't think that it is a good thing to go further. Sorry for that probably unproductive posting :)
Jul 01 2006
prev sibling next sibling parent Sean Kelly <sean f4.ca> writes:
Tom S wrote:
 Would it be hard to add a construct to D that would convert a 
 compile-time string to an identifier ?

This would certainly help with porting C libraries. It may also be useful for some code generation tools, though could result in some ugly code as well. It's for this last reason that I'm hesitant to endorse it, even though I think it could be very handy in some cases. Sean
Jul 01 2006
prev sibling next sibling parent Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Tom S wrote:
 Would it be hard to add a construct to D that would convert a 
 compile-time string to an identifier ?

 
 Comments ? Suggestions ?
 
 

I can think of at least two distinct uses for that and the reverse operation in Pyd: * Abstracting out the main "init" function so that it no longer requires a specific name (e.g. "inittestdll") and C linkage. Boost.Python does this with the preprocessor tricks outlined in Tom S's post. * Removing the requirement for users to enter the names of functions and classes as strings, in addition to the actual symbols. I know DDL has templates that can get this string from the mangle of the class or template, but a built-in language feature is to be preferred. So, my vote is for it, even if it is dreadfully dangerous. I'd be very interested in what Walter thinks of it. -- Kirk McDonald Pyd: Wrapping Python with D http://dsource.org/projects/pyd/wiki
Jul 01 2006
prev sibling next sibling parent John Reimer <terminal.node gmail.com> writes:
Tom S wrote:
 Would it be hard to add a construct to D that would convert a 
 compile-time string to an identifier ?
 
 E.g.
 
 int identof("foo");
 // would be equivalent to:
 int foo;
 // and
 identof("int") foo;
 // and
 identof("int") identof("foo");
 
 

That's a neato idea. These start to look like features that make languages like Lisp so powerful.
Jul 01 2006
prev sibling parent reply Daniel Keep <daniel.keep.list gmail.com> writes:
Tom S wrote:
 Would it be hard to add a construct to D that would convert a 
 compile-time string to an identifier ?
 
 E.g.
 
 int identof("foo");
 // would be equivalent to:
 int foo;
 // and
 identof("int") foo;
 // and
 identof("int") identof("foo");
 
 
 It would allow programmatic data structure construction through 
 templates. It would also be useful while converting C macros like:
 
 [snip]

I've had the same idea myself several times (although I wanted to use "ident" instead). Originally, I wanted it for making properties easier to use. The problem with templates/mixins at the moment is that they can't generate new identifiers. For example, I'd love to be able to do this: # mixin attribute!(int, "foo", Public /*read*/, Private /*write*/); Which would save a huge amount of essentially useless boilerplate code. The problem is, of course, that I can't generate that "foo" properly. The only way to do it is to manually declare the storage, and then alias the getter and setter seperately... and then it ends up being just as long as writing it manually. So this definitely has my vote++ :) -- Daniel
Jul 02 2006
parent Derek Parnell <derek nomail.afraid.org> writes:
On Sun, 02 Jul 2006 17:21:52 +0800, Daniel Keep wrote:


 The problem with templates/mixins at the moment is that they can't 
 generate new identifiers.  For example, I'd love to be able to do this:
 
 # mixin attribute!(int, "foo", Public /*read*/, Private /*write*/);
 
 Which would save a huge amount of essentially useless boilerplate code. 
   The problem is, of course, that I can't generate that "foo" properly. 
   The only way to do it is to manually declare the storage, and then 
 alias the getter and setter seperately... and then it ends up being just 
 as long as writing it manually.

I just had a play around with an idea that might be useful here... ======================= import std.stdio; template AttributeAll(T) { private T _xA; public T get() { return _xA; } public T set(T d) { _xA = d; return d; } } template AttributeAll(T, alias F) { private T _xAF; public T get() { return F(_xAF,true); } public T set(T d) { _xAF = F(d,false); return F(_xAF,true); } } template AttributeRO(T) { private T _xR; public T get() { return _xR; } } template AttributeRO(T, alias F) { private T _xRF; public T get() { return F(_xRF, true); } } template AttributeWO(T) { private T _xW; public T set(T d) { _xW = d; return _xW; } } template AttributeWO(T, alias F) { private T _xWF; public T set(T d) { _xWF = F(d,false); return F(_xWF,true); } } class Car { mixin AttributeAll!(int, QA_Colour) Colour; mixin AttributeAll!(real) Speed; mixin AttributeRO!(real) Torque; mixin AttributeWO!(real, QA_Accel) Accel; mixin AttributeAll!(char[]) Name; // Set torque on acceleration private real QA_Accel(real v, bool act) { if (act == false) { Torque._xR = v * 17 / 3; } return v; } // Validate Colour private int QA_Colour(int v, bool act) { if (act == false) { if (v >= 0 && v < 256) Colour._xAF = v; else throw new Error("Bad colour value."); } return v; } } void main() { auto sample = new Car; sample.Name.set = "Furary"; sample.Colour.set = 4; sample.Speed.set = 6.4455; sample.Accel.set = 1.2; writefln("%s ...\n Colour %s, Speed %s, Torque %s", sample.Name.get, sample.Colour.get, sample.Speed.get, sample.Torque.get ); } ===================== This could be a starting point for better property implementation ? -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 3/07/2006 4:25:24 PM
Jul 02 2006