View mode: basic / threaded / horizontal-split · Log in · Help
March 12, 2012
Re: toHash => pure, nothrow, const, @safe
Le 12/03/2012 13:51, Alex Rønne Petersen a écrit :
> On 12-03-2012 10:40, Walter Bright wrote:
>> On 3/12/2012 1:08 AM, Martin Nowak wrote:
>>> What's wrong with auto-inference. Inferred attributes are only
>>> strengthening
>>> guarantees.
>>
>> Auto-inference is currently done for lambdas and template functions -
>> why? - because the function's implementation is guaranteed to be visible
>> to the compiler. For other functions, not so, and so the attributes must
>> be part of the function signature.
>
> Isn't auto-inference for templates a Bad Thing (TM) since it may give
> API guarantees that you can end up silently breaking?
>

As long as you can explicitly specify that too, and that you get a 
compile time error when you fail to provide what is explicitly stated, 
this isn't a problem.
March 12, 2012
Re: toHash => pure, nothrow, const, @safe
On Sun, 11 Mar 2012 19:54:09 -0400, Walter Bright  
<newshound2@digitalmars.com> wrote:

> Consider the toHash() function for struct key types:
>
> http://dlang.org/hash-map.html
>
> And of course the others:
>
> const hash_t toHash();
> const bool opEquals(ref const KeyType s);
> const int opCmp(ref const KeyType s);
>
> They need to be, as well as const, pure nothrow @safe.
>
> The problem is:
> 1. a lot of code must be retrofitted
> 2. it's just plain annoying to annotate them
>
> It's the same problem as for Object.toHash(). That was addressed by  
> making those attributes inheritable, but that won't work for struct ones.
>
> So I propose instead a bit of a hack. toHash, opEquals, and opCmp as  
> struct members be automatically annotated with pure, nothrow, and @safe  
> (if not already marked as @trusted).

What about a new attribute @type (or better name?) that means "this  
function is part of the TypeInfo interface, and has an equivalent  
xFuncname in TypeInfo_Struct".  Then it implicitly inherits all the  
attributes of that xFuncname (not necessarily defined by the compiler).

Then, we can have several benefits:

1. This triggers the compiler to complain if we don't correctly define the  
function (as specified in TypeInfo_Struct).  In other words, it allows the  
developer to specify "I want this function to go into TypeInfo".
2. It potentially allows additional interface hooks without compiler  
modification.  For example, you could add xfoo in TypeInfo_Struct, and  
then every struct you define @type foo() would get a hook there.
3. As you wanted, it eliminates having to duplicate all the attributes.

The one large drawback is, you need to annotate all existing functions.   
We could potentially assume that @type is specified on the functions that  
currently enjoy automatic inclusion in the TypeInfo_Struct instance.  I'd  
recommend at some point eliminating this hack though.

-Steve
March 12, 2012
Re: toHash => pure, nothrow, const, @safe
On 12-03-2012 14:16, deadalnix wrote:
> Le 12/03/2012 13:51, Alex Rønne Petersen a écrit :
>> On 12-03-2012 10:40, Walter Bright wrote:
>>> On 3/12/2012 1:08 AM, Martin Nowak wrote:
>>>> What's wrong with auto-inference. Inferred attributes are only
>>>> strengthening
>>>> guarantees.
>>>
>>> Auto-inference is currently done for lambdas and template functions -
>>> why? - because the function's implementation is guaranteed to be visible
>>> to the compiler. For other functions, not so, and so the attributes must
>>> be part of the function signature.
>>
>> Isn't auto-inference for templates a Bad Thing (TM) since it may give
>> API guarantees that you can end up silently breaking?
>>
>
> As long as you can explicitly specify that too, and that you get a
> compile time error when you fail to provide what is explicitly stated,
> this isn't a problem.

But people might be relying on your API that just so happens to be pure, 
but then suddenly isn't!

-- 
- Alex
March 12, 2012
Re: toHash => pure, nothrow, const, @safe
On Mon, 12 Mar 2012 10:40:16 +0100, Walter Bright  
<newshound2@digitalmars.com> wrote:

> On 3/12/2012 1:08 AM, Martin Nowak wrote:
>> What's wrong with auto-inference. Inferred attributes are only  
>> strengthening
>> guarantees.
>
> Auto-inference is currently done for lambdas and template functions -  
> why? - because the function's implementation is guaranteed to be visible  
> to the compiler. For other functions, not so, and so the attributes must  
> be part of the function signature.

A "@safe pure nothrow const" might be used as "@system".
That means someone using a declaration may have a different view
than someone providing the implementation.

Those interface boundaries are also a good place for by-hand annotations
to provide explicit API guarantees and enforce a correct implementation.

Though another issue with inference is that it would require a
depth-first-order for the semantic passes.

