On grokking code

Don’t just read, copy and paste: drink up the thinking behind every concept you come across, that you may be richer for it.

Understand not only the outcome, but the decisions that can take you there.

Know not only what is done, but why and how else it could get done.

Doing things for oneself without looking at how others have done it is a good way to do this. Wilfully trying to do it different from others after seeing what they’ve done is anohter.

To know where the thinking takes place, what the thinking is, what decisions are made, and how they’re implemented is to grok a particular practice.

It is usually ill advised to change code you do not grok; it is far too common to have little time or knowledge to grok something. Writing good documentation and good tests is an aid for others, that they may grok your code.

You in some months is one of the others that will be aided, and will need to grok the ccode again.

Notes on Java 6

If you’ve not caught up with what polymorphism is, you should check the previous entry on this series.

Java has a pretty ergonomic standard library (except when it’s not, as in the date and time APIs – Some work has been done in Java 8 to help improve them). You can, and maybe should, peruse the Java API javadocs to better acquaint yourself with the wealth that the platform offers.

One of the mechanisms leveraged in the Java API to achieve this ergonomy is the use of polymorphism through interface implementation. In case this hasn’t been cleared up, the relationship is this: the interface states some behavior should be implemented, and the class contains the implementation of the behavior while leveraging the particular scenario. If it’s still not clear, bear with me and read on: all should be clarified shortly.

Some interfaces and what they mean:

Runnable

A tiny interface – only specifies the “void run()” method. Basically specifies what should get done when a thread is starter with a particular object.

Comparable<T>

This interface defines one single method: “int compareTo(T o)”. That “T” is a reference to the class which implements the interface, so every implementing class should be able to compareTo(anObjectOfTheSameClass); the use of generics is a topic for the future.

This is a simple and useful interface. The return value is interpreted as a particular meaning (this goes first, at the same point, or after the other object in its natural order). If you were to write an algorithm to order any kind of data, then you could make it order Comparable-compliant classes, and not need to know the details of any of them to write useful code. In fact, it’s both trivial and included in Java – you only need to set up a class implementing the List<T> interface filled with Comparable<T> objects, and invoke Collections.sort on the list.

In other languages, it is possible to recreate this effect by overloading the comparison operators in your composite type.

AutoCloseable

This one specifies the “void close()” method; it should free all used resources and do general clean-up. This is necessary for the try with resource construct introduced in Java 7.

Closeable

This one specifies the “void close()” method; if you think this is a dejà-vu, rest assured that it isn’t. There’s a difference between this and the previous interface; Closeable is derived from AutoCloseable. Look at the one, then the other, until you spot it.

Hint: the intent behind deriving a type from another is to execute a conceptually equivalent task in a specific setting.

Notes on Java 5

Today we’ll talk about Polymorphism: poly = many, morph = shape or form, so it’s basically manyformism. Now that we’ve taken the obligatory and unhelpful direct translation of terms, let’s dig in.

The same operations can be executed in many different things, maintaining the concept, although not the details of the operation. Peeling a banana shares the concept with peeling a tangerine, but not the same mechanics. That’s polymorphism, and there are particular ways to express it in different programming languages.

In java, the main way to implement polymorphism is through the overriding of previously declared behaviors.

In the class or interface-based relationship, some blueprint stated that a particular action could be executed, and elsewhere the behavior is specified either for the first time (when implementing interfaces or extending abstract classes), or assertively by overriding the behavior previously declared.

So, a “skinned fruit” is “peelable” (declared action), but the way it’s “peeled” differs from fruit to fruit (implemented).

In another scenario, a “generic-cap”-capped bottle can be opened by removing the cap (defined behavior), but then there are “screw cap”-capped bottles plastic, and “non-screw steel cap”-capped crystal bottles, which may have different behavior.

The generic-cap is similar to the non-screw steel cap, and they are removed the same way (using a bottle opener); but the screw cap needs to be turned – so the behavior is overriden for the latter, although it’s maintained for the former.

