Garrett Bluma

... is a web platform engineer, functional programmer, and amateur type theorist. He recently graduated from Nova Southeastern University with a Master's in Computer Information Systems. He is actively researching formal methods, machine learning, and human computer interaction.

September 21, 2014 at 1:01pm

0 notes

Physical Data Independence

Database developers use the term physical data independence to draw a distinction between the bit-for-bit representation of the data on disk (or in memory), and the abstract concept of data. It is not wise to allow the database user to work with data directly on the disk, or to include device specific semantics in the specification—-both of which micromanage the lower-level semantics breaking the abstractions. By keeping the separation distinct, we find value and a minimization of maintenance costs.

With physical data independence, the business user can write a request for data in a language that contains minimal technical baggage e.g. SQL), which frees up the user to be concerned less with the minute details and more with representing the problem well and formulating a solution. That is to say, by using an abstraction, data can be represented using a generic model with simple transformations that can be composed to produce insightful results.

This distinction is also important for database developers and governing bodies (the technical kind), because it allows standards to develop. A large set of vendors can develop a specification together (e.g. HTML, SQL, Javascript, etc.) and the community benefits. Even on a project with one user, standards provide consistency between versions of the same software over the product life-cycle and it helps simplify the code. The abstraction allows the physical bits to be rearranged, compressed, indexed differently, or transformed in different ways without breaking the higher-level interfaces. Users may take their understanding of one product and use a competitor’s with very little effort.

 

September 18, 2014 at 3:36pm

0 notes

On static quality, mathematics, and programming

"Pirsig defines static quality as everything which can be defined. Everything found in a dictionary, for instance, is static quality. These static forms, if they have enough good or bad quality, are given names and are interchanged with other "people", building the base of knowledge for a culture."
Pirsig’s metaphysics of Quality (Wikipedia)


There is a profound value in reducing the complexity of a dynamic process to something static. Indeed, as Pirsig claims above (and indirectly in his book “Zen and the Art of Motorcycle Maintenance”), the foundation of cultural knowledge was developed from innumerable iterations of this reduction process.

When our ancestors discovered that the words they spoke could be represented as symbols on a page, they created a form of written language, which was static. Storytellers no longer had to repeat their stories in person. They could copy their stories to paper and distribute them, even beyond the reach of the author. Even today, I cherish the chance to read the epics of Homer, written before the founding of Rome, and with no loss of quality. Certainly, we lose the flair of a good orator, but there is an undeniable quality in the static form.

If we let ourselves explore this idea, we can find similar reduction take place in many contexts and medium. (I’ll avoid discussing Marshall McLuhan at this point despite the opportunity being ripe. The reader can explore this on his/her own.)

One interesting context for this dynamic-to-static reduction is education. Learning used to only occur “on the job,” but schools began to group topics into similar subjects and develop curriculum to aid the digestion of that information. This became useful to society, popular, and in the last hundred years, commonplace. Now, the average student is expected to be competent in reading, writing, history, mathematics, science, and technology. These days curriculum is a “thing” and we can discuss the benefits, problems, and exceptions thereof without difficulty.

In the field of mathematics we can see a similar story played out a thousand of times over. A problem comes up, mathematicians stumble around the subject, then a denotational system is developed to clarify and objectify the solutions. This is what Leibniz and Newton did with Calculus; what Stratchey and Scott did with Denotational Semantics; what Turing and Church did for Computation; what Gentzen (and others) did for logic; what Eilinberg and Mac Lane did for Category Theory; and so on.

In my day-to-day life as a working programmer I use the mathematics mentioned above, recognize the value therein, yet I fail to apply this principle anywhere. I’m confused and troubled by our modern inability to innovate on programming in general, but if I could magically alter my workflow to be more “advanced,” I would probably do more of the following. 

  • Use code generators to build code from data (where functionality is dependent on data)
  • Use dependently-typed languages to design DSLs that expand functionality while retaining safety. Dependently typed languages make use of static program semantics, which are themselves able to treat code as data, checking for possible contradictions of logic.
  • Use lightweight data formats instead of communication patterns.
  • Delete more code.

12:42pm

0 notes
Fossilized nautilus shell with crystallized quartz embedded in several chambers of the shell.

Fossilized nautilus shell with crystallized quartz embedded in several chambers of the shell.

June 15, 2014 at 4:01pm

