record: C# like records for D

Steven Schveighoffer schveiguy at gmail.com
Fri Jul 16 22:40:01 UTC 2021


On 7/16/21 4:11 PM, Dylan Graham wrote:
> On Friday, 16 July 2021 at 19:37:53 UTC, Steven Schveighoffer wrote:
>> I would possibly suggest that instead of a record template that 
>> accepts directives using inline lambdas, etc, just accept a model type 
>> and use udas to adjust the record type.
>>

> 
> That is a good idea, and to be honest I haven't looked at it that way. 
> So the record is a separate type from its model? Ie: `class MyRecord {}` 
> based off `struct RecordModel {}`? Or did I misunderstand?
> 
> With regards to things like properties and methods, do you have RecModel 
> inlined in the class and then forward the calls to it? Ie:
> 
> ```D
> struct RecModel {
>      @get int x;
>      auto doubleOfX() { return x; }
> }
> 
> class Rec {
>      private RecModel instance;
> 
>      @property auto x() { return instance.x; }
>      auto doubleOfX() { return instance.doubleOfX; }
> }
> ```

Yeah, something like that. Though there are multiple ways to go about 
it. One is to write a string that represents what you want it to do, and 
then mixin that thing. The way I do it is using `opDispatch` which is 
super-powerful for forwarding calls like that. I'm assuming you are 
already doing something like this anyway! It's just, what are the 
instructions?

I really can't wait to reveal the sql library I've been nursing along 
with my web project. I don't want to post it yet here, because it will 
just garner more questions.

I can point you at some early ideas I had on this kind of model-based 
programming, in a Boston meetup I did a talk for a number of years ago: 
https://www.youtube.com/watch?v=ZxzczSDaobw

> I do like the lambda directives as it, in my mind at least, enforces the 
> idea that the record/class must be a simple data type (ie no crazy 
> methods and such).

I'm not sure what you think is a "crazy" method, but lambdas can do 
whatever a method can do.

I like using models vs. template directives because you get to use the 
actual language to enforce your "model" is sane, and to make readable 
instructions for the metaprogramming processor. Like in one of your 
methods, you have:

```d
property!("getMultipleOfX", (r, m) => r.x * m, int)
```

What is that `int` for? It's not clear from the usage, I have to go look 
it up. Most likely, it's the return type, but it's not nearly as clear as:

```d
int getMultipleOfX(int m) { return x * m; }
```

Plus, I can debug my model without having to debug the metaprogramming 
stuff.

> 
> I do have to admit this was more an exercise in metaprogramming, and 
> since I did manage to make something I figured I'd share it.

It's cool, I love using metaprogramming to write code for me. It's 
without a doubt the best reason to use D. Learning how to use to avoid 
writing boilerplate is life changing!

-Steve


More information about the Digitalmars-d-announce mailing list