Continuation passing style vs. wrapper objects in dmd

Mathias LANG geod24 at gmail.com
Wed May 26 07:48:52 UTC 2021


On Tuesday, 25 May 2021 at 17:21:16 UTC, Andrei Alexandrescu 
wrote:
> dmd has a few string functions with names having "Then" as a 
> prefix that take a lambda and call it with a temporary string 
> converted for OS purposes (zero-terminated, encoded a specific 
> way etc). The use goes like this:
>
> [...]
>
> I was thinking there's an easier way that's also more 
> composable:
>
> int i = stat(stringz(name).ptr, &statbuf));
>
> where `stringz` returns a temporary struct offering primitives 
> such as `ptr` and `opSlice`. In the destructor, the struct 
> frees temporary memory if allocated. Better yet, it can return 
> them as `scope` variable, that way ensuring correctness in safe 
> code.

Well, the usage of CPS is limited to one level here. As your 
example show, we can return whatever we want from 
`toCStringThen`, and if needed, chain the return value with 
something else.

The `struct` approach works to a certain degree: DIP1000 would 
*not* provide the tool to make this pattern work in a `@safe` 
context. I have yet to see a container that is `@safe` to use 
with DIP1000 (e.g. https://github.com/dlang/phobos/pull/8101 ), 
but making the CPS work with DIP1000 is possible (provided 
DIP1000 works as intended). It's from this observation that this 
approach became my preferred one, and that's what led to 
`toCStringThen` (origin: https://github.com/dlang/dmd/pull/8585 ).

But this function is only used a handful of times (~10?) in DMD, 
and only for C functions or in trampoline functions (turning a 
slice into a pointer). Is there a large ROI in finding the best 
possible pattern for it ? There are many large architectural 
problems in DMD that needs to be addressed, such as the absolute 
lack of abstraction despite the OOP hierarchy. The semantic 
routines will cast a base type (`Expression`, `Dsymbol`, etc...) 
to a more specialized type literally everywhere, instead of 
relying on virtual functions / properties available in the base 
classes. Just grep for `cast(TypeFunction)` to get an idea of 
what I mean.


More information about the Digitalmars-d mailing list