Thread overview
cast(function qualifier)
3 days ago
Quirin Schroll
May 02
The status quo is that it is annoying to type-pun function pointers to stronger function attributes as the entire type has to be specified:

```d
(cast(int function(int)pure)&f)(2);
```

This is also error prone as the return type and/or argument types could go out of sync with the actual type of `f`.


`cast` could simply allow a list of function attributes and cast a function pointer or delegate to a type that additionally has those attributes:

```d
(cast(pure)&f)(2);
```

This simple syntactic sugar would make it a bit easier to work with attributes in `@system`/`@trusted` code. Of course, safety checks would still be performed, as for the more explicit cast syntax.
May 02
A highly useful addition to the language.

Kills off ``SetFunctionAttributes`` from std.traits for PhobosV3, so I am hugely supportive of this as I do have code that uses it.

Just don't let it work in ``@safe`` code.

https://dlang.org/phobos/std_traits.html#SetFunctionAttributes
May 02
On Wednesday, May 1, 2024 7:51:45 PM MDT Timon Gehr via dip.ideas wrote:
> The status quo is that it is annoying to type-pun function pointers to stronger function attributes as the entire type has to be specified:
>
> ```d
> (cast(int function(int)pure)&f)(2);
> ```
>
> This is also error prone as the return type and/or argument types could go out of sync with the actual type of `f`.
>
>
> `cast` could simply allow a list of function attributes and cast a function pointer or delegate to a type that additionally has those attributes:
>
> ```d
> (cast(pure)&f)(2);
> ```
>
> This simple syntactic sugar would make it a bit easier to work with attributes in `@system`/`@trusted` code. Of course, safety checks would still be performed, as for the more explicit cast syntax.

It certainly would make the code that has to cast functions pointers to alter their attributes much tcleaner. Of course, there's always the argument that making it clean instead of ugly will make it so that programmers are more willing to do it when such code should be quite rare, but ultimately, if someone is determined to be stupid with casting, they'll do it regardless.

So, ultimately, it's probably a good idea, and the syntax makes sense.

That being said, one concern that I can think of is that it arguably makes
cast() inconsistent. Right now, casting with an attribute only works with
type qualifiers, so it makes sense that cast() would remove all type
qualifiers. However, if stuff like cast(pure) or cast(nothrow) is legal,
then I could see someone expecting that cast() would remove those as well,
which seems like it would be a bad idea in practice (as well as being a
breaking change). But if we don't make cast() remove pure, nothrow, etc.,
then it could be argued that that's inconsistent. I'm not sure that that
inconsistency is worth worrying about, but I could see it coming up at some
point.

In any case, I do agree that making cast work with function attributes on function pointers and delegates would be a good addition.

- Jonathan M Davis



3 days ago

On Thursday, 2 May 2024 at 07:46:48 UTC, Jonathan M Davis wrote:

>

That being said, one concern that I can think of is that it arguably makes
cast() inconsistent. Right now, casting with an attribute only works with
type qualifiers, so it makes sense that cast() would remove all type
qualifiers. However, if stuff like cast(pure) or cast(nothrow) is legal,
then I could see someone expecting that cast() would remove those as well,
which seems like it would be a bad idea in practice (as well as being a
breaking change). But if we don't make cast() remove pure, nothrow, etc.,
then it could be argued that that's inconsistent. I'm not sure that that
inconsistency is worth worrying about, but I could see it coming up at some
point.

Another good argument to add @gc and @impure. Then, one can cast(@gc) to remove a @nogc attribute.

Another option would be to extend cast to allow for negated stuff: cast(!const) would remove const, but not other type qualifiers, e.g. inout or shared. In particular, cast(!shared) would be useful to remove shared whilst not touching const accidentally. Same would work for function attributes: const(!pure) removes pure, but doesn’t touch type qualifiers or other attributes.