Code or Die Welcome to my kitchen

Yak shaving tips, Infosec, Astronomy, Gardening

This is my blog. Proud guardian of a square number of cats and one (1) dog, I currently reside in San Antonio, Texas.

I'm interested in gardening, astronomy, infosec among other pursuits. About this site.

Past and current projects.. You can also browse the blog archive if you like.

Message of the Day: Under construction

Think Computationally

A huge gulf exists between dabbling with code and really getting at the heart of a problem using dedicated computational thinking. This gap marks the main difference between the beginner and advanced learner of code.

Well, what is it?

Computational thinking is the often overlooked but vastly important ability to see beyond individual tools such as frameworks, editors, even programming languages. It entails understanding how to go about logically resolving a specific problem in a progressive and incremental manner much as a computer does.

Breaking down problems like this is second nature to long time programmers, and in my humble opinion it is one of the most important skills to learn as a beginning learner of code.

Realizing the importance of how to go about thinking computationally was a great leap forward in my coding education and opened the door to more advanced computer science concepts such as algorithm efficiency, Big O notation, and understanding how to RTFEM1.

OK, but how do I think computationally?

I can attempt to relate computational thinking to physics (putting my Uni degree to work!) There is a method called the free body diagram2, which shows a body, (whatever the subject of the particular problem,) being worked upon by all external and internal forces. The purpose of the diagram is to illustrate and calculate what will happen to the body given a set of known circumstances.

Similarly, in computer science we can think of the program as our body, and the environment/system as external forces. If we visualize all the external and internal forces on our ‘body’, then we are better equipped to predict future reactions. More importantly, we can more quickly find and explain errors when our predictions fall short.

This to me is the essence of computational thinking, an almost Zen-like philosophical approach to programming, which does much to explain the benevolent stereotype of the wise UNIX sysadmin for whom no error message is entirely inscrutable.

You know the type: after struggling with a certain problem for a while you seek the guru’s advice. With a simple hand wave over the keyboard and a twinkle in their eye, they make the problem disappear.

This is computational thinking in action. Much like a good magic trick, there is nothing mystical happening but the combined power of great experience. The goal is to one day also achieve such a level of mastery that makes debugging look like magic.

So I should “Be one with the machine”. Got it.

Computational thinking can be seen in a pristine form when we take a look at the basic rules of the UNIX philosophy3. I won’t go into too much detail right now on each rule; suffice to say this reading material should be required for anyone who is starting to learn to code.

If there seems to be a lot of Zen Buddhist philosophy wrapped up in many computer science concepts, specifically in programming, it is due to this tradition based in practice which has been passed down over decades.

These concepts are not so much rigid dogma as they are principles proven over time to facilitate the creation, communication, and maintenance of code. These concepts are not etched in stone; if any of the accepted statutes were to one day become inadequate, then it would be our duty as pragmatic programmers to revisit, modify or throw out the tenet if it no longer serves our need.

The reason to be fluid is evident. We have seen paradigm shifts in the past, and we will continue to see them in the future. Machine Learning, AI, quantum computing and more new fields will require many of the same principles which have served us in the past, as well as introduce new methods.

Computational thinking will continue to be valuable since it is such a fundamental way of how we program and solve problems using these marvelous devices called computers.

How Google PageSpeed Insights Helped Optimize This Blog

Google’s PageSpeed Insights is a simple and fast diagnostic tool that provides some very interesting and often revelatory suggestions for the front end developer.

Since we are in the business of optimizing all the things, I thought it would be fun to run this website through the tool.

The good news

My site is performant on mobile and desktop as expected for a static site. Browser caching and minifying of assets were both suggested actions that are quickly and easily implemented.

The not so good news

Unfortunately the mobile user experience score suffered slightly due to some tap targets or links that were too small for comfort and my footer was named as an offending element that falls “outside the viewport.” The report stated: “The page content is 421 CSS pixels wide, but the viewport is only 411 CSS pixels wide.” These were easy “Consider fixing”-designated issues and the tool even gave helpful suggestions on how to achieve it.

The devastating news

Significantly decreasing my score on both the desktop and mobile versions was the fact that there was blocking JavaScript on the page above-the-fold, (a term borrowed from print newspaper publishing. Shout out to my time at The Daily Texan for teaching me that one.)

