Systems design, software engineering, programming and languages.
Sometimes, technical terms might seem overkill. But the goal of language is to allow us to communicate.
In the progress of rewriting agg (doing it right this time) I witnessed how your word pool can also influence your thoughts. Once I've learned a taxonomy of test doubles (objects used to test other objects), my mental models of the tests became more concise and I could refactor the test suites to have a better structure and cleaner code.
To share my enlightenment, you can find the taxonomy on http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html.
I'm currently hearing a lecture on programming paradigms which has left me rather fascinated. Up to now, it has primarily been about the Haskell Language, which seems to be based on simple and elegant concepts.
As a side note, this is my first time getting in practical touch with functional programming and working with such a language, so I might get things wrong.
Basically, in functional languages there's no state and all functions calls lead to some kind of evaluation (or rather transformation) of expressions that return a value. This is totally different from what is contemporarily known as OOP.
Like every so often I have some gut feeling but can't put a finger on it. So I feel like dumping a WIP.
As you might know, I design an object system. Or maybe I'm creating some Frankensteinian monster out of several systems and concepts that influenced my thoughts, most notably Smalltalk, Self, Newspeak and maybe Lisp (despite not ever having written a line of code in any of them, except for the first one).
Anyways, let me explain how the concept looked the last time I worked on it (which already was several months ago).
struct Object
{
const struct Object* const slots[SLOTS_SIZE];
};
(Of course, the level of detail has been reduced heavily.)
A message send in this system, for example a foo:
b (to use Smalltalk syntax), is just syntactic sugar
for the evaluation of a code object stored in the
specified slot (for example in slot foo:),
using appropriate parameters (foo value: b).
A code object, or rather code generally, is a closure (comparable to a Smalltalk block), which basically is a lambda expression whose free variables have been bound.
When an execution context is set up, a certain variable
(this/self) is defined to
reference the object receiving the message. This way, we
can use the well-known programming style of methods.
Since we're using the capability security model, there are no globally accessible objects and no objects can be accessed that have not been passed as a parameter. Note that since everything is an object, it follows that there is no global state. The accessibility relation, however, is transitive, so one can chain multiple message sends and probably have access to a vast part of the object graph.
Also note that both pointers and pointees are
const. This means that all objects and all
indirectly reachable ones are immutable[1]. In other words,
our message sends are referentially transparent or maybe
even pure, probably with the downside of complex "hidden"
state.
But this seems backwards. What use is a immutable operating system? The real world does have state.
This is a requirement of versioning. At each point in time, the system is in a fixed state. A historic state can not be changed by definition. However, with the blink of an eye you can go backwards im time, fork a new branch of evolution and switch between several of them -- on an object/subtree level, of course.
Currently, I plan to use few special types of transparent native references, primarily for improving capability security. In this text, the focus lies on an update-following reference used to give its owner the impression that the current state of the system is mutable by allowing certain objects to always automatically reference the latest version of another object.
Unfortunately, a update-following reference reintroduces side effects, even if they are restricted to certain situations.
Consider the following snippet of code for such a system:
f := [ ... ].
((f value: x) = (f value: x)) ifFalse: [
self error: 'Referential transparency?'.
].
Now that snippet will always pass if it is run in a context in which references are not automatically updated when a new version of an object is created[2].
Such modification of the context is required anyways. After all, we want to be able to "check out" historical state and continue to work from there. This requires even automatically updated references to point to the latest version of an object as it was at that point in time. Similarly, the context can be set up to only include object versions whose date is smaller or equal to the date the snippet was started to be evaluated.
This raises several questions. Can this simple and elegant[3] scheme reduce side-effects significantly? Can it improve the quality of the system? Is object-orientation without/with less/with controlled side effects possible?
Furthermore, code evaluation in this system is still following the execution-pattern and is not designed to be thought of as transformation of expressions. So, can such an object-oriented scheme provide a practically usable way to evaluate expressions lazily?
- Let's ignore
const-casts, the code above is just an illustration - This might not be completely true. How is nondeterminism handled, e.g. random numbers and external events/input?
- Well, at least I hope it is simple and elegant.
Take a break from reading Hofstadter's Gödel, Escher, Bach to check newsfeeds, see this on xkcd:

