11 Август 2008

Evolution of Basecamp homepage

I used an amazing tool webkit2png to capture some screenshots of Basecamp home page at various key moments in its history. Here's the result (click to enlarge):

Feb 2004Oct 2004Mar 2005Mar 2006Jan 2007

31 Май 2008

640k достаточно для всех

Из случайно подвернувшихся новостей (под Pink Floyd, играющий на моём iPhone).

02.05.2007

Отдав должное действиям Apple на рынке цифровой музыки, Балмер выразил сомнение, что новый телефон Apple сможет отвоевать сколько-нибудь значительную долю рынка.

«У iPhone нет абсолютно никаких шансов завоевать значительную часть рынка. Никаких! Это устройство будет продаваться за $500, причем эта цена с учетом скидки за подписание долгосрочного контракта с оператором. […] глядя на 1,3 млрд. проданных во всем мире телефонов, я бы лучше предпочел, чтобы в 60 или 80% из них было установлена наше ПО, чем те 2 или 3%, которые Apple может получить, продавая iPhone», — сказал глава Microsoft.

06.02.2008

В соответствии с отчетом аналитиков агентства Canalys, доля iPhone достигла 28% и занимает второе место на американском рынке, уступая лишь Research in Motion (Blackberry) c ее 41%.

Этот скачок, по сравнению с 19,5% охватом рынка в третьем квартале, позволил Apple обойти весь сектор устройств на базе Windows Mobile, доля которого в четвертом квартале составила 21%, по сообщению Canalys.

P.S. А еще рекомендую послушать Стива Джобса и Билла Гейтса на All Things Digital. Много весьма любопытного о trend'ах.

30 Май 2008

Связывание и внедрение объектов не работает

Вспомним времена Windows 3.1, когда буквально в каждой книге по консумерским приложениям описывалась замечательная технология Object Linking & Embedding. OLE казалась частью светлого будущего — того времени, когда отдельных приложений в мире существовать больше не будет.

OLE и в самом деле весьма продвинутая технология. Она позволяет в документ одного приложения вставить контент, создаваемый другим приложением. Хитрые OLE-контейнеры (единственным экземпляром которых являлся Microsoft Binder) могли даже этот чужой контент разбивать на свои страницы и делать ему сквозную нумерацию.

Теперь же я об OLE вспоминаю, только когда пытаюсь вставить диаграмму в презентацию. На маке ничего аналогичного OLE нет, поэтому приходится экспортировать диаграмму OmniGraffle в картинку и вставлять эту картинку в Keynote.

Но и под Windows OLE почти мертво — его больше не продвигают. Причина в том, что он слишком сложен, а пользователю меньше всего на свете хочется сюрпризов.

Вставка картинки в презентацию — совершенно понятное действие, картинка останется там и ровно такая, какая была.

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

