PocketBible for Windows Progress Update #17

ChatGPT’s interpretation of a youthful version of Craig (the beneficiary of time dilation, apparently) coding on a laptop in a light-speed spaceship while wearing enormous sneakers.

When traveling near the speed of light, one experiences both the dilation of time and the contraction of distance. An astronaut traveling to a distant star at near light speed experiences less time than his friends back on Earth. He arrives at his destination sooner than expected because he also experiences less distance to that destination — as he accelerates toward light speed, his destination appears to be disproportionately closer to him than it would appear if he were at rest.

Then an interesting thing happens as he gets closer and begins to slow down — his destination gets farther away. This is due to the reduction in the effect of length contraction as he slows towards being stationary with respect to the destination.

We see the same thing happen in the software world. As we approach the end of a software project and find ourselves implementing fewer new features and solving fewer bugs, the release date appears to move farther away. The effect of taking 4 weeks at the beginning of a project to solve a major problem is relatively minor in the grand scheme of things. But taking 4 weeks on a single task at the end of a project makes it feel like it is never going to be completed.

Reactivity

One of the major challenges we’ve faced in the last couple of months is related to Vue — the user interface framework we use. Vue is a “reactive” system. That is, if you want to display some text on the screen, you don’t write code that moves to a particular (x,y) location and outputs the text in a particular font, but rather you define an area of the screen that will display text in a certain font, then attach a particular variable in your code to that area of the screen. Now when you change that variable, the screen is updated with its new value. In other words, the user interface reacts directly to changes in your data.

In order to know when it needs to update the screen, Vue wraps its own code around these reactive variables. It is very good at doing its wrapping. If you’re not careful, it can “infect” certain pieces of data with its reactive wrapper. The result is not only inefficiency (since a bunch of unnecessary code is executed when you change the value of a variable) but potential confusion as Vue believes you’re changing data at a time when you shouldn’t be changing it. In reality, Vue shouldn’t be paying attention to it at all, and everything it reports is nonsense.

One common problem is changing the value of a reactive object or variable while Vue is getting its value in order to render the screen layout. This seems easy to avoid (why would you change something while getting its value?) but in reality, it happens often. For example, the table of contents of a book is a static piece of data. But we don’t keep it all in memory at the same time. So when you want to display the table of contents on the screen, we have to read it from the book. Doing so changes the value of the file pointer that tells us where we are while reading the file. In other words, reading static data (the table of contents) changes a value (file position) in the object in our code that represents the book. If Vue has wrapped this object with its reactivity code, it believes you are changing the data while it’s trying to read it.

The other way this can happen is when accessing some piece of data from a book that needs to be constructed the first time it is accessed but is static after that. Consider the field where you type the name of a book of the Bible that you want to go to. That field needs access to a list of all the book names and the abbreviations of those names that are in this Bible. That information isn’t stored directly in the book file — we have to iterate over the list of all the books of the Bible that are in this particular Bible and generate a supplemental list of all possible names and abbreviations. Consider, for example, 2 John. You might enter “2 John”, “2 Jn”, “2John”, “2J”, “2Jn”, “II John”, “Second John”, etc. We keep a list of all possibilities so we can auto-fill the field. So the act of getting the list of book names for the first time will cause the list of names to be stored in the book object for use if you need it later. Storing the list in the book object that has been infected with reactivity code makes Vue believe you’re changing data while it’s trying to read it.

There are certain significant data structures in PocketBible that are susceptible to this unnecessary infection by Vue’s reactivity code. For example, we keep a list of books that you own. Some are open, some are installed but not open, and some are back on the server. We know a little about the ones on the server; more about the ones that are installed; and a lot about the ones that are open. What we know about each book is stored in an “object” that is the representation of that book in the list.

For the most part, this large list of book objects is not directly displayed anywhere on the screen and Vue doesn’t need to know about it. Our code will reference it when getting Bible text or when showing you the table of contents of a reference book. But you’re rarely looking directly at data directly stored in this list. As a result, this list is immune to being infected by reactivity code, and we’re free to change the data it contains whenever we want.

But because this list is so central to almost everything PocketBible does, it isn’t difficult to accidentally expose it to Vue, then have the result of the reactivity infection show up in a completely different part of the app.

We’ve spent a lot of time in the last 3 months chasing down a major bug related to this reactivity infection phenomena. We’ve been seeing the symptoms for quite a while but hadn’t taken the time to look into it until recently. We think we have it solved but it’s the kind of thing that can pop back up at any time.

New Bible Format Implementation

We continued and perhaps finished work on integrating the new Bible format that we’ve been talking about for the last year or so. In addition to the basic functionality we added some enhancements that allow us to see the version numbers of this Bible data and identify where it came from so that future troubleshooting should be easier.

Link Preview

We began work on the link preview function, where hovering over a link causes the target of that link to be displayed in a pop-up window. For example, hovering over a Bible reference will cause that verse to be shown as long as your mouse is hovering over it. The user interface portion of this task (tracking your mouse and popping up a window) is basically complete; now we need to implement code to get the text that populates the window.

We’ll also be adding code to activate the link preview pop-up on long press for touch-screen devices.

Delete Books

We implemented the ability to delete books installed on your machine. This is trickier than you might think, since you have to make sure the book is not left open in one or more panes after it has been deleted.

Miscellaneous

We fixed a problem with devotional start dates and at the same time, found a problem that might be related to 2024 being a leap year. Should be easy to fix once we take the time to look for it.

We fixed a problem when trying to find an installed book when you only know its publisher ID and book ID. This is rarely used but could have caused a hard-to-find bug had we not caught it when we did.

When looking for a Bible to handle a link (or, in general, any book to handle any link) errors were always being reported to the user even though there are some cases where we want to know there was an error but don’t necessarily want to show it to the user.

5 1 vote
Article Rating
Subscribe
Notify of
guest

6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Peter
Peter
6 months ago

As always, I appreciate the behind the scenes look at what’s going on in the coding world, the challenges that come up, and how you’re handling them. It’s always good to remember that this work isn’t all copy/paste. I’ve definitely been there on those small-seeming issues that take way longer to track down and resolve than expected.

Steve Aubrey
Steve Aubrey
6 months ago

From The Tao of Programming.

A manager asked a programmer how long it would take him to finish the program on which he was working. “I will be finished tomorrow,” the programmer promptly replied.

“I think you are being unrealistic,” said the manager, “Truthfully, how long will it take?”

The programmer thought for a moment. “I have some features that I wish to add. This will take at least two weeks,” he finally said.

“Even that is too much to expect,” insisted the manager, “I will be satisfied if you simply tell me when the program is complete.”

The programmer agreed to this.

Several years later, the manager retired. On the way to his retirement luncheon, he discovered the programmer asleep at his terminal. He had been programming all night.

Jeff Crowder
Jeff Crowder
6 months ago

How tantalizing is this introduction! My only concept of light speed travel is the sci-fi depictions from the 1970s and 80s. Naturally I was excited that maybe progress had neared the end. And maybe it has, then you explained the reality of light speed travel😡 😆😆😆

John
John
6 months ago

If you are looking for any beta testers let me know

6
0
Would love your thoughts, please comment.x
()
x