December 25, 2018
On Monday, 24 December 2018 at 19:57:50 UTC, Walter Bright wrote:
> On 12/24/2018 10:10 AM, H. S. Teoh wrote:
>> If you can convince him, that would be great!
>
> You'd need very compelling use cases.
>
> It's like adding more and more horsepower to a car. At some point, it doesn't make the car better.
>
> Or like operator overloading. C++ has much more expansive rules for operator overloading. They lead to clever programs, and some people swear by them, but are they *better* programs? For example,
>
> * iostreams
>
> * regex DSL https://pdfs.semanticscholar.org/e630/5f84bca36251fd5a4ffa5f00e0effc8aaa7d.pdf
>
> ? I don't buy it. I've never seen an elegant use of the more expansive power (even though many insist those two examples are elegant).

I feel like D's operator overloading can be equally abused as C++'s operator overloading. There just aren't people doing that with D (yet).
December 24, 2018
On Tue, Dec 25, 2018 at 12:15:58AM +0000, Rubn via Digitalmars-d wrote:
> On Monday, 24 December 2018 at 19:57:50 UTC, Walter Bright wrote:
[...]
> > Or like operator overloading. C++ has much more expansive rules for operator overloading. They lead to clever programs, and some people swear by them, but are they *better* programs? For example,
> > 
> > * iostreams
> > 
> > * regex DSL https://pdfs.semanticscholar.org/e630/5f84bca36251fd5a4ffa5f00e0effc8aaa7d.pdf
> > 
> > ? I don't buy it. I've never seen an elegant use of the more expansive power (even though many insist those two examples are elegant).
> 
> I feel like D's operator overloading can be equally abused as C++'s operator overloading. There just aren't people doing that with D (yet).

Many things *can* be abused, but aren't because there's little reason to.

D forces you to use opEquals / opCmp for overloading the comparison operators, so at least the behaviour will be (somewhat) consistent no matter how you abuse it.  There's also no comma operator for you to abuse.  The arithmetic operators can still be abused, but there are also better and easier ways of achieving equivalent results by other means in D, so there's not much incentive to do something like that.

For example, compile-time regexes can be achieved by using string mixins, retaining normal regex syntax, so there's not much reason to abuse arithmetic operators with unnatural syntax, just so you can implement compile-time regexes.

While << and >> can theoretically still be overloaded iostream-style, D already removed one of the main motivations for ditching C's stdio.h, namely, that the various printf functions are variadic in a non-typesafe way. D actually has 3 different ways of achieving variadic functions, the most common of which is based on variadic templates and completely type-safe.  Although some people are not a fan of std.format, it does serve its purpose, and has also been extended in powerful new ways in D (cf., the %(...%) array formatter). There's also the built-in ~ concatenation operator, which can be used for concatenating output strings, and std.conv.text, which formats a list of stuff, so there's less reasons for iostream-style << and >>.  Not to mention UFCS, which could be used for chaining output function calls without needing to overload any operators, plus, combined with range-based code, gives you powerful new ways of writing I/O code that essentially marginalizes the utility of iostream-style code.

So yeah, it's still *possible* to abuse operator overloading in D, but the incentives for doing that are pretty low, and there are many other nicer features with higher incentives that people are more liable to use instead.  It's reminiscient of Walter's Boeing thing, about designing interfaces such that the way people are most likely to use it also happens to be the correct way, whereas the wrong way of doing things requires more effort and/or sticks out like a sore thumb, so people are less likely to attempt it.


T

