September 11, 2011
On 09/11/2011 02:12 PM, Jonathan M Davis wrote:
> On Sunday, September 11, 2011 14:00:55 Charles Hixson wrote:
>> On 09/11/2011 01:25 PM, Vladimir Panteleev wrote:
>>> On Sun, 11 Sep 2011 23:02:37 +0300, Charles Hixson
>>>
>>> <charleshixsn@earthlink.net>  wrote:
>>>> I can't figure it out from
>>>> http://www.digitalmars.com/d/2.0/operatoroverloading.html#Binary
>>>
>>> // I assume your data structure looks like this
>>> class Node(Key, Data)
>>> {
>>> Key k;
>>> Node!(Key, Data) left, right;
>>> int level;
>>> // ...
>>>
>>> void opBinary!("in")(Key k)
>>> {
>>> if (level == 0) return false;
> Path: digitalmars.com!not-for-mail
> From: Charles Hixson<charleshixsn@earthlink.net>
> Newsgroups: digitalmars.D.learn
> Subject: Re: defining "in"  What is the proper way in D2?
> Date: Sun, 11 Sep 2011 14:09:57 -0700
> Organization: Digital Mars
> Lines: 15
> Message-ID:<j4j83k$ree$1@digitalmars.com>
> References:<j4j45h$iti$1@digitalmars.com>  <op.v1nu0fdrtuzx1w@cybershadow.mshome.net>  <j4j5uq$m8n$1@digitalmars.com>
> Mime-Version: 1.0
> Content-Type: text/plain; charset=UTF-8; format=flowed
> Content-Transfer-Encoding: 8bit
> X-Trace: digitalmars.com 1315775412 28110 66.245.57.66 (11 Sep 2011 21:10:12 GMT)
> X-Complaints-To: usenet@digitalmars.com
> NNTP-Posting-Date: Sun, 11 Sep 2011 21:10:12 +0000 (UTC)
> User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.2.21) Gecko/20110831 Iceowl/1.0b2 Icedove/3.1.13
> In-Reply-To:<j4j5uq$m8n$1@digitalmars.com>
> Xref: digitalmars.com digitalmars.D.learn:29434
>
> On 09/11/2011 01:33 PM, David Nadlinger wrote:
>> On 9/11/11 10:25 PM, Vladimir Panteleev wrote:
>>> void opBinary!("in")(Key k)
>>
>> Shouldn't that be »void opBinary(string op : "in")(Key k)«? Also, you
>> probably want to use opBinaryRight, because opBinary hooks »if
>> (container in key)«.
>>
>> David
>
> And thanks for THIS, too.  I'd just started to wonder about the order of
> the syntax.  After all, the key is in the container, but not conversely.
>
>>> if (k<  key) return k in left;
>>> if (key<  k) return k in right;
>>> return true;
>>> }
>>> }
>>
>> VOID??  I'm going to presume that this should have been bool.
>> Otherwise, thanks.  That was they syntax I couldn't figure out from the
>> docs.
>>
>> And, yeah.  That's what it looks like.  My find code was wrong, because
>> it should have referenced the node, so what I need to do is move the cod
>> into the node class.  But it was the syntax of defining the opBinary
>> specialization that was hanging me up.  (For some reason I have a hard
>> time wrapping my mind around template code.)
>
> The "in" operator normally returns a pointer to the value that you're trying
> to find (and returns null if it's not there). Making it return bool may work,
> but it's going to be a problem for generic code. That's like making
> opBinary!"*" return a type different than the types being multiplied. It's just
> not how the operator is supposed to be used and could cause problems.
>
> - Jonathan M Davis

OK, but what if the container is supposed to be opaque to external observers, but you still want to be able to tell whether it contains a particular item?  Doesn't returning a pointer violate encapsulation?

Also, the compiler complained about the declaration, causing me to currently substitute, thus:

// bool opBinaryRight!("in")(Key k)
   bool opBinaryRight(string op)(Key k) if (op == "in")

I swiped that code from std.container.d  (which also returns a bool). As what I'm doing is pretty much like a standard container, this seemed like a reasonable place to look.  I sure hope that this doesn't mean I need to instantiate every use of in.  If that's the case I might be better off just staying with find.
September 11, 2011
On 09/12/2011 12:21 AM, Jonathan M Davis wrote:
> On Monday, September 12, 2011 00:11:11 Timon Gehr wrote:
>> On 09/11/2011 11:12 PM, Jonathan M Davis wrote:
>>> On Sunday, September 11, 2011 14:00:55 Charles Hixson wrote:
>>>> On 09/11/2011 01:25 PM, Vladimir Panteleev wrote:
>>>>> On Sun, 11 Sep 2011 23:02:37 +0300, Charles Hixson
>>>>>
>>>>> <charleshixsn@earthlink.net>   wrote:
>>>>>> I can't figure it out from
>>>>>> http://www.digitalmars.com/d/2.0/operatoroverloading.html#Binary
>>>>>
>>>>> // I assume your data structure looks like this
>>>>> class Node(Key, Data)
>>>>> {
>>>>> Key k;
>>>>> Node!(Key, Data) left, right;
>>>>> int level;
>>>>> // ...
>>>>>
>>>>> void opBinary!("in")(Key k)
>>>>> {
>>>>> if (level == 0) return false;
>>>>> if (k<   key) return k in left;
>>>>> if (key<   k) return k in right;
>>>>> return true;
>>>>> }
>>>>> }
>>>>
>>>> VOID??  I'm going to presume that this should have been bool.
>>>> Otherwise, thanks.  That was they syntax I couldn't figure out from
>>>> the
>>>> docs.
>>>>
>>>> And, yeah.  That's what it looks like.  My find code was wrong,
>>>> because
>>>> it should have referenced the node, so what I need to do is move the
>>>> cod
>>>> into the node class.  But it was the syntax of defining the opBinary
>>>> specialization that was hanging me up.  (For some reason I have a hard
>>>> time wrapping my mind around template code.)
>>>
>>> The "in" operator normally returns a pointer to the value that you're
>>> trying to find (and returns null if it's not there). Making it return
>>> bool may work, but it's going to be a problem for generic code.
>>
>> -1
>>
>> I think the fact that "in" for AAs returns a pointer is a mistake and
>> ugly in the first place and any generic code that relies on any
>> container to return a raw internal pointer is flawed by itself imho.
>
> It's an issue of efficiency. It's more efficient to grab the item once, getting
> null if it's not there, then it is to check if it's there and then grab it.
> Being a systems language, D is _very_ interested in efficiency. Keeping the
> pointer returned from in around for much after the call is likely to be bad
> code (and can certainly lead to problems), but there's nothing unsafe about
> the pointer in and of itself.

AAs are built-in. The optimization you describe is quite easily carried out by the compiler. And I am quite sure that in the long run, it will bite us.

Sure. D is a systems language and you should probably be able to have the (unsafe) functionality. But 'in' is a predicate as in x ∈ M . It is really supposed to return a bool. I think Andrei even successfully avoids to mention the fact that it returns a pointer in TDPL.


BTW: Why does the current AA implementation rely on the GC if not for avoiding dangling pointers escaped by in expressions? I think if it is the only reason, efficiency concerns cannot be a rationale for the 'feature'.





September 11, 2011
On Sunday, September 11, 2011 15:28:38 Charles Hixson wrote:
> On 09/11/2011 02:12 PM, Jonathan M Davis wrote:
> > On Sunday, September 11, 2011 14:00:55 Charles Hixson wrote:
> >> On 09/11/2011 01:25 PM, Vladimir Panteleev wrote:
> >>> On Sun, 11 Sep 2011 23:02:37 +0300, Charles Hixson
> >>> 
> >>> <charleshixsn@earthlink.net>  wrote:
> >>>> I can't figure it out from http://www.digitalmars.com/d/2.0/operatoroverloading.html#Binary
> >>> 
> >>> // I assume your data structure looks like this
> >>> class Node(Key, Data)
> >>> {
> >>> Key k;
> >>> Node!(Key, Data) left, right;
> >>> int level;
> >>> // ...
> >>> 
> >>> void opBinary!("in")(Key k)
> >>> {
> >>> if (level == 0) return false;
> > 
> > Path: digitalmars.com!not-for-mail
> > From: Charles Hixson<charleshixsn@earthlink.net>
> > Newsgroups: digitalmars.D.learn
> > Subject: Re: defining "in"  What is the proper way in D2?
> > Date: Sun, 11 Sep 2011 14:09:57 -0700
> > Organization: Digital Mars
> > Lines: 15
> > Message-ID:<j4j83k$ree$1@digitalmars.com>
> > References:<j4j45h$iti$1@digitalmars.com>
> > <op.v1nu0fdrtuzx1w@cybershadow.mshome.net>
> > <j4j5uq$m8n$1@digitalmars.com> Mime-Version: 1.0
> > Content-Type: text/plain; charset=UTF-8; format=flowed
> > Content-Transfer-Encoding: 8bit
> > X-Trace: digitalmars.com 1315775412 28110 66.245.57.66 (11 Sep 2011
> > 21:10:12 GMT) X-Complaints-To: usenet@digitalmars.com
> > NNTP-Posting-Date: Sun, 11 Sep 2011 21:10:12 +0000 (UTC)
> > User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US;
> > rv:1.9.2.21) Gecko/20110831 Iceowl/1.0b2 Icedove/3.1.13
> > In-Reply-To:<j4j5uq$m8n$1@digitalmars.com>
> > Xref: digitalmars.com digitalmars.D.learn:29434
> > 
> > On 09/11/2011 01:33 PM, David Nadlinger wrote:
> >> On 9/11/11 10:25 PM, Vladimir Panteleev wrote:
> >>> void opBinary!("in")(Key k)
> >> 
> >> Shouldn't that be »void opBinary(string op : "in")(Key k)«? Also, you
> >> probably want to use opBinaryRight, because opBinary hooks »if
> >> (container in key)«.
> >> 
> >> David
> > 
> > And thanks for THIS, too.  I'd just started to wonder about the order of the syntax.  After all, the key is in the container, but not conversely.
> > 
> >>> if (k<  key) return k in left;
> >>> if (key<  k) return k in right;
> >>> return true;
> >>> }
> >>> }
> >> 
> >> VOID??  I'm going to presume that this should have been bool.
> >> Otherwise, thanks.  That was they syntax I couldn't figure out from
> >> the
> >> docs.
> >> 
> >> And, yeah.  That's what it looks like.  My find code was wrong,
> >> because
> >> it should have referenced the node, so what I need to do is move the
> >> cod
> >> into the node class.  But it was the syntax of defining the opBinary
> >> specialization that was hanging me up.  (For some reason I have a hard
> >> time wrapping my mind around template code.)
> > 
> > The "in" operator normally returns a pointer to the value that you're trying to find (and returns null if it's not there). Making it return bool may work, but it's going to be a problem for generic code. That's like making opBinary!"*" return a type different than the types being multiplied. It's just not how the operator is supposed to be used and could cause problems.
> > 
> > - Jonathan M Davis
> 
> OK, but what if the container is supposed to be opaque to external observers, but you still want to be able to tell whether it contains a particular item?  Doesn't returning a pointer violate encapsulation?

