Operator overloading -- lets collect some use cases

aarti_pl aarti at interia.pl
Mon Dec 29 04:50:49 PST 2008


Don pisze:
> aarti_pl wrote:
>> Don pisze:
>>> There's been some interesting discussion about operator overloading 
>>> over the past six months, but to take the next step, I think we need 
>>> to ground it in reality. What are the use cases?
>>>
>>> I think that D's existing opCmp() takes care of the plethora of 
>>> trivial cases where <, >= etc are overloaded. It's the cases where 
>>> the arithmetic and logical operations are overloaded that are 
>>> particularly interesting to me.
>>>
>>> The following mathematical cases immediately spring to mind:
>>> * complex numbers
>>> * quaternions (interesting since * is anti-commutative, a*b = -b*a)
>>> * vectors
>>> * matrices
>>> * tensors
>>> * bigint operations (including bigint, bigfloat,...)
>>> I think that all of those are easily defensible.
>>>
>>> But I know of very few reasonable non-mathematical uses.
>>> In C++, I've seen them used for iostreams, regexps, and some stuff 
>>> that is quite frankly bizarre.
>>>
>>> So, please post any use cases which you consider convincing.
>>>
>>
>> DSL support in mother language. As an example I can give SQL in D or 
>> mockup tests description language (usually also in D - not as a 
>> separate script language).
> 
> Could you be more specific about this? For SQL, arithmetic and logical 
> operators don't seem to be involved. 

In fact they both can be involved. Below are operators which are 
understood by SQLite - one of the simplest databases:

Binary:
     ||
     *    /    %
     +    -
     <<   >>   &    |
     <    <=   >    >=
     =    ==   !=   <>   IN  LIKE  GLOB  MATCH  REGEXP
     AND
     OR

Unary:
     -    +    ~    NOT

As you see there are arithmetic operators and as well logical operators, 
which are used in SQL expressions.


> The example you gave showed (if I 
> understand correctly) a wish to make expression templates involving 
> comparison operators, a task which is currently impossible.
> 

Why do you mention expression templates? Its not necessary to use them 
in my opinion. Operator overloading should be just right for this task.

I see built-in operators overloading as a part of wider category of 
defining infix functions (eventually also postfix functions).

When we could get possibility to define infix functions: 'AND' and 'OR' 
I would not overload built-in '&&' and '||'. But having only possibility 
to overload '&&', '||' and others built-ins would be also acceptable.

Overloading of only few of above operators in D is not possible. 
Theoretically you can overload <, <=, >, >=, ==, != (opCmp), but the way 
it is implemented right now is not usable for my purposes.

> I also found your first example a little too simple.
> 
> Query query = Select(a).Where(id == 5);
> 
> I presume you would also want to do things like:
> 
> for(int i=0; i<10; ++i) {
>   Query query = Select(a).Where(id == (arr[i+2] + func(i)) || id==78+i);
> ....
> }

Yes. Partially above expression will be evaluated on runtime with 
standard operators:
val1 = arr[i+2] + func(i)
val2 = 78 + i

but partially it must be stored somehow to be evaluated later by SQL 
database:
Query query = Select(a).Where(id == val1 || id == val2 || id = id1 + 5);
(id, id1 are column names)

(id = id1 + 5 must be stored for evaluation by SQL database)

Also I would like to add a word to my latest post regarding string 
mixins as I see I was not clear enough about it. It should be possible 
to construct queries itself on runtime like below:

DbTable Person = ....; //In my case DbTable keeps table columns and few 
other informations

DbMatrix getPersons(SQLExpression exp) {
	Query query = Select(Person).Where(exp);
	return Database.execute(query);
}

void main() {
   SQLExpression exp = (Person.Name == "John");
   DbMatrix res = getPersons(exp);
}

This is what I mean by constructing queries on runtime. With string 
mixins you will have to do not only mixin(SQL("SELECT ....")) but also 
mixin(SQLExpression()), what gets really complicated in the end.


> meaning you'd also need to overload && and || operators.
> Is that correct?

Yes.

> 
>> In my previous posts I already put few arguments why it is sometimes 
>> much more handy to use "DSL in mother language" approach rather than 
>> string mixins with DSL language itself.
> 
> Still, that doesn't necessarily involve operator overloading. I really 
> want to assemble a list of cases which do.

Yes, it doesn't necessarily involve operator overloading as operator 
overloading is just a sub-case of defining functions - in this case 
infix functions and (possibly) postfix functions.

But I would dare to assume that overloading of built-in infix functions 
would satisfy most of use-cases.

And one more thing. It would be very useful to have possibility to 
define operators overloading as a free functions (not a part of 
class/struct). It will help decoupling of concepts and implementations.

In my system columns are separate concept. They don't have to know 
anything about SQL and SQL expressions in which they appear. Columns are 
used by me to get values from resulting table (DbMatrix). This table can 
be used as a container for values, not necessarily for values taken from 
SQL queries. But to allow nicer syntax with only in-class operator 
overloading I will have to teach columns about SQL expressions. And 
someone who will want to use my table container will get also a lot of 
useless API from columns to create SQL expressions.

BR
Marcin Kuszczak
(aarti_pl)



More information about the Digitalmars-d mailing list