-- 
They pretend to pay us, and we pretend to work. -- Russian saying
December 25, 2018
On Tuesday, 25 December 2018 at 00:40:13 UTC, H. S. Teoh wrote:
> On Tue, Dec 25, 2018 at 12:15:58AM +0000, Rubn via Digitalmars-d wrote:
>> On Monday, 24 December 2018 at 19:57:50 UTC, Walter Bright wrote:
> [...]
>> > Or like operator overloading. C++ has much more expansive rules for operator overloading. They lead to clever programs, and some people swear by them, but are they *better* programs? For example,
>> > 
>> > * iostreams
>> > 
>> > * regex DSL https://pdfs.semanticscholar.org/e630/5f84bca36251fd5a4ffa5f00e0effc8aaa7d.pdf
>> > 
>> > ? I don't buy it. I've never seen an elegant use of the more expansive power (even though many insist those two examples are elegant).
>> 
>> I feel like D's operator overloading can be equally abused as C++'s operator overloading. There just aren't people doing that with D (yet).
>
> Many things *can* be abused, but aren't because there's little reason to.
>
> D forces you to use opEquals / opCmp for overloading the comparison operators, so at least the behaviour will be (somewhat) consistent no matter how you abuse it.  There's also no comma operator for you to abuse.  The arithmetic operators can still be abused, but there are also better and easier ways of achieving equivalent results by other means in D, so there's not much incentive to do something like that.
>
> For example, compile-time regexes can be achieved by using string mixins, retaining normal regex syntax, so there's not much reason to abuse arithmetic operators with unnatural syntax, just so you can implement compile-time regexes.
>
> While << and >> can theoretically still be overloaded iostream-style, D already removed one of the main motivations for ditching C's stdio.h, namely, that the various printf functions are variadic in a non-typesafe way. D actually has 3 different ways of achieving variadic functions, the most common of which is based on variadic templates and completely type-safe.  Although some people are not a fan of std.format, it does serve its purpose, and has also been extended in powerful new ways in D (cf., the %(...%) array formatter). There's also the built-in ~ concatenation operator, which can be used for concatenating output strings, and std.conv.text, which formats a list of stuff, so there's less reasons for iostream-style << and >>.  Not to mention UFCS, which could be used for chaining output function calls without needing to overload any operators, plus, combined with range-based code, gives you powerful new ways of writing I/O code that essentially marginalizes the utility of iostream-style code.
>
> So yeah, it's still *possible* to abuse operator overloading in D, but the incentives for doing that are pretty low, and there are many other nicer features with higher incentives that people are more liable to use instead.  It's reminiscient of Walter's Boeing thing, about designing interfaces such that the way people are most likely to use it also happens to be the correct way, whereas the wrong way of doing things requires more effort and/or sticks out like a sore thumb, so people are less likely to attempt it.
>
>
> T

Being able to and not having a reason to do it are two different things. Someone is going to find a reason to use it and abuse it. Sure you can't overload equality and comma operators, but you can overload just about every other operator.

You can easily make the "+" operator do something entirely different than addition. Same with any of the other operators. They can be used with any other type and can output any unrelated type they wish. That's not going to stick out like a sore thumb, and it isn't that much more difficult to do. I wouldn't exactly call this designing an "interface" as it isn't really an interface so much as a feature. I wouldn't say "correct" and "wrong". There's a lot of things in D that are the "correct" way to do something but are incredibly difficult to do and results in messy code. As an example, until very recently you had to write a hack if you wanted to deprecate a single enum value. More accurate words to use would be something a long the lines of "intended design". I mean I could bring up auto-decoding as well, would you say that's the "correct" way or merely the "intended design" falling flat on its' face ending up being incorrect.
December 25, 2018
On Tue, 25 Dec 2018 00:15:58 +0000, Rubn wrote:
> I feel like D's operator overloading can be equally abused as C++'s operator overloading. There just aren't people doing that with D (yet).

There just aren't as many people thinking that abusing operator overloading is a neat trick these days.

I have seen one person using iostream style << in D, which is kind of scary. May as well just use opCall instead if you need one item printed per function call, like Tango did. (And there *are* good reasons for that -- it reduces overhead both at compile time and runtime.)
December 25, 2018
On Monday, 24 December 2018 at 23:54:19 UTC, Rubn wrote:

>
> When talking implicit conversion (at least in the same sense as C++) you create a new object when doing an implicit conversion. How do you envision the implicit conversion would work?

Similar to how C# does it.
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/implicit

> Why do you need implicit conversion for this ?

I meant that you can't program an event that runs every time an implicit conversion occurs.(Unless you hacked the compiler that does that for you...)

> You could just use explicit conversion for this

I am specifically talking about implicit conversions via inheritance and why it not an idea tool, as (Which I had said before) you have no control on how it does implicit conversions. I am not talking about explicit conversions here.