0 notes
Violin, case, and assorted papers. Fountain pen on paper.

Violin, case, and assorted papers. Fountain pen on paper.

June 12, 2014 at 6:54pm

0 notes
Mount Olympus, SLC, UT. Ink wash with pen overlay.

Mount Olympus, SLC, UT. Ink wash with pen overlay.

May 22, 2013 at 11:00pm

0 notes

On good days and bad days

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian Kernighan

Coding cleverly is a problem for all programmers, but perhaps more so for advanced programmers than novices. Novices tend to stick with what works and don’t reach for deep abstractions when they aren’t needed. However, advanced programmers do this often, and this actually makes their job harder. Clever code demands clever programmers—once we rely on cleverness it’s no longer a bonus.

Cleverness is generally an asset in programming. We don’t get to rely on the usual senses of spatial awareness or linguistic flow when we write code—instead we have to rely on logic and inference. Cause and effect. Evidence, reason, and truth. It takes cleverness to identify why race conditions occur in a distributed system. It takes significantly less cleverness to write a distributed system that exibits race conditions.

We might think to ourselves, “if I just add a level of indirection here, then we get a useful abstraction.” This may be true, but should ask some questions before comitting to a change like that:

Is it disoverable? — If I make this change, will others discover it without my telling them?

Does it improve the project? — Will the indirection save us time or slow us down?

Does it require the cleverness needed to understand the project? — When I debug this, will I need to trace through the code or can I skip a step and just rely on a rule of thumb?

Those of us who have made a career our of cleverness may think that we are always consitently smart—everyday is a good day—but this is not the case. Cleverness comes in fleeting moments of inspiration, not as an infinite resource which we can draw upon when we like. The veteran programmers are acutely aware that, indeed, when a programmer needs to be clever that is precisely the moment that they aren’t. Grit and stubbornness are better attributes than cleverness. (Group discussion and measured analysis is better still.)

So when we design our programs we shouldn’t expect that our future selves will be clever enough to figure out the interdependencies among objects, the changing network architecture, the concurrent projects that are all being worked on at the same time with the same code, etc. Very likely, when we need to make tough decisions, we will still be slogging through a confusing email thread, distracted by meetings every 30 minutes, and having only slept about four hours the night before. We won’t be bringing our A game like we think we will.

Instead, we should expect our own inadequacy and use our current cleverness to make the code maintainable for the bad days. Also, if you think about it, this is an investment for the future becuase we’ll have more free brainpower for other problems.

"many a programmer derives a major part of his professional excitement from not quite understanding what he is doing, from the daring risks he takes and from the struggle to find the bugs he should not have introduced in the first place." — E. W. Dijkstra

May 9, 2013 at 11:00pm

0 notes

Abstraction and cognitive load

When programmers need to make a system simpler, they are told to reach for abstraction as a means of doing this. But abstraction is an odd thing; it escapes easy definition. It’s something we use to make programs better, more comprehensible, more general, more flexible, and hopefully easier to reuse.

“In computer science, abstraction is the process by which data and programs are defined with a representation similar in form to its meaning (semantics), while hiding away the implementation details.” – Wikipedia

But how do we get abstraction?

Abstraction is fundamentally built up from constraints in a system and these constraints guide future changes into patterns. Creating an abstraction is about finding the places where things can become separated. An example of this is the separation of code and data, or commands and queries. This is a truly a challenging task, because not only must a person understand to the structure of the code and its semantics, but they must also predict how someone else will interpret them.

While there may be some technical merit to abstraction, we must admit that abstraction is largely something we do for other people. When we struggle to abstract a system we can’t just say, the tools are ineffective, we must also ask ourselves how can I communicate better?

It is always enticing to reach for new tools to produce cleaner abstractions—this is good to some degree—Haskell, Ocaml, and Scala do provide many wonderful new tools for developing abstractions. They even report when those abstractions are being violated—But the danger of this is letting the compiler tell us how to build our applications. Abstraction should be something we impose on the code, despite its unwillingness to be abstracted. We should not do it reactively. When we react, we give up some of our intended design. Although it is purely conjecture, it may even be the case that languages that interrupt us with numerous error messages actually train us not have good design. We get distracted by details and lose sight of the bigger picture.

