On Tuesday, December 18, 2018 3:36:15 AM MST Pjotr Prins via Digitalmars-d- announce wrote: > On Thursday, 13 December 2018 at 18:29:39 UTC, Adam D. Ruppe > > wrote: > > On Thursday, 13 December 2018 at 10:29:10 UTC, RazvanN wrote: > >> Do you honestly think that they will ever take D into account > >> if @safe and immutable data will be the default? > > > > D needs to stop chasing after what you think people think they > > want and just start being good for us. > > > > The majority of my code is written pretty permissively - I like > > my pointers, my gotos, my GC, my exceptions. But I'm willing to > > consider the change because I actually don't think it will be > > that big of a hassle, and will be better overall. I wanna show > > you something: > > > > /// Static convenience functions for common color names > > nothrow pure @nogc @safe > > static Color transparent() { return Color(0, 0, 0, 0); } > > > > > > The attribute spam is almost longer than the function itself. > > Isn't it the way forward that the compiler deduces these > attributes and fills them in automatically? All these can be > inferenced. Only when the caller wants to guarantee, say pure, it > could add it explicitly. I read somewhere that the compiler > already does this to some degree. And even the generated docs > should be able to show it.
In general, functions that have to have their source available have their attributes inferred. So, templated functions, lambdas, and auto return functions all have attribute inference at this point. Attribute inference was introduced originally as being only for templated functions, because you _have_ to have it for them for them to really work with attributes (at least in any situation where whether an attribute is applicable depends on the template arguments - which is frequently the case), but it's been expanded over time. However, D's compilation model is such that many functions will never have attribute inference, because it's frequently not guaranteed that the compiler has the source code for a function in all cases where it's called. That being said, there are some serious downsides to attribute inference. It makes it much harder to know which attributes actually apply to a function, and it tends to result in folks not bothering with making sure that they're code works with a particular attribute; they just let attribute inference take care of it all and don't worry about it (in which case, the result is comparable to not having attribute inference in some respects). Another big issue is that when the attributes are inferred, it, becomes _very_ easy to accidentally change which attributes a function has when changing its implementation (similar to how its very easy to accidentally make it so that a function no longer works with CTFE). The primary way to combat that is to use explicit attributes on the unittest blocks which test the function, but that's easy to forget to do, and in a way, it's just moving the explicit attributes from the function itself to the unit tests. So, whether it actually fixes anything is debatable. In general, the cleanest approach is to be as explicit about attributes as possible (which means still using attribute inference with templated functions when the attribute should depend on the template arguments but to not use it much of anywhere else). However, that then requires that you mark up your functions everywhere, which can be very tedious, and many folks don't want to do it. Of course, using more attribute inference reduces that particular problem (which is why many folks want it), but you then get a different set of problems due to the fact that attributes are inferred instead of explicit. So, there's really no winning. In some ways, minimizing attribute inference is the best option, and in others, maximizing it would be better. Probably the best solution to the problem would be to have the defaults better match up with what your average program needs, but no set of defaults fits every program, and different coding styles can result in very different opinions on which set of attributes should be the default. I very much doubt that you would find much of a consensus on it even just within the core set of developers working on dmd, druntime, and Phobos. My guess is that if code breakage were somehow not part of the question that the majority of D programmers would be in favor of @safe by default, since the vast majority of code can be @safe (though plenty of the time programmers don't bother to mark it as @safe), and in theory, only small portions of a program should typically need to be marked as @system. But I expect that any other attribute would result in a lot of arguing. For instance, in some respects, pure would be great as the default, but that doesn't interact well at all with stuff like I/O, making it so that you have to write your programs in a certain way for pure to work well for most functions, and not everyone wants to do that. Some folks might want nothrow to be the default, because they don't use exceptions much, but it would be a disaster in code that did use exceptions much. And having const or immutable as the default would be highly controversial. Some folks really want it, but a lot of code simply wouldn't work well that way (including ranges as things currently stand), meaning that a _lot_ of code would have to be marked with mutable (or whatever the attribute would be to undo the default of const or immutable). Some folks might want nothrow to be the default, because they don't use exceptions much, but it would be a disaster in code that did use exceptions much. So, any pretty much any change to the defaults for attributes would likely result in a _lot_ of arguing. The biggest thing that we clearly can do and have talked about from time to time but have never actually done is to introduce a way to reverse attributes that currently can't be reversed - e.g. having something like pure(false). That way, it would become easier to just mark entire modules with an attribute by doing something like @safe: at the top. Of course, that would still leave the problem of either not being able to have templated code in that module or needing a way to indicate that an attribute should be inferred for a function instead of using the explicit attribute that's being used on the entire module. So, a DIP on the subject would probably need to worry about fixing that problem, but regardless of the fine details, we really should get a DIP for that at some point here. And it's well-written, with a solid approach to the problem, I fully expect that it would be accepted. It's just that no one has cared enough to write such a DIP. Of course, even if we _did_ have a solution for reversing attributes, slapping an attribute on the top of the module would still potentially be a maintenance problem, because it's then really easy to miss that an attribute is in effect (it's a problem that we've had on several occasions with druntime and Phobos in the few cases where attributes are mass-applied). So, there is no silver bullet here (though regardless of whether mass-applying attributes is something that should ever be considered good practice, we really should add a way to be able to reverse them). - Jonathan M Davis