>> If you want to support multiple implicit conversion with the current features, then you need multiple alias this, which is not a good solution as
>> A.) It is multiple inheritance. Which we both agree it is a terrible idea.
>> B.) Multi alias this still hasn't been implemented already. *Throws table*
>
> Idk, all this seems shakey. I avoid implicit conversion as much as possible in C++, the times I do use it usually is because of some other limitation in C++ that can be solved a different way in D.

... What limitations in C++ are you talking about?

Alex
December 25, 2018
On 12/24/2018 6:43 PM, Rubn wrote:
> You can easily make the "+" operator do something entirely different than addition.
If you want to make "+" non-commutative, you have to work a little harder.

I'm happy to see that D has successfully inculcated a culture that attempting to use operator overloading for non-arithmetic purposes is a code smell, rather than celebrating it as C++ does. It's like:

#define BEGIN {
#define END }

is considered a smell in C (it didn't use to be, it took a while to stamp that out).

We'll not be accepting such practices into the D standard library, etc., and will do what we can to discourage such.

So yes, if you try hard enough, you can write execrable code. But you'll be on your own with it.
December 25, 2018
On Tuesday, 25 December 2018 at 11:31:17 UTC, Walter Bright wrote:
> On 12/24/2018 6:43 PM, Rubn wrote:
>> You can easily make the "+" operator do something entirely different than addition.
> If you want to make "+" non-commutative, you have to work a little harder.

Not that hard at all, you just do operator overloading like normal.

https://run.dlang.io/is/Jg8Jff

struct Int {
    int value;
	
    this( int input ) {
        value = input;
    }

    Int opBinary(string op)(int a) const if ( op == "+" ) {
        return Int(value + a);
    }
	
    // Hell can make this return a different type and you
    // won't be even be able to do the comparison: (a + b) == (b + a)
    Int opBinaryRight(string op)(int a) const if ( op == "+" ) {
        return Int(value + a + 1);
    }
}

void main() {
    import std.stdio : writeln;
	
    const Int a = 5;
    const int b = 2;

    writeln(a + b, " == ", b + a);
}

> I'm happy to see that D has successfully inculcated a culture that attempting to use operator overloading for non-arithmetic purposes is a code smell, rather than celebrating it as C++ does. It's like:
>
> #define BEGIN {
> #define END }
> is considered a smell in C (it didn't use to be, it took a while to stamp that out).

What makes you think C++ celebrates it? You just point to one person that thinks it's a good idea. The C++ community has tens of thousands more users than D, there are going to be people that think it is a good idea.


> We'll not be accepting such practices into the D standard library, etc., and will do what we can to discourage such.
>
> So yes, if you try hard enough, you can write execrable code. But you'll be on your own with it.

Sadly auto-decoding has already made it into the standard. I'm happy to say auto-decoding won't be making its way into the C++ standard :).

December 25, 2018
On Tuesday, 25 December 2018 at 04:48:22 UTC, 12345swordy wrote:
> On Monday, 24 December 2018 at 23:54:19 UTC, Rubn wrote:
>
>>
>> [snip]
>
> I am specifically talking about implicit conversions via inheritance and why it not an idea tool, as (Which I had said before) you have no control on how it does implicit conversions. I am not talking about explicit conversions here.
>


Instead of implicit conversions, what about using something like
__traits(compiles, cast(U) T.init)
to check whether T can be explicitly casted to U? Then you could just create a canCast function that can detect whether it works or not. You'd still have to write a template function to check, but it works with anything.

See
https://run.dlang.io/is/CfpvUE
December 26, 2018
On Tuesday, 25 December 2018 at 15:03:14 UTC, jmh530 wrote:

> to check whether T can be explicitly casted to U?

That is a completely different issue and has nothing to do with implicit conversion.

-Alex
December 26, 2018
On Monday, 24 December 2018 at 23:28:08 UTC, Walter Bright wrote:
> On 12/24/2018 3:24 PM, H. S. Teoh wrote:
>> I haven't been keeping up with C++ in any serious way ever since I found
>> D; what's the replacement for iostreams these days?

https://github.com/fmtlib/fmt ?

> Not that I'm aware of. Of course, like C's gets(), it'll never go away.

Likely true. Nothing ever goes away.