Yes and no. It does provide direct access to an element in the container, which could cause issues if they keep the pointer around (just like with any iterator or range which has been invalidated by a container being altered). But if you're looking to stop the element from being altered, all you'd have to do is make it a pointer to const.

> Also, the compiler complained about the declaration, causing me to currently substitute, thus:
> 
> // bool opBinaryRight!("in")(Key k)
>     bool opBinaryRight(string op)(Key k) if (op == "in")
> 
> I swiped that code from std.container.d  (which also returns a bool). As what I'm doing is pretty much like a standard container, this seemed like a reasonable place to look.  I sure hope that this doesn't mean I need to instantiate every use of in.  If that's the case I might be better off just staying with find.

I'm a bit surprised that std.container would have it returning bool, but that would work for any case where you're just checking for existence. It _is_ inefficient in many cases though, and is not great design IMHO. It may mean that templated code is ultimately going to have to use static ifs or template constraints to check where in returns a pointer, but the value of in is certainly reduced (albeit not eliminated) when it returns bool.

As for template instantiations, you get a new template instantiation for every type you try and instantiate a template with a new set of template arguments. If the only argument to opBinaryRight is the string for the operator, then it's only going to be instantiated once per operator.

As for sticking with find, you can't implement in such that it's at least as efficient as searching in balance binary tree (O(log n) I believe), then you shouldn't implement n. Ideally, it would be O(1), but that's obviously not always possible. Still, in really needs to be more efficient than find, or it shouldn't be there. But you shouldn't be having to use find just because of template bloat.

