Skip to content

Conversation

@retronym
Copy link
Member

@retronym retronym commented Mar 15, 2019

  • mark methods that are tailrec as such
  • make some more methods tailrec by making them final

  - mark methods that are tailrec as such
  - make some more methods tailrec by making them final
  - mark methods that are tailrec as such
  - make some more methods tailrec by making them final
  - mark methods that are tailrec as such
  - make some more methods tailrec by making them final
@scala-jenkins scala-jenkins added this to the 2.13.1 milestone Mar 15, 2019
def loop(cases: List[CaseDef]): Option[CaseDef] = cases match {
case head :: next :: _ if isDefault(head) => Some(next) // subsumed by the next case, but faster
case head :: rest if !isGuardedCase(head) || head.guard.tpe =:= ConstantTrue => rest find caseImplies(head) orElse loop(rest)
case head :: rest if !isGuardedCase(head) || head.guard.tpe =:= ConstantTrue => rest find caseImplies(head) match { case s @ Some(_) => s case None => loop(rest) }
Copy link
Member Author

Choose a reason for hiding this comment

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

Hand inlined orElse to enable tail call elimination.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm especially impressed by the hardened resistance to semicolon.

if (p(this)) this else outer.nextEnclosing(p)
@tailrec
final def nextEnclosing(p: Context => Boolean): Context =
if (this eq NoContext) this else if (p(this)) this else outer.nextEnclosing(p)
Copy link
Member Author

Choose a reason for hiding this comment

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

Removed override in NoContext to make this self-contained and final.


def isStrictFP: Boolean = !isDeferred && (hasAnnotation(ScalaStrictFPAttr) || originalOwner.isStrictFP)
@tailrec
final def isStrictFP: Boolean = this != NoSymbol && !isDeferred && (hasAnnotation(ScalaStrictFPAttr) || originalOwner.isStrictFP)
Copy link
Member Author

Choose a reason for hiding this comment

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

Removed override in NoSymbol to make this self-contained and final.

Copy link
Contributor

Choose a reason for hiding this comment

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

TIL.

Copy link
Contributor

Choose a reason for hiding this comment

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

(I meant about the change in receiver.)

if (this eq NoSymbol) this
else if (isTopLevel) {
if (isClass) this else moduleClass
} else owner.enclosingTopLevelClass
Copy link
Member Author

Choose a reason for hiding this comment

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

Removed override in NoSymbol to make this self-contained and final.

if (this eq NoSymbol) this
else if (isTopLevel) {
if (isClass) this else moduleClass.orElse(this)
} else originalOwner.originalEnclosingTopLevelClassOrDummy
Copy link
Member Author

Choose a reason for hiding this comment

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

Removed override in NoSymbol to make this self-contained and final.

@retronym retronym force-pushed the topic/tailrec-patrol branch from ab8fadc to 803f4d0 Compare March 15, 2019 00:56
@retronym retronym force-pushed the topic/tailrec-patrol branch from 803f4d0 to 8aae5b2 Compare March 15, 2019 00:57
case s @ Some(str) => s
case None => lookupVariable(vble, site.owner)
}
}
Copy link
Member Author

@retronym retronym Mar 15, 2019

Choose a reason for hiding this comment

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

hand inlined orElse to enable tail call elimination

Copy link
Contributor

Choose a reason for hiding this comment

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

case s @ Some(_) avoids unused var. Or case s @ Some(str @ _) for baroque effect.

Recursion didn't come up in the discussions about "avoid match on options".

@retronym
Copy link
Member Author

retronym commented Mar 15, 2019

  • rollback the unintended changes to imports that IntelliJ made.

checkHeadAssoc(leftAssoc)

@tailrec
def loop(top: Tree): Tree = if (canReduce) {
Copy link
Contributor

@som-snytt som-snytt Mar 15, 2019

Choose a reason for hiding this comment

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

Would be nice if -Xlint:loop enabled tailrec warning on anything called loop.

@som-snytt
Copy link
Contributor

The current news in the airline industry focusing on automation and pilot training has me thinking about automation in software production.

@som-snytt
Copy link
Contributor

The extra vertical space makes me wonder if tailrec should be assumed and for the rare case when I prefer to burn a stack frame, I can add @tailwreck.

It could be emitted as either warning or error, like deprecated and deprecatedError, and similarly be handled in the reporter (suppressed or escalated).

@diesalbla diesalbla added the performance the need for speed. usually compiler performance, sometimes runtime performance. label Mar 15, 2019

/** Reset package class to state at typer (not sure what this is needed for?)
*/
@tailrec
Copy link
Contributor

Choose a reason for hiding this comment

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

Since we are at it, can we make this private[this]. In fact, can we backport #7127 to 2.12.x?

Copy link
Contributor

Choose a reason for hiding this comment

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

Someone could volunteer for private this patrol. Also, if they're not going to make private mean private this in scala 3, then -Xlint:private should make recommendations and -Xlint-fix should scalafix them.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd like to keep this PR focussed on the one cross-cutting improvement.

In general, 2.12.x development should start winding down, so backports need to pay their way

def format(width: Int, writer: Writer): Unit = {
type FmtState = (Int, Boolean, Document)

@tailrec
Copy link
Contributor

Choose a reason for hiding this comment

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

BTW, would the pattern case List() two lines below be more efficient if it were case Nil?

Copy link
Contributor

Choose a reason for hiding this comment

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

or case _: Nil.type. Where is the empty list posse?

Copy link
Contributor

Choose a reason for hiding this comment

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

TIL UnapplySeqWrapper. Not sure whether to say "mind blown" or "code blown". Maybe this is why blandishments about List() are dangerous.

// scala/bug#3971 unwrapping to the outermost Apply helps prevent confusion with the
// error message point.
def callee = {
@tailrec
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we make the callee into a val or a lazy val? It looks to be called twice in the issueError, which is called from the match below.

@som-snytt
Copy link
Contributor

Responding to my previous comment, Paul tried -Ytailrecommend for a few months a decade ago. A quick trial of -Xlint:tailrec needs some tweaks, and then suppressions will be needed for various weirdness, such as a map that delegates to super[SortedSet].map with a comment, "required for disambiguation". Either @tailwreck or reporter-based de-escalation.

@retronym retronym merged commit cb47197 into scala:2.13.x Mar 20, 2019
@retronym retronym modified the milestones: 2.13.1, 2.13.0-RC1 Mar 20, 2019
SethTisue added a commit to SethTisue/scala that referenced this pull request Mar 27, 2019
reverts a small part of scala#7876

caught by community build
@SethTisue
Copy link
Member

#7936 reverts a small piece of this. it's unfortunate that not all non-final classes that are extension points for scala-parallel-collections have comments marking them as such.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance the need for speed. usually compiler performance, sometimes runtime performance.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants