Learn more about our current job openings and benefits of working at FSL.
Detailed reviews and feedback from past and current clients.
Get to know the Management Team behind FullStack Labs.
Our step-by-step process for designing and developing new applications.
Writings from our team on technology, design, and business.
Get answers to the questions most frequently asked by new clients.
Learn about our company culture and defining principles.
A high level overview of FullStack Labs, who we are, and what we do.
A JavaScript framework that allows rapid development of native Android and IOS apps.
A JavaScript framework maintained by Facebook that's ideal for building complex, modern user interfaces within single page web apps.
A server side programming language known for its ease of use and speed of development.
A lightweight and efficient backend javascript framework for web apps.
An interpreted high-level programming language great for general purpose programming.
A JavaScript framework maintained by Google that addresses many of the challenges encountered when building single-page apps.
A JavaScript framework that allows developers to build large, complex, scalable single-page web applications.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
View a sampling of our work implemented using a variety of our favorite technologies.
View examples of the process we use to build custom software solutions for our clients.
View projects implemented using this javascript framework ideal for building complex, modern user interfaces within single page web apps.
View projects implemented using this framework that allows rapid development of native Android and IOS apps.
View projects implemented using this backend javascript framework for web apps.
View projects implemented using this high-level programming language great for general purpose programming.
View projects implemented using this server side programming language known for its ease of use and speed of development.
We have vast experience crafting healthcare software development solutions, including UI/UX Design, Application Development, Legacy Healthcare Systems, and Team Augmentation. Our development services help the healthcare industry by enhancing accessibility, productivity, portability, and scalability.
We offer a range of custom software development solutions for education companies of all sizes. We're experts in Education Software Development and specialists in enhancing the learning experience across web, mobile, and conversational UI.
We're experts in developing Custom Software Solutions for the Logistics Industry. Our work offered a whole new and more efficient way for Logistics companies to manage their crucial operations.
We partner with various construction industry organizations to build custom software development solutions. Our Construction Software Development Services allow construction companies to manage projects, resources, and documentation.
We have vast experience crafting healthcare software development solutions, including UI/UX Design, Application Development, Legacy Healthcare Systems, and Team Augmentation. Our development services help the healthcare industry by enhancing accessibility, productivity, portability, and scalability.
We offer a range of custom software development solutions for education companies of all sizes. We're experts in Education Software Development and specialists in enhancing the learning experience across web, mobile, and conversational UI.
We're experts in developing Custom Software Solutions for the Logistics Industry. Our work offered a whole new and more efficient way for Logistics companies to manage their crucial operations.
We partner with various construction industry organizations to build custom software development solutions. Our Construction Software Development Services allow construction companies to manage projects, resources, and documentation.
Learn more about our current job openings and benefits of working at FSL.
Detailed reviews and feedback from past and current clients.
Get to know the Management Team behind FullStack Labs.
Our step-by-step process for designing and developing new applications.
Writings from our team on technology, design, and business.
Get answers to the questions most frequently asked by new clients.
Learn about our company culture and defining principles.
A high level overview of FullStack Labs, who we are, and what we do.
A JavaScript framework that allows rapid development of native Android and IOS apps.
A JavaScript framework maintained by Facebook that's ideal for building complex, modern user interfaces within single page web apps.
A server side programming language known for its ease of use and speed of development.
A lightweight and efficient backend javascript framework for web apps.
An interpreted high-level programming language great for general purpose programming.
A JavaScript framework maintained by Google that addresses many of the challenges encountered when building single-page apps.
A JavaScript framework that allows developers to build large, complex, scalable single-page web applications.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A dynamic programming language used in all sorts of web and mobile applications.
A cross-platform programming language designed to run robust applications on any device.
A UI toolkit used to build natively compiled applications from a single codebase.
A functional programming language that’s ideal for scalability, maintainability, and reliability.
A Customer Relationship Management (CRM) platform that seamlessly integrates with your business operations.
A high-performance programming language that makes it easy to build simple, reliable, and efficient software.
View a sampling of our work implemented using a variety of our favorite technologies.
View examples of the process we use to build custom software solutions for our clients.
View projects implemented using this javascript framework ideal for building complex, modern user interfaces within single page web apps.
View projects implemented using this framework that allows rapid development of native Android and IOS apps.
View projects implemented using this backend javascript framework for web apps.
View projects implemented using this high-level programming language great for general purpose programming.
View projects implemented using this server side programming language known for its ease of use and speed of development.
In software development, developers leverage a bevy of toolsets to assist with work, such as an IDE (interactive development environment) like VSCode, replete with open-source plugins, or commercial apps like JetBrains’s Webstorm. Not only are there software tools, but there are also mental tools — concepts programmers reflect on in daily work, handy-dandy acronyms that reflect principles: KISS (“Keep it simple, stupid”), SPOT (“Single Point of Truth”), YAGNI (“You Are Not Gonna Need It”). For the bigger picture, there are also patterns of writing code (builder, singleton, functional, etc).
But what about some principles from which those principles are derived? This article explores some concepts taken from the author’s studies of software design, formal logic, and software engineering research. With some concise explanation and simple examples, other programmers could reflect on some more tools that could illuminate underlying principles, or give some food for thought.
As a developer, the following situation may sound familiar. There’s a problem with a pull request that another developer submitted, and as a reviewer, one can write a comment underneath the code in question and specify what the issue is — if it didn’t use a utility method or is merely too verbose, among other things. But what if, in this instance, the code itself is implemented correctly and syntactically looks okay, but the way it works is not correct in the “larger scope” of the system?
Consider the situation: There’s an intermittent failure to retrieve data from a request to a third-party API (403 unauthorized). It requires authentication headers that another part of the application handles (authenticating, storing, and so on). A method is available, getAPIHeaders, which will retrieve them. The code looks like:
Looking at the example above, while the code looks correct, an assumption is faulty. What if the auth data isn’t always available when this method is run, and returns null or undefined, rather than throws an error? It wouldn’t be fair to say the code’s implementation is wrong, only that one of the assumptions it makes is intermittently faulty.
So to clearly communicate in a comment about the issue, there has to be some mention of the context surrounding the error. One could mention implicit coupling or context, but it’s clear there is a “bigger picture” surrounding the code, or what in formal terms is called an abstract state.
As it turns out, the computer scientist and all-around wizard Tony Hoare introduced a formal system in 1969 to describe this state. While developers are certainly familiar with logic statements of if’s and else’s, this kind of logic wraps “around the code” that describes the “state of the computation” before and after the code is executed:
{P} C {Q}
{P}
x = y * 3;
{Q}
The above line is a Hoare Triple, the foundation of Hoare logic. P (the precondition) and Q (the postcondition) are facts about the state of the program, or assertions before and after the code is executed. So if the P, or precondition, in this example is:
P: { y = 5 }
Then this condition of “y equal to 5” must be true before the program runs. (Unlike code, this is simply equality and not an assignment.) In the above Auth Data example, then, perhaps the precondition is something akin to auth data being defined before the code executes. And furthermore, a postcondition cements the formula:
Let’s say the Q (or postcondition) is:
Q: { x = 15, y = 5 }
For each assertion of the Hoare triple to be true, then after the code runs, the state of the program will be such that Q is true. (The code could do something in addition to that, but in order for the Hoare triple to hold it must fulfill the Q.)
{ y = 5 } x = y * 3; { x = 15, y = 5 }
While these examples are basic, Hoare Logic can extend in several ways, such as going over many lines or using intricate logical notation. The insight here is that Hoare Logic provides a provable logical formulation over code, a meaning that goes beyond code and spec, and into assumptions about what state the code is supposed to produce. If the behavior of the system is faulty, it could be because of assumptions of preconditions (or postconditions) that don’t hold or are missing. So if a developer ignored this implication in debugging an issue, it could take longer than necessary (lots of logging all over) instead of considering this logical layer.
This is referred to as Level 3 Design/Logic by Computer Scientist James Koppel. Thinking about the state of the system before the code block is run and after, and whether those states are appropriate, is crucial, and implicates issues relevant not only to the software’s code but in this more abstract logical level.
So another way of looking at this information surrounding the code is that a developer’s mind contains these ideas, at least while the task is recent and the memories are fresh. But since programming is a team sport, the essentials of that info are relevant for the team or enterprise as they review code or refer back to it in the future. The Hoare logic codifies that thinking in the form of rigorous logic and puts it on screen for all to see.
But what about the system as a whole? Is using APIHeaders from one part of the system and plugging into another the right approach in terms of the overall system?
Let’s assume this code also works. But as seen right away, it’s not quite clear what the structure is supposed to be — is the number value for each fruit a quantity? Or price? Or consider this other tidbit, as part of an email messaging system:
What are the characters written in the stream for the last lines meant to do? It appears contextual, so maybe another domain expert could understand what this writing refers to, but the clues for understanding are muddled. As mentioned earlier, some developer’s minds once understood why this data structure was written this way, or what method order is chosen, but it’s not present anymore — and if they’ve left the project, gone completely.
In the 2013 conference paper titled “Dark Knowledge and Graph Grammars in Automated Software Design,” Don Batory and friends describe a problematic cycle of developers writing code to satisfy requirements, then other developers using that code to write according to new requirements, while in each iteration having to retrace the steps that the former developer took to re-examine their decision making. This “Dark Knowledge” is the missing ingredient between each hand-off, which developers new to the codebase have to re-trace and make educated guesses about. While their solution is to introduce the concept of “graph grammars” to automate the encoding of dark knowledge, they state the overall “goal is to encode design decisions explicitly in software…so these decisions can be revisited...” (Batory et al, 2013)
So, revisiting the example above, and adding types (going from JavaScript to TypeScript, highly recommended if a dev hasn’t tried it already!):
Or going back to the message method, and creating a utility that describes what the stream writes, and importing that:
The code now better represents the design, shortening the time for comprehension.
While brief, these points illuminate deeper principles for writing software that can be helpful to reflect on during the process. With Hoare Logic, the existence of a higher level of logic surrounding code is explicated, and ignoring it misses the opportunity for clarification that could save time, if not improve the correctness of the code itself. By taking this a step further and considering the “mind of the programmer” as useful knowledge not just for development, but for persisting ideas into the future of the codebase, the encoded “Dark Knowledge” encoded can save time or even the ability to understand the code choices more than an educated guess.
We’d love to learn more about your project.
Engagements start at $75,000.