dancingrobot84


Things I Read This Week, Pt. 2

Aug 4, 2014 in Programming

Actually I wanted to make a new post for this series every week, but I’ve been pretty busy working full-time at JetBrains on Scala plugin and spending my free time on Purescript Express.js bindings and Coursera assignments. So this is actually what I’ve been reading over the last month.

Phantom types for extra safety in Haskell

Part 1 Part 2

Great articles about interesting technique of taking some errors down to compile time. Though I prefer GADTs approach, Phantom types are pretty cool too.

Type classes: confluence, coherence and global uniqueness

Link

This post is about surprising behaviour of GHC when resolving type-class constraints: though it requires for type-class instances to be non-overlapping, it doesn’t check this constraint eagerly (it may increase compile time). Thus if you have different instances of a type-class in different modules you can accidentally write a program that will use both of this instances simultaneously. And if one of these instances has been kept by mistake (e.g. forgot to delete old code) this can lead to strange runtime errors which would be not so easy to locate. That’s why this is a “must-know” thing for every haskeller.

GHC plans for 7.10.1 (+ 7.8.3 is out)

Reddit discussion

Seems like with kind cohersion and equality Haskell dives deeper into dependent types. And finally Applicative will become a superclass of Monad :)

Rust for functional programmers

Link

Rust is definitely interesting language that caught my attention some time ago, but due to its instability and constant changes in API and syntax I’ve decided to wait and see where it’ll come. The presence of articles like this shows that Rust is moving towards things I appreciate most in modern programming: explicit mutability, higher-order fns, algebraic datatypes, etc. Paired with C-like performance it should make a great language.

This article covers a lot of Rust syntax compared to OCaml and Haskell examples achieving the same things. Plus it has an explanation of Rust’s sophisticated memory model. I hope by the time I’ll finally decide to dive deeper in Rust this article will help a lot.

Mutable algorithms in immutable languages

Part 1 Part 2 Part 3

In this series of posts author implements ST monad step by step. In the 1st part we build abstract interface of monad that’ll create and manage mutable references. The 2nd part brings us implementations of this interface based on IO monad and on Int map. The 3rd part fixes some locality breaches in previous implementations using Rank-N-Types and Phantom types (hi there!) and introduces ST-based implementation. Overall, these posts cover a lot of interesting ideas and useful techniques applicable in functional programming.

Things I Read This Week, Pt. 1

Jun 29, 2014 in Programming

The algebra of algebraic data types

Part 1 Part 2 Part 3

It is a series of articles about connection between algebra and data types. These posts extend the presentation author gave at London Haskell. As for me the first two parts are quite easy while the third is definitely the most interesting and mind-blowing. Thanks to it I was forced to look into the idea of Zippers again and I think that I finally understood it.

CPU Cache Essentials

Link

Short post based on ideas of Scott Meyer’s presentation about writing CPU cache aware code. Not that this post is reopening America, but it’s worth reading once in a while as a reminder to yourself. BTW the presentation itself worth checking out. There is a list of interesting literature about how memory/CPU works at the end of presentation.

Google Material Design

Link

Following recently started Google I/O event they launched site that contains a lot of guidelines and best practices for designers for upcoming Android L operating system. Despite of the world-wide design trend to minimize, simplify and “flatten” interfaces started with Windows Phone and then (poorly) supported by Apple, Google maintained pretty good and consistent design worth taking a look. Well, lets wait and see how they’re going to actually implement their own rules.

Inside the Mirrortocracy

Link

I’m not a big fan of “metaindustry” posts, but this one caught my attention because the problem it reveals sounds totally crazy to me. I thought that tech entrepreneurs have much more common sense to not base their decisions on how employee dresses and looks or how much he can drink on a party, but it seems that your score depends on these more than on your professional skills. I hope that this is a minor threat, but reading redditors’ comments proves that I’m wrong (actually, that’s why I posted here a link to reddit, comments there are totally worth reading).

Питание

Jan 25, 2013 in Misc

Может показаться, что это несколько необычная статья для блога с преимущественно технической тематикой, однако я считаю, что каждому человеку стоит знать основы правильного питания. В конце концов, потребление пищи – это необходимый для любой жизни процесс и поэтому от качества еды будет во многом зависеть и качество жизни.

