Thursday, January 16, 2014

Tracking my reading

  1. Practical Object-Oriented Design in Ruby by Sandi Metz
  2. Programming in Go: Creating Applications for the 21st Century by Mark Summerfield
  3. Learn You a Haskell for Great Good! by Miran Lipovača
  4. Hadoop: The Definitive Guide by Tom White
  5. [POSTPONED] Functional Programming in Scala by Paul Chiusano and Rúnar Bjarnason
  6. Совершенный код Стив Макконнелл [en]
  7. Exceptional Ruby by Avdi Grimm
  8. Programming in Scala: A Comprehensive Step-by-Step Guide by Martin Odersky
  9. Пользовательские истории. Гибкая разработка программного обеспечения Майк Кон [en]
  10. REST in Practice: Hypermedia and Systems Architecture by Jim Webber
  11. The Joy of Clojure by Michael Fogus and Chris Houser
  12. Building Hypermedia APIs with HTML5 and Node by Mike Amundsen
  13. Распределенные системы. Принципы и парадигмы Таненбаум, Эндрю [en]
  14. ERLANG Programming by Francesco Cesarini and Simon Thompson
  15. Erlang and OTP in Action by Martin Logan, Eric Merritt and Richard Carlsson
  16. What Every Programmer Should Know About Memory by Ulrich Drepper
  17. [POSTPONED] Linux Kernel Development by Robert Love
  18. Архитектура операционной системы Unix Морис Дж. Бах [en]
  19. Ruby Hacking Guide
  20. Objects on Rails by Avdi Grimm
  21. 97 этюдов для архитекторов программных систем Нил Форд, Майкл Найгард, Билл де Ора [en]
  22. Язык программирования Си Брайан Керниган, Деннис Ритчи [en]
  23. MySQL. Оптимизация производительности, 2-е издание Заводны Д., Шварц Б., Зайцев П., Ткаченко В., Ленц А. [en]
  24. Предметно-ориентированные языки программирования Мартин Фаулер [en]
  25. Программирование для Linux. Профессиональный подход Митчелл Марк, Оулдем Джеффри, Самьюэл Алекс [en]
  26. MongoDB: The Definitive Guide by Kristina Chodorow and Michael Dirolf
  27. Психбольница в руках пациентов Алан Купер [en]
  28. Event Processing in Action by Opher Etzion and Peter Niblett
  29. Мифический человеко-месяц Фредерик Брукс [en]
  30. Professional XMPP Programming with JavaScript and jQuery by Jack Moffitt
  31. Экстремальное программирование Кент Бек
  32. Nginx HTTP Server by Clément Nedelcu
  33. Rework Бизнес без предрассудков Джейсон Фрайд и Дэвид Хайнемайер Хенссон [en]
  34. Анализ алгоритмов. Вводный курс Дж. Макконелл [en]
  35. Экстремальное программирование: разработка через тестирование Кент Бек [en]
  36. Применение DDD и шаблонов проектирования: проблемно-ориентированное проектирование приложений с примерами на C# и .NET Джимми Нильссон [en]
  37. SQL Antipatterns: Avoiding the Pitfalls of Database Programming by Bill Karwin
  38. Чистый код. Создание, анализ и рефакторинг Роберт Мартин [en]
  39. Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine by Venkat Subramaniam
  40. Beginning Scala by David Pollak
  41. Growing Object-Oriented Software, Guided by Tests by Steve Freeman and Nat Pryce
  42. Введение в системы баз данных К. Дж. Дейт [en]
  43. Analysis Patterns: Reusable Object Models by Martin Fowler
  44. Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans
  45. Ruby Best Practices by Gregory Brown
  46. Эффективная работа с унаследованным кодом Майкл К. Физерс [en]
  47. Structure and Interpretation of Computer Programs by Harold Abelson

Tuesday, January 7, 2014

The best 2013

Infrastructure tool

Vagrant http://www.vagrantup.com/
Nominees: Guard https://github.com/guard/guard

Management tool

GitHub pull request workflow https://help.github.com/articles/using-pull-requests
Nominees: Trello https://trello.com/

UX/UI tool

UserTesting http://www.usertesting.com/

A new language

The winner is not determined :/
Nominees: Clojure http://clojure.org/, Go http://golang.org/

Another look

Haskell http://www.haskell.org/

Distributed computing

