Skip to content

Instantly share code, notes, and snippets.

@wilmoore
Last active April 17, 2023 18:39
Show Gist options
  • Save wilmoore/5d3a1be77375f6ebc325cc111bc88ede to your computer and use it in GitHub Desktop.
Save wilmoore/5d3a1be77375f6ebc325cc111bc88ede to your computer and use it in GitHub Desktop.
Income Sources :: Books :: Build & Launch a SaaS Business in 13 Days

Income Sources :: Books :: Build & Launch a SaaS Business in 13 Days

⪼ Made with 💜 by realpolyglot.dev

Introduction

There are a lot of books out there

Hello, Winner. You've made an excellent decision in picking up this book as part of your journey toward becoming a confident, self-sufficient JavaScript/TypeScript software developer. You can rest assurred that a LOT of hard work has gone into learning the concepts presented to you. There will be NO-fluff and NO-hand-waving here.

The best books I've read on software development, left me with knowledge ...:

  • I was inspired to immediately put into practice.
  • I was able to use across languages and platforms and could lean on throughout the entirety of my career.
  • I was able to use to build non-trivial, real-world software beyond the typical hello world or todo app.

A Word of Encouragement

The world of software development can be rough. Imposter syndrome is real, but you can take control and eliminate it by crafting REAL software solution on your own.

As Peter Theil says, competition is for losers. Find your unique purpose in life, look for problems or gaps in the world, then build creative solutions. Of course, you'll need to be equipped with the knowledge to solve real-world problems in order to achive this. Once you are well-equipped, you'll start to notice unique problems only you are interested in solving because you are now confident that you can solve them.

Why TypeScript?

JavaScript is going to be around for a long time; however, as programs become more complex, you are going to want a type system. I've written A LOT of vanilla JavaScript and I understand most, if not all of the weird gotchas; however, I promise you, TypeScript is much nicer and holding all of JavaScript's gotchas in your head isn't really all that exciting nor beneficial.

Working with a well-designed type system makes writing programs faster, easier to debug, and easier to extend in the future.

Why Libraries; Why Packages?

Small modules or libraries is what brought JavaScript back to life. I was there when JavaScript was declared DEAD. It seemed like everyone had essentially stopped writing JavaScript. Then, all of sudden, there was Node.js, then npm ... and, all of a sudden, JavaScript was everything again. In fact, it was more than everything. People stopped writing PHP and Ruby, and started moving over to Node.js and JavaScript.

As software engineers, a lot of our best work is hidden behind a compiler or obfuscated by source code minification. It can be incredibly satisfying as a software engineer to build something interesting and useful, publish it, and get credit for it.

As a bonus, I've found that publishing a library that people actually use, this can get you recognized in the industry by co-workers as well as by potential employers. I've had many job interviews where I was essentially fast-tracked past other qualified candidates. In many cases, my interviewers asked me softball questions where we talked mostly about my own projects and libraries. This never happened before I started publishing libraries.

My first library success was a package called selectn. This library came to be due to the fact that I was working on a very large team of JavaScript engineers and while refactoring large portions of the code and pair programming with co-workers, I started to notice a pattern emerging where we were writing a lot of boilerplate code around our data fetching functions. We needed to guard against errors where the incoming JSON object was expected to have data at a nested path; but, sometimes, the data did not exist. This meant, we were repeating a lot of boilerplate code. We were not only writing code to guard against the data not being there, but, then we were repeating a lof of that same code once we saw the data was there and went to fetch it.

Furthermore, I noticed that things got even more interesting when passing this data down a promise chain. By being able to see all of the places where there was boilerplate, I was able to not only solve the problem with a purpose built library, but also, I was able to craft the its API in such a way that made it really easy and enjoyable to use.

What are we building & how do you come up with these ideas?

Every software product I've built, I've come across many opportunities to extract pieces of the product out into smaller packages. For example, the last time I developed a web-based audio player, I ended up breaking it up into components. The components were comprised of both visual components such as the audio element and the audio controls (i.e. play, pause, etc), as well as non-visual functionality-based components.

