Re: Question about UDAs

2020-08-03 Thread H. S. Teoh via Digitalmars-d-learn
On Mon, Aug 03, 2020 at 08:16:57PM -0700, Ali Çehreli via Digitalmars-d-learn 
wrote:
[...]
> UDAs were added to D by a request from Manu Evans and that's when I
> learned them. In one of Manu's use cases they would put a @Tweakable
> attribute to certain struct members. The effect of that attribute
> would be to compile special code that would expose that member in a
> dialog box where the developer would "tweak" its value to see how the
> program (a game) would behave at specific values of that member.
> 
> The awesomeness comes from the fact that once they have this
> @Tweakable machinery, they don't change their code at all: They put
> that attribute to certain members during development, find good values
> and then remove it; perhaps in half an hour. The only addition to code
> is one @Tweakable attribute and some magic produces a dialog box; then
> they remove the attribute. Pretty cool. :)

I've also used it for generating getopt-like code for parsing
command-line parameters.  You might have several subsystems in your
program, each of which comes with a set of parameters that can be
configured; instead of sprinkling this information across multiple
places (once in the subsystem to read the values, once in the call to
getopt to parse the option, once in the code for display detailed
description of the setting, once in configuration file parsing code to
basically do the same thing as getopt except with a config file, ad
nauseaum), just create a struct that contains the parameters for each
subsystem, then use UDAs to decorate each setting with command-line
option name, help text, value ranges, or even custom parsing functions
if you want to get fancy. Then write a generic option-parsing function
that introspects the UDAs to generate help text, option names, default
values, precedences, etc.. Another generic function for parsing the
config file.

Then the next time you want to add a setting, it's just a matter of
adding another field to your struct, tag it with the appropriate UDAs,
and it will "magically" appear in your command-line, config file
parsing, and in-program help text without further ado.

Best of all, once you build this infrastructure, you can easily reuse it
across different programs: the getopt wrapper, help text generator,
config file parser are all completely driven by introspection and UDAs,
so there's nothing program-specific about them. Just copy-n-paste them
into another project, and create your structs, and you're all set. :-)


T

-- 
"I'm not childish; I'm just in touch with the child within!" - RL


Re: Question about UDAs

2020-08-03 Thread Ali Çehreli via Digitalmars-d-learn

On 8/2/20 8:00 PM, Cecil Ward wrote:

> Ali Çehreli’s book mentions them briefly with an example
> but that doesn’t seem to qualify as a realistic use-case.

The XML example I chose there qualifies as serialization like H. S. Teoh 
mentions. UDAs on user-defined type members are for marking them for 
later introspection in use cases like "do this for all members but take 
UDAs into account." For example, the UDA in my example contributes as 
"serialize all members as XML but obfuscate the members that have a 
special UDA."


UDAs were added to D by a request from Manu Evans and that's when I 
learned them. In one of Manu's use cases they would put a @Tweakable 
attribute to certain struct members. The effect of that attribute would 
be to compile special code that would expose that member in a dialog box 
where the developer would "tweak" its value to see how the program (a 
game) would behave at specific values of that member.


The awesomeness comes from the fact that once they have this @Tweakable 
machinery, they don't change their code at all: They put that attribute 
to certain members during development, find good values and then remove 
it; perhaps in half an hour. The only addition to code is one @Tweakable 
attribute and some magic produces a dialog box; then they remove the 
attribute. Pretty cool. :)


Manu's presentatian is available here:

 https://www.youtube.com/watch?v=FKceA691Wcg

Slide 25 at minute 18:30 is one spot he talks about it.

Ali




Re: Question about UDAs

2020-08-03 Thread H. S. Teoh via Digitalmars-d-learn
On Mon, Aug 03, 2020 at 03:00:08AM +, Cecil Ward via Digitalmars-d-learn 
wrote:
> When practically speaking would you use UDAs? A real-world use-case?

There are probably more use cases than this, but for me, their primary
usefulness is in declarative programming and compile-time introspection.

Here's one specific use case: serialization.  I have a bunch of structs
and classes that I want to serialize, and instead of writing tons and
tons of boilerplate, I use __traits(allMembers) to introspect a generic
type T and generate serialization code for it.  But sometimes some
fields should not be serialized (e.g., they are transients like caches
and stuff).  Or sometimes certain fields may need special treatment,
like a different serialization method depending on domain-specific
information about their contents.

I *could* hard-code this knowledge into the serialization code, but
UDAs provide a better alternative: I tag my types with various UDAs
recognized by the serialization system, so that when it encounters, say,
a string tagged @hexDigits, it knows that it can use a more compact
representation by parsing the string into binary and storing it as a
compact blob, for example.  Or if a field should not be serialized, I'd
tag it @dontSerialize and the serialization code skips over it. By using
UDAs instead of hard-coding into the serialization code, the
serialization can be made generic and reusable across projects.

Other use cases include automatically creating database schemas based on
types: like a bunch of structs representing records, and UDAs to tag
which fields should be indexed, which fields have constraints, etc..
Then the database backend code can just introspect these types and
automatically generate schemas, query code, etc..

Since UDAs can be arbitrary types, it actually has a lot of uses. For
example, you can use them to inject code for processing data, e.g., by
using a struct as UDA with a method that takes the data and performs
some operation on it. The generic code that reads the UDA can then pass
the data to the method in a completely agnostic way that lets you
separate concerns very cleanly.


T

-- 
In a world without fences, who needs Windows and Gates? -- Christian Surchi


Re: Question about UDAs

2020-08-02 Thread Adam D. Ruppe via Digitalmars-d-learn

On Monday, 3 August 2020 at 03:00:08 UTC, Cecil Ward wrote:
When practically speaking would you use UDAs? A real-world 
use-case?


They are useful when you want to attach some kind of metadata to 
the declarations for a library to read. For example, my script.d 
looks for `@scriptable` for methods that it should expose to the 
script user. My cgi.d uses things like `@URLName("foo")` and/or 
`@DisplayName("whatever")` if you want to override the 
auto-wrapper's default strings.


My day job work project uses it for user-visible documentation of 
their functions too, accessible from a command line interface.



I’ve seen them in use already for core language features 
instead of keywords like "pure"


i wouldn't call those UDAs because they aren't user-defined... 
but yeah it is the same syntax there basically too.


Question about UDAs

2020-08-02 Thread Cecil Ward via Digitalmars-d-learn
When practically speaking would you use UDAs? A real-world 
use-case? I’ve seen them in use already for core language 
features instead of keywords like "pure", and I suppose this 
choice keeps the number of keywords down and the result is 
perhaps easier to extend. The motivation for these usages is 
clear but I don’t understand how I might use them in my own code. 
Ali Çehreli’s book mentions them briefly with an example but that 
doesn’t seem to qualify as a realistic use-case.