View mode: basic / threaded / horizontal-split · Log in · Help
January 23, 2007
seeding the pot for 2.0 features
Now that the big 1.0 is out, I think that we should start considering what 
to put into 2.0. I don't think we need to rush anything into D yet, but maybe 
we should start accumulating a list of things to consider.

One overall thought I had is that it seems the big killer for C++ was to 
some extent that it is a strict superset of C. Maybe we should avoid this 
problem and not requiter that D2.0 be backwards compatible at the source 
level, but only at the ABI level sort of like C and D are now. Anyway, just 
a thought. 

Here are a few of my ideas for 2.0.


1)  Modules structs and classes can have static this() functions, why functions? 
If a static nested constructor were allowed for functions, it would allow 
static function variable to be initialized at load time.



2)  Why is there no tupleof property for interfaces? It would allow for some 
intriguing possibilities.

interface I{...}

class C : I
{
	mixin ImpInterface!(I);
}

template ImpInterface(T)
{
	mixin ImpInterface_!(T.tupleof);

	private ImpInterface_(F, V...)
	{
		mixin Implement!(F)
		static if(V.length > 0
			mixin ImpInterface_!(V);
	}
}

3) promote static foreach to the same level as static if. This with #2 could 
be reel slick.

template ImpInterface(T)
{
	static foreach(F; T.tupleof);
	{
		F	// assumes that F is a function 
			// including name and everything
		{
			// implement F
		}
	}
}

4) I guess that also needs a "implementable function alias". The syntax, 
not to mention the name, could ues a little work, but I expect you get the 
picture.
January 23, 2007
Re: seeding the pot for 2.0 features
BCS wrote:
> Now that the big 1.0 is out, I think that we should start considering 
> what to put into 2.0. I don't think we need to rush anything into D yet, 
> but maybe we should start accumulating a list of things to consider.
> 
> One overall thought I had is that it seems the big killer for C++ was to 
> some extent that it is a strict superset of C. Maybe we should avoid 
> this problem and not requiter that D2.0 be backwards compatible at the 
> source level, but only at the ABI level sort of like C and D are now. 
> Anyway, just a thought.
> Here are a few of my ideas for 2.0.
> 
> 
> 1)  Modules structs and classes can have static this() functions, why 
> functions? If a static nested constructor were allowed for functions, it 
> would allow static function variable to be initialized at load time.
> 
> 
> 
> 2)  Why is there no tupleof property for interfaces? It would allow for 
> some intriguing possibilities.
> 
> interface I{...}
> 
> class C : I
> {
>     mixin ImpInterface!(I);
> }
> 
> template ImpInterface(T)
> {
>     mixin ImpInterface_!(T.tupleof);
> 
>     private ImpInterface_(F, V...)
>     {
>         mixin Implement!(F)
>         static if(V.length > 0
>             mixin ImpInterface_!(V);
>     }
> }
> 
> 3) promote static foreach to the same level as static if. This with #2 
> could be reel slick.
> 
> template ImpInterface(T)
> {
>     static foreach(F; T.tupleof);
>     {
>         F    // assumes that F is a function             // including 
> name and everything
>         {
>             // implement F
>         }
>     }
> }
> 
> 4) I guess that also needs a "implementable function alias". The syntax, 
> not to mention the name, could ues a little work, but I expect you get 
> the picture.
> 
> 


Hrm, I may be a dolt but the above looks like greek -- I have no idea, 
at first glance, what the heck it does -- that's an important concern 
for the target audience, surely? Actually, what is the target audience 
for D? Specifically? Perhaps that's a good place to start :)

Other than that, my suggestions for 2.0 would be to fix the problems in 
1.0. The dreaded mixin noted above is a case in point. How about 
/removing/ that broken macro-expansion feature for 2.0 :D

(somewhat tongue-in-cheek)
January 23, 2007
Re: seeding the pot for 2.0 features
Reply to kris,