Также стоит отметить то, что эта статья есть обобщение информации, полученной мной из различных источников и для краткости изложения я опущу различные научные исследования и доказательства, которые стоят за фактами изложенными здесь. Однако замечу, что прежде чем бросаться в омут с головой и применять на себе нижеизложенные правила, все-таки стоит уделить немного внимания первоисточникам, в которых достаточно подробно изложены некоторые тонкости приведенных здесь обобщений.

Вот небольшой список источников, которыми я руководствовался при подготовке этой статьи:

  • Yougifted Russia – ценнейший ресурс с огромным количеством видео, посвященных питанию, фитнесу и бодибилдингу. Строго рекомендую.
  • SportsWiki – отличный сайт с множеством статей спортивной тематики, но поскольку построен на принципе Википедии, то стоит критически относится к изложенной на нем информации. Советую выбирать статьи, которые проверенны экспертами сайта.
  • Bodybuilding.com – последний в списке, но далеко не последний по значимости. Огромный сайт (а также интернет-магазин) с кучей полезной информации, но, к сожалению, для его использования вам потребуется довольно неплохие english skills.

Что есть питание и почему оно важно

В самом простом объяснении процесс питания есть процесс поедания пищи. Правильное же питание есть система, на основе которой человек выбирает пищу, необходимую для достижения каких-либо целей (например, похудеть или наоборот, набрать мышечную массу), либо если никаких определенных целей у него нет, то для поддержания своего тела в текущем состоянии.

Из пищи мы получаем энергию, которую впоследствии тратим на различные действия. Энергия измеряется в кДж или ккал. Кроме того, с пищей в наш организм поступают витамины, минералы и соли, также необходимые для функционирования организма, однако, их мы пока рассматривать не будем, а поговорим подробнее об энергии.

Соотношение потребляемой и затрачиваемой энергии непосредственно влияет на форму тела: для набора массы необходимо чтобы первый показатель был выше, для похудения – наоборот. Конкретная цифра зависит от возраста, пола, физической активности и скорости обмена веществ. Однако, количество – не единственный показатель на который стоит обратить внимание.

Качество энергии также влияет на то, как будет формироваться тело. Оно напрямую зависит от питательных веществ, содержащихся в потребляемой пище. Основными питательными веществами являются белки, углеводы и жиры. Вклад каждого из этих веществ в общую сумму получаемой энергии различен и для расчета калорийности используется вот такая формула:

Калорийность = 4 * белки + 4 * углеводы + 9 * жиры

Рассмотрим подробнее каждое из этих веществ и его влияние на организм.

Белки (proteins)

Белки являются не только основным “строительным” материалом в организме, но также выполняют множество различных полезных функций на клеточном уровне и в различных биохимических реакциях. Недостаток белка чреват тем, что снижается иммунная функция организма. При избытке же вследствие увеличения выделяемой из организма жидкости также увеличивается выделение некоторых веществ, например, кальция, что может привести к хрупкости костей.

Белки в процессе переработки в организме расщепляются на аминокислоты. В этом деле активно задействуются щелочи и жирные кислоты, а поскольку жирные кислоты в организме получаются, как ни странно, из жира, то повышенное потребление белка положительно сказывается на уменьшении жировой прослойки и увеличении мышечной массы.

По скорости усвоения белки делятся на быстрые и медленные. К первой группе относят белки, содержащиеся в рыбе, яйцах, мясе; во вторую группу попадают растительные белки и казеин, который содержится в молочных продуктах. Быстрые протеины стоит принимать с утра, перед тренировками и после них, медленные лучше оставить на вечер. Также занимающимся стоит учесть то, что белки из обыкновенной пищи должны преобладать над белками из спортивного питания.

Углеводы (carbohydrates)

Функции углеводов в организме довольно разнообразны, но в вопросах питания важно то, что углеводы являются основным и относительно быстрым источником энергии. В организме они расщепляются до глюкозы, а глюкоза – до гликогена, который несет энергию в клетки. Недостаток углеводов заставляет организм производить глюкозу из белков и аминокислот, что в свою очередь может вызвать их недостаток и нарушение обмена веществ. Последствия же избытка углеводов таковы, что организм начинает перерабатывать и запасть их в жиры чтобы понизить уровень глюкозы в крови.

Углеводы делятся на три группы: простые, сложные и неусваиваемые. К первым относятся моно- и дисахариды (все сладкое), ко вторым – полисахариды (крупы, бобовые, овощи), к третьим – пищевые волокна (клетчатка).

