[bolts] bolts.functioneditor - module for building function mixins?

Jean-Louis Leroy jl at leroy.nyc
Thu Apr 9 12:16:08 UTC 2020


On Wednesday, 8 April 2020 at 12:03:23 UTC, aliak wrote:

> Turn an identifier into a string?
>
> int myint;
> assert(__traits(identifier, myint) == "myint");
>
> Like that?

No, the other way around. I don't like to use the string literal 
syntax for template arguments when those strings are meant to be 
identifiers. I.e. instead of:

   mixin makeFunction!("foo", ...);
   mixin makeFunction!("0ops", ...); // weird error deep down

I'd rather write:

   mixin makeFunction!(q.foo, ...);
   mixin makeFunction!(q.0ops, ...); // error reported here

Sorta Lisp-ish. It's such a tiny thing that it doesn't deserve 
its own dub package, except on Fool's Day maybe. But maybe in a 
`bolts.quote`?

> I opened a branch: 
> https://github.com/aliak00/bolts/tree/reflection
> [...]
> At this time I have no idea how well that will work in the 
> general sense but time will tell. It would be great if you 
> could push small pieces of the function editor in to there 
> (make a new file under the reflection module and just start 
> with that?).

So right now I cannot send PRs - not until I get permission form 
my employer. I created a ticket for that but it will take some 
time.

But as part of `openmethods` it's OK, so what about I create a 
`bolts/reflection` subdir there and put stuff in it. You can 
watch it, we can discuss it, and you can send PRs against 
openmethods. It looks like dub doesn't object to having multiple 
`bolts` directories, from different packages. As soon as I get 
the green light, I will PR the entire `bolts/reflection` tree. In 
the meantime, someone who wants to play with this 
work-in-progress can dub depend on openmethods.

Since yesterday, I thought a lot about this. It looks like there 
is a path to making meta-programming a *lot* easier. I now think 
that replacing the __traits and std.traits caboodle with 
meta-objects is more important than creating string mixins, 
although of course we badly want to hide them as much as 
possible. So I am not going to focus only one code generation.

In last night's experiments I pushed the cumbersome nested 
`static foreach` loops on members and overloads to a mixin 
template in a new Aggregate meta-object. And it works 
beautifully.Here is the Mock(Interface) example again (from the 
unit test of bolts.reflection.metaaggregate):

   interface TheFullMonty
   {
     pure int foo() immutable;
     @nogc @trusted nothrow ref int foo(out real, return ref int, 
lazy int) const;
     @safe shared scope void foo(scope Object);
   }

   template Mocker(alias Function, int Index)
   {
     static if (is(Function.returnType.type == void)) {
       enum Mocker = Function.withBody!"";
     } else static if (Function.isRef) {
       enum Mocker = Function.withBody!q{
         static %s rv;
         return rv;
       }.format(Function.returnType.asString);
     } else {
       enum Mocker = Function.withBody!q{
         return %s.init;
       }.format(Function.returnType.asString);
     }
   }

   class Mock(Interface) : Interface
   {
     mixin Aggregate!Interface.forEachFunctionMixin!(Mocker);
   }

[Later] I renamed the branch to bolts-reflection, here: 
https://github.com/jll63/openmethods.d/tree/bolts-reflection/source/bolts/reflection





More information about the Digitalmars-d mailing list