Re: opEquals() non-standard return type

2019-01-24 Thread Jacob Shtokolov via Digitalmars-d-learn

On Wednesday, 23 January 2019 at 17:28:37 UTC, H. S. Teoh wrote:
The best way to do this is to use a string DSL or a delegate as 
template argument. For example:


auto result = User.filter!q{ User.name == "John" };

or:

auto result = User.filter!(u => u.name == "John");



I didn't know about q{} token strings! This looks very cool for 
implementing different DSLs.


Thank you!


Re: opEquals() non-standard return type

2019-01-24 Thread Jacob Shtokolov via Digitalmars-d-learn

On Thursday, 24 January 2019 at 00:47:37 UTC, Ali Çehreli wrote:
Yeah, that can't work. Remove the bool-returning one and your 
code works with the 'alias this' above.


Wow, this is an amazing workaround! I didn't think about it in 
that way.

It perfectly solves the issue.

Thank you!


Re: opEquals() non-standard return type

2019-01-23 Thread Neia Neutuladh via Digitalmars-d-learn
On Wed, 23 Jan 2019 15:19:06 +, Jacob Shtokolov wrote:
> I'm wondering, is that possible to declare multiple versions of
> opEquals() and evaluate them in the different places depending on return
> type?

I looked at this a while ago for similar reasons. It didn't pan out.

When you override the comparison operator, you can't distinguish which 
comparison is overloaded. It takes at least 2^n evaluations of the 
function to determine all the comparisons, possibly more. (I *think* you 
can observe the short-circuiting logic as you do those evaluations to 
determine how each comparison is combined.)


Re: opEquals() non-standard return type

2019-01-23 Thread Ali Çehreli via Digitalmars-d-learn

On 01/23/2019 07:19 AM, Jacob Shtokolov wrote:

> Expressions like `User.id == 10`, `User.age > 18`, etc. should return a
> struct instead of a bool (let's call it `struct BinaryExpression`).

Have you considered 'alias this'?

struct BinaryExpr(T)
{
  T left;
  T right;
  Op op;

  bool value() const {
final switch (op) with (Op) {
  case Equals:
return left == right;
  case NotEquals:
return left != right;
}
  }

  alias value this;
}

> So I'm making the two versions of opEquals: one returns a
> BinaryExpression, and the second - a boolean value.

Yeah, that can't work. Remove the bool-returning one and your code works 
with the 'alias this' above.


Ali



Re: opEquals() non-standard return type

2019-01-23 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Jan 23, 2019 at 03:19:06PM +, Jacob Shtokolov via 
Digitalmars-d-learn wrote:
> Hi,
> 
> I'm trying to check whether it's possible to implement Python's
> SQLAlchemy-like query syntax in D, but I get stuck a bit.
> 
> Here is a simple example of what I want to achieve:
> 
> ```
> auto result = User.filter(User.id == 10);
> result = User.filter(User.name == "John");
> result = User.filter(User.age > 18);
> ```
[...]

The best way to do this is to use a string DSL or a delegate as template
argument. For example:

auto result = User.filter!q{ User.name == "John" };

or:

auto result = User.filter!(u => u.name == "John");

The delegate option will be easier to implement, but the syntax will be
slightly more verbose.  The string DSL option will give you the best
syntax, but then you'll have to implement a compile-time DSL parser.


T

-- 
Bare foot: (n.) A device for locating thumb tacks on the floor.


Re: opEquals() non-standard return type

2019-01-23 Thread Jacob Shtokolov via Digitalmars-d-learn
On Wednesday, 23 January 2019 at 15:28:02 UTC, Jonathan M Davis 
wrote:
But regardless of the specifics of operator overloading in D, D 
does not support overloading _any_ functions on the return type.


Thanks!


Re: opEquals() non-standard return type

2019-01-23 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, January 23, 2019 8:19:06 AM MST Jacob Shtokolov via 
Digitalmars-d-learn wrote:
> Hi,
>
> I'm trying to check whether it's possible to implement Python's
> SQLAlchemy-like query syntax in D, but I get stuck a bit.
>
> Here is a simple example of what I want to achieve:
>
> ```
> auto result = User.filter(User.id == 10);
> result = User.filter(User.name == "John");
> result = User.filter(User.age > 18);
> ```
>
> Expressions like `User.id == 10`, `User.age > 18`, etc. should
> return a struct instead of a bool (let's call it `struct
> BinaryExpression`).
>
> So I'm making the two versions of opEquals: one returns a
> BinaryExpression, and the second - a boolean value.
>
> However, when I want to use the same expression for the `if`
> operator, the compiler cannot decide what function to call and
> shows an error: "overloads bool(int b) and BinaryExpr!int(int b)
> both match argument list for opEquals".
>
>
> I'm wondering, is that possible to declare multiple versions of
> opEquals() and evaluate them in the different places depending on
> return type?
>
> Here is my test code to check: https://run.dlang.io/is/yTFHWp
> Gist:
> https://gist.github.com/run-dlang/67ec42ca73d56d310e8ae765fabede69
>
> Thanks!

D's operator overloading is specifically designed around the idea that
overloaded operators are supposed to act like the operators on the built-in
types and that they _not_ be used for building syntax. opEquals is supposed
to only return bool. If you attempt to make it return pretty much anything
else, you're begging for trouble.

But regardless of the specifics of operator overloading in D, D does not
support overloading _any_ functions on the return type. Overloading is only
done based an a function's arguments. You've declared two overloads with the
exact same types for all of their parameters such that they only differ by
their return type, and you can't do that in D.

- Jonathan M Davis