Простые углеводы наиболее быстро расщепляются и перерабатываются, частенько в жир, поэтому при похудении первым пунктом ограничивается потребление именно простых углеводов. Сложные углеводы в силу невысокой скорости расщепления безопасны в разумных количествах.

Поскольку во время сна человек не потребляет пищи, то утро и первая половина дня – основное время для потребления сложных углеводов. Они восполняют недостаток энергии, который образовался за ночь, не позволяя заниматься этим накопленным в организме веществам. Хотя в зависимости от организма на восполнение могут идти разные запасы: для бодибилдера имеющего небольшую жировую прослойку это будут в основном запасы белка в мышцах; для полного человека – запасы жира. Поэтому для уменьшения количества подкожного жира имеет смысл сделать перед завтраком небольшую зарядку или пробежку. Конечно, тем кто боится потерять мышечную массу лучше подкрепиться сразу после пробуждения.

Жиры (fats)

Жиры являются одной из самых темных тем в питании: с одной стороны не стоит ими злоупотреблять, потому что иначе гарантировано увеличение количества жира в теле; с другой стороны, совершенно исключать их из рациона тоже не стоит, потому что они участвуют во многих процессах, в частности, в образовании гормонов.

Жиры делятся на насыщенные и ненасыщенные. Первые считаются “плохими”, так как в их число входит небезызвестный холестерин, злоупотребление которым врачи связывают с множеством болезней. Такие жиры содержатся в мясных и молочных продуктах и кондитерских изделиях. Ко вторым относятся Омега-3, которые важны для здоровья. Их можно найти в рыбе, орехах и растительном масле.

Конечно то, что в мясе и молоке содержатся насыщенные жиры не должно останавливать вас от их употребления, но стоит выбирать такие продукты, которые содержат их в минимуме: нежирное молоко и творог; нежирные виды мяса, например, мясо птицы или говядину; нежирные части мяса, например, антрекот или лопатка.

Сочетание пищевых веществ и как часто надо кушать

Осталось рассмотреть еще пару важных вопросов.

Начнем с пропорций. Поскольку основная энергия получается из углеводов, то им отводится основное место в рационе, белки и жиры делятся примерно пополам. Итого для обычного человека пропорции энергии, получаемой из различных источников составляют примерно 70% углеводов, 15% белков и 15% жиров. Для желающих похудеть можно немного увеличить количество белков в пользу уменьшения количества жиров и углеводов, например, 65/25/10. Для набирающих массу можно порезать лишь жиры, например, 70/20/10.

Насчет частоты потребления пищи мнения разнятся: обыкновенно советуют кушать до 5-6 раз в день и понемногу. Поскольку никаких научных исследований, которые бы подтверждали вред трехразового питания нет, как и тех, которые доказывают особый эффект частых перекусов, то я считаю, что нужно кушать так как удобно. Все единогласно сходятся лишь в нескольких правилах:

  • Обязательно надо завтракать!
  • Нельзя переедать
  • Пищу чаще варить или запекать, чем жарить
  • Вечером лучше заменить углеводы и жиры белками

Мой рацион

В качестве примера, а также для того, чтобы позже сделать самому сравнение, я напишу также о своем текущем рационе. В общем случае он состоит из трех больших приемов пищи и нескольких перекусов, в основном фруктами. Итак:

  • Завтрак (сложные углеводы, быстрые белки): овсяная или другая каша, молоко, немного вареного мяса птицы (или какого есть в холодильнике)
  • Обед (сложные углеводы, любые белки, немного простых углеводов и жиров): различные супы на первое, каши или картофель на гарнир с мясом или рыбой, немного шоколада
  • Ужин (медленные белки): тарелка творога со сметаной, пара стаканов молока, может быть немного вареного мяса

Обед получился таким разноплановым потому, что я съедаю его обычно после тренировки, во время “углеводного окна”, когда можно кушать любые углеводы для того, чтобы пополнить запас энергии.

Заключение

Вот и все. Конечно, здесь еще многое не сказано, однако, статья и не претендовала на то, чтобы полностью охватить сложную проблему правильного питания. Напоследок могу только сказать: кушайте и будьте здоровы!

Geek Tools

Sep 20, 2012 in Computers

I use a lot of tools in my everyday computer live. Most of them runs in terminal (vim, mutt, zsh), but today’s post is about a couple of useful GUI tools: GeekTool and Alfred.

Alfred

Alfred screenshot