> Hrm, I may be a dolt but the above looks like greek -- I have no idea,
> at first glance, what the heck it does -- that's an important concern
> for the target audience, surely? Actually, what is the target audience
> for D? Specifically? Perhaps that's a good place to start :)
> 
> Other than that, my suggestions for 2.0 would be to fix the problems
> in 1.0. The dreaded mixin noted above is a case in point. How about
> /removing/ that broken macro-expansion feature for 2.0 :D
> 
> (somewhat tongue-in-cheek)
> 

The basic idea that spawned the suggestion was to have a template class that 
implements an arbitrary interface and provides the functionality to transport 
it across a network connection. Given an interface.

interface I
{
int foo();
}

A server side program would do something like this.

class C : I
{
int foo()
{
 static int i = 0;
 return i++;
}
}

ServeInterface!(I)(new C);

and the client would do this:

auto ref = new ConnectInterface!(I)("some.domain.name.org",port);

writef("%d\n", ref.foo());

thus getting access to the C on the server.

I have written a code generator to do this but is is vary painful to work 
with.
January 23, 2007
Re: seeding the pot for 2.0 features
BCS wrote:
> Reply to kris,
> 
>> Hrm, I may be a dolt but the above looks like greek -- I have no idea,
>> at first glance, what the heck it does -- that's an important concern
>> for the target audience, surely? Actually, what is the target audience
>> for D? Specifically? Perhaps that's a good place to start :)
>>
>> Other than that, my suggestions for 2.0 would be to fix the problems
>> in 1.0. The dreaded mixin noted above is a case in point. How about
>> /removing/ that broken macro-expansion feature for 2.0 :D
>>
>> (somewhat tongue-in-cheek)
>>
> 
> The basic idea that spawned the suggestion was to have a template class 
> that implements an arbitrary interface and provides the functionality to 
> transport it across a network connection. Given an interface.
> 
> interface I
> {
> int foo();
> }
> 
> A server side program would do something like this.
> 
> class C : I
> {
> int foo()
> {
>  static int i = 0;
>  return i++;
> }
> }
> 
> ServeInterface!(I)(new C);
> 
> and the client would do this:
> 
> auto ref = new ConnectInterface!(I)("some.domain.name.org",port);
> 
> writef("%d\n", ref.foo());
> 
> thus getting access to the C on the server.
> 
> I have written a code generator to do this but is is vary painful to 
> work with.
> 
> 

Yeah, please forgive me for being a bit flippant; I really didn't get 
#2, so examples are helpful :)
January 23, 2007
Re: seeding the pot for 2.0 features
BCS wrote:
> Now that the big 1.0 is out, I think that we should start considering 
> what to put into 2.0. I don't think we need to rush anything into D yet, 
> but maybe we should start accumulating a list of things to consider.
> 
> One overall thought I had is that it seems the big killer for C++ was to 
> some extent that it is a strict superset of C. Maybe we should avoid 
> this problem and not requiter that D2.0 be backwards compatible at the 
> source level, but only at the ABI level sort of like C and D are now. 
> Anyway, just a thought.

And a good one at that.  But there are two gotchas here that deserve some discussion.

First - You need some way to flag to a compiler which D version is being used.

0) compiler arg that forces one version or the other for all input files (obvious)
1) use a different file extension: ".d2"
2) provide a pragma: "pragma(dversion,2);
3) abuse the version statement: "version dlanguage = 2;"
4) all of the above
5) something else

Second - If the new D stuff were strictly a superset, in terms of syntax and behavior, then only new constructs would 
fail on older compilers; not the other way around.

> Here are a few of my ideas for 2.0.
> 
> 
> 1)  Modules structs and classes can have static this() functions, why 
> functions? If a static nested constructor were allowed for functions, it 
> would allow static function variable to be initialized at load time.

Like this?

void foobar(){
    static uint baz;
    static void this(){  baz = 111; }
}