Hilarious, but now I'm scared.
People often measure size or complexity of a software project by counting Source Lines Of Code. While this can often show whether some source code is large or not (and therefore provide relative and crude estimates about productivity), relying on it can be fatal.
Textual source code can be considered to be only one arbitrary representation of software[1]. Depending on the language chosen the complexity of the code can vary greatly. I also hope it's obvious to any regular reader of this blog that systems have more than two dimensions, which instantly proves that the SLOC count can't tell anything about the complexity of the software.
Worse, while textual representation is two-dimensional, SLOC measures only one of it. Thus, trying to control complexity by creating constraints on the amount of SLOC is obviously critical.
If the code wants to grow, be it because of a rudimentary programming framework, better understanding of the problem by the programmer or something else, it can reach its upper limit without the problem becoming any more complex inherently. In fact, additional code might make the system even less complex.
When the vertical bound is (close to be) reached, growth will continue in horizontal direction. And hundreds of characters long lines with several statements are far more problematic than just adding them above.
Code growth should not be prohibited per se. It should be closely monitored whether it is benign. And as long as it is, it is the job of the programmer to transform the code so that it always has the best design possible.
- See also CodingStandardsAreMisleading
Last week I found an interesting site while searching for a thorough explanation of red-black trees on the web:
Confuzzlement is a glorious state of being that involves a lot of confusion, frustration, and maybe a little bit of raving lunacy. In a good way, of course. Confuzzled people celebrate their ignorance openly and strive to reach a higher level of ignorance by learning from other confuzzled people. A confuzzled person is proud to be ignorant, but the unwashed masses are often incapable of seeing the subtle difference between being brilliantly clever, pretending to be stupid because you can't be bothered to think, and being genuinely stupid. They key to being confuzzled is having fun with it. -- Julienne Walker
When I found this talk by Bruce Schneier, I was instantly interested and expected something technical. Turns out my expectation was wrong, the talk was still very insightful nevertheless.
Schneier talks about security on a very high level. In fact, I'd rather say that it's a good talk on mental models and the human mind in general, with security as an example.
To quote from a transcript I found online (formatting by me),
Now there are several biases in risk perception. A lot of good experiments in this. And you can see certain biases that come up again and again. So I'll give you four.
- We tend to exaggerate spectacular and rare risks and downplay common risks -- so flying versus driving.
- The unknown is perceived to be riskier than the familiar. One example would be, people fear kidnapping by strangers, when the data supports kidnapping by relatives is much more common. This is for children.
- Third, personified risks are perceived to be greater than anonymous risks -- so Bin Laden is scarier because he has a name.
- And the fourth is people underestimate risks in situations they do control and overestimate them in situations they don't control.
This seems to make sense, I found these patterns to exist widely. But he goes on:
And there's another cognitive bias I'll call confirmation bias, where we tend to accept data that confirms our beliefs and reject data that contradicts our beliefs. So evidence against our model, we're likely to ignore, even if it's compelling. It has to get very compelling before we'll pay attention.
This one is really important. Again, it's a pattern that I've noticed often, unfortunately even in my own thoughts.
Again, questions are raised: Is that what we perceive reality? And are we rational beings?
I don't think so. To quote Heinlein:
Man is not a rational animal, he is a rationalizing animal.
Once again I realized that there's still so much we don't know, so much we still have to learn. All of us, but especially me.
I'm refering to the following words of Alan Kay on the FONC mailing list:
All I can say, is that it is not about code, and I'm pretty sure that playing with code won't help STEPS. In many ways it's about escaping from code! Escaping from thinking in terms of code.
It's about concepts in dynamic relation, that beg to be represented clearly, and then be put into a runnable form, most often via a new language made for the purpose.
"Well, of course,", I should've thought, "he's been saying this for several years now!":
We don't know how to design systems yet. So let's not make what we don't know into a religion for god's sake. What we need to do is to constantly think and think and think about what's important. And we have to have our systems let us get to the next levels of abstractions as we come to them.
-- Alan Kay in his talk at OOPSLA 97
Somehow, I managed to not get it until now.
Many people abolish it. Others, however, implement it in new versions of their high-level language.
Some weeks ago, I finished reading Eric Raymond's The Cathedral and the Bazaar (the book). Raymond presents a thorough analysis of the hacker culture and invites the reader to a journey of self-reflection (provided she's part of that culture and hasn't done it so far). I'd recommend reading it -- maybe except for The Magic Cauldron. I'm not that down with that kind of economics in this context.
The analysis of the bazaar model was probably the most interesting one. I was surprised when I recognized its parallels with eXtreme Programming.
One of the lessons Raymond mentions is Release early,
release often. And listen to your customers. He goes
on and mentions the importance of constant, even daily
improvement that should be visible to the users[1], giving
them an ego-satisfying piece of action
and keeping
them motivated. Raymond claims that this is one the main
reasons of Linux' success.
But these are also the cornerstones of agile methodologies, namely points 1, 3, 4 and 5 of the Manifesto.
Of course there are differences. The bazaar model is just an analysis, a set of guidelines for other hackers; agile methodologies are aimed at professional firms working for customers. Agile methodologies are realized by formal processes, while collaborations in the open source culture seem to evolve informally. But the similarities are interesting.
- In this context, this includes (potential) co-developers as well.
Newspeak is a programming language in the spirit of Smalltalk. In fact, its current prototype is even hosted in Squeak. It is also influenced by Self, being completely based on message sends (there are not even variables, at least in concept). But unlike Self, Newspeak is class based.
We're not talking about classes in the sense of Java, nor in the sense of Smalltalk. Newspeak features an entirely different approach, with classes representing namespaces and modules.
I've not read much about that language and I've not programmed a single line in it, so I'm not going to do a write up here. Instead, I refer you to a series of articles that was a very interesting read.
- http://blog.3plus4.org/2008/12/04/a-taste-of-nested-classes-part-1/
- http://blog.3plus4.org/2008/12/07/a-taste-of-nested-classes-part-2/
- http://blog.3plus4.org/2009/02/15/a-taste-of-nested-classes-part-3/
- http://blog.3plus4.org/2009/02/22/a-taste-of-nested-classes-intermission/
- http://blog.3plus4.org/2009/03/08/a-taste-of-nested-classes-part-4/
You might want to check out the archive containing all posts.