Practical examples for these can be found here: https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html

By the way, that’s just the way Java does it, which is fitting due to the nature of this series; there are more ways to implement polymorphism, and that may be the topic of a future article.

A blind spot on my posting schedule

I was going to forgo posting today, second Friday in a row. I didn’t even notice until I saw a youtuber I lightly follow state that he was taking a rest from his daily schedule. Then it hit me so hard I’m reeling: I didn’t even think about writing today’s post.

Part of the culture I live in that fridays are usually seen as the beginning of the weekend. This atmosphere at work and home may have blindsided me. I won’t fall again.

To address this, I though about working mornings – or shift my writing schedule to the night before (write Sunday through Thursday, publish Monday through Friday), which I think will work better due to my activity patterns.

I’m happy that I caught this pattern, although it was a lucky strike. I’ve missed 3/45 days. It’s not bad – not perfect, which is what I hoped when I started, but not bad, either: over 90% of posts have been made.

As for the missing ones, I decided my course of action – I’ll write next year until I fill my quota. What this means today is that I’ll be writing until January 4th 2017. Hopefully I won’t accrue many more obligations.

In other news, you may notice some changes I’ve made to my Now page, and some to the things I can’t pay attention to right now. I’m trying to account for reorganization imposed due to increased work-related commitments. You may not notice them, but those pages are still sum up accurately what I’m up to.

Next week we’ll continue with our regularly scheduled posts.

Notes on Java 4

If you read yesterday’s post, you should remember that in order to cast form one type to another the compiler must know the relationship between the types.

In java, there are two main types of relationship between the types:

  • Interface relationship
  • Class relationship

These are called “Inheritace”, which is an Object Oriented Programming term referring to the fact that some types are based in other types, which can be exploited nicely in practical situations.

Interface relationship is either from interface to interface or from interface to class. Now, I need to explain what an interface is. Remember what a class is? A blueprint of operations and data? Interfaces are blueprints of blueprints, which contain only the signatures of operations, and the description of data and operations which belongs to the blueprint (called static members, we’ll see more details later).

In any case, Interfaces can extend interfaces – that is, imply the data and operations from another interface and add more. Classes can implement interfaces, which means that they can define the operations for their particular situation or set of data.

What’s a signature for an operation, you ask? It’s the collection of data that makes an operation uniquely identifiable: name of the operation, type returned, number of parameters received and number (and ordering) of those parameters. The name of the parameters is not taken into account for the signature, only their order and type.

Class based relationship is different from interface based relationship. There can be only one class from which information and operations are derived in Java, although there can be many interfaces. There are two kinds of classes – abstract and concrete. The abstract ones are halfway between a “regular” class and an interface: they can have both implemented and merely described operations, and data pertaining both the blueprint and the actual building (class [or interface] and object, for those who didn’t go back and read previous articles).

In any case, you can extend or implement fro many interfaces, but only extend from a single class. As every object type  can extend or implement another one, then there is a neat chain all the way to the most general type, Object.

Concrete classes can’t have unimplemented operations! If you’re extending a class or implementing an interface in a concrete class (namely, one which is not identified with the “abstract” keyword), you need to implement all behavior described by the abstract classes and interfaces.

If an object type has a class or interface relationship with another object type, it can be cast from one to the other. Only the operations and data described in the target class or interface will be available for use after casting. The relationship is needed because the computer needs to know what data and operations are going to be available. All object types in Java have at least a relationship with the Object class, so everything can be cast into an Object (although not necessarily the other way around. Think about why).

If for some reason you try casting some type into another to which it has not any relationship (int to boolean, or Java.util.ArrayList to java.sql.Date), things will crash and burn as soon as the computer takes notice. Sometimes this will be at compile-time, sometimes at runtime.

To make things clearer: relationships are hierarchical. If not in the same direct line of relationships, the relationship does not exist. If you picture it as a family tree, cousins can be cast into a common uncle/aunt or grandparent, but not into each other.

