Skip to content

Document opDollar (issue 7520) #292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 26, 2013
Merged

Document opDollar (issue 7520) #292

merged 4 commits into from
Oct 26, 2013

Conversation

quickfur
Copy link
Member

@quickfur quickfur commented Mar 2, 2013

I got tired of waiting for somebody to do this, so I decided to do it myself. Please review and tell me if my understanding of opDollar is off. :)

@don-clugston-sociomantic
Copy link
Contributor

opDollar can also be a non-template function, in which case no compile-time index is passed to it.

@quickfur
Copy link
Member Author

quickfur commented Mar 4, 2013

Updated.

Hmm, it just occurred to me. is it possible to declare opDollar with a runtime argument instead? Or only compile-time index is supported?

@don-clugston-sociomantic
Copy link
Contributor

Only compile-time index is supported. It's always known at compile time, so there's no point to a runtime version.

@quickfur
Copy link
Member Author

quickfur commented Mar 4, 2013

Hmm, apparently the compiler rejects it if you use more than one argument in [] but declare opDollar without the compile-time argument.

@ghost
Copy link

ghost commented Mar 4, 2013

Why not ask @9rnsr, he implemented this and likely knows all working cases rather than us guessing what works and doesnt.

@9rnsr
Copy link
Contributor

9rnsr commented Mar 4, 2013

@AndrejMitrovic No problem. @donc is the first opDollar patch implementer (see bug 3474, so he knows about the detail well. I can say the things he talked are correct.

More details:

  • opDollar also works for slice operator.
    a[$ .. $] is translated to a.opSlice(a.opDollar(), a.opDollar()) or a.opSlice(a.opDollar!0(), a.opDollar!0()).
  • Even if indexee is a complex expression, it is evaluated only once.
    (complex_expr)[$] is translated to auto __tmp = complex_expr; __tmp.opIndex(__tmp.opDollar!0());

@monarchdodra
Copy link
Contributor

It might be interesting to note that ˋopDollarˋ is not restricted in its return type, and can return any type you want, provided it is accepted by opSlice (or opDollar).

This is exploited with infinite ranges, as a convenient way to random access "slice to end": ˋmyInfiniteRange[5 .. $];ˋ. Basically, opDollar just returns a state-less object typed as ˋstruct DollarTokenˋ, and then, an ˋopSlice(size_t low, DollarToken)ˋ overload is provided. The actual value returned by ˋopDollarˋ is irrelevent here, and only the static type it carries is of importance.

As a matter of fact, in that case, opDollar can even be declared as a compile time known enum: ˋenum opDollar = DolarToken.init;ˋ

Some RA ranges with "expensive but still o(1) length" can also exploit this: If the rane knows you want to slice to the end, it can get away with not evaluating the actual length (for example, range.chunks, in an open pull request).

If you want to see some code example, look in std.range: repeat, cycle, chunks, and a couple others exploit this.

@monarchdodra
Copy link
Contributor

opDollar also works for slice operator. a[$ .. $] is translated to
a.opSlice(a.opDollar(), a.opDollar()) or a.opSlice(a.opDollar!0(), a.opDollar!0())

I think there was a recent optimization that when you slice [$ .. $], then opDollar is only evaluated once. This is the impression I was given looking at a compiler change that had broken one of my pulls, but I could be mistaken. Not sure it is worth documenting though.

@alexrp
Copy link
Member

alexrp commented Mar 8, 2013

I think there was a recent optimization that when you slice [$ .. $], then opDollar is only evaluated once.

This is absolutely positively a bug. This is an optimization that is observable by the code. It is invalid. Please file a bug. Stuff like that is not OK.

@monarchdodra
Copy link
Contributor

This is absolutely positively a bug.

That's what I kind of thought actually: Is it allowed to do that?

In any case, the first thing to do is verify my claims: They could be wrong. I won't have a test machine for a couple of days though, that I won't be able to confirm or deny myself (much less file a bug) in the near future.

@monarchdodra
Copy link
Contributor

I think I missunderstood this:

dlang/dmd@6e2f1ec

It is actual the "ce" in "(ce)[0 .. $]" that got only evaluated once. False alarm then.

}

void test() {
Rectangle r(10,20);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a C++'ism, not valid D syntax.

H. S. Teoh added 2 commits March 8, 2013 15:29
Expand with feedback from Kenji, Don, et al.
@ghost
Copy link

ghost commented Oct 18, 2013

This looks good. Are there more examples to be added or are we good with this so far?

@9rnsr
Copy link
Contributor

9rnsr commented Oct 26, 2013

It's better to open new pull requests for more examples later. I merge this now.

9rnsr added a commit that referenced this pull request Oct 26, 2013
Document opDollar (issue 7520)
@9rnsr 9rnsr merged commit 2b6ff78 into dlang:master Oct 26, 2013
@quickfur quickfur deleted the opdollar branch August 8, 2014 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants