Oleg Andreev

Software designer with focus on user experience and security.
You may start with my selection of articles on Bitcoin.
Переводы некоторых статей на русский.
Product architect at Chain.
Author of Gitbox version control app.
Author of CoreBitcoin, a Bitcoin toolkit for Objective-C.
Author of BTCRuby, a Bitcoin toolkit for Ruby.
Former lead dev of FunGolf GPS, the best golfer's personal assistant.
I am happy to give you an interview or provide you with a consultation.
I am very interested in innovative ways to secure property and personal interactions: all the way from cryptography to user interfaces. I am not interested in trading, mining or building exchanges.
This blog enlightens people thanks to your generous donations: 1TipsuQ7CSqfQsjA9KU5jarSB1AnrVLLo
Generational Garbage Collection and the Radioactive Decay Model
“That is what happens when a conventional generational garbage collector is used for a program whose object lifetimes resemble the radioactive decay model. The collector simply assumes that young objects have a shorter life expectancy than old objects, and concentrates its effort on collecting the generations that contain the most recently allocated objects. In the radioactive decay model, these are the objects that have had the least amount of time in which to decay, so the generations in which they reside contain an unusually low percentage of garbage. For the radioactive decay model, therefore, a conventional generational collector will perform worse than a similar non-generational collector.”
Paper by William D. Clinger and Lars T. Hansen (PostScript)
Interactive development with Io: how to reload prototypes
The major feature of a dynamic language is interactivity. With Smalltalk you may run the program and inspect/change it at runtime. This implies some GUI for VM with built-in crappy text editor: you don’t edit files, you edit objects now.
This does not sound very comfortable for many reasons. First, you would always want to have a “canonical” state of your application which is not affected by runtime mutations: that is, plain text files stored under some version control. Next, you would like to use a different text editor or GUI and it is much simpler to achieve when you operate with plain files instead of fancy VM/language-specific API.
How do we combine interactivity of Smalltalk with text file editing? Let’s take the puriest OO language ever designed: Io.
1. Each file contains an expression.
2. The only way to load the file is to evaluate it in context of some object: object doFile("file.io"). The return value would be a result of the expression in the file.
3. We may have a convention that some files return a prototype object: the object which is used as a prototype for other objects created in runtime.
4. To load “prototype object” we use a special loader object which would track the file-to-object mapping: Article := Loader load("article.io")
5. Loader monitors the filesystem and when some file is changed, it loads it into another object and replaces the prototype with that object: Article become(load("article.io"))
6. At that point, all articles in the system suddenly have another version of Article proto.
You have to follow some safety rules. For instance, proto’s descendants should not modify the proto and rely on such modifications.
Of course, this method still does not allow you to change/inspect breakpoint message somewhere and use a debugger after the proto is reloaded and VM stepped on that message. Or wire some Smalltalk-like GUI to your app.
Simple proto-based reloading helps development a lot and in contrast to class loading methods with full app reload, works faster and for full range of source code including all libraries. Rails dependency system does not reload gems, but does a pretty good job with constant reloading. All ruby/rails issues with global data applied.
Null Pattern revisited again
Now, working with Objective-C where nil eats messages, I realized that the code is more elegant, but it takes significant amount of time to debug it. You create if/else branches and breakpoints to trace the nil, then you fix the bug which causes it and erase the conditional code. You get your elegant code back and wait for another issue to arise later.
“Essentially, Haas Unica came about as a result of analysing the original version of Helvetica, its variants (as they were in 1980) and similar faces and seeking to improve them - to produce the ultimate archetypal sans serif face. A single face to unite them all, if you like. ”
See also: From Helvetica to Haas Unica (flickr set)
Why Events Are A Bad Idea
The paper discusses how thread-oriented programming is more efficient (in terms of performance and development cost) than event-oriented.
My personal observation is that cooperative multitasking (based on coroutines, fibers) requires less and easier to read code comparing to evented callback-based code.
Improving brackets in Objective C syntax
The Objective C syntax is poisoned with nested square brackets:
[[[Class alloc] initWithApple:a andOrange:o] autorelease];
First, lets move opening bracket behind the name of the receiver:
Class[alloc][initWithApple:a andOrange:o][autorelease];
You may agree that this is much easier to write now. However, at this point we lose compatibility with ANSI C (think buffer[index]).
Lets omit brackets for messages without arguments and use a space as a delimiter:
Class alloc [initWithApple:a andOrange:o] autorelease;
At this point we may get back compatibility with ANSI C by making a non-context free grammar (parser should recognize that a[b:c] could not be used for index operations).
You can implement exactly that syntax in Io using the standard language features.
.css and .js files
Stylesheet and javascript URLs and content should be controlled by application code. Putting static files into public folder is so nineties.
Git: merging WIP commits into master
Before starting a work on a distinct feature, you create a branch:
$ git checkout -b myfeature
You write code, create fast commits, merge in master, rewrite code etc.
$ git checkout master$ git merge myfeature --squash
Now you have merged all the changes into the working tree, but not committed in the master branch (because of --squash option)
You may git add some files to produce nice commits as described in the previous article.
Git: simple rules for master branch
These rules are designed for an easy code review using “git log -p”. This command shows the history of commits with patches.
1. Commit message should include task reference number (# of ticket/case in bug tracker, url of wiki etc.). If there’s no reference number, then the ticket must be really trivial or include refactoring only.
2. Commit represents an atomic working patch. No “WIP” commits with undefined behavior are allowed. In your private branches you can do whatever you want, but when merging to master, you must aggregate commits in a set of working patches. If you don’t do that, the single feature would be spread among 30 commits with arbitrary code being written and erased between the start and the end.
3. Commit should be small. You should split a big commit in a few independent ones. More safe commits should be stored first. Good example: you had fixed some performance issue. First, commit a benchmark which shows the previous performance, then commit an updated code. This helps to test the previous code using newer benchmark without manipulating code by hand.
Rule 2 tells you not to pollute master branch with tons of WIP commits and rule 3 tells you to squash WIP commits wisely: do not put everything in a huge patch.
It is much easier to follow these rules when you look what others do with the code using git log each time you pull updates.