Alfred is a small program basically intended to run other apps. AFAIK its closest analog in Linux world is Krunner from KDE which I used a lot in old days. Alfred has more features than Krunner and it will become even more powerful when you buy Powerpack for £15. By the way, you need it anyway if you’re going to use the tip below.

As for the tip, it’s about iTunes integration: it’s OK in most cases, but I was disappointed when I’ve known that Alfred’s playlist is played only once without repetition. And there’s no option that enables it.

But real hackers don’t lay their heads down! To enable repeating the playlist you have to edit itunes.applescript.src file in Resources folder inside Alfred’s package contents. As you may already guessed this is Applescript source file that’s being compiled when Alfred starts. If you don’t know Applescript and don’t want to learn it here is my patch for v1.3.1(261):

126c126
< 		make new user playlist with properties {name:playlistname, song repeat: all}
---
> 		make new user playlist with properties {name:playlistname}

GeekTool

GeekTool, on the other hand, is used to display some useful information on your desktop. It’s like good old widgets but without Dashboard needed to be active to see them. Conky does the same thing in Linux.

Geektool has 3 types of widgets: file, image, shell script. File shows contents of some file on your HDD. Maybe it’s useful for viewing logs or something like this, but I found this quite pointless. Image does the same, only shows it as image. It gets file or URL as argument. The most interesting part is Shell Script which shows output of some terminal tool on your desktop. This is really powerful. Besides, GeekTool can refresh this output automatically.

Geek tool screenshot

Here is a screenshot from my current desktop. Date and time were quite simple to get, currently playing track was not so simple, but still simpler than artwork from Last.fm. I’m going to tell about this last one.

The main idea is to download album cover, say, into /tmp/artwork.png and then show it with Image from GeekTool. I wrote simple daemon using Python and PyObjC which spies on iTunes and when it changes currently playing track detect artist and album and get cover from Last.fm if any exists. Here is daemon’s code:

import requests
import json
import Foundation
from AppKit import *
from PyObjCTools import AppHelper

class SongInfo(NSObject):
    last_album = ""
    last_artist = ""

    def getSongInfo_(self, song):
        ui = song.userInfo()
        artist = ui.objectForKey_('Artist')
        album = ui.objectForKey_('Album')
        if self.last_artist != artist and self.last_album != album:
            params = {
                "method" : "album.getinfo",
                "api_key": "PUT_HERE_YOUR_API_KEY",
                "artist" : artist,
                "album"  : album,
                "format" : "json"
            }
            r = requests.get("http://ws.audioscrobbler.com/2.0/",params=params)
            album_info = json.loads(r.text)
            if album_info.get("album") and album_info["album"].get("image"):
                img_url = [x["#text"]
                            for x in album_info["album"]["image"]
                            if x["size"] == "large"]
                if img_url:
                    f = open("/tmp/artwork.png", "w")
                    f.write(requests.get(img_url[0]).content)
                    f.close()
                    self.last_artist = artist
                    self.last_album = album

nc = Foundation.NSDistributedNotificationCenter.defaultCenter()
song_info = SongInfo.new()
nc.addObserver_selector_name_object_(song_info, 'getSongInfo:', 'com.apple.iTunes.playerInfo',None)

AppHelper.runConsoleEventLoop()

Now lets put this daemon to autostart. I did it with launchd. First, create file com.dancingrobot84.lastfm-artwork.plist in ~/Library/LaunchAgents with this content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>com.dancingrobot84.lastfm-artwork</string>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>UserName</key>
    <string>YOUR_USERNAME</string>
    <key>ProgramArguments</key>
    <array>
        <string>python</string>
        <string>FULL_PATH_TO_DAEMON</string>
    </array>
    <key>WorkingDirectory</key>
    <string>YOUR_HOME_DIR</string>
  </dict>
</plist>

Second, load daemon with this command

launchctl load -w ~/Library/LaunchAgents/com.dancingrobot84.lastfm-artwork.plist

Now you’re going to have a cover of your currently playing track in /tmp/artwork.png.

Working with MongoDB

Jun 28, 2012 in Programming

Last 6 months I spent working in the office on some Facebook app. It is written in Python using Django and uWSGI, but the interesting part is that MongoDB is the primary and only database there. It was not my choice, but anyway it seemed attractive to use some cutting-edge tech like this one so I signed up. This is a collection of small random notes on features, pitfalls and useful techniques of MongoDB.

Optimizing

