Re: Overloading relational operators separately; thoughts?

2016-10-02 Thread Atila Neves via Digitalmars-d
On Wednesday, 28 September 2016 at 01:18:58 UTC, Minty Fresh 
wrote:
Currently, D offers fine grained overloading for most of the 
unary and arithmetic binary operators, but at some point a 
decision was made to lump together all of the relational 
operators (and if necessary, the equality operators) into a 
single function `opCmp`.
And while it does add a lot of convenience and consistency to 
how operators behave, it does also put a lot of limitations on 
what they can do.


[...]


opCmp was a good idea.

Allowing opBinary to bypass opCmp is also a good idea.

Atila


Re: Overloading relational operators separately; thoughts?

2016-10-02 Thread Minty Fresh via Digitalmars-d

On Saturday, 1 October 2016 at 17:53:44 UTC, Russel Winder wrote:
On Sat, 2016-10-01 at 14:55 +, Chris Wright via 
Digitalmars-d wrote:



Groovy doesn't allow you to overload comparison operators
individually,
and probably most JVM languages likewise. This is to retain
compatibility
with Java, which has `.compareTo()` instead of `isLessThan()` 
etc.


Yes it does.  http://groovy-lang.org/operators.html

There is *also* compareTo.

Ruby allows you to override individual comparison operators, 
with a

special operator `<=>` for combined comparisons. Nim lets you
overload
arbitrary operators and create your own; some old discussions
suggest
that the Comparable type is based on `<` alone.


Groovy also supports the spaceship operator.


`<=>` exists for the general case, which is what `opCmp` covers 
in D. Overloading each relational operator individually is made 
possible to address any sort of special cases.
The issue being, in D there is no room for any manner of special 
case.


Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread Russel Winder via Digitalmars-d
On Sat, 2016-10-01 at 14:55 +, Chris Wright via Digitalmars-d
wrote:

> Groovy doesn't allow you to overload comparison operators
> individually, 
> and probably most JVM languages likewise. This is to retain
> compatibility 
> with Java, which has `.compareTo()` instead of `isLessThan()` etc.

Yes it does.  http://groovy-lang.org/operators.html

There is *also* compareTo.

> Ruby allows you to override individual comparison operators, with a 
> special operator `<=>` for combined comparisons. Nim lets you
> overload 
> arbitrary operators and create your own; some old discussions
> suggest 
> that the Comparable type is based on `<` alone.

Groovy also supports the spaceship operator.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread Minty Fresh via Digitalmars-d

On Friday, 30 September 2016 at 23:31:19 UTC, Sai wrote:
Genuine question: In the post Java languages, how many 
languages allowed unrestricted operator overloading and did 
that cause any similar mess?


Thanks in advance for any answers.


Although there maybe a bit of bias here, but I'd say Rub does it 
quite well (although the syntax for unary operator overloads is a 
bit bizarre), since I work with the language on a daily basis.


But going a step further there's languages like Haskell that 
allow defining completely new operators.


Both of the aforementioned have amassed an exceedingly large 
following at this point.


Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread Minty Fresh via Digitalmars-d

On Friday, 30 September 2016 at 22:38:07 UTC, Walter Bright wrote:

On 9/30/2016 1:14 PM, Minty Fresh wrote:

Metathesiophobia


Repeatedly suggesting people who don't agree with you have 
mental disorders does not advance your case and is not 
appreciated here.


Metathesiophobia is not a mental disorder, it's a phobia. There's 
quite a bit of distinction there.
Specifically it's an ungrounded fear or dislike of change. It's 
altogether not uncommon, actually.


A more productive way forward is for you (and those who agree 
with you) to prepare a formal DIP and submit it. It's the way 
significant language change proposals are done.


That was sort of the initial intent of this thread. To test the 
waters and see if the idea would have support.

But it seems the community is extremely torn on the matter.


Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread Chris Wright via Digitalmars-d
On Fri, 30 Sep 2016 19:33:33 +, pineapple wrote:
> How many people have to state it how many times in how many different
> ways before it gets through? These are stupid goals. They reflect
> intention that has no basis in reason, that has no basis in reality,
> that is a blindly-enforced dogma.

More like: this is the common use case, so let's try to make that as 
smooth as possible, both for implementors and readers. And mucking about 
in the same area can add wrinkles that confuse people.

The takeaway should be that we should exercise caution, not that we 
should refuse to change the language. But the basic idea does make sense.

I'm not sure it's straightforward to make other operators consistent in 
the same way. You could try to enforce things like: typeof(a OP b) should 
be co/contravariant with typeof(a) or typeof(b) for math operators; 
opApply and opIndex should deal with the same types (though it's valid to 
add extras); that kind of thing. It does seem inconsistent that no 
attempt was made, but the language was only Walter Bright for nearly a 
decade, and one person doesn't have that much time.

With most of the language and compiler work still being Walter Bright, he 
has much more say in the direction of the language than anyone else.

> It always would have been simpler if, in the first place, opBinary had
> caught comparison operators and opCmp and opEquals were omitted.
> Instead, those making the decisions went out of their way to impose
> these arbitrary limitations. If we can start now to untangle that
> mistake, it will make D more tenable for real-world code.

That would have been tricky, or at least unpleasant, before auto return 
types. Auto return types were introduced after 2010, and opCmp was 
introduced before 2006.


Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread Chris Wright via Digitalmars-d
On Fri, 30 Sep 2016 23:31:19 +, Sai wrote:
> Genuine question: In the post Java languages, how many languages allowed
> unrestricted operator overloading and did that cause any similar mess?

Groovy doesn't allow you to overload comparison operators individually, 
and probably most JVM languages likewise. This is to retain compatibility 
with Java, which has `.compareTo()` instead of `isLessThan()` etc.

Ruby allows you to override individual comparison operators, with a 
special operator `<=>` for combined comparisons. Nim lets you overload 
arbitrary operators and create your own; some old discussions suggest 
that the Comparable type is based on `<` alone.


Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread pineapple via Digitalmars-d

On Saturday, 1 October 2016 at 07:13:39 UTC, Martin Nowak wrote:
The fact that it's not possible to overload < but have to use 
the ternary opCmp is even a performance problem. All std 
algorithms only use less as a predicate, leading to lots of 
unnecessary cycles when e.g. sorting UDTs.


On Saturday, 1 October 2016 at 11:53:07 UTC, Andrei Alexandrescu 
wrote:
Apparently in dmd the generated code is less efficient: 
https://goo.gl/OWxbA0. In gdc it's the same: 
https://godbolt.org/g/NmUyXM. I couldn't test with ldc, 
http://ldc.acomirei.ru seems down. -- Andrei


On Saturday, 1 October 2016 at 06:46:31 UTC, Russel Winder wrote:
This debate is about whether D constrains people as Java does 
or whether it enables people as C++ and Python do.


Or use C++ or Python which allow for this. Fine, end of D 
having a future amongst a large section of the programming 
population. This is fine. Unless D wants to be a player in this 
game.


This has already been done, read the thread. SQLAlchemy. The 
expression language is a a lovely builder DSL for constructing 
SQL entirely in Python with no parser overhead. No operator 
overloading, no DSL for builder languages. See same on the JVM: 
in Java you can't do it, Kotlin, Ceylon, Scala, Groovy, do it 
beautifully, and a lot of people do.


This isn't a PR yet because it's not nearly ready for general 
consumption, but these are all good points and I'd greatly 
appreciate if you would all please take a few minutes to express 
them in the DIP and get the changes merged so that we can have 
something that lays out clearly the pros and cons of this change.


https://github.com/pineapplemachine/DIPs/blob/operator_overload_expansion/DIPs/DIP1003.md


Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread Andrei Alexandrescu via Digitalmars-d

On 10/1/16 7:33 AM, Andrei Alexandrescu wrote:

On 10/1/16 3:13 AM, Martin Nowak wrote:

The fact that it's not possible to overload < but have to use the
ternary opCmp is even a performance problem. All std algorithms only use
less as a predicate, leading to lots of unnecessary cycles when e.g.
sorting UDTs.


I've also been often annoyed by having to write

return a < b ? -1 : a > b;

in e.g. checkedint. Does inlining take care of this? -- Andrei


Apparently in dmd the generated code is less efficient: 
https://goo.gl/OWxbA0. In gdc it's the same: 
https://godbolt.org/g/NmUyXM. I couldn't test with ldc, 
http://ldc.acomirei.ru seems down. -- Andrei




Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread Andrei Alexandrescu via Digitalmars-d

On 10/1/16 3:13 AM, Martin Nowak wrote:

The fact that it's not possible to overload < but have to use the
ternary opCmp is even a performance problem. All std algorithms only use
less as a predicate, leading to lots of unnecessary cycles when e.g.
sorting UDTs.


I've also been often annoyed by having to write

return a < b ? -1 : a > b;

in e.g. checkedint. Does inlining take care of this? -- Andrei



Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread Martin Nowak via Digitalmars-d
On Wednesday, 28 September 2016 at 20:16:08 UTC, Walter Bright 
wrote:

On 9/28/2016 6:58 AM, Timon Gehr wrote:

An excellent example of that is the std.regex package.
It's actually a bad example, because it is irrelevant: it is 
obviously a bad
idea to implement regex using operator overloading, because 
the regex operators

have no D equivalent.


Yet this "obviously bad" idea regularly resurfaces as a cool 
use of expression templates and respected people in the 
industry like it and advocate it.




Assume I have two symbolic expressions a and b:

Expression a=variable("a"), b=variable("b");

Why should I be allowed to do

auto c = a + b; // symbolic value a + b

but not

auto d = a <= b; // symbolic value a <= b


Because there is no way to stop the former but still have 
operator overloading.


The fact that it's not possible to overload < but have to use the 
ternary opCmp is even a performance problem. All std algorithms 
only use less as a predicate, leading to lots of unnecessary 
cycles when e.g. sorting UDTs.


While I agree with your point on expression templates, 
overloading comparison operators has valid use cases.




Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread Russel Winder via Digitalmars-d
On Fri, 2016-09-30 at 23:31 +, Sai via Digitalmars-d wrote:

> Genuine question: In the post Java languages, how many languages 
> allowed unrestricted operator overloading and did that cause any 
> similar mess?

It is not feasible to provide a count, as there is always another
language one forgot.

Groovy, Kotlin, Ceylon, and Scala certainly allow operator overloading.
Scala even allows new operator symbol definition. There are some
incomprehensible Scala programs because of this. But then there are
many incomprehensible D programs – you can play code golf in any
language. Just because there is a feature in a language doesn't mean it
has to be abused.

I cannot remember offhand whether Fantom, Golo, Gosu, etc. allow
operator overloading.

The core lesson of Python is that if you allow everything to happen,
there can still be a base of excellent code. Paternalism/maternalism in
programming languages is massively overrated. Youngsters will escape
the constraints. In the case of D operator overloading restrictions to
the glories (!) that is C++.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread Russel Winder via Digitalmars-d
On Fri, 2016-09-30 at 21:43 +, Dominikus Dittes Scherkl via
Digitalmars-d wrote:

> But operator overloading doesn't increase the language 
> expressiveness.

Expressiveness is not a metric, there isn't even a partial order, it is
a qualitative thing, thus personal to a great extent. What I consider
expressive and what you consider expressive likely are entirely
unrelated. There can be a shared agreement or a disagreement. What is
not acceptable is to state that one person's opinion is true for all
people 
 
> They provide nothing that you can't already do using ordinary 
> function calls.

Correct.

> So forget expressiveness as an argument.

No.

> Operator overload is syntactic sugar, added to serve a single 
> purpose: to allow mimic buildin types. So they should provide 
> everything needed to do so, and nothing more. Adding more may be 
> asked for, but this is not reasonable, because it is unrelated to 
> the original purpose but increases only the possibilities to 
> obfuscate the code by doing something misleading (there are 
> already endless such possibilities, but that makes asking for 
> more no more reasonable).

All high level languages are syntactic sugar, the one true language is
machine code, all else is fluff. It just happens that layers of
abstraction and "syntactic sugar" are really rather important to
building complex software systems. 

Any programming language is in fact a meta-language to enable people to
construct new languages. All programs are DSLs for some domain. The
question at hand is whether a programming language has the right tools
for the job. Operator overloading is one tool in the creation of DSLs.
D currently seems to have a very hobbled version of this compared to
C++, Python, and a very grandiose scheme compared to Go, Fortran.

This debate is about whether D constrains people as Java does or
whether it enables people as C++ and Python do.

