Thoughts on improving operators

Gor Gyolchanyan gor.f.gyolchanyan at gmail.com
Wed Oct 5 04:40:45 PDT 2011


The whole point was to put the question mark to a better use.
I mean, it's used in the ternary operator exclusively.
It's such a waste of a token.
The question mark logically belongs to bools (which goes good with the
ternary operator), but the bools are much more ofter worked with in
the form of predicates, so I'd want to make that question mark more
useful.

On Wed, Oct 5, 2011 at 3:32 PM, Christophe <travert at phare.normalesup.org> wrote:
> Gor Gyolchanyan , dans le message (digitalmars.D:146100), a écrit :
>> I agree. But there's something that can be done to help make the
>> operators even more usable.
>> Example: named foreach loops over objects:
>>
>> struct TestStruct
>> {
>> public:
>>     this(string text) { _text = text.dup; }
>>
>>     int opApply(string name : "text")(int delegate(ref dchar) dg)
>>     {
>>         int result;
>>         foreach(ref c; _text)
>>         {
>>             result = dg(c);
>>             if(result)
>>                 break;
>>         }
>>         return result;
>>     }
>>
>> private:
>>     dchar[] _text;
>> }
>>
>> unittest
>> {
>>     auto ts = TestStruct("Hello, world!");
>>     foreach(ref c; ts.text)
>>         if(isAlpha(c))
>>             ++c;
>>     assert(ts == "Ifmmp, xpsme!");
>> }
>>
>> Dropping the string name of the operator will mean, using it on the
>> object itself (which is the only choice now).
>> This would be a very handy way to define more then one type of opApply
>> for an object without the need to create and return private structures
>> with opApply in them.
>
> This is already possible for opApply.
>
> http://www.d-programming-language.org/statement.html#ForeachStatement
>
> See foreach over delegates.
>
>
> With your proposal, the parsing of all operators becomes more
> complicated: each time you see a symbol, you must check if it is
> followed by a special operator, if it is, then you don't evaluate the
> symbol, but the operator with this symbol name as template argument.
> Even if the compiler was implemented that way without bugs, you could
> still lose the programmer. I'd prefer to keep the langage simple enough
> so I can see what will get being caller...
>
> In short, I don't know if ts.empty? is going to call ts.empty.opPred, or
> ts.opPred!"empty" ?
>
> I don't think naming predicates is such a big issue. 'isEmpty' is not
> that ugly. And in special cases, you can even decide to call the
> predicate just 'empty'. No one forces you to have a naming convention
> for predicates. If the proposal is used and empty? is used, that doesn't
> change the fact that you should not have a method called empty in your
> structure because of parsing ambiguity, so you could ave used an empty
> method in the first place (instead of isEmpty).
>
> On way to solve this ambiguity would be to use ts?empty. But then you
> lose the ternary operator... And this doesn't work nicely with opIndex
> or opApply, for example.
>
> About using ? as a post-fix unary operator converting to bool, I would
> say 'why not ?'. But I think overloading opPred (and other logical
> operators && and ||) is not a good idea at all. These operators must
> keep the same meaning in any condition.
>
>
>
> Finally, if you hate constructing a structure to be used by opIndex, use
> a delegate, and construct the structure on the fly with a template:
>
> struct Indexable(T)
> {
>  this(T delegate(size_t) dg_) { dg = dg_; }
>  T delegate(size_t i) dg;
>  T opIndex(size_t i) { return dg(i); }
> }
>
> indexable(T)(T delegate(size_t) dg)
> {
>  return Indexable!T(dg);
> }
>
> struct Foo
> {
>  int a, b;
>  auto byIndex()
>  {
>    return indexable((){ return i==0? a: b; })
>  }
> }
>
>
> We could even improve the template by templating the index argument,
> proposing to have a length method, etc...
>
> --
> Christophe
>


More information about the Digitalmars-d mailing list