Interface relationships are tools used to create an abstraction called polymorphism, which we’ll see soon. Keep your eyes peeled.

Notes on Java 3

Casting is a process by which you interpret certain data differently than what is says in the label. To continue with that same analogy: casting is like changing the label on a jar without changing the contents – and acting as if what the label said was the absolute truth.

The behavior varies with primitive data types and Objects, which are the composite data type Java functions with. So let’s get primitive data types out of the way:

Numeric types can be casted into other numeric types; the way they’re stored in memory is changed, and data may be lost when casting from a type with more memory to a type with less memory. Characters (char) and bytes count as numeric types for this case. Booleans (boolean) can’t be casted. More nuances can be picked up from the docs, particularly if you see table 5.1.

String is not there for a reason – it falls in the Object classification, and not the primitive data type classification.

Let’s get some nomenclature out of the way to avoid confusion.

Composite types in Java are created with classes, which are a blueprint for how data is laid out  + operations grouped with the data (a class can be considered a data type). A particular instance (or building made from that blueprint) is an Object. So, what you cast is an object, which is created by following a blueprint called a class.

Class = blueprint (or recipe?), Object = building (or hopefully delicious food!).

Those analogies are imperfect, don’t take them too far. But they’ll hold for a bit.

So, when you define a class, you’re doing much of what the people who built the language made for primitive data types: you’re stating what data is going to be there, how it is to be laid out, and a developing a set of operations that can have privileged access to the data in a way that developers using the types may not have.

Cool? Cool. Now, back to casting: to get a data type to morph into another, they need to be somewhat compatible. There’s a particular type of casting called boxing and unboxing which go from a primitive type to an object which handles the primitive type. This is useful for some reasons we’ll talk about in the future, just be content to know that this happens.

In order for you to have a good handle of type correspondence: int => Integer is the only odd one. The rest of equivalent object types are called the same as primitive data types with capitalized name (boolean => Boolean). These work implicitly much of the time, basically because language designers decided it was good enough that way – this reminds me a bit of the shenanigans that go on with the String type. In any case, it allows you to mix and match primitives and objects and use operators just as if they were primitives, or objects. This is, I think, ugly.

So, yeah, boxing and unboxing happen automagically.

Having covered those, and with you having hopefully taken a look at my post on data types, I want to tackle the last bit about casting: casting between composite types.

If you paid any attention, you may remember that casting only works between types with compatible data, and that some information may be lost when doing the casts. In the case of composite data types, it’s not easy to transform between them, so the computer must know beforehand what the relationship is between the two types you’re using in the cast. The how of it is a topic for the near future… just remember that casts happen automatically when you signal them – you don’t need to write code to specify what to do with each particular datum, only that you want this to behave as if it were that.

If you paid a bit more attention, you may have noticed that classes contain operations. Different classes may have not only different data, but different operations, so what you can do with a particular collection of data is dependent on how you’re choosing to treat it. You can have a different set of operations available, usually fewer than the original type, or the same amount of operations, as well as data availalble, when you perform a cast.

What’s the cast syntax, you ask? This series is about Java, you say?

RandomType variableName = (RandomType)aRandomVariable;

This series is mainly about insights. Practical advice is easily found elsewhere. That’s why so much verbiage, so little code. But if you have any particular questions, don’t hesitate to ask. Worst case scenario is I can’t answer your query, and that’s not so bad, seeing as you already don’t have my answer.

Notes on Java 2

Last time there were some notes regarding the size of data and primitive types of data in Java.

Now we’ll talk about the String.

The String occupies a very special niche in the Java language; it’s not a type like the integers, or doubles: it is an object. But you can have Strings in java without having any Object-related syntax. In fact, you can represent a String in code just like any other constant value.

