Thread overview
declarations as template parameters
Aug 30, 2015
Daniel N
Aug 30, 2015
Adam D. Ruppe
Aug 30, 2015
Daniel N
Aug 30, 2015
Timon Gehr
Aug 31, 2015
Meta
Sep 03, 2015
Daniel N
Sep 03, 2015
Daniel N
August 30, 2015
Frequently when trying to implement missing language-features in the library, it grinds to a halt because it's not possible to send declarations as template parameters.

i.e. ex!(int i);

Phobos solved this in a for me very undesirable way, ex:
  mixin(bitfields!(uint, "x", 1));
It no longer looks like a D-style declaration.

The obvious alternative is using strings and while I personally actually prefer that to the multiple parameters approach, I know a number of people who are vocally opposed to forcing library end-users to deal with string-based api:s and they do have a point, if only there was a better alternative?

ex!(int, "i"); // oh ze horror!
ex!q{int i};   // at least it now looks like a declaration again.

In before someone says: "Bikeshedding!"

Yes, it's just a few chars, but there's also a bigger difference, type-safety, good error messages and you don't really want to start parsing 'D' for something this trivial, every-time there is a new feature you have to update your little parser, etc. Well, I guess you could mixin the string as a declaration and then reflect over it... maybe it's the best way, didn't try that approach yet.

I did come up with a new(?) way though... as all the other methods above, it has it's ups and downs... but I didn't see any code in the wild using this method before, so I thought I'd share it.

struct Struct
{
  mixin restricted!((uint Size) => 777); // look ma, no strings!
  mixin restricted!(uint Size = 777);    // not working, "ideal version"
}

A more complete motivating example at asm.dlang.org(just a quick hack not production ready):
http://goo.gl/RSziKx

I guess it could be possible to solve using UDA:s instead... maybe I'll try that next, just checking if I'm the only one dreaming about "declarations as template parameters".


August 30, 2015
On Sunday, 30 August 2015 at 16:31:17 UTC, Daniel N wrote:
> I guess it could be possible to solve using UDA:s instead... maybe I'll try that next, just checking if I'm the only one dreaming about "declarations as template parameters".

What I would love would be being able to pass an anonymous struct to a template. Then you can reflect over it to get declarations and group them too.

(Actually, I'd love to be able to use anonymous structs anywhere a typename is expected. Then you could do:

struct { int a; } foo; // declare a variable named foo as type struct { int a; }

but that might break the parser.)
August 30, 2015
On Sunday, 30 August 2015 at 18:43:32 UTC, Adam D. Ruppe wrote:
> On Sunday, 30 August 2015 at 16:31:17 UTC, Daniel N wrote:
>> I guess it could be possible to solve using UDA:s instead... maybe I'll try that next, just checking if I'm the only one dreaming about "declarations as template parameters".
>
> What I would love would be being able to pass an anonymous struct to a template. Then you can reflect over it to get declarations and group them too.
>
> (Actually, I'd love to be able to use anonymous structs anywhere a typename is expected. Then you could do:
>
> struct { int a; } foo; // declare a variable named foo as type struct { int a; }
>
> but that might break the parser.)

Hmmm yeah, I remember wanting that too... how about this? Passing an anonymous class via a function instead of template.

import std.traits;

enum codeof(S...) = S[0].stringof;

string fun(T)(T sigh)
{
  import std.typetuple;
  import std.algorithm : map;
  import std.string : format;
  import std.range : zip, join;

  alias names = FieldNameTuple!T;
  alias types = staticMap!(codeof, FieldTypeTuple!T);

  return zip([types], [names]).
         map!(a => format("  %s %s;\n", a[0], a[1])).
         join();
}

void main()
{
  struct Yay
  {
    mixin(fun(new class
    {
      int a;
    }));
  }
}
August 30, 2015
On 08/30/2015 08:43 PM, Adam D. Ruppe wrote:
> On Sunday, 30 August 2015 at 16:31:17 UTC, Daniel N wrote:
>> I guess it could be possible to solve using UDA:s instead... maybe
>> I'll try that next, just checking if I'm the only one dreaming about
>> "declarations as template parameters".
>
> What I would love would be being able to pass an anonymous struct to a
> template. Then you can reflect over it to get declarations and group
> them too.
>
> (Actually, I'd love to be able to use anonymous structs anywhere a
> typename is expected. Then you could do:
>
> struct { int a; } foo; // declare a variable named foo as type struct {
> int a; }
>
> but that might break the parser.)

It does not break the parser. There's only one existing feature that can start with "struct{" in a place where one might want to use this feature, and there disambiguation is easy.
August 31, 2015
On Sunday, 30 August 2015 at 18:43:32 UTC, Adam D. Ruppe wrote:
> On Sunday, 30 August 2015 at 16:31:17 UTC, Daniel N wrote:
>> I guess it could be possible to solve using UDA:s instead... maybe I'll try that next, just checking if I'm the only one dreaming about "declarations as template parameters".
>
> What I would love would be being able to pass an anonymous struct to a template. Then you can reflect over it to get declarations and group them too.
>
> (Actually, I'd love to be able to use anonymous structs anywhere a typename is expected. Then you could do:
>
> struct { int a; } foo; // declare a variable named foo as type struct { int a; }
>
> but that might break the parser.)

This would go great with Algebraic.

alias List(T) = Algebraic!(
    struct Cons { T data; This* next; },
    struct Nil  {},
);
September 03, 2015
On Monday, 31 August 2015 at 21:14:42 UTC, Meta wrote:
>
> This would go great with Algebraic.
>
> alias List(T) = Algebraic!(
>     struct Cons { T data; This* next; },
>     struct Nil  {},
> );

Good example!

I thought of another interesting use for my lambda trick(rough draft, but shows promise)...
http://dpaste.dzfl.pl/8b26f2ec133d

September 03, 2015
On Thursday, 3 September 2015 at 19:44:13 UTC, Daniel N wrote:
> I thought of another interesting use for my lambda trick(rough draft, but shows promise)...
> http://dpaste.dzfl.pl/8b26f2ec133d

PS Hmm I guess, just a more complicated way of writing 'with(...)' though ;)