> You are allowed to walk. You can express everything that is 
> possible with operator overloading in lots of other ways. And you 
> can express everything that operator overloading was designed for 
> with it - but maybe not everything beyond that. Use other ways to 
> express such. If the compactness of expression written using 
> operators is everything you are interested in - define some 
> language and write a parser for it, and enjoy how short you can 
> express everything you need with it.
> You can even write such stuff directly in your D code and let 
> some string mixins massage it to compile.

Or use C++ or Python which allow for this. Fine, end of D having a
future amongst a large section of the programming population. This is
fine. Unless D wants to be a player in this game. 

> I can't see the point to relax the rules for operator overloading 
> unless you can show that they prevent parts of the original 
> design goal.

This has already been done, read the thread. SQLAlchemy. The expression
language is a a lovely builder DSL for constructing SQL entirely in
Python with no parser overhead. No operator overloading, no DSL for
builder languages. See same on the JVM: in Java you can't do it,
Kotlin, Ceylon, Scala, Groovy, do it beautifully, and a lot of people
do.

Java only survives as a language for constructing new systems because a
very large part of the Java programming community cannot be bothered to
learn new stuff that doesn't have Java on the label. Even then many are
not sure about this Java 8 thing. Indeed many are not even sure Java 5
was a good thing. Yes there are a lot of people still writing new stuff
in Java 1.4.2 because generics, streams, modern programming techniques
are new fangled syntactic sugar that is not needed to express the
algorithm. I can give lots of anecdotal evidence on this drawn from
workshops I have presented.

The question here is whether D wants to include these sorts of things
or reject them.

But at the heart of the debate is whether a DIP will be evolved into a
change to the D language or whether it will be rejected even before it
is put together.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: Overloading relational operators separately; thoughts?

2016-10-01 Thread Russel Winder via Digitalmars-d
On Fri, 2016-09-30 at 15:38 -0700, Walter Bright via Digitalmars-d
wrote:

> A more productive way forward is for you (and those who agree with
> you) to 
> prepare a formal DIP and submit it. It's the way significant language
> change 
> proposals are done.

But is the effort worth it? Will the DIP and PR be assessed? Does it
have any chance of success? Is there any chance of this long standing
position of D on overloading operators being overturned?

Saying "Go prepare a DIP" is both indicating the right thing to do, but
also a mechanism of deflecting the idea from having any chance of
success at all.

So does a well prepared DIP have a chance of changing D's operator
overloading or not?  

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread pineapple via Digitalmars-d

On Friday, 30 September 2016 at 22:38:07 UTC, Walter Bright wrote:
A more productive way forward is for you (and those who agree 
with you) to prepare a formal DIP and submit it. It's the way 
significant language change proposals are done.


A good idea.

I have written a rough initial draft for this DIP and it 
currently resides here, in a fork: 
https://github.com/pineapplemachine/DIPs/blob/operator_overload_expansion/DIPs/DIP1003.md


I invite anyone with an opinion - which I imagine is just about 
everyone who has participated in this thread - to please 
contribute to the DIP before it's submitted as a PR and for 
review.


I ask that arguments for and against listed in the DIP not 
include anything to the effect of merely "it would offer more 
flexibility" or "it would offer too much flexibility", as I think 
several pages of discussion have made clear that those holding 
either opinion are not likely to be swayed by arguments taking 
the opposing form.




Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Timon Gehr via Digitalmars-d

On 01.10.2016 01:31, Sai wrote:



I understand the concern of possible mess due to unrestricted use of
operator overloading (like C++).


C++ does it in std.



Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Timon Gehr via Digitalmars-d

On 30.09.2016 23:43, Dominikus Dittes Scherkl wrote:

On Friday, 30 September 2016 at 09:55:36 UTC, pineapple wrote:

On Friday, 30 September 2016 at 00:50:54 UTC, Jonathan M Davis wrote:

Except that it kind of is. It's an example of a language allowing you
to mess with too much and make it so that it doesn't function as
expected, which is what happens when you overload operators to act in
a way inconsistent with how they work with the built-in types.


Please don't do this; it destroys threading.



On Friday, 30 September 2016 at 19:09:25 UTC, Timon Gehr wrote:

On 30.09.2016 18:11, Jonathan M Davis via Digitalmars-d wrote:

Regardless, D already has a lot of powerful stuff in it, much of
which will
allow you to blow your foot off if you're really inclined to. The
overloaded
operators just so happened to be implemented in a way that doesn't
let you
blow your feet off as freely as C++'s overloaded operators will let
you do.



OTOH, feet are useless if you are not allowed to walk (even if you
choose not to blow them off).

You are allowed to walk.


There's a continuum here. Another data point:
https://www.youtube.com/watch?v=IqhlQfXUk7w

(Though here, one seems to require a good set of feet.)


You can express everything that is possible
with operator overloading in lots of other ways.


Everybody knows this. And everyone in the above video is getting where 
they are going.



And you can express
everything that operator overloading was designed for with it