This issue was given an ominous “Should fix” designation in red. I was supremely humbled and after quickly stepping through the five stages of grief, I took a look at the improvement suggestions.

As I suspected, it turned out the blocking JavaScript is my totally cool and awesome comment system, which, as is JavaScript’s wont, loads up asynchronously. This has a noticeable effect only when there are a large number of comments to load from Firebase, which completely makes sense.

While I ponder how to reconcile this issue and perhaps make a change in the future, I am satisfied that it is not a tremendous deal-breaker. My pages load on mobile and desktop just fine and dandy. However, I found it really great to know that this marvelous tool exists. Thanks Google!

Book Review - Ruby Under a Microscope

Ruby Under a Microscope is a great primer into understanding the underlying mechanics of the Ruby language. It demystifies the “magic” surrounding seemingly simple things, for example parsing a string, and I’m a big fan of demystification.

Ruby Under a Microscope, An Illustrated Guide to Ruby Internals by Pat Shaughnessy

This book for me hits the sweet spot between technical aptitude and plain language for both advanced and intermediate levels of study.

What lies beneath (spoiler: it’s C)

Starting out as a novice programmer it is usual to hear that Ruby is an interpreted language. As an interpreted language1, it does not require a compilation step before or at runtime to turn the high-level expressions you’ve written in the text editor into machine-readable bytecode.

However, lurking below this simple explanation is the Matz’s Ruby Interpreter2 (MRI, also called CRuby for reasons that will be quickly apparent,) a series of interpreters which do the heavy lifting when it comes to reducing and interpreting code. It accomplishes this using C and YARV (Yet Another Ruby Virtual Machine3). This applies to Ruby 1.9 and onwards when YARV was merged into Ruby core; before this Ruby was much slower due to the fact that implementation, still in C, was designed as a single-pass interpreted language.

In this capacity, C is acting as an intermediate language4, as it takes the source code of a Ruby program and translates it into a form more suitable for generating object or machine code.

In the book, author Pat Shaughnessy takes us through the life cycle of a simple Ruby “Hello World” program. In excruciating detail we are shown how MRI takes apart each character in a Ruby program and determines the syntax rules to apply. We are also shown the control flow of MRI as the pointer moves through the stack. I found this really fascinating and useful to know.

Hash optimization in Ruby 2.0

Apart from displaying the process broken down into atomic chunks, the book does a great job of showing us how to benchmark and test pretty much anything related to the Ruby language. My favorite example of this is the experiment (Experiment 7-2) on how fast Ruby is able to insert key-value pairs into a hash and comparing this speed in Ruby 1.8 as opposed to 2.0 (with the aforementioned YARV in place.)

The results are surprising. To my understanding, in Ruby 1.8 there is a measurable time lag every 67th key/value pair insertion that is due to bin allocation being performed behind the scenes. Ruby has to “re-size” the amount of memory or bins needed to fit the key/value pairs. In Ruby 2.0, YARV optimizes this allocation. For hashes under 7 elements, hash data is simply saved in an array, known as packed hashes. Once you try to insert the 7th key/value pair, this packed hash is discarded and the actual hash function is called and bins allocated. In this way, hash tables are sized automatically by Ruby, which evenly distributes values across bins and minimizes collisions, (collisions here refers to having to dig into a bin to get a value, i.e. bins are kept shallow.)

Last words

All in all, the book is a very valuable and eye-opening account on the innards of Ruby. There are chapters on JRuby, and metaprogramming. In future editions it will be interesting to see if new developments will be covered. I hope so.

I liked this book because it forces one to reckon with reality and think beyond interpreters, beyond the simple I/O of programs. We know we are getting “hardcore” when we start delving into computer science topics such as abstract syntax trees, memory allocation, pointers, etc. All these concepts have been abstracted away in our modern interpreted languages. This is an amazing feat in of itself, nonetheless I would recommend this book to anyone with more than a passing interest in coding and programming or computer science, even if Ruby is not the language of choice. Here’s why:

In any programming language one will find the same fundamental building blocks of computer science. This book inspired me to dig deeper and was one of the main reasons I decided to learn more fundamental computer science topics and even learn C itself!

I recommend starting with any of the freely available online university introductory computer science courses, particularly Stanford’s5 or Harvard’s6.