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
Virtually all commercial applications in the 1960’s were based on files of fixed-length records of multiple fields, which were selected and merged. Codd’s relational theory dressed up these concepts with the trappings of mathematics (wow, we lowly Cobol programmers are now mathematicians!) by calling files relations, records rows, fields domains, and merges joins. To a close approximation, established data processing practise became database theory by simply renaming all of the concepts. Henry G. Baker to ACM forum

Conference On Emerging Programming Languages

An event to bring together bright folks working on unfinished or recently finished programming languages. Even relatively young languages like Scala would not qualify; this event is all about the sharpest part of the cutting edge.”
The most interesting one is ooc — another attempt to add objects, inheritance and improve packaging in C. via Steve Dekorte
In addition to Hash Table, B-tree and Fixed Length APIs, TokyoCabinet got Table API with flexible schema, indexes and multicolumn queries. PDF slides.

In addition to Hash Table, B-tree and Fixed Length APIs, TokyoCabinet got Table API with flexible schema, indexes and multicolumn queries. PDF slides.

Snow Leopard with legacy macports and rubygems

We assume you had Leopard with standard Ruby shipped with OS, tons of macports and rubygems already installed. Then you install Snow Leopard on top of it (not clean install).

The problem is that standard 10.6 dynamic libraries all went 64 bit and could not be linked with 32 bit code. This could be fixed by rebuilding/reinstalling all the macports and rubygems.

1. Install the latest Xcode shipped with Snow Leopard.

2. “port” command will fail with a message about incompatible Tcl architecture. The proper version of macport is 1.8 which is not released yet. You can obtain it from SVN trunk and built it by hand (./configure && make && sudo make install). I have also added trunk version of ports to sources.conf (see the link above for instructions) to be sure that I have the latest SL-compatible ports in the list. Maybe this is was wrong assumption, but it worked for me just fine.

3. Remove all ports:
$ sudo port -f uninstall installed

4. Update rubygems to 1.3.1 at least (please google for instructions).

5. Remove vendor gems (gem uninstall refuses to remove them and fails to do batch remove):

$ gem list | cut -d" " -f1 > installed_gems
$ sudo mv /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8 /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8.bak
$ sudo mkdir /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8

Note: installed_gems file contains a list of all installed gems so that you can cat and xarg it for installing all gems back.

6. Uninstall all gems

$ sudo gem list | cut -d" " -f1 | xargs sudo gem uninstall -aIx

7. Make the rubygems use 64 bit architecture.

$ cat installed_gems | xargs sudo env ARCHFLAGS="-Os -arch x86_64 -fno-common" gem install --no-ri --no-rdoc

Note: it is NOT i686 (as I thought it should be), it is x86_64 instead.

Here are convenient aliases for “sudo gem install” for both architectures:

alias sgi32="sudo env ARCHFLAGS=\"-Os -arch i386 -fno-common\" gem install --no-ri --no-rdoc"
alias sgi64="sudo env ARCHFLAGS=\"-Os -arch x86_64 -fno-common\" gem install --no-ri --no-rdoc"


You may also put alias sgi="sgi64" in your .bash_login on snow leopard.


Now we all can proceed doing productive work. \o/


References:
1. http://www.nabble.com/-MacPorts—19446:-openssl-fails-to-compile-on-x86_64-td23247203.html
2. http://jaredonline.posterous.com/got-mysql-to-work-with-rails-in-mac-os-106-sn
3. http://cho.hapgoods.com/wordpress/?p=158

Snow Leopard

Snow Leopard shows a rare case when upgrade brings you more valuable performance and bug fixes rather then incredible new features.

Steve Dekorte on programming language shootouts

Writing a Mandelbrot set calculator in a high level language is like trying to run the Indy 500 in a bus. While it might be amusing for a car magazine to test circuit times for various busses on a race course, it really tells potential bus buyers very little about which bus they should buy as the problem of cost efficiently maximizing transportation throughput on normal roads involves different tradeoffs than the problem of no-expense-spared maximization of transportation speed on an extremely windy road.”

CSS box model

W3C box model (width specifies pure content area width) represents bottom-up philosophy where content specifies the area for itself. Parent elements should adapt to it.

IE6 box model (width specifies content area with borders and paddings) represents top-down philosophy where designer specifies available spaces for nested elements.

In fact, content designers don’t care about the container width and html designers think better in terms of IE6 box model. Thanks to stupid standards, we all have to make additional calculations in our heads when working with styleshits.

“Type hints” syntax suggestion for Ruby

According to previous note on interfaces in dynamically typed languages, it would be great if the API could specify type expectations even easier than a to_type message send to each argument in method body.

class Person
  def initialize(name.to_s, birthday.to_date = DEFAULT_DATE)
    ...
  end
end

Should be interpreted as:

class Person
  def initialize(*args)
    args.size == 2 or raise ArgumentError 
    name = args[0].to_s
    birthday = (args[1] || DEFAULT_DATE).to_date
    ...
  end
end

This idea can be applied to other languages as well.

Reading code is hard

Why’s that? Consider Dostoevskiy’s “Crime and Punishment”: it is just 1 Mbyte. And what size is your codebase?

Interfaces in dynamic object-oriented languages

Object interface is a set of messages with defined behavior the object should respond to.

In statically typed languages, interface is required by type declaration. In dynamically typed languages this is done by telling object of unknown type to cast itself to the desired type.

# User's code expects object responding to #to_page
# when casted to page, we expect proper #render and #size behavior
class SomeController
  def process(object)
    page = object.to_page
    page.render
    page.size
  end
end


# 1. Page class with #to_page interface returning self
class Page
  def to_page
    self # return self since it is already a page
  end

  # page public api

  def render 
  end

  def size
  end
end

# 2. Non-page class with #to_page interface
class AtomicBomb
  def to_page
    # return a relevant article
    Page.wikipedia_article("Nuclear weapon")
  end
end

# 3. Class without #to_page, but with #render method
# fails with "object does not respond to #to_page" exception
# and does not cause undesirable side effects
class Foo
  def render
    # very specific nasty rendering method
  end
end

# 4. Class without #render
# fails with "object does not respond to #to_page" exception 
# rather than with less descriptive "object does not respond to #render"
class Baz
end

This technique minimizes duck typing collisions by reducing the number of exposed methods to a single “to_{unique_type_name}” method. It also protects you from inventing obtrusive method names with type prefixes such as “page_render” or “page_size_in_characters” (see example above).

The rule of thumb:

1. When API consists of more than one method, introduce #to_my_type method

2. Whenever you receive an object from an unknown source (e.g. defined in a different file), use explicit type casting with #to_some_type method.

Note: never ever make others ask about the kind of an object using #respond_to?. This method should be used for legacy code and indicates possible duck typing issues.

Also, #is_a?(SomeAbstractInterfaceModule) is considered badly designed compared to #to_* methods.

Correct BlankSlate in Ruby

class BlankSlate
  class <<self; alias __undef_method undef_method; end
  alias __instance_eval instance_eval
  ancestors.inject([]){|m,a| m + a.methods }.uniq.
    each { |m| (__undef_method(m) rescue nil) unless m =~ /^__/ }
end

class MyProxy < BlankSlate; end

Note 1: ancestors.inject{…} ensures that all Kernel methods like :p are properly removed.

Note 2: alias __instance_eval could be safely removed if you don’t need this method.