Compiler Needs More Time

Complexity...

You have seen this compiler message:

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

Chart { ... } <<== Error

It is the compiler telling me in the vaguest way possible that my code needs to be better factored. If it only pointed out which block took the longest time - or had the highest cyclometric complexity - or which type was hard to check... what was the type it could not identify... just a hint, please!

I've googled how to "break up the expression" - lots of general advice... no real heuristic...

Sarun has a good method... comment out some of your code - a consistant block and see if the compiler can make the "Kessel Run in less than twelve parsecs" (Millennium Falcon).

When it can compile then you kinda have a target... get that commented-out code better factored - make it quicker to TYPE CHECK. Wait a minute... it is not running the code - it is just taking too long to type check! So how do we make that easier? Seems like a bunch of explicitly typed structs and classes (as Swift code is) would have no problem being typecast - huh?

References:

How to break up Struct & Classes - Hacking with Swift

"Taylor Swift writes SO many breakup songs." ... "Oh wait. Were you serious?"

How to fix "The compiler is unable to type-check this expression in reasonable time" error. - Sarun W

Apple Developer Forum ... topic has one good piece of advice. There is some type-related issue around here
The actual issue might be:
The expression is actually too complex for Swift compiler
You have some type-related errors inside the expression

To eliminate the second case, you need to check
All the syntax is really valid.
All the properties used there are really declared and have the right types and annotations.
All the methods used there are really declared and have the right signatures.
All the views used there are really declared as valid
Views.



Hard code to test.

I've been getting the Type Checking Error for a day or so... and not making much progress... so I switched gears. I decided to invert my problem domain a touch. Instead of figuring out where my code was too "complex" for the all-mighty compiler - that needs more time. I decided to just hard code the position of the Buy RuleMark... and see if I can work into figuring where that blue line should be... where is getting to be the position of the line. Here in this example screen shot - I've placed it at index 20.

Don't let me confuse you ... 20 is a "time index" for the X-Axis. I've found that Charts API will plot weekend days/hours if I allow Charts to use "Date" as the X-Axis. I don't want "no stinking weekends" plotted. So I convert all the points to an "ordinal" value on the X-Axis.

This ordinal X-Axis works well for plotting the general price charts... but then when I want to overlay my Buy & Sell transaction upon the stock chart... I've got to calculate some date to ordinal stuff. This is where I've had problems...

I'm getting closer... do you have any ideas - cause it seems I must be doing it the hard way?

There is a lot of value in getting just the bare bones of a feature on the screen - just that blue line over there gives me the motivation to continue this very rough part of the journey. I'm thinking of that blue line as a "tracer bullet" to my target. Yes, it is hard-coded data... but I can start to see I'm not but one brilliant idea away from a generalized code solution.

Researching...

In reflection upon my troubles... I know that the issue I was fighting was very much self inflected bad code.

But I kept wondering what "Type Checking" truely means to a compiler running in the milisecond world of computer instructions. In my physical world it took me well over 30 hours to wressel that aligator to the dirt... and I'm still picking up pieces of aligator. So from my prespective ... why did the Swift Compiler give up type checking my code after say... best guess ... 60 seconds (yes that is forever in the computer's time domain)... but in the human time domain... after 5 or 10 compiles with that stinking type checking error... couldn't the compiler throw me a hint... could it extend the time limit a bit to see if maybe another 60 seconds of human time would resolve something better to report?

That is where my head is at... so I did a search for compiler flags... maybe down deep in the guts of the Swift Compiler there is a way to extend the damn Type Checking timeout value.

It looks promising here's a reference... I may have to go deeper into this rats nest.

See also: https://useyourloaf.com/blog/slow-swift-compiler-performance/

  • -Xfrontend -warn-long-function-bodies=<limit>

  • -Xfrontend -warn-long-expression-type-checking=<limit>

From https://developer.apple.com/library/archive/releasenotes/DeveloperTools/RN-Xcode/Chapters/Introduction.html#//apple_ref/doc/uid/TP40001051-CH1-SW878

  • The compiler can now warn about individual expressions that take a long time to type check.To enable this warning, go the Build Settings, Swift Compiler - Custom Flags, Other Swift Flags, and add the -Xfrontend -warn-long-expression-type-checking=<limit> flag, where <limit> is the lower limit of the number of milliseconds that an expression must take to type check in order for the warning to be emitted.
    This allows users to identify those expressions that are contributing significantly to build times and rework them by splitting them up or adding type annotations to attempt to reduce the time spent on those expressions. (32619658)


I tried this compiler flag last night... did NOT get the results I expected... in fact even with a small value 200 mili-seconds I didn't get any noticable change in behavior. Maybe I set it wrong? You try it...

My TYPE error

If you are keeping score.... the compiler was absolutely correct. Somewhere in the Chart { ... } block of expressions was a type error. Being just a step away from a caveman... it took me well over 30-50 hours to find it. The compiler got off easy... it didn't waste more than an hour of compile time on this ridiculous problem.

Turns out one of the things I've tried to notice and quit doing is my habit/practice of renaming things in my code... I don't worry too much about the first thing that pops to mind. I use the first thing... and change it... again and again,,, and again. But this seems like a bad habit / a poor practice - so I've been trying not to do it.

I typically do this to start a coding session. It allows me to ease into the context. Or I find that it is a task I do later at night... a clean-up chore.

It was because I finally broke down... and started renaming types in my code that I noticed the PROBLEM. I refactored the variable name "item" to "point". Inside the ForEach of the Chart, the code is building the plot using these points - for a bad reason I had used the variable name "item". I think it came from a for-in example code... I never can remember the ForEach syntax.

Well, when I got that refactored... it STUNG me. The call to plot the "buy" stock as a RuleMark was passing a point... but the signature was receiving a "data" type - NOT the same thing at all. Easy to spot when the item name was specific. Hard to spot when the name was generic.

Lesson to learn... renaming is time well spent. Do it - don't squelch it.