Thread overview
[Issue 17953] inout-like mechanism to infer function attributes from callback attributes
Oct 31, 2017
anonymous4
Oct 31, 2017
anonymous4
Dec 17, 2022
Iain Buclaw
Jun 24
Bolpat
Jun 26
Dlang Bot
October 31, 2017
https://issues.dlang.org/show_bug.cgi?id=17953

--- Comment #1 from anonymous4 <dfj1esp02@sneakemail.com> ---
Apparently even templates don't help here much:
---
import std.typecons:Nullable;
Nullable!V convert(T,V)(Nullable!T v, scope V delegate(T) c)
{
        if(v.isNull)return Nullable!V();
        return Nullable!V(c(v.get()));
}

void f() pure
{
        Nullable!long v;
        Nullable!int v1=v.convert!(long,int)((a){ return cast(int)a; });
}
---
Error: pure function 'f' cannot call impure function 'convert!(long,
int).convert'

--
October 31, 2017
https://issues.dlang.org/show_bug.cgi?id=17953

anonymous4 <dfj1esp02@sneakemail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Hardware|Other                       |All
                 OS|Other                       |All

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=17953

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P4

--
April 05
https://issues.dlang.org/show_bug.cgi?id=17953

Bastiaan Veelo <Bastiaan@Veelo.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Bastiaan@Veelo.net

--- Comment #2 from Bastiaan Veelo <Bastiaan@Veelo.net> ---
This came up again at the DLF quarterly meeting April 5, 2024, with industry partners, and Walter asked to make sure there is a feature request. As discussed there:

For arguments and return types of various mutability we have the `inout` keyword that saves us from having to define multiple function overloads[1]. A similar solution for other attributes does not exist.

For example, if you have foreach loops over a struct S both in a @nogc context
and with an allocating loop body,
```d
void f()
{
    S s;
    foreach (a; s)
        allocating(a);
}

void g() @nogc
{
    S s;
    foreach (a; s)
        nonallocating(a);
}

void allocating(int) {}

void nonallocating(int) @nogc {}
```

then S needs both of these opApply overloads:

```d
    int opApply(scope int delegate(int) dg);
    int opApply(scope int delegate(int) @nogc dg) @nogc;
```

Similar for @safe, nothrow, pure and their permutations.

Templating opApply[2] can help in many of these cases, but problems arise when classes and inheritance get involved[3].

There is a DIP for argument dependent attributes[4] but work on it has stalled.

[1] https://dlang.org/spec/const3.html#inout
[2] https://dlang.org/spec/statement.html#template-op-apply
[3] https://youtu.be/9lOtOtiwXY4?si=KME_ZddnrecMdWOJ&t=359
[4] https://github.com/dlang/DIPs/pull/198

--
June 24
https://issues.dlang.org/show_bug.cgi?id=17953

Bolpat <qs.il.paperinik@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |qs.il.paperinik@gmail.com

--- Comment #3 from Bolpat <qs.il.paperinik@gmail.com> ---
This can be done using templates:
```d
int f(DG)(scope DG callback)
{
    return callback("Hello, World");
}

void main() @safe
{
    import std.stdio;
    f((string str) { writeln(str); return 0; });
}
```

For opApply, for some reason, this works:
```d
struct S
{
    private int opApplyImpl(DG)(scope DG dg)
    {
        static if (is(DG : int delegate(string)))
                return dg("Hello, World!");
                else
            return dg(0, "Hello, World!");
    }
    alias opApply = opApplyImpl!(int delegate(string));
    alias opApply = opApplyImpl!(int delegate(size_t, string));
}

void main() @safe
{
    import std.stdio;
    foreach (s; S())
    {
        static assert(is(typeof(s) == string));
        writeln(s);
    }
    foreach (i, s; S())
    {
        static assert(is(typeof(i) == size_t));
        static assert(is(typeof(s) == string));
        writeln(i, " ", s);
    }
}
```

--
June 26
https://issues.dlang.org/show_bug.cgi?id=17953

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #4 from Dlang Bot <dlang-bot@dlang.rocks> ---
@Bolpat created dlang/dlang.org pull request #3859 "Specify `opApply` as an alias to a function template instance" fixing this issue:

- Fix Bugzilla Issues 23666, 17953, 23116, and 24633

https://github.com/dlang/dlang.org/pull/3859

--