Akka cluster http://doc.akka.io/docs/akka/snapshot/common/cluster.html

Software architecture / Programming paradigm

Functional reactive programming http://en.wikipedia.org/wiki/Functional_reactive_programming
Nominees: The Lambda architecture http://manning.com/marz/

Beautiful monster

Hadoop http://hadoop.apache.org/
Nominees: Scala http://www.scala-lang.org/

Media

Russian-speaking community of LiveJournal http://www.livejournal.com/

The future is here

Сoursera https://www.coursera.org/

Scientific paper

In Search of an Understandable Consensus Algorithm https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf

IT book

Learn You a Haskell for Great Good! by Miran Lipovača http://learnyouahaskell.com/

Popular science book

The Selfish Gene by Richard Dawkins http://en.wikipedia.org/wiki/The_Selfish_Gene

SF book

Anathem by Neal Stephenson http://en.wikipedia.org/wiki/Anathem
Nominees: The Windup Girl by Paolo Bacigalupi http://en.wikipedia.org/wiki/The_Windup_Girl

Holiday

Christmas in Budapest https://plus.google.com/photos/103860575551465174860/albums/5965900612072805649

Quality of life

35-hour workweek

Tuesday, July 9, 2013

What I don't like about LISP

This post is not about parenthesis. It would be too easy.

I really miss literals in Lisp. Ruby has tons of literals: numerics, strings, heredocs, symbols, regular expressions, arrays, hashes, ranges, classes, eigenclasses, modules... Special syntax for everything :) Everything has their own unique appearance. And such diversity allows to grasp landscape nearly instantly. It's expressive.

In contrast, Lisp is poor in that respect. Lisp code is a garden overgrown with trees. Identical trees. With numbers, strings and symbols hanging on them. Compared to that, ruby code is full of variety: wagons, houses, kennels, containers and plastic bags.

Don't get me wrong. I am not against s-expressions. I am against the fact, what s-expressions consist of a limited set of literals. And even if you write a custom internal DSL, you just cut and fertilize your monotone trees.

By the way, Clojure knows about the problem.

Monday, January 14, 2013

Hypermedia API is about DRY

The hype around Hypermedia API (HATEOAS) just got too much recently. Opponents and advocates cross swords. But critics overlook one main point: Hypermedia API allows you to not repeat youself.

I could describe the topic in terms of "Hypermedia as the Engine of Application State". The "State Engine" directly relates to the issue. But I prefer to use more familiar dictionary.

Consider yet another project tracker. There is a domain rule: only Project Owner is able to delete a user story AND only stories in "initial" state can be deleted. With the "traditional" REST approach the rule gets duplicated several times: on the server side and for each client app. Without such duplication a client cannot reason about visibility of the "delete story" control. Even worse, the rule is implemented in several languages, increasing the likelihood of errors.
# Server side
def deletable_by?(user)
  user.owner? @project && initial?
end
// Android client
private boolean isDeletableBy(User user, Story story) {
  return user.isOwner(story.getProject()) && story.isInitial();
}
...
if (isDeletableByUser(user, story)) {
  renderDeleteWidgetFor(story);
} else ...

// JavaScript client
function isDeletableBy (user, story) {
  return user.isOwner(story.project) && story.isInInitialState()
}
...
<% if (isDeletableBy(user, story) { %>
  <%= renderDeleteWidgetFor(story) %>
<% } %>
With HATEOAS the rule is implemented once and only once. It doesn't spread domain logic across clients. They become fairly "silly".
# JSON generation on the server side
if story.deletable_by? current_user
  json_builder.delete_link_for story
end
// Android client
if (story.hasDeleteLink()) {
  renderDeleteWidgetFor(story);
} else ...
// Javascript client
<% if (story.hasLink('delete') { %>
  <%= renderDeleteWidgetFor(story) %>
<% } %>
See, clients don't "figure out" or "calculate" button visibility. They render the button only if the "delete" link is present. That's all. It simplifies the iterative development process: changes in domain logic require only server code to be rewritten.
# Changed rule
def deletable_by?(user)
  user.owner? @project
end
JavaScript, Android, iOS clients remain untouched. They still rely on absence/presence of the "delete" link. The "traditional" REST approach requires to rewrite/recompile/redestribute ALL client applications!

Summing up: Hypermedia API keeps domain logic on the server side. It reduces cost and encourages improvements.