January 23, 2007
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
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
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
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
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
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
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
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
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
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