I am a proponent of static types, but I think it is worth heeding old advice. Get away from the computer. Pull out a pen and paper. And design the thing without all the distractions, even helpful ones. When you go back to the computer you’ll have an advantage in all respects.

11:00pm

0 notes

Abstraction and cognitive load

When programmers need to make a system simpler, they are told to reach for abstraction as a means of doing this. But abstraction is an odd thing; it escapes easy definition. It’s something we use to make programs better, more comprehensible, more general, more flexible, and hopefully easier to reuse.

“In computer science, abstraction is the process by which data and programs are defined with a representation similar in form to its meaning (semantics), while hiding away the implementation details.” – Wikipedia

But how do we get abstraction?

Abstraction is fundamentally built up from constraints in a system and these constraints guide future changes into patterns. Creating an abstraction is about finding the places where things can become separated. An example of this is the separation of code and data, or commands and queries. This is a truly a challenging task, because not only must a person understand to the structure of the code and its semantics, but they must also predict how someone else will interpret them.

While there may be some technical merit to abstraction, we must admit that abstraction is largely something we do for other people. When we struggle to abstract a system we can’t just say, the tools are ineffective, we must also ask ourselves how can I communicate better?

It is always enticing to reach for new tools to produce cleaner abstractions—this is good to some degree—Haskell, Ocaml, and Scala do provide many wonderful new tools for developing abstractions. They even report when those abstractions are being violated—But the danger of this is letting the compiler tell us how to build our applications. Abstraction should be something we imposeon the code, despite its unwillingness to be abstracted. We should not do it reactively. When we react, we give up some of our intended design. Although it is purely conjecture, it may even be the case that languages that interrupt us with numerous error messages actually train us not have good design. We get distracted by details and lose sight of the bigger picture.

I am a proponent of static types, but I think it is worth heeding old advice. Get away from the computer. Pull out a pen and paper. And design the thing without all the distractions, even helpful ones. When you go back to the computer you’ll have an advantage in all respects.

March 29, 2013 at 12:19pm

0 notes

A couple notes on teaching programming

I spent some time tonight teaching the basics of programming to a friend. We were focusing on C# in particular, covering the basics of object-oriented programming, instantiation, control structures, and the like… It’s always refreshing to take a step back and re-evaluate the fundamentals with fresh eyes. Many of the things that I have become accustomed to are actually incredibly strange, and some of the things I used to find problematic are actually quite easy to teach.

For example. At one point we got stuck on the intricacies of how variables are overridden in child objects. Even though the variable was updated in the subclass, the parent values were used instead—this was counter-intuitive and rather difficult to convey. We had to manually trace the references back from the point of usage to find out that, in our context, our object was being treated as the parent class. It inherited a set of supposedly hidden variables, and it was returning those variables when we expected them to be hidden. This was a bit too much for my friend to absorb, so we moved on.

Object instantiation was surprisingly easy to describe however. It made sense that objects can hold properties about themselves in a sort of namespace. Even that the objects have local functions which operate on local data. The process of constructing an instance of a class, as if it were a template, was also simple and direct.

We didn’t cover exceptions. I suspect these will cause some trouble down the road…

On the other hand, we talked a bit about functional programming. I always hesitate to talk about stuff like this because, even if I find it interesting, that doesn’t mean it is worth distracting someone else. But it was funny to realize how very few tools are needed to get a big pay-off: function application, local identifiers, function arguments, and namespaces. And it’s worth mentioning that tracing references and variable assignment was simpler too.

Obviously this is very subjective, but the experience was interesting. We certainly can’t extrapolate any kind of bigger themes out of this, like “FP is always easier,” but my initial hesitation seems somewhat unwarranted.

January 28, 2013 at 11:00pm

0 notes

A Hindley-Milner type system in PHP

PHP is famously bad at preserving type safety.

Having spent the last few years working in functional languages with strong typing, I’ve gotten more familiar types and how to use them for great good. However, in my day job I still primarily write PHP. How to reconcile these differences? Well, implement a type system and embed it!

Below is a Hindley-Milner type system in PHP, which I ported from the Python version that Rob Smallshire wrote.

This is not professional piece of code, however it does prove that the type system can find faults in some examples. The syntax is not very friendly however, thus the next logical step would be to implement a language which could export type expressions and PHP code… we’ll see if I ever get around to that.

Anyway, feel free to leave comments if you find this useful or interesting.