December 17, 2018
On Monday, 17 December 2018 at 09:41:01 UTC, Dukc wrote:
> On Saturday, 15 December 2018 at 19:53:06 UTC, Atila Neves wrote:
>
>> @safe and pure though...
>
> Why @safe? Can't you just write "@safe:" on top and switch to @system/@trusted as needed?

Argh, I forgot that you are not supposed to @safe templates away.
December 17, 2018
On Monday, 17 December 2018 at 09:41:01 UTC, Dukc wrote:
> On Saturday, 15 December 2018 at 19:53:06 UTC, Atila Neves wrote:
>
>> @safe and pure though...
>
> Why @safe? Can't you just write "@safe:" on top and switch to @system/@trusted as needed?

Not quite. It doesn't work the way most people expect for member functions and causes problems for templates.
December 17, 2018
On 12/15/2018 11:53 AM, Atila Neves wrote:
> @safe and pure though...

@safe is not so hard to adopt, since by using @trusted one can proceed incrementally.

Going pure, however, is much harder (at least for me) because I'm not used to programming that way. Making a function pure often requires reorganization of how a task is broken up into data structures and functions.

For example,

https://github.com/dlang/dmd/blob/master/src/dmd/target.d

It's nearly all global variables that manipulate other global variables. I recently added a parameter to _init() so that it didn't need to access global.params.

Now if the Target.* __gshared's could instead be replaced with fields, then _init() could be made pure.
December 18, 2018
On Mon, 2018-12-17 at 12:16 -0800, Walter Bright via Digitalmars-d-announce wrote:
> […]
> 
> Going pure, however, is much harder (at least for me) because I'm not used
> to
> programming that way. Making a function pure often requires reorganization
> of
> how a task is broken up into data structures and functions.
> 
> […]

I can recommend a short period of working only with Haskell. And then a short period working only with Prolog. Experience with Java and Python people trying to get them to internalise the more declarative approach to software, shows that leaving their programming languages of choice behind for a while is important in improving their use of their languages of choice.

For Java people this is quite easy since there is Frege (an implementation of Haskell on the JVM) and Clojure (a Lisp on the JVM). They do not have to leave the comfort of their JVM to get away from Java. On return to Java, people's use of Option<T>, and lambda expressions, etc. was markedly different – and a lot more declarative, making testing as well as comprehensibility of their much better.

For Python people you have to play slightly different games, such as requiring no use of for and while loops, since there is no pure declarative language on the PVM – the computational model of the PVM actually makes declarative programming quite hard, but it is possible, and it improves code comprehensibility and testability.

The problem for people immersed in the C, and C++ world is internalising declarative as a concept. I have tried, and failed a few times, as well as succeeding some. As C++ evolves towards being more and more declarative, it seems hard for the average C++ programmer to really move on from "old style C++", despite all the literature on "modern C++". But as the standards committee drag C++ along the increasingly declarative code route, things change, albeit relatively slowly.

Rust I feel has a pivotal role in all this. By emphasising the ML view on mixed declarative and imperative programming, it has found an interesting middle ground that seems to work very well. Many of the C programmers who though C++ overcomplicated and not worth looking at, are taking to Rust and in doing so leaving C behind.

On a personal level, I am now doing most of my programming in Rust rather than D, but this is as much to do with the GStreamer community choosing Rust as the replacement for C for GStreamer. But this is from a library implementers perspective, rather than an application perspective – but the choice pushes through. D (with GtkD and GStreamerD) is in many ways as good a choice as gtk- rs and gstreeamer-rs for writing applications – except:

– documentation for gtk-rs and gstreamer-rs is better than for GtkD and
GStreamerD; and
– the standard Rust executor and futures system has been integrated into gtk-
rs, something not present in GtkD.
– GStreamer core developers have an obsessive fear of the word "garbage
collector".

I did a lightning talk at the GStreamer conference in Edinburgh a couple of months ago, concluding that I think D (which about half the audience knew of) is overall better than Rust for GTK+ and GStreamer applications, but recognising that Rust is actually the replacement for C and C++ for GTK+ and GStreamer applications. (Obviously Python has an ongoing role in all this as well.)

I think D has missed the opportunity to get significant traction in the GTK+
and GStreamer milieus. :-(


-- 
Russel.
===========================================
Dr Russel Winder      t: +44 20 7585 2200
41 Buckmaster Road    m: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



December 18, 2018
On Tuesday, 18 December 2018 at 08:17:28 UTC, Russel Winder wrote:
> Rust I feel has a pivotal role in all this. By emphasising the ML view on mixed declarative and imperative programming, it has found an interesting middle ground that seems to work very well. Many of the C programmers who though C++ overcomplicated and not worth looking at, are taking to Rust and in doing so leaving C behind.

AIU rust, clojure and prolog are impure.
December 18, 2018
On Tue, 2018-12-18 at 09:59 +0000, Kagamin via Digitalmars-d-announce wrote:
> 
[…]
> AIU rust, clojure and prolog are impure.

Clearly Rust is because it allows for mutability, though it is not the default.

Clojure is but you have to work hard for that, the initial language is effectively pure.

I have no idea how the term impure can be applied to Prolog.

-- 
Russel.
===========================================
Dr Russel Winder      t: +44 20 7585 2200
41 Buckmaster Road    m: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



December 18, 2018
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.
December 18, 2018
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



December 18, 2018
On Tuesday, 18 December 2018 at 10:19:14 UTC, Russel Winder wrote:
> Clojure is but you have to work hard for that, the initial language is effectively pure.

https://ideone.com/y8KWja clearly it isn't, its site only claims that most code happens to be pure, but it looks like it's not checked in any way and not sure if purity can be even checked there.
December 18, 2018
On Tuesday, 18 December 2018 at 12:20:48 UTC, Kagamin wrote:
> On Tuesday, 18 December 2018 at 10:19:14 UTC, Russel Winder wrote:
>> Clojure is but you have to work hard for that, the initial language is effectively pure.
>
> https://ideone.com/y8KWja clearly it isn't, its site only claims that most code happens to be pure, but it looks like it's not checked in any way and not sure if purity can be even checked there.

From the Clojure homepage: "Clojure is impure, yet stands behind the philosophy that programs that are more functional are more robust." The goal is to make it easy to program in a functional style, not to provide a pure functional programming language. It is like OCaml in that respect.