- Jonathan M Davis
September 11, 2011
On 09/12/2011 12:28 AM, Charles Hixson wrote:
> On 09/11/2011 02:12 PM, Jonathan M Davis wrote:
>> On Sunday, September 11, 2011 14:00:55 Charles Hixson wrote:
>>> On 09/11/2011 01:25 PM, Vladimir Panteleev wrote:
>>>> On Sun, 11 Sep 2011 23:02:37 +0300, Charles Hixson
>>>>
>>>> <charleshixsn@earthlink.net> wrote:
>>>>> I can't figure it out from
>>>>> http://www.digitalmars.com/d/2.0/operatoroverloading.html#Binary
>>>>
>>>> // I assume your data structure looks like this
>>>> class Node(Key, Data)
>>>> {
>>>> Key k;
>>>> Node!(Key, Data) left, right;
>>>> int level;
>>>> // ...
>>>>
>>>> void opBinary!("in")(Key k)
>>>> {
>>>> if (level == 0) return false;
>> Path: digitalmars.com!not-for-mail
>> From: Charles Hixson<charleshixsn@earthlink.net>
>> Newsgroups: digitalmars.D.learn
>> Subject: Re: defining "in" What is the proper way in D2?
>> Date: Sun, 11 Sep 2011 14:09:57 -0700
>> Organization: Digital Mars
>> Lines: 15
>> Message-ID:<j4j83k$ree$1@digitalmars.com>
>> References:<j4j45h$iti$1@digitalmars.com>
>> <op.v1nu0fdrtuzx1w@cybershadow.mshome.net> <j4j5uq$m8n$1@digitalmars.com>
>> Mime-Version: 1.0
>> Content-Type: text/plain; charset=UTF-8; format=flowed
>> Content-Transfer-Encoding: 8bit
>> X-Trace: digitalmars.com 1315775412 28110 66.245.57.66 (11 Sep 2011
>> 21:10:12 GMT)
>> X-Complaints-To: usenet@digitalmars.com
>> NNTP-Posting-Date: Sun, 11 Sep 2011 21:10:12 +0000 (UTC)
>> User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US;
>> rv:1.9.2.21) Gecko/20110831 Iceowl/1.0b2 Icedove/3.1.13
>> In-Reply-To:<j4j5uq$m8n$1@digitalmars.com>
>> Xref: digitalmars.com digitalmars.D.learn:29434
>>
>> On 09/11/2011 01:33 PM, David Nadlinger wrote:
>>> On 9/11/11 10:25 PM, Vladimir Panteleev wrote:
>>>> void opBinary!("in")(Key k)
>>>
>>> Shouldn't that be »void opBinary(string op : "in")(Key k)«? Also, you
>>> probably want to use opBinaryRight, because opBinary hooks »if
>>> (container in key)«.
>>>
>>> David
>>
>> And thanks for THIS, too. I'd just started to wonder about the order of
>> the syntax. After all, the key is in the container, but not conversely.
>>
>>>> if (k< key) return k in left;
>>>> if (key< k) return k in right;
>>>> return true;
>>>> }
>>>> }
>>>
>>> VOID?? I'm going to presume that this should have been bool.
>>> Otherwise, thanks. That was they syntax I couldn't figure out from the
>>> docs.
>>>
>>> And, yeah. That's what it looks like. My find code was wrong, because
>>> it should have referenced the node, so what I need to do is move the cod
>>> into the node class. But it was the syntax of defining the opBinary
>>> specialization that was hanging me up. (For some reason I have a hard
>>> time wrapping my mind around template code.)
>>
>> The "in" operator normally returns a pointer to the value that you're
>> trying
>> to find (and returns null if it's not there). Making it return bool
>> may work,
>> but it's going to be a problem for generic code. That's like making
>> opBinary!"*" return a type different than the types being multiplied.
>> It's just
>> not how the operator is supposed to be used and could cause problems.
>>
>> - Jonathan M Davis
>
> OK, but what if the container is supposed to be opaque to external
> observers, but you still want to be able to tell whether it contains a
> particular item? Doesn't returning a pointer violate encapsulation?
>
> Also, the compiler complained about the declaration, causing me to
> currently substitute, thus:
>
> // bool opBinaryRight!("in")(Key k)

That is not valid syntax and probably will never be.

> bool opBinaryRight(string op)(Key k) if (op == "in")
>
> I swiped that code from std.container.d (which also returns a bool). As
> what I'm doing is pretty much like a standard container, this seemed
> like a reasonable place to look.

I agree.


> I sure hope that this doesn't mean I
> need to instantiate every use of in. If that's the case I might be
> better off just staying with find.

How do you mean, instantiate it?





September 11, 2011
On Monday, September 12, 2011 01:04:39 Timon Gehr wrote:
> On 09/12/2011 12:21 AM, Jonathan M Davis wrote:
> > On Monday, September 12, 2011 00:11:11 Timon Gehr wrote:
> >> On 09/11/2011 11:12 PM, Jonathan M Davis wrote:
> >>> On Sunday, September 11, 2011 14:00:55 Charles Hixson wrote:
> >>>> On 09/11/2011 01:25 PM, Vladimir Panteleev wrote:
> >>>>> On Sun, 11 Sep 2011 23:02:37 +0300, Charles Hixson
> >>>>> 
> >>>>> <charleshixsn@earthlink.net>   wrote:
> >>>>>> I can't figure it out from http://www.digitalmars.com/d/2.0/operatoroverloading.html#Bina ry
> >>>>> 
> >>>>> // I assume your data structure looks like this
> >>>>> class Node(Key, Data)
> >>>>> {
> >>>>> Key k;
> >>>>> Node!(Key, Data) left, right;
> >>>>> int level;
> >>>>> // ...
> >>>>> 
> >>>>> void opBinary!("in")(Key k)
> >>>>> {
> >>>>> if (level == 0) return false;
> >>>>> if (k<   key) return k in left;
> >>>>> if (key<   k) return k in right;
> >>>>> return true;
> >>>>> }
> >>>>> }
> >>>> 
> >>>> VOID??  I'm going to presume that this should have been bool.
> >>>> Otherwise, thanks.  That was they syntax I couldn't figure out
> >>>> from
> >>>> the
> >>>> docs.
> >>>> 
> >>>> And, yeah.  That's what it looks like.  My find code was wrong,
> >>>> because
> >>>> it should have referenced the node, so what I need to do is move
> >>>> the
> >>>> cod
> >>>> into the node class.  But it was the syntax of defining the
> >>>> opBinary
> >>>> specialization that was hanging me up.  (For some reason I have a
> >>>> hard
> >>>> time wrapping my mind around template code.)
> >>> 
> >>> The "in" operator normally returns a pointer to the value that
> >>> you're
> >>> trying to find (and returns null if it's not there). Making it
> >>> return
> >>> bool may work, but it's going to be a problem for generic code.
> >> 
> >> -1
> >> 
> >> I think the fact that "in" for AAs returns a pointer is a mistake and ugly in the first place and any generic code that relies on any container to return a raw internal pointer is flawed by itself imho.
> > 
> > It's an issue of efficiency. It's more efficient to grab the item once, getting null if it's not there, then it is to check if it's there and then grab it. Being a systems language, D is _very_ interested in efficiency. Keeping the pointer returned from in around for much after the call is likely to be bad code (and can certainly lead to problems), but there's nothing unsafe about the pointer in and of itself.
> 
> AAs are built-in. The optimization you describe is quite easily carried out by the compiler. And I am quite sure that in the long run, it will bite us.
> 
> Sure. D is a systems language and you should probably be able to have the (unsafe) functionality. But 'in' is a predicate as in x ∈ M . It is really supposed to return a bool. I think Andrei even successfully avoids to mention the fact that it returns a pointer in TDPL.
> 
> 
> BTW: Why does the current AA implementation rely on the GC if not for avoiding dangling pointers escaped by in expressions? I think if it is the only reason, efficiency concerns cannot be a rationale for the 'feature'.

It is no more dangerous than keeping an iterator or range around after its been invalidated. In fact, it's _exactly_ the same thing. And there's no way that you're going to get rid of that issue in an efficient manner. That's why std.container has the stable* functions. Pointers are allowed in SafeD and are perfectly safe. It's stuff like pointer arithmetic which is unsafe and disallowed in SafeD.

Yes, there are issues if you keep the pointer around after the container has been altered, but ranges have exactly the same issue. It's a known and accepted problem. The solution is to just not keep the pointer around. If a programmer keeps such a pointer aronud (or keeps a range around after altering a container with a non-stable* function), then they're risking buggy code. That doesn't mean that the feature is a bad idea.

- Jonathan M Davis
September 11, 2011
Timon Gehr:

> AAs are built-in. The optimization you describe is quite easily carried out by the compiler. And I am quite sure that in the long run, it will bite us.

With the LDC compiler if you perform an AA lookup, and after one or few lines you do it again, (because you are using an if and you are not using the pointer nature of the return value of "in AA"), LDC most times uses a single AA lookup.

This little group of optimizations were added to LDC just to improve AA usage. With such simple optimizations I think 99% of times you don't need "in AA" to return a pointer. So probably returning a bool is enough. I don't think I have ever stored the return pointer of "in AA", I have used it locally, just to save one AA lookup.

Bye,
bearophile
September 12, 2011
On 09/11/2011 04:07 PM, Timon Gehr wrote:
> On 09/12/2011 12:28 AM, Charles Hixson wrote:
>> On 09/11/2011 02:12 PM, Jonathan M Davis wrote:
>>> On Sunday, September 11, 2011 14:00:55 Charles Hixson wrote:
>>>> On 09/11/2011 01:25 PM, Vladimir Panteleev wrote:
>>>>> On Sun, 11 Sep 2011 23:02:37 +0300, Charles Hixson
>>>>>
>>>>> <charleshixsn@earthlink.net> wrote:
>>>>>> I can't figure it out from
>>>>>> http://www.digitalmars.com/d/2.0/operatoroverloading.html#Binary
>>>>>
>>>>> // I assume your data structure looks like this
>>>>> class Node(Key, Data)
>>>>> {
>>>>> Key k;
>>>>> Node!(Key, Data) left, right;
>>>>> int level;
>>>>> // ...
>>>>>
>>>>> void opBinary!("in")(Key k)
>>>>> {
>>>>> if (level == 0) return false;
>>> Path: digitalmars.com!not-for-mail
>>> From: Charles Hixson<charleshixsn@earthlink.net>
>>> Newsgroups: digitalmars.D.learn
>>> Subject: Re: defining "in" What is the proper way in D2?
>>> Date: Sun, 11 Sep 2011 14:09:57 -0700
>>> Organization: Digital Mars
>>> Lines: 15
>>> Message-ID:<j4j83k$ree$1@digitalmars.com>
>>> References:<j4j45h$iti$1@digitalmars.com>
>>> <op.v1nu0fdrtuzx1w@cybershadow.mshome.net>
>>> <j4j5uq$m8n$1@digitalmars.com>
>>> Mime-Version: 1.0
>>> Content-Type: text/plain; charset=UTF-8; format=flowed
>>> Content-Transfer-Encoding: 8bit
>>> X-Trace: digitalmars.com 1315775412 28110 66.245.57.66 (11 Sep 2011
>>> 21:10:12 GMT)
>>> X-Complaints-To: usenet@digitalmars.com
>>> NNTP-Posting-Date: Sun, 11 Sep 2011 21:10:12 +0000 (UTC)
>>> User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US;
>>> rv:1.9.2.21) Gecko/20110831 Iceowl/1.0b2 Icedove/3.1.13
>>> In-Reply-To:<j4j5uq$m8n$1@digitalmars.com>
>>> Xref: digitalmars.com digitalmars.D.learn:29434
>>>
>>> On 09/11/2011 01:33 PM, David Nadlinger wrote:
>>>> On 9/11/11 10:25 PM, Vladimir Panteleev wrote:
>>>>> void opBinary!("in")(Key k)
>>>>
>>>> Shouldn't that be »void opBinary(string op : "in")(Key k)«? Also, you
>>>> probably want to use opBinaryRight, because opBinary hooks »if
>>>> (container in key)«.
>>>>
>>>> David
>>>
>>> And thanks for THIS, too. I'd just started to wonder about the order of
>>> the syntax. After all, the key is in the container, but not conversely.
>>>
>>>>> if (k< key) return k in left;
>>>>> if (key< k) return k in right;
>>>>> return true;
>>>>> }
>>>>> }
>>>>
>>>> VOID?? I'm going to presume that this should have been bool.
>>>> Otherwise, thanks. That was they syntax I couldn't figure out from the
>>>> docs.
>>>>
>>>> And, yeah. That's what it looks like. My find code was wrong, because
>>>> it should have referenced the node, so what I need to do is move the
>>>> cod
>>>> into the node class. But it was the syntax of defining the opBinary
>>>> specialization that was hanging me up. (For some reason I have a hard
>>>> time wrapping my mind around template code.)
>>>
>>> The "in" operator normally returns a pointer to the value that you're
>>> trying
>>> to find (and returns null if it's not there). Making it return bool
>>> may work,
>>> but it's going to be a problem for generic code. That's like making
>>> opBinary!"*" return a type different than the types being multiplied.
>>> It's just
>>> not how the operator is supposed to be used and could cause problems.
>>>
>>> - Jonathan M Davis
>>
>> OK, but what if the container is supposed to be opaque to external
>> observers, but you still want to be able to tell whether it contains a
>> particular item? Doesn't returning a pointer violate encapsulation?
>>
>> Also, the compiler complained about the declaration, causing me to
>> currently substitute, thus:
>>
>> // bool opBinaryRight!("in")(Key k)
>
> That is not valid syntax and probably will never be.
>
>> bool opBinaryRight(string op)(Key k) if (op == "in")
>>
>> I swiped that code from std.container.d (which also returns a bool). As
>> what I'm doing is pretty much like a standard container, this seemed
>> like a reasonable place to look.
>
> I agree.
>
>
>> I sure hope that this doesn't mean I
>> need to instantiate every use of in. If that's the case I might be
>> better off just staying with find.
>
> How do you mean, instantiate it?
>
>
>
>
>
container.binaryOp("in")!(something I haven't figured out yet.

Template syntax doesn't make any sense to me yet.  I'm just copying examples and adapting them with a cut and try and see what works and what doesn't.  More failures than successes.

OTOH, it does seem better than C++ template syntax, but that's VERY faint praise indeed.

September 12, 2011
On 09/12/2011 02:53 AM, Charles Hixson wrote:
> On 09/11/2011 04:07 PM, Timon Gehr wrote:
>> How do you mean, instantiate it?
>>
> container.binaryOp("in")!(something I haven't figured out yet.
>
> Template syntax doesn't make any sense to me yet. I'm just copying
> examples and adapting them with a cut and try and see what works and
> what doesn't. More failures than successes.
>
> OTOH, it does seem better than C++ template syntax, but that's VERY
> faint praise indeed.
>

You can explicitly instantiate it like this:

container.opBinaryRight!"in"(elem);

but you should be able to write

elem in container

instead, which is the same thing.


September 12, 2011
On 09/11/2011 06:02 PM, Timon Gehr wrote:
> On 09/12/2011 02:53 AM, Charles Hixson wrote:
>> On 09/11/2011 04:07 PM, Timon Gehr wrote:
>>> How do you mean, instantiate it?
>>>
>> container.binaryOp("in")!(something I haven't figured out yet.
>>
>> Template syntax doesn't make any sense to me yet. I'm just copying
>> examples and adapting them with a cut and try and see what works and
>> what doesn't. More failures than successes.
>>
>> OTOH, it does seem better than C++ template syntax, but that's VERY
>> faint praise indeed.
>>
>
> You can explicitly instantiate it like this:
>
> container.opBinaryRight!"in"(elem);
>
> but you should be able to write
>
> elem in container
>
> instead, which is the same thing.
>
>

Thanks, both for the reassurance, and for the alternate syntax.

September 12, 2011
On Sun, 11 Sep 2011 18:11:11 -0400, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 09/11/2011 11:12 PM, Jonathan M Davis wrote:
>> On Sunday, September 11, 2011 14:00:55 Charles Hixson wrote:
>>> On 09/11/2011 01:25 PM, Vladimir Panteleev wrote:
>>>> On Sun, 11 Sep 2011 23:02:37 +0300, Charles Hixson
>>>>
>>>> <charleshixsn@earthlink.net>  wrote:
>>>>> I can't figure it out from
>>>>> http://www.digitalmars.com/d/2.0/operatoroverloading.html#Binary
>>>>
>>>> // I assume your data structure looks like this
>>>> class Node(Key, Data)
>>>> {
>>>> Key k;
>>>> Node!(Key, Data) left, right;
>>>> int level;
>>>> // ...
>>>>
>>>> void opBinary!("in")(Key k)
>>>> {
>>>> if (level == 0) return false;
>>>> if (k<  key) return k in left;
>>>> if (key<  k) return k in right;
>>>> return true;
>>>> }
>>>> }
>>>
>>> VOID??  I'm going to presume that this should have been bool.
>>> Otherwise, thanks.  That was they syntax I couldn't figure out from the
>>> docs.
>>>
>>> And, yeah.  That's what it looks like.  My find code was wrong, because
>>> it should have referenced the node, so what I need to do is move the cod
>>> into the node class.  But it was the syntax of defining the opBinary
>>> specialization that was hanging me up.  (For some reason I have a hard
>>> time wrapping my mind around template code.)
>>
>> The "in" operator normally returns a pointer to the value that you're trying
>> to find (and returns null if it's not there). Making it return bool may work,
>> but it's going to be a problem for generic code.
>
> -1
>
> I think the fact that "in" for AAs returns a pointer is a mistake and ugly in the first place and any generic code that relies on any container to return a raw internal pointer is flawed by itself imho.

That reminds me, I should write opIn for dcollections maps.  It will return a cursor (not a pointer).

Hm... probably have to overload cursor.opStar and opCast(bool) at that point too for the sake of generic code...

-Steve