Some facts about strings in java:

  • They are immutable, which means they have special behavior to make them much like primitive data types
  • They respond to the sum operator + (by having Java transform every value involved into a String representation, then concatenate them)
  • If two variables have the same string literal assigned to them, they actually point to the same memory address

Some details about the meaning of string immutability:

If you assign a variable a particular String, then change the value stored in the variable, then the memory address the variable points to changes, and a new string is created.

As a corollary of having multiple variables point to the same memory address if assigned to the same String literal, if you change the data in memory (supposedly you can’t but sun.misc.Unsafe exists), all the string variable’s data changes together.

If a two variables contain parts of the same string (ie: String a = “babcdol”; String b = “bab”;) then both strings point to the same spot – but the length changes. Playing with sun.misc.Unsafe helps shed light on the matter. This is because of a mechanism called the String Pool.

Strings are, perhaps, the weirdest data type in java thanks to these features. Shenanigans ensue when used as parameters, if you expect them to function like other Java objects.

Next time we’ll talk about casting, or converting variables from a type to another.

Brief Notes on Data Types

I’ve mentioned data types a couple of times by now, and will probably mention them again. Thinking about them is interesting because it’s a window, albeit small, into the way programming languages work. Here are some notes on the nature of data types I’ve thought about, and an invitation to think further.

Data

Data is the plural of datum, and datum is a unit of information. All sensory input we receive is data, and it’s stored in our brains in the form of neural connections. We can pass it along in the form of sound waves (talking), symbols (writing), and generally through the encoding in a medium using a predefined system of symbols. In the case of computers, we store the data in the form of arranged matter, usually moved through magnetized equipment or electrical current in patterns of two states. Thus, binary (encoded) data. Also called digital information, although I find the name too generic (digital information can cover any data encoded using a discrete set values, as opposed to analog data, so while binary data is digital, not al digital data is binary).

Processors

Processors are collections of electronic components arranged in a way that they react transforming collections of electric signals predictably. This is one of the main components of modern computer architectures. When you hear about an 8-, 16-, 32- or 64-bit computer, it usually refers to the size of the collection of signals that the processor handles: a wire (or binary datum) is a bit: a certain voltage represents the a 0, and another one represents a 1. Those digits can be interpreted as part of an n-bit number. They can also be interpreted as instructions. Instructions are numbers are configurations of physical media are any kind of data, because the only medium to express any and all data in a computer is through discrete digits. Understanding this is central to understanding data types.

Data Types

Data types are what happen when you decide to treat sequences of data in a special way. In other words, when you make certain patterns’ meaning and your actions on them dependent on other, predetermined patterns. You need, first, to know what transformations the processor should do on the data (sequences of instructions to be applied on the data) if the data has a particular type. If we didn’t have any programming languages, we’d do this by hand – as instructions are numbers are configurations of physical media, we could do this by setting up a particular medium arranged with data that the processor interprets the way we want. This is what a computer BIOS is, by the way. So, we’d know what data we put where, and what we want to treat it like. If it’s letters, we can make capitalize them or lower their case. If it’s numbers, we can add or subtract them.

We assign arbitrary values to particular arrangements of data – thus the integer number 64 is a sequence 01000000 in the medium is an ‘@’ if interpreted in the context of ASCII encoding. Agreeing on what a particular string of symbols mean is the root of many, many issues in modern computing (read about: ISO-8859-1, ASCII,  Unicode). In any case, this interpretation and the set of operations we define on a particular datum is what makes a data type.

Programming Languages & Data Types

As we do have programming languages, the work of determining what to do with a particular datum in a particular moment, what is allowed and what is not, is taken from our hands. All languages enforce rules on what can be done with a particular datum; for instance: what datum can be transformed into which other one and how to go about doing it, or what happens if a datum that was stored as a number needs to be added to a datum that was stored as a letter.

The C programming language offers a very close experience to what you’d see working on assembly language, as its restrictions on what to do with data are very low. Want to add (or subtract, or compare) a number and a character? Go ahead. The operations are executed on the numeric values represented by the data.

