August 21, 2018 Re: Generically call a function on Variant's payload? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 08/20/2018 10:57 PM, Jonathan M Davis wrote:
>
> Runtime reflection is theoretically possible in D, but it requires
> generating the appropriate stuff for every type involved so that the runtime
> stuff has something to work with. Java built all of that into the language
> and has the JVM to boot, which fundamentally changes some of what can be
> done. With D, we're basically in exactly the same boat as C or C++ except
> that we have better compile-time type introspection. In principle, a runtime
> reflection facility could be built using that, but even if it were part of
> Phobos, it would still have to be opt-in. So, I don't know how useful such a
> solution would ever be outside of very specific use cases. Regardless, given
> that D's object files, linking, etc. are using the C tools, it was never
> going to be the case that Java-style runtime reflection would be built in to
> D like it is with Java.
Yea. Not to disagree at all with those reasons, but that is unfortunate. I've long been interested in how various features of D (not exclusively D, though) combine in ways that, in effect, obsolete much of traditional OOP inheritence-based polymorphism - offering the same abilities of OOP but without many of the notable downsides. Java-style runtime reflection would take us that much further in this regard. (Plus, it would make D that much more of a universal-toolbox of a language.) Oh well, dreams vs reality ;)
|
August 21, 2018 Re: Generically call a function on Variant's payload? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky (Abscissa) | On Monday, 20 August 2018 at 00:27:04 UTC, Nick Sabalausky (Abscissa) wrote: > Suppose I've wrapped a Variant in a struct/class which ensures the Variant *only* ever contains types which satisfy a particular constraint (for example: isInputRange, or hasLength, etc...). > > Is there a way to call a function (ex: popFront) on the Variant, *without* knowing ahead of time all the possible static types it might might contain? I assume you mean at compile time AoT of development of your library? Yes, don't use Variant; use https://github.com/s-ludwig/taggedalgebraic |
August 21, 2018 Re: Generically call a function on Variant's payload? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | On 08/21/2018 03:03 AM, Nicholas Wilson wrote:
> On Monday, 20 August 2018 at 00:27:04 UTC, Nick Sabalausky (Abscissa) wrote:
>> Suppose I've wrapped a Variant in a struct/class which ensures the Variant *only* ever contains types which satisfy a particular constraint (for example: isInputRange, or hasLength, etc...).
>>
>> Is there a way to call a function (ex: popFront) on the Variant, *without* knowing ahead of time all the possible static types it might might contain?
>
> I assume you mean at compile time AoT of development of your library?
>
> Yes, don't use Variant; use https://github.com/s-ludwig/taggedalgebraic
>
TaggedAlgebraic requires a finite list of every type it can contain. That's the deal-breaker for what I had in mind. I need something less like Algebraic and more like Variant, which *doesn't* require a finite, canonical list of every type it can contain.
The more I think about it though, the more I'm not so sure that the extensibility is important enough to warrant all of this, or...more importantly...that all of this is even necessary anyway for users to accomplish the use-cases I had in mind. I think I may go with an entirely different approach.
|
August 21, 2018 Re: Generically call a function on Variant's payload? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky (Abscissa) | On 8/21/18 3:11 PM, Nick Sabalausky (Abscissa) wrote: > On 08/21/2018 03:03 AM, Nicholas Wilson wrote: >> On Monday, 20 August 2018 at 00:27:04 UTC, Nick Sabalausky (Abscissa) wrote: >>> Suppose I've wrapped a Variant in a struct/class which ensures the Variant *only* ever contains types which satisfy a particular constraint (for example: isInputRange, or hasLength, etc...). >>> >>> Is there a way to call a function (ex: popFront) on the Variant, *without* knowing ahead of time all the possible static types it might might contain? >> >> I assume you mean at compile time AoT of development of your library? >> >> Yes, don't use Variant; use https://github.com/s-ludwig/taggedalgebraic >> > > TaggedAlgebraic requires a finite list of every type it can contain. That's the deal-breaker for what I had in mind. I need something less like Algebraic and more like Variant, which *doesn't* require a finite, canonical list of every type it can contain. > > The more I think about it though, the more I'm not so sure that the extensibility is important enough to warrant all of this, or...more importantly...that all of this is even necessary anyway for users to accomplish the use-cases I had in mind. I think I may go with an entirely different approach. If you examine how the code for variant works, it's quite clever. It establishes a "handler" that is generated with full compile-time type info available when the value is *assigned*, but then cast to a function taking a void pointer and an operation. This way, the user of the variant doesn't have to know what is inside, just the handler does. The code that sets the payload is the one that establishes how to use it. The same type of pattern could be used to, for instance, provide all the functions that a range uses. But it's not something that can be tacked on to Variant. You'd have to write your own type, because you'd have to handle the different functions that you know are common between the types in question (e.g. the operations supported on a variant are here: https://github.com/dlang/phobos/blob/master/std/variant.d#L163) -Steve |
August 21, 2018 Re: Generically call a function on Variant's payload? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 08/21/2018 03:27 PM, Steven Schveighoffer wrote:
>
> If you examine how the code for variant works, it's quite clever. It establishes a "handler" that is generated with full compile-time type info available when the value is *assigned*, but then cast to a function taking a void pointer and an operation. This way, the user of the variant doesn't have to know what is inside, just the handler does. The code that sets the payload is the one that establishes how to use it.
>
> The same type of pattern could be used to, for instance, provide all the functions that a range uses.
>
> But it's not something that can be tacked on to Variant. You'd have to write your own type, because you'd have to handle the different functions that you know are common between the types in question (e.g. the operations supported on a variant are here: https://github.com/dlang/phobos/blob/master/std/variant.d#L163)
Oooh, that's really cool! I might try my hand at something like that.
I bet it actually could be generalized to a certain extent. Variant would just have to be templated on the expected interface. Then it could compile-time loop over the list of functions expected, and introspect each of them enough to build the handler and the forwarders. Doesn't exactly sound fun to implement, but I'd bet it could be done.
|
Copyright © 1999-2021 by the D Language Foundation