Apple Swift Optionals Syntax Rethought

NOTE: This is pretty stream of consciousness stuff. I’m just throwing out ideas.

In the Swift language an optional is a variable that can have an unknown value.  Let’s start with that. I’m not happy with the syntax of dealing with optionals, not that they exist since they have a real purpose.

First, what are the ways in which a variable can become unknown?

• Programming errors, such as forgetting to initialize an optional before trying to use it,

• Code setting it to an unknown value due to:

  • Bad code/memory access
  • External inputs
  • A real life representation of an unknown value (such as an unknown age).

This last really represents the interesting case since it moves us from binary logic to trinary:

  • Yes
  • No
  • I do’t know

Trinary logic lets code deal with the real world in more realistic ways and is similar to NULL values in SQL that can be queried. But, that’s beside the point.

Now lets look at some simple Swift code dealing with optionals:

Screen Shot 2015-08-28 at 9.23.56 AM

This is ok and people like this but I find it feels clunky having to test for unknowns everywhere with the if let idiom when the runtime should be able to do this. There is a lot of inline “boilerplate” that interrupts the logic flow just to handle the exceptional case. Handling unknown optionals inline breaks up the intent of the code.

What if we pulled handling unknown optionals into their own scope?  Let’s steal an idea from COBOL (yes!) and invent a new construct and call it wheneverUnknown.  wheneverUnknown would be invoked automatically by the runtime whenever [no pun intended] it detected an unknown value in an optional.  Think of this as try-catch routing except for unknowns and they are handled out of line from the main logic, which actually helps factor the code.

So what would the new code look like?  Here is a mockup.

Screen Shot 2015-08-28 at 9.21.39 AM

This, to me, seems more streamlined, simpler to “grok”, and is not inline.  A couple of things to note here.  The code after line 49 is only executed if the runtime encounters an unknown valued optional, so for all intents and purposes the logic ends at line 45.

The next thing to note is that we never handled the exception at line 45. This would be an example of forgetting to initialize an optional (bug) as opposed to the other two cases where we may not know the names.  How do we handle this bug? Let’s expand our wheneverUnknown  scope capabilities.  The wheneverUnknown examples in this function are scoped to the function.  Let’s do the same thing at the class level.

Screen Shot 2015-08-28 at 9.30.56 AM

Lines 33-36 is a similar wheneverUnknown that adds an any keyword which would trap any unhandled unknown and is class-scoped.  Actually, this could be moved into the function itself and would work similarly, but would be scoped to the function alone.

No, I have no plans to implement this.  The idea came up looking at a Twitter post and I got into a short interchange about this idea and really couldn’t get the idea across in tweets.  I just wanted to expand on the idea and clarify my thoughts a bit.

Advertisements

A Need for Code Understandability Metrics

I had an interesting Twitter chat with someone during the PhillyETE conference. One of the major takeaways from for me was that source code is written in order to be read (in addition to being executed.) Humans are going to spend a lot of time reading your code (even if its only you). The code should be written in a way that enhances its understandability. The chat got me thinking.

Testing is a hot topic. Many developers do TDD, BDD, unit testing, integration testing, deployment testing, etc. But when it comes to testing whether or not our code is understandable, we mostly fall back on code reviews. We don’t test the understandability of the code we review.

What does a code review test? I’d argue a code review’s purpose isn’tt to test anything, its purpose is to assess the quality of the code, its functionality for overlooked defects, to share knowledge amongst peers, and its readability.

For the most part code reviews are highly subjective and personal, guided only by experience and the process established to run them. “Readability” is often used interchangeably with “understandability”. A program with no white space is a lot harder to read than a program with white space. That doesn’t make the program any more understandable.

One point that came up in the chat was that whether the code is understandable is dependent on the business and understanding the business processes. It’s domain driven. (Assuming a non-DSL programming environment). I’d argue the domain information is independent of whether or not someone can read the code and easily understand what it does.

Knowing what code does is functional (no pun intended). The domain information is the purpose or reason for the code and function. You need to know how your bank implements a funds transfer, that’s domain information. Understanding that the code takes a value out of one database structure and adds the same value to another database structure is functional and independent of the banking domain.

Understanding why the code does something is different from understanding how it does it. These are two different levels of understanding.

So, why am I focusing on understandability? I’d argue that the greater the understandability of the code, the easier it is to manage, debug, pass on, etc. Read, “easier” as “more efficient” if that helps.

What makes one piece of code more understandable than another? Uncle Bob Martin’s book, Clean Code, is a good place to start. But there is a big problem. How do you quantitatively measure whether a piece of code is more understandable than another? One may argue that itâs highly subjective. I’d argue not. Here is a simple example:

What does this do? +/X>100 This is a real programming language.

What does this do?    for number in X
                                        if number > 100 print(number)
Which one is more understandable? You say that you need to know the language to understand the code. Of course. But I can give both of these examples to random non-programmers on the street and a majority could figure out what the second example does. It’s more understandable. “Well it’s more English-like.” True.

If you’re a c/C++ programmer, what does this do?

main(a,b)char**b;{int c=1,d=c,e=a-d;for(;e;e–)_(e)<_(c)?c=e:_(e)>_(d)?d=e:7;
while(++e<a)printf(“\xe2\x96%c”,129+(**b=8*(_(e)-_(c))/(_(d)-_(c))));}

(this from the Obfuscated C contest.) The understandability is [intentionally] bad even though you may know the language.

We need a way to measure and objectively compare one piece of code against another for understandability. We need metrics. We need tools.

This is an extremely hard problem to solve. It encompasses the language, white space, all of the “clean coder” concepts and others. It is, however, I’d argue independent of domain knowledge.  I believe it’s important.

Any volunteers? Flame on!