May 29, 2019
On Wednesday, 29 May 2019 at 01:14:04 UTC, Walter Bright wrote:
> On 5/28/2019 3:12 PM, Jonathan Marler wrote:
>> You are correct that call graphs are not acyclic, however, the inference of attributes only applies to templated-functions, not regular functions.  So we don't need to walk the entire graph to determine whether or not a template is allowed to use the GC, you only need to trace each template to it's nearest non-template function.
> Your algorithm will have to work for the worst case, which is all template code. This is hardly unreasonable, as Phobos is nearly entirely templates, with cyclical expansions. Worse, it's not just attribute inference, you proposed different code paths for different attributes, meaning the graph changes, too.
>
> It's a combinatorial explosion.

You do realize that all template code literally compiles to nothing right?

A template isn't code, it's just a "template" that can be instantiated.  If all you have is templates then there's nothing to instantiate them.

May 29, 2019
On Tuesday, 28 May 2019 at 22:33:46 UTC, aliak wrote:
> The thing you said about overloading on return types made me go and check around a bit. I already knew that swift does this at least. So I guess it isn't ambiguous since it's been implemented. But maybe it has something to do with the type system implementation they use?

It is possible, but when you have implicit type conversion... then you need to set up some strict presedence rules?

Overloading over inferred attributes can be solved by a SAT solver, AFAIK, but that would require very good heuristics to perform well. The problem is most likely not in that complexity class, but simpler.

Anyway, a solver can for each function find an expression for whether it is nogc or gc based on the ct parameters, so it is decidable. Same for nothrow.





May 29, 2019
On Tuesday, 28 May 2019 at 16:08:38 UTC, Andrei Alexandrescu wrote:
> int fun(int) pure;
> int fun(int);
>
> pure int gun(int x)
> {
>    return fun(x);
> }
>
> This doesn't work, but on the face of it it's not ambiguous - the second overload of fun() would not compile anyway.
>
> I was wondering whether allowing overloading on attributes in general would be a good idea. I suspect templates and attribute deduction make that difficult.

It worked between 2.075 and 2.085, called the pure overload.
May 29, 2019
The fix was https://github.com/dlang/dmd/pull/9406
May 29, 2019
On Wednesday, 29 May 2019 at 02:50:24 UTC, Jonathan Marler wrote:
> On Wednesday, 29 May 2019 at 01:14:04 UTC, Walter Bright wrote:
>> On 5/28/2019 3:12 PM, Jonathan Marler wrote:
>>> [...]
>> Your algorithm will have to work for the worst case, which is all template code. This is hardly unreasonable, as Phobos is nearly entirely templates, with cyclical expansions. Worse, it's not just attribute inference, you proposed different code paths for different attributes, meaning the graph changes, too.
>>
>> It's a combinatorial explosion.
>
> You do realize that all template code literally compiles to nothing right?
>
> A template isn't code, it's just a "template" that can be instantiated.  If all you have is templates then there's nothing to instantiate them.

I'm pretty sure Walter knows how templates work given that he's implemented them twice.
May 29, 2019
On Wednesday, 29 May 2019 at 02:45:37 UTC, Jonathan Marler wrote:
> On Wednesday, 29 May 2019 at 01:14:04 UTC, Walter Bright wrote:
>> [...]
>
> Well, I didn't propose an algorithm.  I was just providing a visual aid to your graph analogy. My suggesion has nothing to do with attribute inference on templates.  If it did then you are completely right that this would be a combinatorial explosion.  The idea is actually pretty "dumb" at its core.  What's the simplest way to pass this information to a template?
>  Just add a template parameter.
>
> [...]

Doesn't Jai do something similar to this? I.e. it passes in the "context" of the caller so that you can alter your code on what the environment is outside the function. So the context would could be a struct

struct Conctext {
  bool isNogc; bool isSafe; // etc...
}

It's be akin to introducing the concept of a "compile time this" isn't it?
May 29, 2019
On Tuesday, 28 May 2019 at 16:08:38 UTC, Andrei Alexandrescu wrote:
> int fun(int) pure;
> int fun(int);
>
> pure int gun(int x)
> {
>    return fun(x);
> }
>
> This doesn't work, but on the face of it it's not ambiguous - the second overload of fun() would not compile anyway.
>
> I was wondering whether allowing overloading on attributes in general would be a good idea. I suspect templates and attribute deduction make that difficult.

That's a problematic idea.
It means that adding an attribute on the caller can change the function that is called.
Which seems exceedingly brittle.
Arguing from a from a "principle of least surprise" standpoint.
This is undesirable.

-
Stefan
May 29, 2019
On Tuesday, 28 May 2019 at 16:08:38 UTC, Andrei Alexandrescu wrote:
> int fun(int) pure;
> int fun(int);
>
> pure int gun(int x)
> {
>    return fun(x);
> }

I think it really depends on the attribute.  I haven't thought too much about the other attributes, but for `pure` I don't see the use case.  If you can make the implementation of `fun(int)` pure, why would you need an additional impure implementation?

Mike

May 29, 2019
On Wednesday, 29 May 2019 at 12:39:16 UTC, aliak wrote:
> On Wednesday, 29 May 2019 at 02:45:37 UTC, Jonathan Marler wrote:
>> On Wednesday, 29 May 2019 at 01:14:04 UTC, Walter Bright wrote:
>>> [...]
>>
>> Well, I didn't propose an algorithm.  I was just providing a visual aid to your graph analogy. My suggesion has nothing to do with attribute inference on templates.  If it did then you are completely right that this would be a combinatorial explosion.  The idea is actually pretty "dumb" at its core.  What's the simplest way to pass this information to a template?
>>  Just add a template parameter.
>>
>> [...]
>
> Doesn't Jai do something similar to this? I.e. it passes in the "context" of the caller so that you can alter your code on what the environment is outside the function. So the context would could be a struct
>
> struct Conctext {
>   bool isNogc; bool isSafe; // etc...
> }
>
> It's be akin to introducing the concept of a "compile time this" isn't it?

Yes, last time I heard Jai was using sort of an implicit runtime  parameter.  However, I'm far from convinced it's a good idea at runtime .

With implicit template parameters, they would only affect the template if they were used, so you only pay for it if you are using it.  Not so with implicit runtime parameters.

May 29, 2019
On Wednesday, 29 May 2019 at 09:50:13 UTC, Atila Neves wrote:
> On Wednesday, 29 May 2019 at 02:50:24 UTC, Jonathan Marler wrote:
>> On Wednesday, 29 May 2019 at 01:14:04 UTC, Walter Bright wrote:
>>> [...]
>>
>> You do realize that all template code literally compiles to nothing right?
>>
>> A template isn't code, it's just a "template" that can be instantiated.  If all you have is templates then there's nothing to instantiate them.
>
> I'm pretty sure Walter knows how templates work given that he's implemented them twice.

Yeah, no argument from me.