Since this application was dedicated for Facebook audience the first requirement for my work was to optimize maximally and because database is the root of web-application I’ve started to look for optimizing techniques. That’s what I’ve found for MongoDB:

  1. Always profile. This should always be the first item in every optimizator’s list. You should know what to optimize and thus you have to do profiling and by “profiling” I mean “profile everything”: database, server-side code, client-side code and etc.
  2. Create indices and use hints. That was something I’ve expected to find first. Index can be created by using ensureIndex command. Hints help query optimizer to use right index for particular query. Hints are set via hint command.
  3. Limit results. The less you select the faster it works. Results can be limited with limit command.
  4. Select only relevant fields. Same thing, just push map of fields as a second param to find command.
  5. Rewrite some queries in map/reduce. Map/reduce is easy to parallel and if your server has more than one core or CPU (I believe it has) or you have several DB servers rewriting some “heavy” queries will increase their performance, often impressive.
  6. Use modifier operators. I’m talking about $inc, $set, $push and others. They are always faster than retrieve-update-save circle.

Now let’s take a closer look at a couple of things in Mongo: indices and map/reduce.

Indices and keys

Indices in Mongo work like the ones in SQL databases. Unique and primary keys can be achieved in Mongo through indices. If you’re a pedantic programmer and you always set PKs and UKs for proper fields in your DB you can simply skip this paragraph. For everybody else: always set unique key for unique fields! There is no other way to avoid duplicates because MongoDB has no transactions and therefore it has no transactional consistency, only atomic one. It means that actuality of your data is guaranteed only for current DB command.

For example, imagine you haven’t set unique key and coded some badass test in your app instead. This test selects count of documents that have the same data as yours in unique field and if this count is more than 0 then throw error, otherwise create new entry. As I said before actuality is guaranteed only for current command and if your count was 0 in test time it doesn’t mean that you have no similar entries in the time of adding new entry. When your app is under some heavy load you’ll get a tons of duplicate entries in database.

How really map/reduce works

I assume that you’ve already heard about map/reduce model. It took two best practices from functional programming and combined them. MongoDB’s modification of M/R includes the third optional function: finalize. I’m going to tell how these things work:

  1. All the data you’ve selected goes through map function first and map is called on each entry of it. On this step you group data by some key.

  2. Groups of data from previous step is now passed to reduce function which should perform some magic and return reduced value for each group.

    Here goes some important thing: reduce is not called when it’s nothing to reduce. I’ll better explain it on some example.

    Imagine you have a collection of cars. There are five entries in it:

    {'firm': 'Porsche', 'model': '911 Boxster'},
    {'firm': 'Porsche', 'model': 'Carrera GT'},
    {'firm': 'BMW', 'model': 'M3'},
    {'firm': 'BMW', 'model': 'X6'},
    {'firm': 'Audi', 'model': 'Q5'}
    

    Now you want to select count of models for each firm and add 10 to this number. You expect these results:

    ('Porsche', 12),
    ('BMW', 12),
    ('Audi', 11)
    

    You write map function:

    function map () {
        emit(this.firm, 1);
    }
    

    It groups your data like this:

    ('Porsche', 1),
    ('Porsche', 1),
    ('BWM', 1),
    ('BWM', 1),
    ('Audi', 1)
    

    And some internal Mongo voodoo groups them again:

    ('Porsche', [1, 1]),
    ('BMW', [1, 1]),
    ('Audi', 1)
    

    And pass to reduce function:

    function reduce(key, vals) {
        var count = 0;
        vals.forEach(function(e) {
            count += e;
        });
        return count + 10;
    }
    

    And you get these:

    ('Porsche', 12),
    ('BMW', 12),
    ('Audi', 1)
    

    Notice the difference?

    Now you must be thinking “what’s going on?”. But look closer to mapped results: Porsche and BMW have array of 1s and Audi has only “1”. Because there’s only one result in it Mongo thinks that it’s already reduced and not performs reduce function again.

  3. “Well, what should I do if I want correct results?” you ask. You should user finalize function. That’s where your data passed after reducing. After rewriting reduce and finalize you’ll get expected results:

    function reduce(key, vals) {
        var count = 0;
        vals.forEach(function(e) {
            count += e;
        });
        return count;
    }
    
    function finalize(key, val) {
        return val + 10;
    }
    

Conclusion

MongoDB is a great thing for its own purposes. I would recommend it for fast prototyping of apps, logging and caching. It’s easy, fast and quite reliable. Try it sometime!