I also hope we still don't mangle inferred attributes.
March 12, 2012
Re: toHash => pure, nothrow, const, @safe
Walter:

> toHash, opEquals, and opCmp as struct members be automatically 
> annotated with pure, nothrow, and @safe (if not already marked 
> as @trusted).

I have read the other answers of this thread, and I don't like 
some of them.

In this case I think this programmer convenience doesn't justify 
adding one more special case to D purity. So for me it's a -1.

Bye,
bearophile
March 12, 2012
Re: toHash => pure, nothrow, const, @safe
On Monday, March 12, 2012 14:23:28 Alex Rønne Petersen wrote:
> On 12-03-2012 14:16, deadalnix wrote:
> > Le 12/03/2012 13:51, Alex Rønne Petersen a écrit :
> >> On 12-03-2012 10:40, Walter Bright wrote:
> >>> On 3/12/2012 1:08 AM, Martin Nowak wrote:
> >>>> What's wrong with auto-inference. Inferred attributes are only
> >>>> strengthening
> >>>> guarantees.
> >>> 
> >>> Auto-inference is currently done for lambdas and template functions -
> >>> why? - because the function's implementation is guaranteed to be visible
> >>> to the compiler. For other functions, not so, and so the attributes must
> >>> be part of the function signature.
> >> 
> >> Isn't auto-inference for templates a Bad Thing (TM) since it may give
> >> API guarantees that you can end up silently breaking?
> > 
> > As long as you can explicitly specify that too, and that you get a
> > compile time error when you fail to provide what is explicitly stated,
> > this isn't a problem.
> 
> But people might be relying on your API that just so happens to be pure,
> but then suddenly isn't!

True, but without out, pure, @safe, and nothrow are essentially useless with 
templates, because far too many templates depend on their arguments for 
whether they can be pure, @safe, and/or nothrow or not. It's attribute 
inference for templates that made it possible to use something stuff like 
std.range and std.algorithm in pure functions. Without that, it couldn't be 
done (at least not without some nasty casting). Attribute inference is 
necessary for templates.

Now, that _does_ introduce the possibility of a template being to be pure and 
then not being able to be pure thanks to a change that's made to it or 
something that it uses, and that makes impossible for any code using it to be 
pure. CTFE has the same problem. It's fairly easy to have a function which is 
CTFEable cease to be CTFEable thanks to a change to it, and no one notices. 
We've had issues with this in the past.

In both cases, I believe that the best solution that we have is to unit test 
stuff to show that it _can_ be pure, @safe, nothrow, and/or CTFEable if the 
arguments support it, and then those tests can guarantee that it stays that 
way in spite of any code changes, since they'll fail if the changes break 
that.

- Jonathan M Davis
March 12, 2012
Re: toHash => pure, nothrow, const, @safe
On Monday, March 12, 2012 09:14:17 Martin Nowak wrote:
> > So I propose instead a bit of a hack. toHash, opEquals, and opCmp as
> > struct members be automatically annotated with pure, nothrow, and @safe
> > (if not already marked as @trusted).
> 
> How about complete inference instead of a hack?

Because that requires having all of the source code. The fact that we have .di 
files prevents that. You'd have to be able to guarantee that you can always see 
the whole source (including the source of anything that the functions call) in 
order for attribute inferrence to work. The only reason that we can do it with 
templates is because we _do_ always have their source, and the fact that non-
templated functions must have the attributes in their signatures makes it so 
that the templated functions don't need their source in order to determine 
their own attributes.

The fact that we can't guarantee that all of the source is available when 
compiling a particular module seriously hampers any attempts at general 
attribute inference.

- Jonathan M Davis
March 12, 2012
Re: toHash => pure, nothrow, const, @safe
On 12-03-2012 18:38, Jonathan M Davis wrote:
> On Monday, March 12, 2012 14:23:28 Alex Rønne Petersen wrote:
>> On 12-03-2012 14:16, deadalnix wrote:
>>> Le 12/03/2012 13:51, Alex Rønne Petersen a écrit :
>>>> On 12-03-2012 10:40, Walter Bright wrote:
>>>>> On 3/12/2012 1:08 AM, Martin Nowak wrote:
>>>>>> What's wrong with auto-inference. Inferred attributes are only
>>>>>> strengthening
>>>>>> guarantees.
>>>>>
>>>>> Auto-inference is currently done for lambdas and template functions -
>>>>> why? - because the function's implementation is guaranteed to be visible
>>>>> to the compiler. For other functions, not so, and so the attributes must
>>>>> be part of the function signature.
>>>>
>>>> Isn't auto-inference for templates a Bad Thing (TM) since it may give
>>>> API guarantees that you can end up silently breaking?
>>>
>>> As long as you can explicitly specify that too, and that you get a
>>> compile time error when you fail to provide what is explicitly stated,
>>> this isn't a problem.
>>
>> But people might be relying on your API that just so happens to be pure,
>> but then suddenly isn't!
>
> True, but without out, pure, @safe, and nothrow are essentially useless with
> templates, because far too many templates depend on their arguments for
> whether they can be pure, @safe, and/or nothrow or not. It's attribute
> inference for templates that made it possible to use something stuff like
> std.range and std.algorithm in pure functions. Without that, it couldn't be
> done (at least not without some nasty casting). Attribute inference is
> necessary for templates.
>
> Now, that _does_ introduce the possibility of a template being to be pure and
> then not being able to be pure thanks to a change that's made to it or
> something that it uses, and that makes impossible for any code using it to be
> pure. CTFE has the same problem. It's fairly easy to have a function which is
> CTFEable cease to be CTFEable thanks to a change to it, and no one notices.
> We've had issues with this in the past.