IMO, this doesn't seem all that useful.  I would much rather have D allow non-static expressions for static 
initializers; which would help cover this case and several others.  Were the evaluation of delegates made to implicitly 
call on conversion to the lvalue's type, then this would work:

void foobar(){
    static uint baz = { return 111; }; // static anon delegate w/implicit call
}

> 
> 
> 
> 2)  Why is there no tupleof property for interfaces? It would allow for 
> some intriguing possibilities.

Agreed. IMO, you should be able to tupleof() *anything* and get a bag of types that describe the target's type in 
detail.  If this is the route D is going to take for reflection, then it must be more expressive.

> 
> 3) promote static foreach to the same level as static if. This with #2 
> could be reel slick.

Yes.  While we can get by utilizing recursion for iteration, it makes some idioms a major PITA.

Honestly, this is how I interpreted Walter's first demonstration of foreach() with tuples the first time around.  It 
wasn't until I started using tuples that I realized that it was non-static.

> 4) I guess that also needs a "implementable function alias". The syntax, 
> not to mention the name, could ues a little work, but I expect you get 
> the picture.

You lost me here.  Care to elaborate? :)


5) I'll contribute one more: a "true closure" syntax.  I really don't care keyword magic is used to make this
work, just as long as it's less verbose than creating a class w/a single method to simulate the same thing.

//old and busted:
int delegate() foobar(int c){
    return { return c; }; // delegate references current stack frame - this is worse than broken.
}

//new hotness:
int delegate() foobar(int c){
    return final{ return c; }; // delegate is propped up by copy of the context that is on the heap
}

It doesn't need to use 'final' per-se - any keyword that isn't confusing will do (like 'alias').  The problem, as you 
can imagine, is a pain to implement and has some non-trival side-effects of its own (like aliasing a stack frame that 
has inout parameters).  This really needs some discussion.

-- 
- EricAnderton at yahoo
January 24, 2007
Re: seeding the pot for 2.0 features
Reply to Pragma,

> First - You need some way to flag to a compiler which D version is
> being used.
> 
> 0) compiler arg that forces one version or the other for all input
> files (obvious)
> 1) use a different file extension: ".d2"
> 2) provide a pragma: "pragma(dversion,2);
> 3) abuse the version statement: "version dlanguage = 2;"
> 4) all of the above
> 5) something else

magic! {try parser(1.0, file); catch paser(2.0,file);}

> 
> void foobar(){
> static uint baz;
> static void this(){  baz = 111; }
> }
> IMO, this doesn't seem all that useful.  I would much rather have D
> allow non-static expressions for static initializers;

I think non const would be better than non static, or was that a typo?

>> 4) I guess that also needs a "implementable function alias". The
>> syntax, not to mention the name, could ues a little work, but I
>> expect you get the picture.
>> 
> You lost me here.  Care to elaborate? :)

From the example I gave, the foreach would iterate over the members of I.tupleof 
and generate a function for each method that "I" defines. Take a look at 
my reply to kris for an example of what this would be used for. (short vertion: 
network transport of an interface)

> 
> 5) I'll contribute one more: a "true closure" syntax.  I really don't
> care keyword magic is used to make this
> work, just as long as it's less verbose than creating a class w/a
> single method to simulate the same thing.
> 

yah.

my choice: dynamic init structs and explicit context for delegates

int i,j,k;
// pickle i,j,k then use them
auto (new struct {int i_ = i; int j_ = j; int k_ = k; }).delegate(int m){return 
((i_ * m)+j_)*m +k_;}
January 25, 2007
Re: seeding the pot for 2.0 features
BCS wrote:
> Now that the big 1.0 is out, I think that we should start considering 
> what to put into 2.0. I don't think we need to rush anything into D yet, 
> but maybe we should start accumulating a list of things to consider.
> 
> One overall thought I had is that it seems the big killer for C++ was to 
> some extent that it is a strict superset of C. Maybe we should avoid 
> this problem and not requiter that D2.0 be backwards compatible at the 
> source level, but only at the ABI level sort of like C and D are now. 
> Anyway, just a thought.