Other languages, like Javascript, collapse in a particular way. Want to add a number and a character? Your number is now a character, and you get a collection of characters (i.e.: 1+’a’ = ‘1a’); Want to multiply them? You get NaN (Not a Number).

Some languages prevent you from doing this, and warn you that you’re trying to execute some ambiguous operation, like Python. (It is surprising that 2*’a’ = ‘aa’, but that’s a solid, unambiguous way to interpret it. 2+’a’, though… is the answer ‘2a’ or 99? Python asks you to transform the character into numbers, or viceversa, and refuses to guess).

Epilogue

Some data types are not represented in such a straightforward way as ASCII characters or integer numbers (see: Floating Point numbers). Other data types are built from the group of types the language already knows how to work with; those are called composite, or compound, data types. Perhaps future musings will cover these ones.

Tomorrow, we’re going back to the Java Notes.

Notes on Java 1

Java is an Object Oriented programming language. In this series of posts, we’ll explore different aspects of it: data types, target machine(s), object model, and other details of interest.

Sadly, even though I’d planned to make this in a certain order, and due to my goal of writing a daily post, I’ll not start with the story of the language, but with the primitive data types.

The primitive data types of a language are those which aren’t composed of any other data types. If you’ve never worked with a low level language (and, of course, if you’re new to programming) you may be unaware of certain distinguishing features of the data types: size, operations permitted, the way they’re interpreted, and relation between it and the other types.

In Java, we have 8 primitive data types, which can be roughly divided in categories:

Integer types

  • byte, which is 8-bits in size, signed (two’s complement negative); it’s an integer numeric type at its core.
  • short, which is just like byte, except 16-bits in size
  • int, same old, but 32-bits
  • long, you guessed it, but 64-bits

Floating Point types (which are imprecise and comply with the IEEE 754 floating point spec; wikipedia explanation here)

  • float, which is 32-bits
  • double, which is 64 bits

Units of Data

  • boolean, which is true or false and with undefined size.
  • char, which is 16-bits and represents an Unicode character.

Those types are, along with the Object system, the backbone of Java and its architecture.

Speaking about the object system, the String object is… special. It can be created with quotes (“This is a String”), thus not requiring the paraphernalia that object instantiation needs in Java. I’ll cover the String in a future article.

There’s something to notice: numeric data can be interpreted as another type (int as byte, long as short, float as int…) if going from a smaller type to a larger one, this can happen implicitly, as well as when going from integer types to floating point types.

Going in the other direction implies that data can be lost – it may not fit! So the transformation must be explicit, to acknowledge that we know what’s going on.

We’ll talk more about this and other subjects soon.

Improving Practices

A while ago I started looking into PDCA, and noticed they play nicely with the self improvement and deliberate practice research. They’re worth looking into.

I tried formulating a process which took itself into account, and while a formal specification proved beyond the time and focus I could give it at the time, I came away with an intuitive grasp that helped me apply continuous improvement to my efforts to become better all the time.

This means that my improvement in any particular area is bound to accelerate for a while. It’s hard to account for increase in the rate of improvement – is it because of the process or would you normally increase your rate of growth in that particular discipline?. But at least I get a sense of happiness which helps me practice deliberately and get better, so the mood boost is a good boon.

In loose terms, this is what should be going on:

  • When you work on something, notice what you do, and measure whatever performance indicator you can
  • Meditate on how you can improve the performance on the indicators
  • Execute on the improvements, while measuring
  • If you improved on your indicator, keep your change; otherwise discard it.

Now, verify the ways you’re measuring, the ways you’re meditating – in short, think about how you’re checking your progress.

In diverse areas, I’ve come up with different ways to improve my process; from a Nick Winter inspired automation of certain measurements through my text editor to discussing the changes with someone instead of just meditating on my own, I feel more thrilled to work, and work on my work.

This way, I don’t only improve through practice, but I improve practice itself.