Своенравность штуки, кстати, не только суеверие — встроенные (embedded) объекты порой действительно ведут себя неожиданно (например, при попытке их resize'ить, что выполняется масштабированием метафайла без активации OLE-сервера), а контейнеры зачастую начинают больше глючить.

Теперь о том, как можно сотворить более простой функциональный аналог OLE. Хитрости здесь две:

1. Сделать в OmniGraffle опцию «при каждом сохранении экспортировать диаграмму в картинку и класть рядом».

2. Сделать, чтобы Keynote проверял, не изменились ли на диске картинки, которые были вставлены в документ, и, если да, ненавязчиво предлагал опцию быстренько обновить их с диска.

Эффект такой же, ощущение предсказуемости процесса в разы выше. Заодно такие возможности полезны и для других применений.

Золотое правило: интерфейс не должен содержать сложных концепций.

Второе золотое правило: если из-за какой-то функции программа начинает больше глючить, пользователь свяжет эту функцию с мистикой и начнет её бояться.

Сложные функции больше подвержены ошибкам. Не пугайте ваших пользователей.

24 Апрель 2008

Измеряем интеллигентность

Терпимость (как правило) характерна для людей средней интеллигентности. Люди менее образованные (обычно) боятся отличаться, а более интеллигентные (часто) считают, что те, кто от них отличается, неправы.

19 Апрель 2008

Крокодилы — это наше всё

Спецификация дизайна, разработанного сегодня с dottedmag'ом. (Начало опущено, ибо скучное.)

3.2. …Назовем такую последовательность Большим Красным Попугаем (Big Red Parrot, BRP), а каждый элемент ее несокращенной записи (например, bar:12) назовем Куском Мяса (Piece of Flesh, PoF).

4. Большой красный попугай — мысленная концепция, она слишком длинная и дорогая, чтобы быть примененной в реальном анализе. Поэтому нам необходимо ввести Маленького Зеленого Крокодила (Little Green Crocodile, LGC). Но перед этим отметим важный факт.

4.1. Большие красные попугаи линейно упорядоченны.

4.2. Маленький зеленый крокодил — шаблон, соответствующий набору больших красных попугаев.

4.3 Взрослый (полностью построенный) маленький зеленый крокодил всегда начинается с обрубка хвоста (да, их купируют, как у спаниелей), обозначаемого звездочкой.

4.4. Пример крокодила — «* bar:15..21 (bar:22..bar:30 / bar:24)* foo:1..3».

4.5. После обрубка хваста идет набор кусков мяса, и/или диапазонов кусков мяса, и/или колец (которые он позаимствовал у удава).

4.6. Кусок мяса — это просто позиция в сорцах, например foo:5.

4.7. Диапазон кусков мяса — это два куска мяса, путь исполнения между которыми можно по ним однозначно (и быстро) определить. Будем писать foo:n..bar:m или же сокращенно foo:n..m. Что конкретно означает фраза «путь исполнения между которыми можно по ним однозначно (и быстро) определить», предстоит еще уточнить. (Например, это может означать, что оба куска мяса находятся в одной и той же функции, так что простым проходом исходного кода можно легко перечислить, что было между ними.) Совершенно точно, что между этими двумя кусками мяса может располагаться сложный цикл, так что под «быстро определить» понимается не перечисление всех Больших Красных Попугаев, а некое концептуальное понимание того, какие инструкции входят в диапазон.

4.8. Кольцо — это возможность неограченного числа повторений некоторой части крокодила, с остановкой на одном из кусков мяса, входящих в эту часть. Пример — «(bar:22..bar:30 / bar:24)*» (выполнено сколько угодно итераций цикла bar:22..bar:30, при этом на последней из них мы остановились на bar:24).

4.9. По мере развития теории крокодилов мы, возможно, выведем особей с другими разновидностями частей.

5. С маленькими зелеными крокодилами определено несколько фундаментальных операций.

5.1. Утолщение маленького зеленого крокодила относительно гоала X. Пусть голова (голова у крокодила справа) выглядит как foo:7..8. Пусть смежные с foo:7..8 строчки foo:5, foo:6, foo:9 и foo:10 не влияют на результат X. Тогда мы расширяем голову до foo:5..10.

5.2. Удлинение маленького зеленого крокодила. Пусть хвост (он слева) крокодила выглядит как bar:5. Тогда мы выясняем, откуда мы могли прийти к bar:5, и приписываем эту точки слева, получая что-то вроде «bar:4..5», а потом, по мере продолжения удлинения, «boz:88 bar:1..5».

5.3. Кормление маленького зеленого крокодила дописывает заданный кусок мяса справа, делая его новой головой.

5.4. Заднее попугаенье (backward parrotizing) маленького зеленого крокодила получает набор маленьких зеленых крокодилов, описывающий набор больших красных попугаев, исполняемых непосредственно перед большими красными попугаями, которых описывает исходный маленький зеленый крокодил.

5.5. Переднее попугаенье (forward parrotizing) маленького зеленого крокодила получает набор маленьких зеленых крокодилов, описывающий набор больших красных попугаев, исполняемых непосредственно после больших красных попугаев, которых описывает исходный маленький зеленый крокодил.

5.6. Крокодильчонок — это крокодил без обрубка хвоста. Купированием крокодильчонка получают взрослого маленького зеленого крокодила. Например, из «foo:7 bar:5..10» получается «* foo:7 bar:5..10». Во всём остальном крокодильчонки ведут себя также, как и взрослые крокодилы (что естественно, они же тоже крокодилы, только еще маленькие).

6. Крокодилы — это наше всё.

6.1. В анализе каждому construct'у соответствует кусок мяса, например, foo:7.

6.2. Первым делом из этого куска выращивают крокодильчонка (например, можно взять пустого крокодильчонка и накормить его этим куском). Получаем крокодильчока foo:7.

6.3. Далее мы выясняем, есть ли в кэше крокодилы, головна которых совпадает с нашим крокодильчонком. Если есть, мы удлиняем крокодильчонка до тех пор, пока он либо не совпадет с каким-то крокодилом из кэша (за исключением обрубка хвоста, разумеется), либо пока он не перестанет быть похожим на крокодилов их кэша.

6.4. Если крокодильчонок совпал с кем-то в кэше, то всё скучно, берем результат из кэша. Рассматриваем случай, когда он не совпал.

6.5. Теперь у гоала зовется preRun, и мы начинаем его реально вычислять. Пусть наш goal — «значение переменной Z». У нас есть несколько стратегий вычисления, которые могут быть выражены через операции с крокодилом.

6.6. Мы можем купировать крокодильчонка после первого же куска мяса, получив «* foo:7», выполнить поиск всех присваиваний переменной Z и соединив их результаты. Такой уровень точности анализа (grade) мы можем назвать NO_FLOW. Мы получим ответ (NO_FLOW: * foo:7 => A | B | C), который можно кэшировать.

6.7. Мы можем выполнять заднее попугаенье, по необходимости удлинняя крокодильчонка, в поисках присваиваний Z. Например, в момент, когда крокодильчонок станет bar:25..30 foo:1..7, мы можем встретить Z=42. Тогда мы запишем ответ (EXACT: bar:25..30 foo:1..7 => 42). С другой стороны, мы могли встретить присваивание Z=Y, и тогда мы бы продолжили искать значение Y с тем же крокодильчонком, который мог стать при этом еще длиннее, и в итоге закэшировали ответ вроде (EXACT: boz:15 bar:20..30 foo:1..7 => 24). [Хитрый реализационный момент — как удлиннять крокодильчонка, при этом для Y сделав вид, что его середина — это голова.]

6.8. Мы можем использовать эвристику, чтобы упростить крокодила перед записью в кэш. Например, циклы (повторяющиеся последовательности) можно заменять кольцами, если они не влияют на наш гоал (или если вляют не сильно, и мы хотим немного потерять точность анализа). Ясно, что чем более общего вида получится крокодил, тем полезнее будет кэш.

17 Апрель 2008

Scorpions в Новосибирске

Вернулся с концерта Scorpions в Новосибирске. Как всегда, понравилось, но средне (ибо я за хорошую акустику и отсутствие толпы с аплодисментами). Прозвучало:

Hour I (Humanity: Hour I, 2007);
Coming Home (Love at First Sting, 1984);
The Zoo (Animal Magnetism, 1980);
No Pain No Gain (Face The Heat, 1993);
Deep and Dark (Unbreakable, 2004);
Coast to Coast (Lovedrive, 1979); — спасибо Константину за «опознание» этой мелодии
Always Somewhere (Lovedrive, 1979);
Send Me An Angel (Crazy World, 1990);
You And I (Pure Instinct, 1996);
Living For Tomorrow (Still Loving You, 1992);
Hey You (Animal Magnetism, 1980);
321 (Humanity: Hour I, 2007);
Alien Nation (Face The Heat, 1993);
Dynamite (Blackout, 1982);
Blackout (Blackout, 1982);
Соло барабанщика;
Still Loving You (Love at First Sting, 1984);
Humanity (Humanity: Hour I, 2007);
Wind Of Change (Crazy World, 1990);
Rock You Like A Hurricate (Love at First Sting, 1984);
When The Smoke Is Going Down (Blackout, 1982);
A Moment In A Million Years (Eye II Eye, 1999).

Есть подозрение, что где-то в конце я пропустил Is There Anybody There (Still Loving You, 1992).

06 Март 2008

ФИТ 2007–2008

4-й курс ФИТ НГУ (будущего) выпуска 2008 года — полный и откровенный пиздец. Людям по 20 лет, а они ведут себя, как в 14. Кто-нибудь постоянно на кого-нибудь обижается, какие-то бурлящие мелкособственнические сиюминутные переживания, весь прочий идиотизм, который должен был пройти годы назад.

И здесь я с большой любовью передаю привет нашему прошлогоднему выпуску. Взрослым людям, которых интересовал поиск работы, технологии, фондовые рынки, дизайн и кошки, раскрутка нелегальных сайтов, ежики (здравствуй, Лёня!), покупка автомобилей, Firefox (Матвей, вечный респект); которые женились, играли на гитаре и покупали решения задач по графике. Довольно стабильным людям, которые более-менее знали, чего хотят. Господа, среди вас было приятно находиться, и вы в основном успешно противостояли системе и маразму.

Остальные — ну повзрослейте же вы, наконец. Вадим, черт побери. Леон, мать вашу. Дьяков. Попова. Ужас.