View mode: basic / threaded / horizontal-split · Log in · Help
July 01, 2006
identof || toIdent - feature suggestion / question
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 +/
July 01, 2006
Re: identof || toIdent - feature suggestion / question
> 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 :)
July 01, 2006
Re: identof || toIdent - feature suggestion / question
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
July 01, 2006
Re: identof || toIdent - feature suggestion / question
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
July 01, 2006
Re: identof || toIdent - feature suggestion / question
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.
July 02, 2006
Re: identof || toIdent - feature suggestion / question
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
July 03, 2006
Re: identof || toIdent - feature suggestion / question
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
Top | Discussion index | About this forum | D home