It isn't always obvious how to break these up ahead of time. Usually, I code until I have something that works, then, as I modify the code, the opportunities to break things up usually presents itself. I've found that it is better to not force this process and allow it to happen organically. I've found that when it happens organically, the extracted packages tend to be much more useful on their own vs trying to force it. Whenever I've forced it, I've noticed that the extracted packages were almost never all that useful on their own.

What exactly will I learn from all of this?

  • How To build a simple text parser
  • Just enough about regular expressions to be useful
  • How to setup and organize a TypeScript/JavaScript library
  • Test driven development
  • How to publish a library to the npm registry and maintain it

As a software engineer, eventually, you'll find it necessary to build a parser for a text-based data format that doesn't yet exist.

Without the ability to parse text, we wouldn't be able to build web scraping tools, compilers, full-text search engines, JSON & CSV parsers, or natural language processing programs. You'll find text parsing a lot in data science as well.

Let's consider a source code compiler for a moment. A compiler is a set of programs that first reads source code (text), breaks it up into tokens, then it tries to make contextual sense of those tokens given the order in which they are found. There are more steps to it than that, but that is out of scope for now. Ultimately, a compiler tries to understand the source code then it converts it into a running program.

Writing compilers is a non-trivial task. Writing fast compilers is even more difficult. Fortunately, this manuscript is not about compilers; but I had to mention them because, usually, text books on compilers is the only place you'll find information about how to build a text parser. That's unfortunate because, text parsing is a very important topic in computer science.

Chapter 1 :: You've been lied to about "Regular Expressions"

large complex problems become easier to understand and ultimately, solve, once you've broken them down into smaller chunks.

Lexical analysis, lexing, or tokenization is a programming task that separates the given series of text into smaller components based on some rules. The first step in a compiler is the lexical analysis step. Lexical analysis is enabled by something called a grammar. A grammar is just a list (or an array) of rules. Each rule is given a name and a regular expression matching a pattern in the source text.

For example, you might want to write a program that identifies height in a block of text such as "3 FT 10 IN". You could write a fairly simple (naive) regular expression to do that.

/\b\d+ FT \d+ IN/gm

The above regular expression, if said in plain english would read as: "Look for a word boundary, then immediately following that word boundary, look for one or more numeric characters, then expect a single literal space character, then "FT", then another literal space, one or more numerice characters, a space, then "IN".

The power of regular expression is that you can "express" all of the above, with just a few symbols. That is why I like to think of regular expressions as a domain specific language for matching textual patterns.

That being said, the more complicated the regular expression, the more difficult it is to read, debug, or update. For example, the text "3 FT 10 IN" is fairly simple; however, what if we were required to match all of the following with a single regular expression:

  • 3 FT 10 IN
  • 3FT 10IN
  • 3FT10IN
  • 3' 10"
  • 3 ' 10 "
  • 3'10"

The regular expression could no longer be naive. It would have to be a complex regular expression such as:

/\b(?<nfeet>\d)+[\s]*(?<feet>FT|')[\s]*(?<ninches>\d)+[\s]*(?<inches>IN|")/gm

This is where things start to get weird. There are several places where characters are optional, and if we were to intoduce even one more variable, this regular expression goes from somewhat hairy, to completely unmanageable.

If you haven't already come across the following quote, keep progamming long enough and you will:

Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.

That quote has been echoed by hundreds, if not thousands of programmers over the years advising other programmers to stay away from regular expressions. This is a lie. You've been lied to about "Regular Expressions". They aren't something to shy away from. They are a tool just like everything else in software. They are to be use carefully, but not to be abused. Complex regular expressions are an abuse. By keeping them simple, they will not only do the job better than anything else, but they'll also be easy to maintain.

Keep your regular expression simple. Don't try to match everything in a single pass. The grammar for text parsers generally are broken up into tiny patterns that match the smallest unit of characters that can provide enough context to be meaningful.

Chapter 2 :: Defining the Problem / Project

...

references


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