...

The first thing that comes to my mind is explicit properties.  I believe 
they can be done without using new keywords or sacrificing much 
generality.  Eventually the implicit properties could be deprecated, 
when everyone feels they are no longer widely used.
January 25, 2007
Re: seeding the pot for 2.0 features
On Wed, 24 Jan 2007 02:09:09 +0200, BCS <ao@pathlink.com> wrote:
[snip]
> my choice: dynamic init structs and explicit context for delegates
>
> int i,j,k;
> // pickle i,j,k then use them
> auto (new struct {int i_ = i; int j_ = j; int k_ = k; }).delegate(int  
> m){return ((i_ * m)+j_)*m +k_;}
>

While we are at it, why not just let the compiler to generate context for  
delegates? ;)
E.g.

  int i, j;
  return int delegete(int m) {return i * m + j;}
->
  return int (new struct {int i_ = i; int j_ = j}).delegete(int m) {return  
i_ * m + j_;}
January 25, 2007
Re: seeding the pot for 2.0 features
Kristian Kilpi wrote:
> On Wed, 24 Jan 2007 02:09:09 +0200, BCS <ao@pathlink.com> wrote:
> [snip]
> 
>> my choice: dynamic init structs and explicit context for delegates
>>
>> int i,j,k;
>> // pickle i,j,k then use them
>> auto (new struct {int i_ = i; int j_ = j; int k_ = k; }).delegate(int  
>> m){return ((i_ * m)+j_)*m +k_;}
>>
> 
> While we are at it, why not just let the compiler to generate context 
> for  delegates? ;)
> E.g.
> 
>   int i, j;
>   return int delegete(int m) {return i * m + j;}
> ->
>   return int (new struct {int i_ = i; int j_ = j}).delegete(int m) 
> {return  i_ * m + j_;}


I think that has been proposed but has some problems. For instance


auto dg = int delegate(int m) {return i * m + j;}

fnUsingDg(dg);	// doesn't need context

i++;
j++;	// did that effect the context?

if(boolFn())
	return dg;	// now we need context
else
			// or do we??
	return int delegate(int m) {return i + j;}

the explicit form has some advantages in clarity

maybe a cut down version


auto {i; j; k;}.dup.delegate(int m)
	{
		return ((i_ * m)+j_)*m +k_;
	}

going back to my other idea (the one involving implementing an interface 
from its tuple) you might be able to build a template that builds and 
instance a struct


BuildContext(alias A...){ ... }
int i,j,k;

return BuildContext!(i,j,k).delegate()
  {
    return i+j+k;
    // refers to members of context not function
  };

I'm not quite sure how to make it work under the hood but it would 
involve having aliases tuples that can act as:
  a type list to build structs
  a name list to name struct members
  a type/argument list to form a function
  a symbol list to access the symbols instancing the templates

BuildContext!(alias A...)()
{
  auto ret = new struct
  {
    // same types, same symbols
    A.types A.symbols;

    void set(A.types val)
    {
      // copy args
      *this = val;
    }
  }
  // call using whatever was used to instance the template
  ret.set(A.values);

  return ret;
}

Ahh, Errr. That would be a trick, and is asking for quite a lot.
January 26, 2007
Re: seeding the pot for 2.0 features
BCS wrote:
> 1)  Modules structs and classes can have static this() functions, why 
> functions? If a static nested constructor were allowed for functions, it 
> would allow static function variable to be initialized at load time.


I think I have a better solution, let function statics behave like 
globals as far as access goes (plus default to private if that isn't 
already the case).

int[int] k;

void fn()
{
	static int[int] i;
	...
}

static this()
{
	foreach(int[2] j; [cast(int[2]) [1,0],[2,1],[4,2],[8,3],...])
	{
		k[j[1]] = j[0];
		fn.i[j[0]] = j[1];
	}
}
« First   ‹ Prev
1 2 3 4 5
Top | Discussion index | About this forum | D home