July 01, 2006
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
> 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
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
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
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
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
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