Hopefully. My qualm is with the design. (It is not that significant, 
it's basically in the "fly that sits on your face at an irregular 
frequency" corner.)



- but
maybe not everything beyond that. Use other ways to express such. If the
compactness of expression written using operators is everything you are
interested in


Am not. You might be confusing me with someone else. But don't assume 
I'm going to accept huge overhead, because this does destroy the point 
of the original exercise at some point.



- define some language


Yes, I can design my own programming language. However, I don't 
currently have the resources to create the perfect tool for every job I 
face.



and write a parser for it,


Sure, I also have a parser. Now what? It does not integrate nicely with 
D code.



and enjoy how short you can express everything you need with it.


Conciseness never hurts. I'm interested in using notation that is 
similar to the one I use on paper and in scientific publications. It's 
also about ensuring correctness by making it easy to understand at a 
glance what is written down (by e.g. a domain expert). This is 
understood to have certain limitations (e.g. there's no built-in 
integral operator), but the notation that does exist corresponds 
precisely -- there is no misusing of names anywhere.




You can even write such stuff directly in your D code and let some
string mixins massage it to compile.
...


This does not scale. (It works for some things, not others.)


I can't see the point to relax the rules for operator overloading unless
you can show that they prevent parts of the original design goal.
...


Then I'm not interested in trying to convince you because you can always 
just claim that the use case I present was not part of the original 
design goal (which is not written down formally anywhere).



PS: opCmp can return float, so the comparison can result in NaN (not
conparable) - and as this is necessary to mimic some basic types (all
floatingpoint types) removing this possibility would indeed prevent
parts of the original design goal!


I know. I believe I was even the first one to point this out on the NG. 
It was an accident, not designed. The cause was lack of some pointless 
restriction.


Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Sai via Digitalmars-d

   a.isLessThan(b)



I understand the concern of possible mess due to unrestricted use 
of operator overloading (like C++). Java has clearly driven the 
point home by banning the operator overloading altogether.


Genuine question: In the post Java languages, how many languages 
allowed unrestricted operator overloading and did that cause any 
similar mess?


Thanks in advance for any answers.




Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Timon Gehr via Digitalmars-d

On 30.09.2016 22:14, Andrei Alexandrescu wrote:

On 09/30/2016 03:18 PM, Timon Gehr wrote:

On 30.09.2016 21:02, Timon Gehr wrote:

On 30.09.2016 03:15, Chris Wright wrote:

...



Wouldn't that be fun?



Certainly.


On a related note:

alias Seq(T...)=T;

struct S{
int x;
S opBinary(string op:"+",T...)(T args){
S r=this;
foreach(a;args) r.x+=a;
return r;
}
}

void main(){
import std.stdio;
assert(S(1) + Seq!(2,3,4) == S(10));
}


That looks awfully cool! -- Andrei



[my code here]


Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Walter Bright via Digitalmars-d

On 9/30/2016 1:14 PM, Minty Fresh wrote:

Metathesiophobia


Repeatedly suggesting people who don't agree with you have mental disorders does 
not advance your case and is not appreciated here.


A more productive way forward is for you (and those who agree with you) to 
prepare a formal DIP and submit it. It's the way significant language change 
proposals are done.




Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Dominikus Dittes Scherkl via Digitalmars-d

On Friday, 30 September 2016 at 09:55:36 UTC, pineapple wrote:
On Friday, 30 September 2016 at 00:50:54 UTC, Jonathan M Davis 
wrote:
Except that it kind of is. It's an example of a language 
allowing you to mess with too much and make it so that it 
doesn't function as expected, which is what happens when you 
overload operators to act in a way inconsistent with how they 
work with the built-in types.


Let me see if I understand your argument: We can't make D more 
expressive because a language far more popular than D is so 
expressive it makes it possible to do unconventional things, if 
you are so inclined?
But operator overloading doesn't increase the language 
expressiveness.
They provide nothing that you can't already do using ordinary 
function calls.

So forget expressiveness as an argument.
Operator overload is syntactic sugar, added to serve a single 
purpose: to allow mimic buildin types. So they should provide 
everything needed to do so, and nothing more. Adding more may be 
asked for, but this is not reasonable, because it is unrelated to 
the original purpose but increases only the possibilities to 
obfuscate the code by doing something misleading (there are 
already endless such possibilities, but that makes asking for 
more no more reasonable).


On Friday, 30 September 2016 at 19:09:25 UTC, Timon Gehr wrote:

On 30.09.2016 18:11, Jonathan M Davis via Digitalmars-d wrote:
Regardless, D already has a lot of powerful stuff in it, much 
of which will
allow you to blow your foot off if you're really inclined to. 
The overloaded
operators just so happened to be implemented in a way that 
doesn't let you
blow your feet off as freely as C++'s overloaded operators 
will let you do.



OTOH, feet are useless if you are not allowed to walk (even if 
you choose not to blow them off).
You are allowed to walk. You can express everything that is 
possible with operator overloading in lots of other ways. And you 
can express everything that operator overloading was designed for 
with it - but maybe not everything beyond that. Use other ways to 
express such. If the compactness of expression written using 
operators is everything you are interested in - define some 
language and write a parser for it, and enjoy how short you can 
express everything you need with it.
You can even write such stuff directly in your D code and let 
some string mixins massage it to compile.


I can't see the point to relax the rules for operator overloading 
unless you can show that they prevent parts of the original 
design goal.


PS: opCmp can return float, so the comparison can result in NaN 
(not conparable) - and as this is necessary to mimic some basic 
types (all floatingpoint types) removing this possibility would 
indeed prevent parts of the original design goal!


Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Andrei Alexandrescu via Digitalmars-d

On 09/30/2016 03:18 PM, Timon Gehr wrote:

On 30.09.2016 21:02, Timon Gehr wrote:

On 30.09.2016 03:15, Chris Wright wrote:

...



Wouldn't that be fun?



Certainly.


On a related note:

alias Seq(T...)=T;

struct S{
int x;
S opBinary(string op:"+",T...)(T args){
S r=this;
foreach(a;args) r.x+=a;
return r;
}
}

void main(){
import std.stdio;
assert(S(1) + Seq!(2,3,4) == S(10));
}


That looks awfully cool! -- Andrei



Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Minty Fresh via Digitalmars-d

On Friday, 30 September 2016 at 19:46:35 UTC, bachmeier wrote:
Claiming that operator overloading only applies to a specific 
user-defined type makes it worse. Having it work one way for 
three types, a different way for four other types, and a third 
way for yet another type doesn't sound like a minor thing.


But operators already behave in different way for different 
types. Built-in types inclusive. The most trivial and nit-picky 
difference would be between integer types and floating point 
types.


ie. Division between two integers yields an integer, division 
between two floats yields a float, but then division between an 
integer and a float also yields a float.
Alternatively, the bit-shift operators `<<` and `>>` don't 
function at all for floats.
But then we have also wonderful floating point values like `NaN` 
and `Infinity` for which arithmetic and relational operators 
behave differently altogether.


Another would static arrays, versus dynamic arrays, versus 
associative arrays. The first two support concatenation via `~`, 
only the second supports in-place concatenation `~=`, and the 
last has no notion of concatenation at all.


A counter argument that might be raised is that those are 
different types altogether. They are intended to behave in 
different ways entirely. Completely different data structures. 
Their similarities are only superficial.


And such a counter argument would be absolutely correct. Markedly 
so. They are completely different types.
The same is true of user-defined types. Their behavior should not 
be equated to (nor expected to be like) the behaviors of types 
they only resemble superficially.


But have fun debating design decisions that were made long ago 
and aren't going to change.


That's exactly the kind of decision making you see in C++ and 
PHP. Metathesiophobia would be one way of describing it. Stubborn 
blindness to real world usage is more contextually appropriate 
though, I feel.


Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread bachmeier via Digitalmars-d

On Friday, 30 September 2016 at 01:07:49 UTC, Chris Wright wrote:
The perl example is a line of code buried somewhere that 
changes the meaning of the rest of the code. Operator 
overloading is restricted to a specific user-defined type. With 
such a dramatic difference in the scope of the change, the 
analogy is useless.


I was responding to someone that wrote: "I also have the presence 
of mind to recognize that my opinions are not universal, and they 
are certainly no basis for imposing arbitrary limits upon another 
person's behavior". I gave an example of what happens when you 
don't want "arbitrary limits".


Claiming that operator overloading only applies to a specific 
user-defined type makes it worse. Having it work one way for 
three types, a different way for four other types, and a third 
way for yet another type doesn't sound like a minor thing.


But have fun debating design decisions that were made long ago 
and aren't going to change.


Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread pineapple via Digitalmars-d
On Friday, 30 September 2016 at 16:25:45 UTC, Jonathan M Davis 
wrote:
But if you or anyone else wants to do wacky stuff with 
overloaded operators that is not consistent with the built-in 
types, you're free to do so within how D's overloaded operators 
work. You're just not going to be able to do it as freely as 
you can in C++, because that goes against the goals of the 
operator overloading feature in D, and some of the improvements 
that were in line with the goals happen to have gotten in the 
way of such operator overloading abuse.


In your arguments in favor of this limitation of operator 
overloading, you keep referring to these goals, of what operator 
overloads have been intended to do. You've stated and restated 
that same explanation even though it's completely unconvincing 
because while stating this intention you have failed entirely to 
justify it.


How many people have to state it how many times in how many 
different ways before it gets through? These are stupid goals. 
They reflect intention that has no basis in reason, that has no 
basis in reality, that is a blindly-enforced dogma.


It always would have been simpler if, in the first place, 
opBinary had caught comparison operators and opCmp and opEquals 
were omitted. Instead, those making the decisions went out of 
their way to impose these arbitrary limitations. If we can start 
now to untangle that mistake, it will make D more tenable for 
real-world code.


And make no mistake: Perl is fantastic for real-world code 
because real-world code is not elegant, and it doesn't follow the 
rules, and it doesn't care how you meant for a feature to be 
used. Practical languages give the programmer a great deal of 
expressive power, and it's okay if the rules allow nonsense 
expressions because it's up to the programmer, not the language, 
to know what's nonsense and what's not.




Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Timon Gehr via Digitalmars-d

On 30.09.2016 21:02, Timon Gehr wrote:

On 30.09.2016 03:15, Chris Wright wrote:

...



Wouldn't that be fun?



Certainly.


On a related note:

alias Seq(T...)=T;

struct S{
int x;
S opBinary(string op:"+",T...)(T args){
S r=this;
foreach(a;args) r.x+=a;
return r;
}
}

void main(){
import std.stdio;
assert(S(1) + Seq!(2,3,4) == S(10));
}



Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Timon Gehr via Digitalmars-d

On 30.09.2016 18:11, Jonathan M Davis via Digitalmars-d wrote:

Regardless, D already has a lot of powerful stuff in it, much of which will
allow you to blow your foot off if you're really inclined to. The overloaded
operators just so happened to be implemented in a way that doesn't let you
blow your feet off as freely as C++'s overloaded operators will let you do.



OTOH, feet are useless if you are not allowed to walk (even if you 
choose not to blow them off).


Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Timon Gehr via Digitalmars-d

On 30.09.2016 03:15, Chris Wright wrote:

On Thu, 29 Sep 2016 10:41:38 +0200, Timon Gehr wrote:


On 29.09.2016 06:15, Walter Bright wrote:

On 9/28/2016 1:40 PM, Timon Gehr wrote:

(This is NOT expression templates.)


Right, but it's an enabler of expression templates. Discussion of more
powerful operator overloading cannot be divorced from expression
templates, and once ETs are in we'll be stuck with them forever.
...


They work today, just not with comparison operators.


To take it the other way, D could enforce that the return type of
arithmetic operators is compatible with at least one of the operands --
by implicit cast or constructor or being the same type.



It wouldn't infer with any of my use cases, but I don't see the point.


Wouldn't that be fun?



Certainly.


Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Jonathan M Davis via Digitalmars-d
On Friday, September 30, 2016 12:31:45 Minty Fresh via Digitalmars-d wrote:
>
> It's up to the developer to ensure that their code works
> correctly with existing facilities, not the language. I can
> already write code that will work in amazing and ridiculous ways
> with generic code in the standard library. It does not follow
> that the language is responsible or at fault for the code
> behaving in ways that are unexpected.

Of course, you can write code that behaves badly. There's no way that that
can be completely prevented while still allowing you to do useful,
productive things. But the folks asking to be able to overload < separately
just so that they can make it behave differently than what opCmp does are
basically asking for a way to be allowed to make their code behave badly
with the comparison operators in a way that opCmp doesn't currently allow.
The request is to improve support for an idiom that many consider to be
horrible coding practice, and Walter does not think that explicitly
supporting such an idiom makes any sense.

He hasn't gone to extra effort to prevent every possible misuse of
overloaded operators that he could. He simply defined some of the overloaded
operators in a way that was a significant improvement for the use case that
he thought that overloaded operators should be used for, and as a side
effect, it happens to have made it harder for a use case that he thinks is
bad practice. I think that he made the right decision.

But if you or anyone else wants to do wacky stuff with overloaded operators
that is not consistent with the built-in types, you're free to do so within
how D's overloaded operators work. You're just not going to be able to do it
as freely as you can in C++, because that goes against the goals of the
operator overloading feature in D, and some of the improvements that were in
line with the goals happen to have gotten in the way of such operator
overloading abuse.

- Jonathan M Davis



Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Jonathan M Davis via Digitalmars-d
On Friday, September 30, 2016 09:55:36 pineapple via Digitalmars-d wrote:
> On Friday, 30 September 2016 at 00:50:54 UTC, Jonathan M Davis
>
> wrote:
> > Except that it kind of is. It's an example of a language
> > allowing you to mess with too much and make it so that it
> > doesn't function as expected, which is what happens when you
> > overload operators to act in a way inconsistent with how they
> > work with the built-in types.
>
> Which language is more widely used? D or Perl?
>
> Let me see if I understand your argument: We can't make D more
> expressive because a language far more popular than D is so
> expressive it makes it possible to do unconventional things, if
> you are so inclined?

perl is always widely considered to be a horrible language even if it is
useful. And the example that was given for what you can do with perl is
pretty insane.

Regardless, D already has a lot of powerful stuff in it, much of which will
allow you to blow your foot off if you're really inclined to. The overloaded
operators just so happened to be implemented in a way that doesn't let you
blow your feet off as freely as C++'s overloaded operators will let you do.

- Jonathan M Davis



Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread Minty Fresh via Digitalmars-d
On Friday, 30 September 2016 at 00:50:54 UTC, Jonathan M Davis 
wrote:


Except that it kind of is. It's an example of a language 
allowing you to mess with too much and make it so that it 
doesn't function as expected, which is what happens when you 
overload operators to act in a way inconsistent with how they 
work with the built-in types. The perl example is more extreme, 
but the point still stands that having normal, common 
constructs operate in a way that's inconsistent with how they 
normally work tends to make code harder to read and maintain. 
Certainly, it can result in very unexpected behavior when 
mixing it with generic code that uses those operations.


- Jonathan M Davis


It's up to the developer to ensure that their code works 
correctly with existing facilities, not the language. I can 
already write code that will work in amazing and ridiculous ways 
with generic code in the standard library. It does not follow 
that the language is responsible or at fault for the code 
behaving in ways that are unexpected.


Furthermore, it's completely reasonable to write code that works 
with the generic facilities in the standard library, even if it 
doesn't behave exactly like a built in type.


ie.

  foo.reduce!"a + b"; // => produces an integer
  bar.reduce!"a + b"; // => produces an AST node

So long as the types produced by the operation are correct, this 
will work just fine.


Re: Overloading relational operators separately; thoughts?

2016-09-30 Thread pineapple via Digitalmars-d
On Friday, 30 September 2016 at 00:50:54 UTC, Jonathan M Davis 
wrote:
Except that it kind of is. It's an example of a language 
allowing you to mess with too much and make it so that it 
doesn't function as expected, which is what happens when you 
overload operators to act in a way inconsistent with how they 
work with the built-in types.


Which language is more widely used? D or Perl?

Let me see if I understand your argument: We can't make D more 
expressive because a language far more popular than D is so 
expressive it makes it possible to do unconventional things, if 
you are so inclined?




Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Chris Wright via Digitalmars-d
On Thu, 29 Sep 2016 10:41:38 +0200, Timon Gehr wrote:

> On 29.09.2016 06:15, Walter Bright wrote:
>> On 9/28/2016 1:40 PM, Timon Gehr wrote:
>>> (This is NOT expression templates.)
>>
>> Right, but it's an enabler of expression templates. Discussion of more
>> powerful operator overloading cannot be divorced from expression
>> templates, and once ETs are in we'll be stuck with them forever.
>> ...
> 
> They work today, just not with comparison operators.

To take it the other way, D could enforce that the return type of 
arithmetic operators is compatible with at least one of the operands -- 
by implicit cast or constructor or being the same type. Wouldn't that be 
fun?


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Chris Wright via Digitalmars-d
On Thu, 29 Sep 2016 17:50:54 -0700, Jonathan M Davis via Digitalmars-d 
wrote:
> Except that it kind of is. It's an example of a language allowing you to
> mess with too much and make it so that it doesn't function as expected,
> which is what happens when you overload operators to act in a way
> inconsistent with how they work with the built-in types.

The perl example is a line of code buried somewhere that changes the 
meaning of the rest of the code. Operator overloading is restricted to a 
specific user-defined type. With such a dramatic difference in the scope 
of the change, the analogy is useless.


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Jonathan M Davis via Digitalmars-d
On Thursday, September 29, 2016 22:37:51 Minty Fresh via Digitalmars-d wrote:
> On Thursday, 29 September 2016 at 22:27:50 UTC, bachmeier wrote:
> > You're looking for https://www.perl.org/ That's a highly viable
> > language, where you can do things like bury $[ = 1 somewhere in
> > your code to change from 0-indexing to 1-indexing of arrays.
> > They take pride in unpredictable, unreadable code.
>
> This is not at all relevant to the current argument.

Except that it kind of is. It's an example of a language allowing you to
mess with too much and make it so that it doesn't function as expected,
which is what happens when you overload operators to act in a way
inconsistent with how they work with the built-in types. The perl example is
more extreme, but the point still stands that having normal, common
constructs operate in a way that's inconsistent with how they normally work
tends to make code harder to read and maintain. Certainly, it can result in
very unexpected behavior when mixing it with generic code that uses those
operations.

- Jonathan M Davis



Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread bachmeier via Digitalmars-d

On Thursday, 29 September 2016 at 22:37:51 UTC, Minty Fresh wrote:

On Thursday, 29 September 2016 at 22:27:50 UTC, bachmeier wrote:
You're looking for https://www.perl.org/ That's a highly 
viable language, where you can do things like bury $[ = 1 
somewhere in your code to change from 0-indexing to 1-indexing 
of arrays. They take pride in unpredictable, unreadable code.


This is not at all relevant to the current argument.


I see


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Minty Fresh via Digitalmars-d

On Thursday, 29 September 2016 at 22:27:50 UTC, bachmeier wrote:
You're looking for https://www.perl.org/ That's a highly viable 
language, where you can do things like bury $[ = 1 somewhere in 
your code to change from 0-indexing to 1-indexing of arrays. 
They take pride in unpredictable, unreadable code.


This is not at all relevant to the current argument.


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread bachmeier via Digitalmars-d

On Thursday, 29 September 2016 at 20:16:00 UTC, pineapple wrote:
I repeat: Your thinking like this limits D's viability for 
real-world code.


You're looking for https://www.perl.org/ That's a highly viable 
language, where you can do things like bury $[ = 1 somewhere in 
your code to change from 0-indexing to 1-indexing of arrays. They 
take pride in unpredictable, unreadable code.


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Jonathan M Davis via Digitalmars-d
On Thursday, September 29, 2016 20:16:00 pineapple via Digitalmars-d wrote:
> On Thursday, 29 September 2016 at 19:39:35 UTC, Jonathan M Davis
>
> wrote:
> > The reality of the matter is that D's operator overloading was
> > designed specifically so that you could overload the built-in
> > operators to be used with your own types so that they could act
> > like the built-in types. It was not intended or designed to
> > allow for the symbols use for those operators to then be used
> > for other arbitrary stuff that's unrelated to what they mean
> > for the built-in types.
>
> I repeat: Your thinking like this limits D's viability for
> real-world code.
>
> Yes, I understand, the reason operator overloading works the way
> it does now is because members of the community wanted to
> arbitrarily limit programmers working in the language. Because
> they believed theirs was the singular appropriate way to use the
> language, to the exclusion of all others.
>
> I'm opinionated too, but I also have the presence of mind to
> recognize that my opinions are not universal, and they are
> certainly no basis for imposing arbitrary limits upon another
> person's behavior.

Except that the limits aren't arbitrary. Walter designed D's overloaded
operators for a specific purpose - to mimic the built-in operators. If you
want to make them do something else, and you're able to do so with how
they're designed, then that's your choice, but that's not what they're
designed for, and there is no attempt to support it.

You could just as easily ask why D's overloaded operators don't support
arbitrary operators, allowing you do stuff like opBinary!"#" to support # in
your code and complain that the current limitation on that is arbitary. The
feature _could_ have been made to do something like that, but that wasn't
its intended purpose, and there are reasons why it's a bad idea, so that's
not how D's operator overloading was designed.

The comparison operators have a specific purpose, and the functions for
overloading them were designed with that in mind. It just so happens that
that conflicts with what you want to do, but that doesn't mean that the
limitation is arbitrary. Rather, code correctness and conciseness of code
was valued, so they were overloaded using functions that could be used to
derive those operators rather than explicitly overloading each operator
individually. And because the ability to overload operators to do aribtrary
stuff was never one of the goals of the design, the fact that having
functions like opEquals and opCmp conflicted with the ability to overload
each comparison operator to do arbitrary stuff was not considered to be a
problem.

It's a design tradeoff that just doesn't happen to be in line with what you
want to do.

Just because C++ overloaded operators in a way that happens to support doing
arbitrary stuff with all of them doesn't mean that D needs to or that the
restriction is arbitrary.

> On Thursday, 29 September 2016 at 19:39:35 UTC, Jonathan M Davis
>
> wrote:
> > And there are plenty of folks who think that overloading
> > operators to do stuff fundamentally different from how they
> > work for the built-in types is bad practice and consider it to
> > be an abuse of operator overloading. So, the fact that D limits
> > that is going to be viewed as positive by many folks.
>
> Let me see if I understand your thinking:
>
> What you're saying is that because some people may not want to
> use a feature in a specific way, D should disallow anyone from
> using the feature in that way? That, somehow, contrary to logic,
> you believe this contributes positively to D's usability and
> appeal?

There are plenty of folks who think that overloading operators to mean
anything other than what they mean for the built-in types is bad practice.
Walter seems to be in agreement with that. So, when he designed D's operator
overloading, he did not attempt to support that. He didn't do a lot to
prevent it either, but in cases where it made sense to derive multiple
operators from a single function, he did so, even if it meant that you then
couldn't overload those operators to mean something other than what they
meant for the built-in types, because he considered what you got out of
combining them was worth far more than trying to support what many think is
bad practice.

t's not like Walter sat down and tried to prevent every misuse of operator
overloading. He simply didn't choose a design that fully supports such
misuse. Rather, he chose a design that better supports the intended use.
The tradeoff just so happens to leave you without being able to do something
that he considers to be bad practice, so he doesn't see it as a loss. And
neither do I. But that wasn't even the primary goal of why the operators
work they do. It's just a side effect of there being design goals that were
better served by a design that happened to inhibit operator overloading
abuse.

You'd have a much better argument if the language 

Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread pineapple via Digitalmars-d
On Thursday, 29 September 2016 at 19:39:35 UTC, Jonathan M Davis 
wrote:
The reality of the matter is that D's operator overloading was 
designed specifically so that you could overload the built-in 
operators to be used with your own types so that they could act 
like the built-in types. It was not intended or designed to 
allow for the symbols use for those operators to then be used 
for other arbitrary stuff that's unrelated to what they mean 
for the built-in types.


I repeat: Your thinking like this limits D's viability for 
real-world code.


Yes, I understand, the reason operator overloading works the way 
it does now is because members of the community wanted to 
arbitrarily limit programmers working in the language. Because 
they believed theirs was the singular appropriate way to use the 
language, to the exclusion of all others.


I'm opinionated too, but I also have the presence of mind to 
recognize that my opinions are not universal, and they are 
certainly no basis for imposing arbitrary limits upon another 
person's behavior.


On Thursday, 29 September 2016 at 19:39:35 UTC, Jonathan M Davis 
wrote:
And there are plenty of folks who think that overloading 
operators to do stuff fundamentally different from how they 
work for the built-in types is bad practice and consider it to 
be an abuse of operator overloading. So, the fact that D limits 
that is going to be viewed as positive by many folks.


Let me see if I understand your thinking:

What you're saying is that because some people may not want to 
use a feature in a specific way, D should disallow anyone from 
using the feature in that way? That, somehow, contrary to logic, 
you believe this contributes positively to D's usability and 
appeal?




Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Minty Fresh via Digitalmars-d
On Thursday, 29 September 2016 at 19:39:35 UTC, Jonathan M Davis 
wrote:
The language can't stop you from doing at least some arbitrary 
stuff with them (like making + do subtraction), but the whole 
goal was for user-defined types to be able to act like the 
built-in types, and as such, it would make no sense to alter 
them towards being treated like symbols that you can do 
whatever you want with.


Having `+` do subtraction isn't something you'd normally see. 
It's not a use case that would normally exist.


Having `+` do addition, but do so in a database layer is a use 
case that actually may exist. The operator still behaves like a 
built-in type. It may perform addition as part of a SQL query, 
for example.


Whether the expression `a + b` is translated into machine 
language, or translated into SQL, both still perform addition. A 
value represented by `a` is added to a value represented by `b`. 
Whether `a` and `b` are variables in D, or columns in a database 
table is irrelevant.


And as it stands, D can already do this. It's the inability to 
perform an equivalent action for the expression `a > b`.


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Timon Gehr via Digitalmars-d

On 29.09.2016 18:41, Sai wrote:

I.e. you can overload '+' to do bad things. Yes, you can, and as I
replied upthread that can be done because there's no way to prevent
that while having operator overloading at all.

But that is not justification for allowing such disasters for the
comparison operators. I.e. one weakness is not justification for
opening the door to all weakness.


If I understand the issue correctly, one will not be able to overload
<=, >, etc for symbolic math, like CAS (mimicking mathematica for
example), how can I do it now?

Wouldn't the current rules discourage someone from implementing CAS like
library in D?




Not really, but it's annoying.


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Jonathan M Davis via Digitalmars-d
On Thursday, September 29, 2016 19:11:55 pineapple via Digitalmars-d wrote:
> On Thursday, 29 September 2016 at 18:38:42 UTC, Jonathan M Davis
>
> wrote:
> > You just can't use overloaded operators for it, since it would
> > not be in line with what the operators are supposed to mean and
> > be used for.
>
> This is not a valid argument because what an operator is
> "supposed to mean" is up to the programmer who wishes to
> implement that operator for their data type. Not up to me. Not up
> to you.
>
> Your thinking like this limits D's viability for real-world code.
> Programmers do not care how you think they are supposed to use
> the language. They care only that they can get their job done in
> a way that makes sense to them. What makes sense to them will not
> be the same as what makes sense to you. Relinquish the notion
> that you or anyone can have the slightest idea what any language
> feature is "supposed to mean and be used for".

Every language feature is designed with a purpose. Sometimes that purpose is
broader than other times. And once the feature is there, you can do whatever
is legal to do with the feature whether that was really what it was intended
for or not, but if what you're trying to do goes against what the feature
was designed for, don't expect to get support for making it do more stuff
that goes against why it's in the language in the first place - especially
when plenty of folks think that what you're trying to do is bad practice.

The reality of the matter is that D's operator overloading was designed
specifically so that you could overload the built-in operators to be used
with your own types so that they could act like the built-in types. It was
not intended or designed to allow for the symbols use for those operators to
then be used for other arbitrary stuff that's unrelated to what they mean
for the built-in types. The decisions made in how the operators are
overloaded were geared entirely towards better supporting having your types
act like built-in types, and none of it was designed with the idea that you
would do arbitrary stuff via overloading the operators (which is why the
language does stuff like derive some operators from others; it supports the
goal of making them work like the built-in types, and supporting arbitrary
usage of those operators was never a goal, so losing out on the ability is
not considered to be a problem). The language can't stop you from doing at
least some arbitrary stuff with them (like making + do subtraction), but the
whole goal was for user-defined types to be able to act like the built-in
types, and as such, it would make no sense to alter them towards being
treated like symbols that you can do whatever you want with.

And there are plenty of folks who think that overloading operators to do
stuff fundamentally different from how they work for the built-in types is
bad practice and consider it to be an abuse of operator overloading. So, the
fact that D limits that is going to be viewed as positive by many folks.

You're obviously free to do whatever you want with overloaded operators in D
within the bounds of how they work, but we're not going to change them with
the goal of making them less restrictive about mimicking the operators for
the built-in types when the entire reason that they're in the language is to
mimic the operators for the built-in types. And if you do try and make them
work differently than for the built-in types, then your code is likely to be
considered by many to be following bad programming practices.

- Jonathan M Davis



Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Minty Fresh via Digitalmars-d

On Thursday, 29 September 2016 at 19:11:55 UTC, pineapple wrote:
Relinquish the notion that you or anyone can have the slightest 
idea what any language feature is "supposed to mean and be used 
for".


Basically what led to D's CTFE implementation in the first place, 
IIRC.


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread pineapple via Digitalmars-d
On Thursday, 29 September 2016 at 18:38:42 UTC, Jonathan M Davis 
wrote:

You just can't use overloaded operators for it, since it would
not be in line with what the operators are supposed to mean and
be used for.


This is not a valid argument because what an operator is 
"supposed to mean" is up to the programmer who wishes to 
implement that operator for their data type. Not up to me. Not up 
to you.


Your thinking like this limits D's viability for real-world code. 
Programmers do not care how you think they are supposed to use 
the language. They care only that they can get their job done in 
a way that makes sense to them. What makes sense to them will not 
be the same as what makes sense to you. Relinquish the notion 
that you or anyone can have the slightest idea what any language 
feature is "supposed to mean and be used for".




Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Matthias Bentrup via Digitalmars-d
On Thursday, 29 September 2016 at 18:38:42 UTC, Jonathan M Davis 
wrote:


Then you could always do something like a.myOp!"<"(b) and 
a.myOp!">="(b) if you still want to have the operator in there 
somewhere. You can name the functions whatever you want. You 
just can't use overloaded operators for it, since it would not 
be in line with what the operators are supposed to mean and be 
used for.


- Jonathan M Davis


Also with mixins and a CTFE D parser you could replace the 
operators by any desired function calls.





Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Jonathan M Davis via Digitalmars-d
On Thursday, September 29, 2016 18:14:22 Minty Fresh via Digitalmars-d wrote:
> On Thursday, 29 September 2016 at 18:07:37 UTC, Russel Winder
>
> wrote:
> > On Thu, 2016-09-29 at 10:52 -0700, Walter Bright via
> >
> > Digitalmars-d wrote:
> >> On 9/29/2016 9:41 AM, Sai wrote:
> >> > If I understand the issue correctly, one will not be able to
> >> > overload <=, >, etc
> >> > for symbolic math, like CAS (mimicking mathematica for
> >> > example),
> >> > how can I do it
> >> > now?
> >>
> >> a.isLessThan(b)
> >
> > How wonderfully Java.
>
> Personally, I'm amused because this implies the prospect of:
>
>a.isGreaterThanOrEqualTo(b)
>
> I mean, there is an acceptable level of verbosity. This is not it.

Then you could always do something like a.myOp!"<"(b) and a.myOp!">="(b) if
you still want to have the operator in there somewhere. You can name the
functions whatever you want. You just can't use overloaded operators for it,
since it would not be in line with what the operators are supposed to mean
and be used for.

- Jonathan M Davis



Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Minty Fresh via Digitalmars-d
On Thursday, 29 September 2016 at 18:07:37 UTC, Russel Winder 
wrote:
On Thu, 2016-09-29 at 10:52 -0700, Walter Bright via 
Digitalmars-d wrote:

On 9/29/2016 9:41 AM, Sai wrote:
> 
> If I understand the issue correctly, one will not be able to

> overload <=, >, etc
> for symbolic math, like CAS (mimicking mathematica for 
> example),

> how can I do it
> now?


a.isLessThan(b)


How wonderfully Java.


Personally, I'm amused because this implies the prospect of:

  a.isGreaterThanOrEqualTo(b)

I mean, there is an acceptable level of verbosity. This is not it.


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Russel Winder via Digitalmars-d
On Thu, 2016-09-29 at 10:52 -0700, Walter Bright via Digitalmars-d
wrote:
> On 9/29/2016 9:41 AM, Sai wrote:
> > 
> > If I understand the issue correctly, one will not be able to
> > overload <=, >, etc
> > for symbolic math, like CAS (mimicking mathematica for example),
> > how can I do it
> > now?
> 
> 
> a.isLessThan(b)

How wonderfully Java.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Walter Bright via Digitalmars-d

On 9/29/2016 9:41 AM, Sai wrote:

If I understand the issue correctly, one will not be able to overload <=, >, etc
for symbolic math, like CAS (mimicking mathematica for example), how can I do it
now?



   a.isLessThan(b)



Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Sai via Digitalmars-d
I.e. you can overload '+' to do bad things. Yes, you can, and 
as I replied upthread that can be done because there's no way 
to prevent that while having operator overloading at all.


But that is not justification for allowing such disasters for 
the comparison operators. I.e. one weakness is not 
justification for opening the door to all weakness.


If I understand the issue correctly, one will not be able to 
overload <=, >, etc for symbolic math, like CAS (mimicking 
mathematica for example), how can I do it now?


Wouldn't the current rules discourage someone from implementing 
CAS like library in D?





Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread rikki cattermole via Digitalmars-d

On 30/09/2016 2:18 AM, Jacob Carlborg wrote:

On 2016-09-29 14:57, rikki cattermole wrote:

Me and Cauterite were toying with the idea of AST macros but in a
completely new form a while ago.

Below is the usage of it.

Something you'll notice about it is that it could turn the asm block
into a library solution (which is clearly what we'd want anyway). Not to
mention Linq style queries.

In theory it shouldn't be too complex to implement since you are only
doing basic checks to determine if to parse the given statement / block
to a rewriter function.

```D
void main() {
// \/ parsed by iasm.c by matches {}'s and sending contents to it
asm {
...
}

import linq;
@Linq
DataSource source = ...;
Tree[] trees = source.trees.where(name = "abc").limit(20);

import Assembly_x86;

asm {
...
}
}

struct Linq {
string __ast(OnType, ExpectedType)(string statement) {
assert(statement == "source.trees.where(name =
"abc").limit(20);");
static assert(OnType == DataSource);
static assert(ExpectedType == Tree[]);
}
}

// Assembly_x86.d

struct X86 {}
struct ASM {

string __ast(OnType, ExpectedType)(string statement) {
assert(statement == "asm {\n...\n};");
static assert(OnType == X86);
static assert(ExpectedType == void);
}
}

@ASM
X86 asm;
```


Hmm, I find this to be somewhat difficult to follow. You get the AST as
a string? Which means you need to implement a parser. How will the macro
invocation be transformed? Return a string from the macro which will be
reparsed by the compiler and inserted at the call site?


I'll expand on what I wrote above.

There are two kinds of invocations here. Blocks and statements.
Statements are the type of thing you expect from e.g. Linq. Where as 
blocks would be what asm would be defined as being.


The invocation defines where the start/end of the input file to be 
passed to __ast is and that is all it does.


In each case, if the first token (or for assignment statements the first 
token of the expression) is a variable that happens to have a UDA on it 
with __ast member it will pass said invocation text directly to it. What 
ever that may be.


As far as guarantees go for the input, it will always end in a 
semicolon. To determine if it was a statement vs a block just check if 
ExpectedType is void.


So something like:

```D
 @Linq
 DataSource source = ...;
 Tree[] trees = source.trees.where(name = "abc").limit(20);
```

Could be transformed into:

```D
@Linq
DataSource source = ...;
Tree[] trees = mixin(__traits(getAttributes, 
source)[0].__ast("source.trees.where(name = "abc").limit(20);"));

```

They key here is explicitly marking non-vanilla-D-code as such without 
adding syntax like ``macro{ stuff here }``.


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Minty Fresh via Digitalmars-d
On Thursday, 29 September 2016 at 12:54:54 UTC, Jacob Carlborg 
wrote:

BTW, there's a CTFE parser generator for D around somewhere.


And that will handle all that the DMD parser does? I don't 
think so.


I agree with this entirely. Lest you have an entire D compiler 
implemented in CTFE (reductio ad absurdum), you're working with a 
limited subset of the language, and pose additional challenges 
for a developer trying to debug.


Not to mention that string mixins render IDE features like code 
completion and error highlighting essentially unusable.


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Jacob Carlborg via Digitalmars-d

On 2016-09-29 14:57, rikki cattermole wrote:

Me and Cauterite were toying with the idea of AST macros but in a
completely new form a while ago.

Below is the usage of it.

Something you'll notice about it is that it could turn the asm block
into a library solution (which is clearly what we'd want anyway). Not to
mention Linq style queries.

In theory it shouldn't be too complex to implement since you are only
doing basic checks to determine if to parse the given statement / block
to a rewriter function.

```D
void main() {
// \/ parsed by iasm.c by matches {}'s and sending contents to it
asm {
...
}

import linq;
@Linq
DataSource source = ...;
Tree[] trees = source.trees.where(name = "abc").limit(20);

import Assembly_x86;

asm {
...
}
}

struct Linq {
string __ast(OnType, ExpectedType)(string statement) {
assert(statement == "source.trees.where(name = "abc").limit(20);");
static assert(OnType == DataSource);
static assert(ExpectedType == Tree[]);
}
}

// Assembly_x86.d

struct X86 {}
struct ASM {

string __ast(OnType, ExpectedType)(string statement) {
assert(statement == "asm {\n...\n};");
static assert(OnType == X86);
static assert(ExpectedType == void);
}
}

@ASM
X86 asm;
```


Hmm, I find this to be somewhat difficult to follow. You get the AST as 
a string? Which means you need to implement a parser. How will the macro 
invocation be transformed? Return a string from the macro which will be 
reparsed by the compiler and inserted at the call site?


--
/Jacob Carlborg


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Jacob Carlborg via Digitalmars-d

On 2016-09-29 11:31, pineapple wrote:


This is not an argument to justify adding just any feature, it's an
argument that it is idiocy to give a programmer a powerful tool, and
then impose arbitrary limitations upon how they are allowed to use it.

One of the most popular topics of discussion in this forum is "Why is D
not more widely adopted?" and "What can we do to get broader adoption
for D?"

Perhaps one of the more obvious answers is: Do not prevent programmers
from doing something solely on the basis that _you_ would not want to do
it.

I think camelCase is hideous, but does that mean I should forbid another
programmer defining symbols in that style? Of course not. That they are
able to write their code that way doesn't mean I have to, and doesn't
mean I have to use or interface with their code. I agree that '+' should
always mean addition and '~' should always mean concatenation, but does
that mean I should forbid another programmer from defining them
differently? Of course not. Just because they are able to do it that way
doesn't mean I have to, or that I have to use their code.

If I thought '>' and '<' should always mean arithmetic comparison, does
that mean I should forbid another programmer from defining them
differently?

You need to understand that _you are not the only one writing code in
this language_. Your use cases do not summarize all possible use cases.
That you do not need to use a tool in a specific way is not a valid
argument against allowing others to use the tool that way.

Give us a rational argument. We are unconcerned with your personal
dogma. What you refer to as a weakness I view as a strength. Programmers
require more flexibility and expressiveness, not less.


Well said.

--
/Jacob Carlborg


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread rikki cattermole via Digitalmars-d
Me and Cauterite were toying with the idea of AST macros but in a 
completely new form a while ago.


Below is the usage of it.

Something you'll notice about it is that it could turn the asm block 
into a library solution (which is clearly what we'd want anyway). Not to 
mention Linq style queries.


In theory it shouldn't be too complex to implement since you are only 
doing basic checks to determine if to parse the given statement / block 
to a rewriter function.


```D
void main() {
// \/ parsed by iasm.c by matches {}'s and sending contents to it
asm {
...
}

import linq;
@Linq
DataSource source = ...;
Tree[] trees = source.trees.where(name = "abc").limit(20);

import Assembly_x86;

asm {
...
}
}

struct Linq {
string __ast(OnType, ExpectedType)(string statement) {
assert(statement == "source.trees.where(name = "abc").limit(20);");
static assert(OnType == DataSource);
static assert(ExpectedType == Tree[]);
}
}

// Assembly_x86.d

struct X86 {}
struct ASM {

string __ast(OnType, ExpectedType)(string statement) {
assert(statement == "asm {\n...\n};");
static assert(OnType == X86);
static assert(ExpectedType == void);
}
}

@ASM
X86 asm;
```


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Jacob Carlborg via Digitalmars-d

On 2016-09-29 09:58, Walter Bright wrote:


I.e. you can overload '+' to do bad things. Yes, you can, and as I
replied upthread that can be done because there's no way to prevent that
while having operator overloading at all.

But that is not justification for allowing such disasters for the
comparison operators. I.e. one weakness is not justification for opening
the door to all weakness.


You're using the same justification when rejecting most feature requests 
you don't like: you had one bad experience with C++ and therefore it 
must be banned for all eternity. It's not a valid argument.



Interestingly, by shutting the door on misuse of the comparison
operators, it seems D has been successful in discouraging nutburger
designs like overloading '+' to mean 'OR'.


It's also shutting the door on doing a lot of useful things. My goal is 
no to use the comparison operators to mean something different than 
comparison. The goal is, for example, to build a corresponding SQL query 
out of an expression. But the == operator would still be used for equality.


One major issue with using string literals is, if we use the SQL query 
as an example again, as follows:


First try:

auto bar = `"bar"`;
auto query = "SELECT * FROM foo WHERE bar = " ~ bar;

Is have the issue of SQL injection.

Second try:

auto bar = "bar";
auto foo = "foo";
auto q = query("SELECT * FROM foo WHERE bar = $1 AND foo = $2", bar, foo);

This has the issue that the value and the place of where a value is used 
far away from each other in the code making it more difficult to read. 
This was "solved" in Rails by using an associative array mapping the 
column names to the values:


foo = "foo"
bar = "bar"
Foo.where(bar: bar, foo: foo)

That has the issue of only working with equality and "AND". Now way to 
do less than or "OR".


Third try:

auto foo = "foo";
auto bar = "bar";
Foo.where(q => q.foo == foo && q.bar == "bar");

The above expression would be translated to the query in the second 
example, with the values properly escaped. Now this is how I want the 
code to look like.



The language you just provide a set of tools, then it's up the to the
programmer
to do what he/she wants to do.


That can be used to justify any feature at all.



I know you really want AST macros for D. We've discussed that at length
before.

BTW, there's a CTFE parser generator for D around somewhere.


And that will handle all that the DMD parser does? I don't think so.

--
/Jacob Carlborg


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread pineapple via Digitalmars-d
On Thursday, 29 September 2016 at 12:20:42 UTC, Russel Winder 
wrote:
Opinionated is not always bad. Look at Go, the developers know 
that
there is no sane way of doing generics so they ban it. Also 
they know
that exceptions are totally incomprehensible to all programmers 
so they

ban them. Rust developers know that all memory handling must be
explicit all the world falls apart. Opinionated languages 
clearly get
traction – not usually because of the opinions, it has to be 
said, more
usually because of the amount of money thrown at marketing. 
Except

Python, obviously.


Reminds me of this - 
https://twitter.com/paniq/status/757951588057096192


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Russel Winder via Digitalmars-d
On Thu, 2016-09-29 at 11:50 +, Minty Fresh via Digitalmars-d wrote:
> On Thursday, 29 September 2016 at 11:29:55 UTC, Russel Winder 
> wrote:
> > 
> > However, this has come up many times, and every time Walter 
> > says "no, it's wrong". Whilst the C++ iostreams << may have 
> > problems, using this as a single point argument as to why 
> > overloading fails in all other cases except numeric arithmetic 
> > is bad philosophy. In my view this is holding D back.
> 
> To add some thoughts to this,
> 
> The use of << being bad is purely a matter of opinion.
> If you believe that << is to only be used for bit-shifting 
> operations, you might hold the view that it is bad.

But, but, but, << means very much less than, everyone knows this. What
is this bitshifting of which you speak.

!

> On the other hand, if you come from a background like Haskell or 
> Ruby, you might have a very different opinion.

Is there anyone from an Haskell background here. :-) Anyway everyone
who wants to make Haskell code mainstream is using Frege.

> ie.
> In Ruby, << is named the shovel operator. It's uses are things 
> like appending an element into an Array.

Groovy, and indeed Python, likewise. We ignore the mess Algol68 and
Scala have got themselves into with this.

> 
> Hence, a less opinionated point is necessary here.

Opinionated is not always bad. Look at Go, the developers know that
there is no sane way of doing generics so they ban it. Also they know
that exceptions are totally incomprehensible to all programmers so they
ban them. Rust developers know that all memory handling must be
explicit all the world falls apart. Opinionated languages clearly get
traction – not usually because of the opinions, it has to be said, more
usually because of the amount of money thrown at marketing. Except
Python, obviously.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Russel Winder via Digitalmars-d
On Wed, 2016-09-28 at 21:15 -0700, Walter Bright via Digitalmars-d
wrote:
> On 9/28/2016 1:40 PM, Timon Gehr wrote:
> > 
> > What's wrong with that usage?
> 
> Because then something other than comparison is happening with <=, <,
> >, >= and 
> there'll be nothing in the code to give the user a hint.

This is a very "tunnel vision" view of programming language and the way
programs are constructed and perceived. But sadly I know we have been
round this many times, and you will not be changing you viewpoint. But
even though I know nothing will change, I feel required to take on the
challenge again. Until you cite psychology of programming experimental
data to back up any position, it is all just opinion and personal
experience. I am happy with << as very much less than, or output
depending on context, you are not. But it is bad philosophy for me to
say << is comprehensible to me and so it is comprehensible to everyone,
and equally bad philosophy for you to say the same with
s/comprehensible/incomprehensible/.

This sort of thing happened in Python with the reduce function, leaving
Python 3 in a truly inconsistent position regarding higher order
functions.

So when it comes to writing DSLs I'll stick with Python and Groovy,
until D gets it right.

[…]


-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Minty Fresh via Digitalmars-d
On Thursday, 29 September 2016 at 11:29:55 UTC, Russel Winder 
wrote:
However, this has come up many times, and every time Walter 
says "no, it's wrong". Whilst the C++ iostreams << may have 
problems, using this as a single point argument as to why 
overloading fails in all other cases except numeric arithmetic 
is bad philosophy. In my view this is holding D back.


To add some thoughts to this,

The use of << being bad is purely a matter of opinion.
If you believe that << is to only be used for bit-shifting 
operations, you might hold the view that it is bad.
On the other hand, if you come from a background like Haskell or 
Ruby, you might have a very different opinion.


ie.
In Ruby, << is named the shovel operator. It's uses are things 
like appending an element into an Array.


Hence, a less opinionated point is necessary here.


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Russel Winder via Digitalmars-d
On Wed, 2016-09-28 at 20:30 +, pineapple via Digitalmars-d wrote:
> On Wednesday, 28 September 2016 at 20:16:08 UTC, Walter Bright 
> wrote:
> > 
> > Because there is no way to stop the former but still have 
> > operator overloading.
> > 
> > To reiterate, operator overloading exists in D to support the 
> > inclusion of arithmetic library types. Any other purpose is 
> > discouraged, and that includes expression templates and things 
> > like << for iostreams.
> 
> This is an obsolete way of thinking about operators. Operator 
> overloading exists to make the programmer's life easier, and 
> limiting the ways in which a valuable tool can be used drives 
> people to languages which allow them to be more expressive.

Definitely, yes. 

However, this has come up many times, and every time Walter says "no,
it's wrong". Whilst the C++ iostreams << may have problems, using this
as a single point argument as to why overloading fails in all other
cases except numeric arithmetic is bad philosophy. In my view this is
holding D back.

> For my job I write Python. We use a database layer called 
> sqlalchemy that allows us to express queries by writing, for 
> example, `session.query(some_table).filter(row1 == row2)` and I 
> cannot begin to express how useful this is when writing code, 
> when maintaining code, and when attempting to understand code 
> that someone else wrote.

Definitely. I spend a lot of my time trying to inculcate people into
DSL-based thinking as an extension of abstraction and leading towards
understanding and modelling the solution to problems in the domain.
Python has it's problems, C++ more, but this is a far superior way of
going than the Java approach of "operator overloading is too hard for
programmers to deal with so let's ban it". Hence Groovy, Scala, Kotlin,
Ceylon, etc. all of which bring back this feature Java eschewed from
C++ – possibly because the Oak developers had their problems. 

> The objective should never be to stop the programmer from doing 
> something because you personally dislike the practice.

I guess it depends on whether the language is wanting to gain traction
in the market or remain a pet project.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread pineapple via Digitalmars-d
On Thursday, 29 September 2016 at 07:58:26 UTC, Walter Bright 
wrote:

On 9/28/2016 11:48 PM, Jacob Carlborg wrote:

If that is not allowed, why is this allowed:


I.e. you can overload '+' to do bad things. Yes, you can, and 
as I replied upthread that can be done because there's no way 
to prevent that while having operator overloading at all.


But that is not justification for allowing such disasters for 
the comparison operators. I.e. one weakness is not 
justification for opening the door to all weakness.


Interestingly, by shutting the door on misuse of the comparison 
operators, it seems D has been successful in discouraging 
nutburger designs like overloading '+' to mean 'OR'.


The language you just provide a set of tools, then it's up the 
to the programmer

to do what he/she wants to do.


That can be used to justify any feature at all.


This is not an argument to justify adding just any feature, it's 
an argument that it is idiocy to give a programmer a powerful 
tool, and then impose arbitrary limitations upon how they are 
allowed to use it.


One of the most popular topics of discussion in this forum is 
"Why is D not more widely adopted?" and "What can we do to get 
broader adoption for D?"


Perhaps one of the more obvious answers is: Do not prevent 
programmers from doing something solely on the basis that _you_ 
would not want to do it.


I think camelCase is hideous, but does that mean I should forbid 
another programmer defining symbols in that style? Of course not. 
That they are able to write their code that way doesn't mean I 
have to, and doesn't mean I have to use or interface with their 
code. I agree that '+' should always mean addition and '~' should 
always mean concatenation, but does that mean I should forbid 
another programmer from defining them differently? Of course not. 
Just because they are able to do it that way doesn't mean I have 
to, or that I have to use their code.


If I thought '>' and '<' should always mean arithmetic 
comparison, does that mean I should forbid another programmer 
from defining them differently?


You need to understand that _you are not the only one writing 
code in this language_. Your use cases do not summarize all 
possible use cases. That you do not need to use a tool in a 
specific way is not a valid argument against allowing others to 
use the tool that way.


Give us a rational argument. We are unconcerned with your 
personal dogma. What you refer to as a weakness I view as a 
strength. Programmers require more flexibility and 
expressiveness, not less.




Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Timon Gehr via Digitalmars-d

On 29.09.2016 06:15, Walter Bright wrote:

On 9/28/2016 1:40 PM, Timon Gehr wrote:

What's wrong with that usage?


Because then something other than comparison is happening with <=,


You also complained about '+'.


<, >,

= and there'll be nothing in the code to give the user a hint.

...


Actually, comparison is precisely what is happening. The hint about what 
is happening precisely is that the entire codebase does symbolic 
computations all over the place, and it is very clear what the involved 
types are.





(This is NOT expression templates.)


Right, but it's an enabler of expression templates. Discussion of more
powerful operator overloading cannot be divorced from expression
templates, and once ETs are in we'll be stuck with them forever.
...


They work today, just not with comparison operators.



D has many very powerful modeling abilities, but so far we've tried to
stay away from things that make context-free user understanding of code
unduly difficult. It should not be necessary to use an IDE to understand
code.
...


That is and has always been the responsibility of the programmer. (IDEs 
don't even help that much.)



In that category are things like text macros, AST macros, user-defined
syntax, non-arithmetic operator overloading, and expression templates.


What's the definition of "arithmetic" here?


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Walter Bright via Digitalmars-d

On 9/28/2016 11:48 PM, Jacob Carlborg wrote:

If that is not allowed, why is this allowed:


I.e. you can overload '+' to do bad things. Yes, you can, and as I replied 
upthread that can be done because there's no way to prevent that while having 
operator overloading at all.


But that is not justification for allowing such disasters for the comparison 
operators. I.e. one weakness is not justification for opening the door to all 
weakness.


Interestingly, by shutting the door on misuse of the comparison operators, it 
seems D has been successful in discouraging nutburger designs like overloading 
'+' to mean 'OR'.




The language you just provide a set of tools, then it's up the to the programmer
to do what he/she wants to do.


That can be used to justify any feature at all.



The use of them to create DSLs (a technique called "expression
templates" in C++) is discouraged in D, for several reasons. The
recommended way to create DSLs in D is to parse strings using CTFE.


That's one of the ugliest things about D. Because suddenly you will not have any
help of any tools, like editors, IDEs, linters, syntax analysis and so on. One
also needs to implement a complete parser, how many complete parsers do we have
for D?


I know you really want AST macros for D. We've discussed that at length before.

BTW, there's a CTFE parser generator for D around somewhere.


Re: Overloading relational operators separately; thoughts?

2016-09-29 Thread Jacob Carlborg via Digitalmars-d

On 2016-09-28 06:02, Walter Bright wrote:


The limitations are deliberate based on the idea that comparison
operators need to be consistent and predictable, and should have a close
relationship to the mathematical meaning of the operators. Overloading
<= to mean something other than "less than or equal" is considered poor
style in D, and the same goes for the other arithmetic operators.


If that is not allowed, why is this allowed:

struct MyInt
{
int value;

MyInt opBinary(string op)(MyInt rhs) if (op == "+")
{
return MyInt(value - rhs.value);
}
}

assert(MyInt(3) + MyInt(3) == MyInt(0));

The language you just provide a set of tools, then it's up the to the 
programmer to do what he/she wants to do.



The use of them to create DSLs (a technique called "expression
templates" in C++) is discouraged in D, for several reasons. The
recommended way to create DSLs in D is to parse strings using CTFE.


That's one of the ugliest things about D. Because suddenly you will not 
have any help of any tools, like editors, IDEs, linters, syntax analysis 
and so on. One also needs to implement a complete parser, how many 
complete parsers do we have for D?


--
/Jacob Carlborg


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Jonathan M Davis via Digitalmars-d
On Wednesday, September 28, 2016 21:15:32 Walter Bright via Digitalmars-d 
wrote:
> Because then something other than comparison is happening with <=, <, >, >=
> and there'll be nothing in the code to give the user a hint.
[snip]
> D has many very powerful modeling abilities, but so far we've tried to stay
> away from things that make context-free user understanding of code unduly
> difficult. It should not be necessary to use an IDE to understand code.

A related issue is generic code. Having the same operator or function name
mean essentially the same thing for every type that has it is required for
generic code to work. To some extent, that's also checked by having the
semantics of the code checked (e.g. that front returns something as opposed
to being void or that popFront takes no arguments), but there's only so
much that can be done there. And no, even then, you can't guarantee that the
function in question operates the way that the generic code expects. But if
common function names mean the same thing and act the same way for types in
general, then they play well with generic code, whereas as soon as someone
takes a common function and makes it do something different from what's
normal, it does not play well with generic code at all.

Overloaded operators are the prime example of this, because there is a clear
expectation for what their basic behaviors are, and they're functions that
are built into the language. Next in line would be extremely common idioms
such as the range-based functions. Once you start getting to less common
stuff, then the issue of whether a function with a particular name acts the
same way in one library as another is significantly diminished, but for the
common stuff, it's critical for generic code that folks don't go and make
common functions operate in a way that is inconsistent with how they would
function on most every other type out there and how everyone is going to
expect them to behave when they see them.

Having a type implement something like expression templates is an utter
disaster for generic code, just like it's a disaster if front does something
like call popFront every time that it's called. Consistent semantics for
common functions is very important for generic code as well as for code
legibility and maintainability.

- Jonathan M Davis



Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Mike Parker via Digitalmars-d

On Thursday, 29 September 2016 at 04:39:37 UTC, Minty Fresh wrote:



This applies to operator overloads just like everything else. 
They're just syntactic sugar for functions. Documenting their 
behavior is just as necessary.


I disagree with this. Operators are different in that the symbols 
themselves already have meaning and are a core part of the 
language. When I see a function in code that was written by 
someone else, I have no idea what it really does, no matter how 
it was named, until I pull up the documentation or the source and 
actually read it. I expect that I'm going to have to do that. 
Using operators in ways they were not intended to be used is 
breaking my expectations.


When I'm scanning D code and see a '+', I'm going to think 
addition (and not concatenation or appending or anything else). 
It isn't going to occur to me that the types involved are doing 
something completely different and I ought to look in the 
documentation to see what that is. And I shouldn't have to worry 
about it. That sort of cognitive disruption is really annoying.


In D1, operators were overloaded *by name* and not by symbol. I 
loved that, because it made it quite clear that opAdd is an 
addition and doing something different with it would be akin to 
having a function named printFoo launching an audio player. And 
if printFoo *did* launch an audio player, I'm quite confident 
most programmers would consider the function horribly misnamed. 
The same applies to operators, as I see it.


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Minty Fresh via Digitalmars-d
On Thursday, 29 September 2016 at 04:15:32 UTC, Walter Bright 
wrote:

On 9/28/2016 1:40 PM, Timon Gehr wrote:

What's wrong with that usage?


Because then something other than comparison is happening with 
<=, <, >, >= and there'll be nothing in the code to give the 
user a hint.


There's also nothing to give the user a hint that binary 
arithmetic operators may also not do what they expect them to do.
Going further, there may be nothing to give the user a hint that 
a named function doesn't to what its name suggests.


All of the above are shortcomings in documentation, or short 
comings in implementation.


Even with the current system of using `opCmp`, it's still 
possible to implement these operators such that they behave in a 
way that would confound the user (ie. have their results be 
nondeterministic, external side effects, etc.)


D has many very powerful modeling abilities, but so far we've 
tried to stay away from things that make context-free user 
understanding of code unduly difficult. It should not be 
necessary to use an IDE to understand code.


No, you're right. It's not the responsibility of the IDE to 
perform such tasks. It's the responsibility of the documentation. 
D is already is such a state the language is difficult for a 
context-free user without access to documentation.


Even the standard library. Especially the standard library.
Things like `.each` in std.algorithm returning void, whereas the 
bizarrely named `.tee` in std.range actually retuning the input 
range. Things like the `SList` and `DList` types defined in 
std.container requiring explicit initialization to work. Things 
like the behavior and semantics of type tuples (or alias lists). 
Things like the differences between `.byLine` vs `.byLineCopy` in 
std.stdio.
All of these rely on the developer having documentation. There's 
no way around it. D as a language is already way too complex to 
do anything without it.


This applies to operator overloads just like everything else. 
They're just syntactic sugar for functions. Documenting their 
behavior is just as necessary.


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Walter Bright via Digitalmars-d

On 9/28/2016 1:40 PM, Timon Gehr wrote:

What's wrong with that usage?


Because then something other than comparison is happening with <=, <, >, >= and 
there'll be nothing in the code to give the user a hint.




(This is NOT expression templates.)


Right, but it's an enabler of expression templates. Discussion of more powerful 
operator overloading cannot be divorced from expression templates, and once ETs 
are in we'll be stuck with them forever.



D has many very powerful modeling abilities, but so far we've tried to stay away 
from things that make context-free user understanding of code unduly difficult. 
It should not be necessary to use an IDE to understand code.


In that category are things like text macros, AST macros, user-defined syntax, 
non-arithmetic operator overloading, and expression templates.


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Minty Fresh via Digitalmars-d

On Wednesday, 28 September 2016 at 20:40:49 UTC, Timon Gehr wrote:

This is not surprising. C++ has no good options.


This is further made worse by some C++'s more inane design 
decisions (ie. allowing overloading of the comma operator).


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Timon Gehr via Digitalmars-d

On 28.09.2016 22:16, Walter Bright wrote:

On 9/28/2016 6:58 AM, Timon Gehr wrote:

An excellent example of that is the std.regex package.

It's actually a bad example, because it is irrelevant: it is obviously
a bad
idea to implement regex using operator overloading, because the regex
operators
have no D equivalent.


Yet this "obviously bad" idea regularly resurfaces as a cool use of
expression templates and respected people in the industry like it and
advocate it.
...


This is not surprising. C++ has no good options.




Assume I have two symbolic expressions a and b:

Expression a=variable("a"), b=variable("b");

Why should I be allowed to do

auto c = a + b; // symbolic value a + b

but not

auto d = a <= b; // symbolic value a <= b


Because there is no way to stop the former but still have operator
overloading.
...


What's wrong with that usage? (This is NOT expression templates.)




The string parsing approach is not useful here: how do I use existing
expressions that are accessible in the scope to build new expressions?


You seem to be asking for expression templates.


No. It's symbolic computation at run time. Think Wolfram Mathematica.


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Minty Fresh via Digitalmars-d
On Wednesday, 28 September 2016 at 20:16:08 UTC, Walter Bright 
wrote:
To reiterate, operator overloading exists in D to support the 
inclusion of arithmetic library types. Any other purpose is 
discouraged, and that includes expression templates and things 
like << for iostreams.


It seeds rather harsh to discourage every possible use case of a 
feature sans one, simply because one does not agree with the 
others.




Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread pineapple via Digitalmars-d
On Wednesday, 28 September 2016 at 20:16:08 UTC, Walter Bright 
wrote:
Because there is no way to stop the former but still have 
operator overloading.


To reiterate, operator overloading exists in D to support the 
inclusion of arithmetic library types. Any other purpose is 
discouraged, and that includes expression templates and things 
like << for iostreams.


This is an obsolete way of thinking about operators. Operator 
overloading exists to make the programmer's life easier, and 
limiting the ways in which a valuable tool can be used drives 
people to languages which allow them to be more expressive.


For my job I write Python. We use a database layer called 
sqlalchemy that allows us to express queries by writing, for 
example, `session.query(some_table).filter(row1 == row2)` and I 
cannot begin to express how useful this is when writing code, 
when maintaining code, and when attempting to understand code 
that someone else wrote.


The objective should never be to stop the programmer from doing 
something because you personally dislike the practice.




Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Walter Bright via Digitalmars-d

On 9/28/2016 6:58 AM, Timon Gehr wrote:

An excellent example of that is the std.regex package.

It's actually a bad example, because it is irrelevant: it is obviously a bad
idea to implement regex using operator overloading, because the regex operators
have no D equivalent.


Yet this "obviously bad" idea regularly resurfaces as a cool use of expression 
templates and respected people in the industry like it and advocate it.




Assume I have two symbolic expressions a and b:

Expression a=variable("a"), b=variable("b");

Why should I be allowed to do

auto c = a + b; // symbolic value a + b

but not

auto d = a <= b; // symbolic value a <= b


Because there is no way to stop the former but still have operator overloading.



The string parsing approach is not useful here: how do I use existing
expressions that are accessible in the scope to build new expressions?


You seem to be asking for expression templates. They do actually work in D, but 
I recommend against them.


To reiterate, operator overloading exists in D to support the inclusion of 
arithmetic library types. Any other purpose is discouraged, and that includes 
expression templates and things like << for iostreams.


AST macros are an alternative to expression templates. Having AST macros has 
been proposed before multiple times, and has been debated at length. I haven't 
seen any new information that would justify reopening the issue.


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Minty Fresh via Digitalmars-d
On Wednesday, 28 September 2016 at 04:02:59 UTC, Walter Bright 
wrote:
The use of them to create DSLs (a technique called "expression 
templates" in C++) is discouraged in D, for several reasons. 
The recommended way to create DSLs in D is to parse strings 
using CTFE.


I don't really come from a C++ background. Actually, I have a 
strong distaste for the language. Professionally, I word with 
Ruby.


Again, string DSLs face a number of issues. A few that come to 
mind are:
  1. A parser + code generator must be implemented, which is a 
lot of additional work.

  2. The quality and precision of error messages degrades.
  3. You loose the ability to perform actions like making 
declarations within the context of the DSL (ie. assigning a 
commonly re-used expression to a variable), unless your DSL is 
turing complete.



An excellent example of that is the std.regex package.


You know, if someone had managed to implement a regex DSL using 
operator overloading, something must have gone _terribly_ wrong. 
Regex is traditionally done in strings, lest the language 
supports regex literals.


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Walter Bright via Digitalmars-d

On 9/28/2016 2:48 AM, Matthias Bentrup wrote:

In Mathematics the comparison operators are also commonly used for semi orders,
which cannot be implemented by opCmp, because opCmp has no way to indicate that
two values are incomparable.

Interestingly the floating point types are semi ordered (due to NaNs), and for
those D has some (non-overridable and deprecated) operators like !<, which would
be easily extendable to any semi order, whereas the suggested replacement (i.e.
test for NaNs manually) works only on floats.


I'm aware of the limitation, and a fair amount of thought was given on it, but 
the solution used generally for unordered is to test for it separately, and 
people seem happy with it.


The !<, etc., operators have been an utter failure (not a failure technically, 
but people found them hopelessly confusing and would not use them).




Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Guillaume Boucher via Digitalmars-d
On Wednesday, 28 September 2016 at 14:27:58 UTC, Chris Wright 
wrote:

Increment, decrement, and
test for equality is sufficient mathematically, but we want 
programs that

terminate in our lifetimes.



Only for BigInts you need those three.  For ints decrement is not 
needed.  And for most other data types increment/decrement is not 
sufficient, e.g. for reals or any kind of vectors/matrices.


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Chris Wright via Digitalmars-d
On Wed, 28 Sep 2016 10:06:43 +, pineapple wrote:
> I think the cleanest possible solution would be to allow comparison
> operators to be overridden with opBinary and opBinaryRight, as well, but
> use opCmp and opEquals instead if they exist. I can't think of any way
> this would break existing code.

What happens with this?

  struct MyInt {
int value;
MyInt opBinary(string op)(MyInt other) {
  return MyInt(mixin("value " ~ op ~ " other.value"));
}
  }

Obvious pattern for wrapping a value. Comparisons used to be unsupported, 
producing an appropriate error message:

  Error: need member function opCmp() for struct MyInt to compare

Now they produce a different, opaque error message, which will have to be 
created, but the current equivalent is:

  Error: recursive opCmp expansion

That's not a breakage, but it is an unfortunate direction for the quality 
of error messages.


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Chris Wright via Digitalmars-d
On Tue, 27 Sep 2016 23:05:54 -0700, Jonathan M Davis via Digitalmars-d
wrote:

> On Wednesday, September 28, 2016 03:28:50 Minty Fresh via Digitalmars-d
> wrote:
>> Lastly, if operators are intended to behave so strictly, why does this
>> not extend then to binary arithmetic operators (+, -, *, /, %, etc.)
>> They don't follow the same rules as the binary relational operators,
>> after all.
> 
> It's not possible in the general case to define the arithmetic operators
> as functions of each other. They actually need to be defined separately
> in order to work.

Specifically for making efficient programs. Increment, decrement, and 
test for equality is sufficient mathematically, but we want programs that 
terminate in our lifetimes.



Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread John Colvin via Digitalmars-d

On Wednesday, 28 September 2016 at 13:58:35 UTC, Timon Gehr wrote:

Assume I have two symbolic expressions a and b:

Expression a=variable("a"), b=variable("b");

Why should I be allowed to do

auto c = a + b; // symbolic value a + b

but not

auto d = a <= b; // symbolic value a <= b

The string parsing approach is not useful here: how do I use 
existing expressions that are accessible in the scope to build 
new expressions?


Thanks for expressing this so clearly. This is exactly the sort 
of thing I want to be able to do.


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Timon Gehr via Digitalmars-d

On 28.09.2016 06:02, Walter Bright wrote:

On 9/27/2016 6:18 PM, Minty Fresh wrote:

So, I'm just interested in other people's thoughts are on the subject,
and
whether there are any plans to allow overloading these operators
separately.


The limitations are deliberate based on the idea that comparison
operators need to be consistent and predictable, and should have a close
relationship to the mathematical meaning of the operators. Overloading
<= to mean something other than "less than or equal" is considered poor
style in D, and the same goes for the other arithmetic operators.
...


The restrictions enforce that <= computes a boolean result. "less than 
or equal" is not necessarily the same as "decide /now/ whether this is 
less than or equal and give me a boolean". The restriction is annoying 
if you are implementing e.g. symbolic algebra. opCmp is a good thing to 
have for the common case, but why disable opBinary?




The use of them to create DSLs (a technique called "expression
templates" in C++) is discouraged in D, for several reasons. The
recommended way to create DSLs in D is to parse strings using CTFE.


One anecdote: In the big-O library discussion, my initial proposal 
relied on string parsing. Andrei promptly criticized this and used 
operator overloading instead.



An excellent example of that is the std.regex package.
...


It's actually a bad example, because it is irrelevant: it is obviously a 
bad idea to implement regex using operator overloading, because the 
regex operators have no D equivalent.


Assume I have two symbolic expressions a and b:

Expression a=variable("a"), b=variable("b");

Why should I be allowed to do

auto c = a + b; // symbolic value a + b

but not

auto d = a <= b; // symbolic value a <= b

The string parsing approach is not useful here: how do I use existing 
expressions that are accessible in the scope to build new expressions?


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Timon Gehr via Digitalmars-d

On 28.09.2016 11:48, Matthias Bentrup wrote:

On Wednesday, 28 September 2016 at 04:02:59 UTC, Walter Bright wrote:

The limitations are deliberate based on the idea that comparison
operators need to be consistent and predictable, and should have a
close relationship to the mathematical meaning of the operators.


In Mathematics the comparison operators are also commonly used for semi
orders, which cannot be implemented by opCmp, because opCmp has no way
to indicate that two values are incomparable.
...


Yes it does.

float opCmp(S rhs){
return float.nan; // incomparable
}



Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread pineapple via Digitalmars-d

I'd also like to point out a generally sound design principle:

Give the programmer as much power and flexibility as possible - 
but don't forget to provide tools for simplifying common use 
cases, and don't forget to define sensible defaults.


It makes a lot of sense that opCmp and opEquals exist, they fit 
the by-far-most-common use case perfectly, but they aren't always 
flexible enough for what the programmer wants to do. What if 
comparison operators should return something other than booleans? 
What if `!=` should be implemented differently from `==`? These 
overrides great tools to have, but it would be better if they 
weren't the only options we had.


Similarly, it makes a lot of sense that postfix operators are 
rewritten in terms of prefix operators, but that's not always 
flexible enough for what the programmer wants to do. It's a great 
default to have, but it would be better if we also had the option 
to define our own distinct behaviors for postfix operators.


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread pineapple via Digitalmars-d
On Wednesday, 28 September 2016 at 03:28:50 UTC, Minty Fresh 
wrote:
Using strings and mixins does have quite a number of downsides. 
The additional work required to past the DSL aside, you also 
usually lose the scope in which things are declared (especially 
if you wish to reference or declare variables/functions/other 
constructs within your DSL), error reporting becomes much less 
precise, and the transition between the outer code and the 
inner DSL becomes jarring (especially in terms of syntax 
highlighting).


That said, I love the fact D has a separate operator for 
concatenation. It's extremely useful to not have that ambiguity.


Another thought is, operators not behaving as expected doesn't 
strike me as a failure of the language, given the language 
supports operator overloading. It's a failure in documentation 
to explain what the operators are intended to do, or a failure 
in implementation to behave as they should.


I agree that opCmp has the benefit of unambiguity, but I still 
think Minty makes very good points.


I think the cleanest possible solution would be to allow 
comparison operators to be overridden with opBinary and 
opBinaryRight, as well, but use opCmp and opEquals instead if 
they exist. I can't think of any way this would break existing 
code.


On Wednesday, 28 September 2016 at 09:48:48 UTC, Matthias Bentrup 
wrote:
In Mathematics the comparison operators are also commonly used 
for semi orders, which cannot be implemented by opCmp, because 
opCmp has no way to indicate that two values are incomparable.


Interestingly the floating point types are semi ordered (due to 
NaNs), and for those D has some (non-overridable and 
deprecated) operators like !<, which would be easily extendable 
to any semi order, whereas the suggested replacement (i.e. test 
for NaNs manually) works only on floats.


It's probably a terrible idea, but I'd love if those FP 
comparison operators would be de-deprecated and made possible to 
overload using opBinary.


On Wednesday, 28 September 2016 at 06:05:54 UTC, Jonathan M Davis 
wrote:
The increment and decrement operators are in a similar boat to 
the comparison operators in that post and pre can be derived 
from a single function. So, it's not just the comparison 
operators that got combined.


Incidentally, I'm a little surprised and disappointed that D 
doesn't allow pre- and postfix operators to be separately 
overloaded. Postfix operators should default to their current 
behavior, where `x` is the same as `auto t = x; x = x; 
return t;` where prefix unary  is defined, but I also think 
it'd be fantastic if we introduced an opUnaryPostfix override. 
(And should that be done, for the sake of clarity, it might be a 
good idea deprecate usage of opUnary in favor of calling the 
method opUnaryPrefix.)






Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Matthias Bentrup via Digitalmars-d
On Wednesday, 28 September 2016 at 04:02:59 UTC, Walter Bright 
wrote:
The limitations are deliberate based on the idea that 
comparison operators need to be consistent and predictable, and 
should have a close relationship to the mathematical meaning of 
the operators.


In Mathematics the comparison operators are also commonly used 
for semi orders, which cannot be implemented by opCmp, because 
opCmp has no way to indicate that two values are incomparable.


Interestingly the floating point types are semi ordered (due to 
NaNs), and for those D has some (non-overridable and deprecated) 
operators like !<, which would be easily extendable to any semi 
order, whereas the suggested replacement (i.e. test for NaNs 
manually) works only on floats.




Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Jacob Carlborg via Digitalmars-d

On 2016-09-28 03:18, Minty Fresh wrote:

Currently, D offers fine grained overloading for most of the unary and
arithmetic binary operators, but at some point a decision was made to
lump together all of the relational operators (and if necessary, the
equality operators) into a single function `opCmp`.
And while it does add a lot of convenience and consistency to how
operators behave, it does also put a lot of limitations on what they can
do.

For example, it's not currently possible to implement comparison
operators that would behave lazily and only compute a certain value once
a function call forces the computation.

Similarly, it's not possible to construct a DSL that would produce code
or a query in another language, by returning values behave like AST
nodes rather than actually performing a comparison.

ie.
  table.users
   .where!((users) => users.joined_on >= 3.days.ago)
   .joins(table.posts)
   .on!((posts, users) => posts.user_id == users.id)
   .limit(10)
   .toSql;

It's a little odd to me that D puts so little focus on DSLs, since
language features like template constraints, `opDispatch`, and even the
fact that binary operators are overloadable via a single templated
function are all very useful tools for implementing them.


I completely agree. Or we could go with an even more general approach: 
AST macros [1].


[1] http://wiki.dlang.org/DIP50

--
/Jacob Carlborg


Re: Overloading relational operators separately; thoughts?

2016-09-28 Thread Jonathan M Davis via Digitalmars-d
On Wednesday, September 28, 2016 03:28:50 Minty Fresh via Digitalmars-d wrote:
> Lastly, if operators are intended to behave so strictly, why does
> this not extend then to binary arithmetic operators (+, -, *, /,
> %, etc.)
> They don't follow the same rules as the binary relational
> operators, after all.

It's not possible in the general case to define the arithmetic operators as
functions of each other. They actually need to be defined separately in
order to work. The comparison operators don't have that problem. And in the
cases where the arithmetic operations are essentially being passed on to a
member variable such that it's just the operator itself that's changing, and
the code is otherwise the same, the fact that opBinary takes a string for
the operator makes it trivial to use string mixins so that you only need one
function body for all of the operators, whereas in the cases where you can't
do that (e.g. the operation involves multiple member variables), you can
declare separate functions.

The increment and decrement operators are in a similar boat to the
comparison operators in that post and pre can be derived from a single
function. So, it's not just the comparison operators that got combined. In
the cases where it made sense to combine operators, they were combined, and
in the cases where it didn't make sense, they weren't. It would be nice if
more could be combined, but most of them actually need to be separate to
work. Fortunately though, some of them can be combined, and those were
combined, which makes operator overloading in D easier and less error-prone.

- Jonathan M Davis



Re: Overloading relational operators separately; thoughts?

2016-09-27 Thread Walter Bright via Digitalmars-d

On 9/27/2016 6:18 PM, Minty Fresh wrote:

So, I'm just interested in other people's thoughts are on the subject, and
whether there are any plans to allow overloading these operators separately.


The limitations are deliberate based on the idea that comparison operators need 
to be consistent and predictable, and should have a close relationship to the 
mathematical meaning of the operators. Overloading <= to mean something other 
than "less than or equal" is considered poor style in D, and the same goes for 
the other arithmetic operators.


The use of them to create DSLs (a technique called "expression templates" in 
C++) is discouraged in D, for several reasons. The recommended way to create 
DSLs in D is to parse strings using CTFE. An excellent example of that is the 
std.regex package.


There are no plans to change this.


Re: Overloading relational operators separately; thoughts?

2016-09-27 Thread Minty Fresh via Digitalmars-d
On Wednesday, 28 September 2016 at 03:12:05 UTC, Jonathan M Davis 
wrote:
On Wednesday, September 28, 2016 01:18:58 Minty Fresh via 
Digitalmars-d wrote:
Basically, having them be overloaded separately is error-prone, 
and it leads to folks overloading them in ways that have 
nothing to do with what they mean for the built-in types, which 
makes code harder to read and maintain. D has a concatenation 
operator specifically because Walter thought that it was 
horrible to use + for concatenation.


If you want to write DSLs, then use strings and mixins. D gives 
you a _lot_ of power in that area, and it avoids the problems 
associated with making overloaded operators do things other 
than what those operators are normally intended to do. With 
strings, you can make your DSL look however you want - even 
doing stuff like using various Unicode symbols as operators if 
you want to. Even with how C++ overloads operators, overloading 
operators gives you fairly limited options with what you can do 
with a DSL, whereas you have full freedom with strings - and 
without the problems that come with trying to make your DSL 
look like normal D code.


- Jonathan M Davis


Using strings and mixins does have quite a number of downsides. 
The additional work required to past the DSL aside, you also 
usually lose the scope in which things are declared (especially 
if you wish to reference or declare variables/functions/other 
constructs within your DSL), error reporting becomes much less 
precise, and the transition between the outer code and the inner 
DSL becomes jarring (especially in terms of syntax highlighting).


That said, I love the fact D has a separate operator for 
concatenation. It's extremely useful to not have that ambiguity.


Another thought is, operators not behaving as expected doesn't 
strike me as a failure of the language, given the language 
supports operator overloading. It's a failure in documentation to 
explain what the operators are intended to do, or a failure in 
implementation to behave as they should.


Lastly, if operators are intended to behave so strictly, why does 
this not extend then to binary arithmetic operators (+, -, *, /, 
%, etc.)
They don't follow the same rules as the binary relational 
operators, after all.


Re: Overloading relational operators separately; thoughts?

2016-09-27 Thread Jonathan M Davis via Digitalmars-d
On Wednesday, September 28, 2016 01:18:58 Minty Fresh via Digitalmars-d wrote:
> So, I'm just interested in other people's thoughts are on the
> subject, and whether there are any plans to allow overloading
> these operators separately.

Basically, having them be overloaded separately is error-prone, and it leads
to folks overloading them in ways that have nothing to do with what they
mean for the built-in types, which makes code harder to read and maintain.
D has a concatenation operator specifically because Walter thought that it
was horrible to use + for concatenation.

If you want to write DSLs, then use strings and mixins. D gives you a _lot_
of power in that area, and it avoids the problems associated with making
overloaded operators do things other than what those operators are normally
intended to do. With strings, you can make your DSL look however you want -
even doing stuff like using various Unicode symbols as operators if you want
to. Even with how C++ overloads operators, overloading operators gives you
fairly limited options with what you can do with a DSL, whereas you have
full freedom with strings - and without the problems that come with trying
to make your DSL look like normal D code.

- Jonathan M Davis



Overloading relational operators separately; thoughts?

2016-09-27 Thread Minty Fresh via Digitalmars-d
Currently, D offers fine grained overloading for most of the 
unary and arithmetic binary operators, but at some point a 
decision was made to lump together all of the relational 
operators (and if necessary, the equality operators) into a 
single function `opCmp`.
And while it does add a lot of convenience and consistency to how 
operators behave, it does also put a lot of limitations on what 
they can do.


For example, it's not currently possible to implement comparison 
operators that would behave lazily and only compute a certain 
value once a function call forces the computation.


Similarly, it's not possible to construct a DSL that would 
produce code or a query in another language, by returning values 
behave like AST nodes rather than actually performing a 
comparison.


ie.
  table.users
   .where!((users) => users.joined_on >= 3.days.ago)
   .joins(table.posts)
   .on!((posts, users) => posts.user_id == users.id)
   .limit(10)
   .toSql;

It's a little odd to me that D puts so little focus on DSLs, 
since language features like template constraints, `opDispatch`, 
and even the fact that binary operators are overloadable via a 
single templated function are all very useful tools for 
implementing them.


So, I'm just interested in other people's thoughts are on the 
subject, and whether there are any plans to allow overloading 
these operators separately.