That could be solved with a @ctfe attribute or something, no? Like, if 
the function has @ctfe, go through all possible CTFE paths (excluding 
!__ctfe paths of course) and make sure they are CTFEable.

>
> In both cases, I believe that the best solution that we have is to unit test
> stuff to show that it _can_ be pure, @safe, nothrow, and/or CTFEable if the
> arguments support it, and then those tests can guarantee that it stays that
> way in spite of any code changes, since they'll fail if the changes break
> that.
>
> - Jonathan M Davis


-- 
- Alex
March 12, 2012
Re: toHash => pure, nothrow, const, @safe
On Monday, March 12, 2012 18:44:06 Alex Rønne Petersen wrote:
> > Now, that _does_ introduce the possibility of a template being to be pure
> > and then not being able to be pure thanks to a change that's made to it
> > or something that it uses, and that makes impossible for any code using
> > it to be pure. CTFE has the same problem. It's fairly easy to have a
> > function which is CTFEable cease to be CTFEable thanks to a change to it,
> > and no one notices. We've had issues with this in the past.
> 
> That could be solved with a @ctfe attribute or something, no? Like, if
> the function has @ctfe, go through all possible CTFE paths (excluding
> !__ctfe paths of course) and make sure they are CTFEable.

1. That goes completely against how CTFE was designed in that part of the idea 
was that you _wouldn't_ have to annotate it.

2. I don't really know how feasible that would be. At minimum, the fact that 
CTFE works with classes now would probably render it completely infeasible for 
classes, since they're polymorphic, and the compiler can't possibly know all 
of the possible types that could be passed to the function. Templates would 
screw it over too for the exact same reasons that they can have issues with 
pure, @safe, and nothrow. It may or may not be feasible without classes or 
templates being involved.

So, no, I don't think that @ctfe would really work. And while I agree that the 
situation isn't exactly ideal, I don't really see a way around it. Unit tests 
_do_ catch it for you though. The only thing that they can't catch is whether 
the template is going to be pure, nothrow, @safe, and/or CTFEable with _your_ 
arguments to it, but as long as it's pure, nothrow, @safe, and/or CTFEable 
with _a_ set of arguments, it will generally be the fault of the arguments 
when such a function fails to be pure, nothrow, @safe, and/or CTFEable as 
expected. If the unit tests don't hit all of the possible static if-else 
blocks and all of the possible code paths for CTFE, it could still be a 
problem, but that just means that the unit tests aren't thorough enough, and 
more thorough unit tests will fix the problem, as tedious as it may be to do 
that.

- Jonathan M Davis
March 12, 2012
Re: toHash => pure, nothrow, const, @safe
On Mon, Mar 12, 2012 at 01:55:33PM -0400, Jonathan M Davis wrote:
[...]
> So, no, I don't think that @ctfe would really work. And while I agree
> that the situation isn't exactly ideal, I don't really see a way
> around it. Unit tests _do_ catch it for you though. The only thing
> that they can't catch is whether the template is going to be pure,
> nothrow, @safe, and/or CTFEable with _your_ arguments to it, but as
> long as it's pure, nothrow, @safe, and/or CTFEable with _a_ set of
> arguments, it will generally be the fault of the arguments when such a
> function fails to be pure, nothrow, @safe, and/or CTFEable as
> expected. If the unit tests don't hit all of the possible static
> if-else blocks and all of the possible code paths for CTFE, it could
> still be a problem, but that just means that the unit tests aren't
> thorough enough, and more thorough unit tests will fix the problem, as
> tedious as it may be to do that.
[...]

Tangential note: writing unit tests may be tedious, but D's inline
unittest syntax has alleviated a large part of that tedium. So much so
that I find myself writing as much code in unittests as real code.
Which is a good thing, because in the past I'd always been too lazy to
write any unittests at all.


T

-- 
Ruby is essentially Perl minus Wall.
1 2 3 4 5 6 7
Top | Discussion index | About this forum | D home