Category: образование

усы2

Материалы курсов по Clojure за 2014-й год

В 2014-м мы с ребятами делали курсы по Clojure. Все серьезно, набор в группы, работа с преподавателями, домашки. Записали мы тогда 17 часов лекций. Всё на русском. На курсы пришло больше двухсот человек.

С тех пор сделать это еще раз у нас не нашлось сил, а про курсы спрашивали. Ну и мы наконец решили все это выложить как есть. Университет с самообслуживанием. Лекции по-прежнему классные, домашки по-прежнему можно порешать, только нет дедлайнов и проверить их будет некому. Поэтому, все кто спрашивал — вам спасибо и вперед!

clojurecourse.by

P.S. Всем, кто учился — привет!
усы2

(no subject)

— Десять лет в школе ерунду вбивают какую-то, как программирование вообще в жизни пригодится?
— Сдал экзамены, все рекурсии и указатели сразу из головы выветрились.
— Вот пошел я в магазин хлеб покупать, как мне информатика пригодится? Условные операторы с циклами, что ли, я продавщице рассказывать буду?

Just saying. Компьютеры вокруг нас, а программирование нет.
усы2

Навык привычки

Около месяца назад я решил оптимизировать клавиатурную раскладку. Прикинув, сколько и чего я пишу в последнее время (Clojure, CSS, русский/латинский текст), я сделал следующие оптимизации:

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

Общее направление — минимизировать количество нажатий шифта, что должно уменьшить нагрузку на пальцы. Это не универсальный рецепт, многое зависит от того, чем вы занимаетесь — скажем, в CSS и в JS имеет смысл вынести на безшифтовой режим фигурные скобки.

Я даже написал тулзу, чтобы научно обосновать свои действия, вот примерный выхлоп:

    cljs (97) —————————————

    backslash            \      503           81   |
     brackets           []    25786         3142   {}
        colon            ;     5079  <<     7769   :
         dash            -    23239         1606   _
      numbers   1234567890     9598  <<    85609   !@#$%^&*()
         plus            =     1866          490   +
        punct           ,.     8730         1651   <>
       quotes            ‘      827  <<     8544   “
        slash            /     4575         4226   ?
        tilda            `      142           10   ~

    css (7) —————————————

     brackets           []       26  <<      600   {}
        colon            ;      818          866   :
         dash            -      564          184   _
      numbers   1234567890     1757          458   !@#$%^&*()
         plus            =       11            1   +
        punct           ,.      560           51   <>
       quotes            ‘       60           24   “
        slash            /       56            0   ?

    js (2) —————————————

    backslash            \       71  <<     1094   |
     brackets           []     2564  <<     9168   {}
        colon            ;     4736         5409   :
         dash            -     1516  <<     2917   _
      numbers   1234567890     5437  <<    25052   !@#$%^&*()
         plus            =     6720          970   +
        punct           ,.    20530          549   <>
       quotes            ‘     2794  <<     6924   “
        slash            /     5279          517   ?
        tilda            `     1492            2   ~

Две цифровые колонки посередине — это частотность символов из группы. Знак << означает что имеет нехилый смысл поменять кнопку и ее шифтовый эквивалент.

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

(let [[x & xs] @atom]
  (swap! *context* #(assoc % :key "abc")))

Самое интересное здесь — это процесс адаптации. Для меня это не новый опыт — у меня уже есть клавиатура с нестандартной раскладкой, вот такая:

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

И они оказались правы. Примерно так процесс адаптации и происходит. Я прошел его один раз с клавиатурой, и вот недавно второй раз с новой раскладкой.

Забавнее всего, что в процессе обучения подобным механическим навыкам не участвует личность. Мы привыкли говорить — я знаю, я умею, мне нужно научиться. Здесь личность только мешает — учиться неохота, эмоции переполняют, ничего не получается, выигрыш далеко за горизонтом и вообще сомнительный. Проще всего к тренировке подойти отстраннено: как будто ты не себя тренируешь, а собаку. Чужую какую-то собаку. На входе энное количество механических повторений, некая регулярность. На выходе собака умеет печатать. Хочет она, не хочет, даже если она принципиально против — обучение встроено в организм и мозгом не управляется. Если есть тренировка — собака научится. То, что личность собаки в данном случае совпадает с инициатором тренировки — необязательная деталь.

То же самое и со многими другими видами обучения — новый редактор, новый язык программирования, новый курс на Курсере. Полезно смотреть за собой, улавливать структуру поведения, четко разделять цель (научиться чему-то), процесс обучения и собственную эмоциональную реакцию на него. Последнее надо научиться изолировать — эмоции идут и развиваются сами по себе, влиять на процесс они не должны.

усы2

Дистанционное образование

Идея в следующем. Дистанционное образование набирает обороты, Coursera и Udacity ломятся от курсов, можно учиться не выходя из дома, понятно.

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

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

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

И наконец последнее звено. Киноязыку уже порядка 100 лет, и эти 100 лет он неустанно наращивал приемы нарратива, чтобы вас клещами было не отодрать от экрана (нет, это не про взрывающиеся вертолеты). Естественно, всё это строилось на огромном базисе драматургии и театрального искусства. Уже понятно, к чему я клоню?

Короче, представьте себе курс по квантовой механике, составленный Ричардом Фейнманом, срежиссированный Стивеном Спилбергом, и со Стивеном Фраем в роли лектора. Не в том смысле что это будет приключенческий фильм, но чтобы смотрелось так же лихо. Спилберг, поверьте, истории рассказывать умеет. А Джордж Клуни, например, выдал в суде такую полуторачасовую речь, что все подумали, что они смотрят фильм.

Только не путайте с «образовательными» фильмами BBC, их главная цель — крутиться без звука на телевизоре в холле, и они больше запутывают, чем вводят в курс дела. Нет, представьте, что все эти суперпрофессионалы направят усилия на то, чтобы действительно положить вам в голову знания и адекватную картину мира той области, про которую курс. Уверен, это получится куда круче старичка, который всю жизнь простоял за кафедрой и все делает сам, как умеет.

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

Конечно, затраты на производство такого курса будут огромными. Но и потенциальный импакт сравним с эффектом от летнего блокбастера. Что выберешь ты — пойти скучать в аудиторию или посмотреть лекцию по биологии, снятую Финчером?

Чтобы не быть голословным, вот пара примеров неплохо построенного изложения:

Adventures in Thoughts

Why sky is dark at night?

Обратите внимание, насколько короткие и компактные эти «лекции» и насколько неплохо они доносят суть не самых тривиальных явлений. Даже эти обычные ребята уже очень неплохо рассказывают истории. Представляете, что будет, если взяться серьезно?

усы2

Clojure impresses

Нашему Clojure-проекту исполнилось полгода, из них последние три месяца его используют заказчики. Пора подводить промежуточные итоги.

Кложа со всех сторон такой правильный язык, что мне даже неудобно.

С одной, это правильный Питон — писать быстро, динамично, код компактный, легкий, лаконичный. Куда более лаконичный, чем питоновский, за счет ФП, макросов и прекрасной стандартной библиотеки.

Удобный перочинный нож на каждый день. Присылают .docx файл с табличкой — копирую его в Sublime, парой регэкспов подчищаю до регулярного формата (в sublime я этому научился-таки, а в vim регэкспы запомнить так и не могу, к вопросу о юзабилити vim-а), потом тремя-пятью трехстрочными функциями паршу и генерю что мне нужно.

Короче, когнитивного оверхеда никакого нет (особенно если repl уже запущен), и мне кажется, вообще всё надо на Кложе писать. Какой-нибудь енвайромент соорудить заместо bash, в котором все будет просто, логично и все главные нужные, но забытые в линуксе вещи будут, какой-нибудь feature-full process/task management framework, желательно network-transparent; и оттуда строить светлое будущее.

С другой стороны, Кложа одновременно и правильная Джава — вся та же Джавовая инфраструктура, доступ к любым библиотекам, maven-репозиториям, генерация Джава-кода, прямой интероп. Тоже минимум оверхеда, всё, что нужно сделать — выучить язык, и уже можно мягко и нежно продолжать достраивать Джава-проект на Кложе, без революций.

Плюс скорость. Тут сразу получается чуть хуже, чем у Скалы (по слухам) и голой Джавы, и иногда для разгона надо приложить усилия — типы кое-где дописать, инты анбокснуть, ленивости убрать или, наоборот, добавить. Написать джава-класс, в конце концов. Я в этом плохого ничего не вижу, потому что мы уже получили два в одном — быстрый прототип можно плавно и инкрементально перевести в производительное промышленное приложение. Такой мостик, которого нет у Питона, Руби (мы же не считаем всерьез мостиком возможность «переписать на C»?), Джавы.

С третьей стороны, и совсем не так давно, Кложа — это еще и правильный Джаваскрипт. Я на 100% оценил идею, что код сервера и клиента должны быть на одном языке, только кто решил, что это должен быть Джаваскрипт?

На бытовом уровне ClojureScript круче js хотя бы потому, что в js ты постоянно вошкаешься в поисках библиотеки, объединяющей строки или еще чего-то банального, но забытого разработчиками Netscape. Ну, по крайней мере, пока ты не профессионал и не написал свой utils.js. В cljs все сразу под рукой в стандартной библиотеке.

На промышленном уровне cljs, как наследник clojure, гораздо адекватнее, практичнее и однозначнее, чем js. На нем можно что-то строить, поддерживать и развивать, а не прыгать по плитам на одной ноге вокруг замаскированных ловушек, и не тратить дни на изобретение тысяча сто дватцать восьмого способа превратить код, сделанный из палок и соломы, во что-то, похожее на инженерное сооружение.

Ну и он, надо сказать, прёт вперед с каждым месяцем. Сейчас source maps прикручивают, скоро никаких аргументов за js не останется.

В-четвертых, изучение Кложи прокачивает внутреннего инженера. Хватаешься всяких полезных вещей — composable abstractions, примеров хорошей декомпозиции, учишься отличать важное от неважного, выделять среди моментов чистого хипстерства вещи, которые влияют на реальные, измеримые эксплутационные характеристики. Понимаешь, как важно, когда абстракции помещаются в голове.

Вот чему я научился бы, свяжи я свою карьеру с Питоном? The Zen of Python (хорошая штука, чего уж там), Джанге, WSGI и PyPy? А если бы с Руби, так вообще нахватался бы плохого. Вот в нашем Кложе-мире много новых взглядов на старые проблемы. Они, хоть и практичный язык, на самом деле на Джаве только бутстрапились, а сейчас потихоньку всё переписывают. Datomic, core.logic, reducers, cljs, enlive, lighttable, в самом языке stm, protocols, подход к стейту, много интересного короче и пищи для размышлений. Не любой код на Кложе — идеал, конечно, но это тоже работает в плюс — смотришь на хорошее, смотришь на плохое, анализируешь, почему так и в чем существенная разница. Да даже просто наблюдение сложности maven на фоне изящного lein подарило мне немало минут медитации об устройстве мира. Правда, как они ТАК всё зафакапили на ровном месте?

Тут секрет еще в чем? Чтобы выучить Кложу, надо посмотреть хотя бы пяток лекций Рича Хики. То есть, можно конечно и по-другому выучить, но тогда я не понимаю в чем смысл. А Рич Хики крутой чувак и все время правильные вещи говорит, универсальные. Если и есть надежда, что кто-то нашу software industry спасет, так это может быть он. Ну не DHH же в конце концов. И, давайте будем реалистичными, не Хаскель. Хаскель больше про объяснения и рефлексию, чем про спасение.

В лекции про муравьев, например, Рич раскрыл практическую сторону Кложи — симуляцию колонии муравьев можно сделать и на Джаве (JVM же общая), но очень сложно. Кложа дает правильные примитивы, в терминах которых можно мыслить — stm, транзакции, стейт, его изменение и синхронизация (например, традиционные actors здесь называются agents, плюс много других concurrent примитивов). Когда этого нет, никто конечно не мешает их написать, но люди, у которых есть жизнь, скорее вляпают глобальный лок на время рендеринга или еще какую-нибудь гадость. Потому что просто и идиоматично для Джавы. И потом будут бодаться с бизнесом — и тормозит, и ненадежно, и исправляется только выбрасыванием. Чтобы сделать правильно, надо было с самого начала правильно идти по довольно тонкой тропке выверенных решений; в условиях реальных проектов кто ж так сумеет? Нужен правильный инструмент.

Пользуясь случаем, хочу сказать, что мыслить в терминах Кложи про стейт и его изменение легко, удобно, и трудно ошибиться. Мне когда-то казалось, что STM это что-то толстое, серьезное и страшное, вроде БД, но нет, удобное и понятное, и пригождается даже в мелочах.

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

Иммутабельность и персистентные структуры совсем не просаживают производительность, по крайней мере мне заметить пока не удалось. Видимо, если хоть как-то вовлечено io, всё нивелируется. Естественно, плюсы от них бесконечны.

Макросы — простые и понятные пушистые зверьки, позволяющие кое-где срезать углы или отложить вычисления. Адское непонянтное программирование на них (как в Midje) считается какашкой, обычно за макросом просматривается все, во что он разворачивается.

Скобки перестают напрягать и парить через несколько дней, а Кложевский способ вызова функций начинает казаться более логичным, чем традиционный, очень быстро. К тому же, скобки в Кложе оптимизированы по сравнению с Лиспом — их нужно меньше, и они бывают нескольких видов. Читается значительно лучше.

С синтаксисом всё в порядке — управляющих конструкций больше, чем в любом языке, что я видел (любят заточенные под разные случаи частные случаи макросы вроде ->> или condp).

И немного приятных мелочей. Кложа — это действительно очень прикольный язык трансформации данных. Его надо каким-то DSL, мне кажется, оформить и во все остальные языки встраивать, или в базы данных, или в NoSQL вместо js.

(->>
  (str "http://api.twitter.com/1/users/lookup.json?screen_name=" (str/join "," names))
  slurp
  json/read-json
  (map (juxt (comp str/lower-case :screen_name) :id_str))
  (into {}))

(reduce #(min %1 (@emitted %2 0)) limit ins)

(reduce #(%2 %1) (update-in record [:rules] conj name) actions)

(reduce (fn [s [f t r]] (str (subs s 0 f) r (subs s t)))
        (:text tweet)
        (reverse (sort replacements)))

Это действительно очень компактный код. Мне, например, нравится, что я могу свой любимый шрифт Nitti поставить (а он блистает на крупных размерах) и все равно многое на экран входит, несколько логических блоков как минимум. В Джаве этому количеству информации соответствуют три-четыре разных файла, какой шрифт не ставь, хреново.

Это нормальные-дефисы-в-именах вместо уродливых_подчеркиваний или ВерблюжьегоРегистра, да и вообще много прикольных спецсимволов в именах можно использовать. ->> например вполне валидный идентификатор.

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

усы2

Clojure@Echo 02 Библиотеки, web-стек, ClojureScript

Третья лекция про язык Clojure. Лекция будет полезна всем интересующимся пригодностью Clojure на практике (батарейками) и задающимся вопросом «а не написали ли на ней killer-app уже?». Где-то после первого часа начинаются вопросы, не знаю, насколько там все разборчиво. Видео в этот раз особенно урывочное (фотоаппарат барахлил), но немного есть.

Видео:


Слайды можно посмотреть отдельно на Спикердеке, а можно скачать pdf. Видео можно скачать на Vimeo.

Предыдущие лекции выложены тут и тут.
усы2

Clojure@Echo 01 структуры данных, полиморфизм, интероп

Следующая лекция про язык Clojure. В этот раз про структуры данных, полиморфизм (мультиметоды и протоколы) и интероп с Джавой. Лекция будет полезна всем начинающим изучать язык и интересующимся. Специально для ystrot продолжительность этой лекции всего 1 час.

Видео:


Слайды можно посмотреть отдельно на Спикердеке, а можно скачать pdf. Видео можно скачать на Vimeo.

Дополнительно хочу заметить вот что:

Обзор алгоритма работы персистентных векторов и словарей.

Trie — это несбалансированное дерево, в котором ветвление происходит по префиксам. В случае PersistentHashMap префиксами являются 5-битовые кусочки хэш-кода.

Reify отличается от proxy тем, что реализует интерфейсы с меньшим уровнем indirection (меньше динамизма, лучше производительность): http://stackoverflow.com/questions/5821892/why-should-i-use-reify-instead-of-proxy-in-clojure

Предыдущая лекция выложена тут.
усы2

Clojure@Echo 00 обзор, concurrency

В прошлый вторник я рассказывал у нас в компании про JavaClojure. Это первая, вводная лекция — я Кложу в компанию притащил, мне и отдуваться теперь, популяризировать. Звук есть весь, видео вот не всё (фотоаппарат потому что, 29 минут максимум пишет), но кое-где есть. Слайды все есть.

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

Видео:


Слайды, если разберетесь, можно посмотреть отдельно на Спикердеке, а можно скачать pdf.


На вопрос про разницу Скалы и Кложи отвечали тут.

(no subject)

А теперь к интересному. На собеседовании к нам часть кандидатов решает задачи на C, часть (малая) — на чем-то высокоуровневом (C#, Python). Так вот, на этом контрасте видно — я сейчас говорю о самых лучших кандидатах, вопросов к профессионализму которых нет вообще — как на C вы час решаете с человеком задачу, учли кучу случаев, исписали две страницы кода, а на выходе малозначительная не утилитка даже, а функция, но зато уже (!) с кучей допущений насчет входных данных, неврозом по поводу утекающей памяти1, с допущениями по порядку вызова и прилагающимся сюда неврозом по поводу надежности вызывающей стороны; и неистребимым ощущением неудовлетворенности в целом. А на Python-е за пятнадцать минут у тебя уже готово и чтение файла, и парсинг какой угодно, и все это надежно, и общее ощущение хорошо и правильно выполненной работы. Я первый раз даже не готов оказался — через пятнадцать минут и вот, всё, пожалуйста, что дальше делать? Хотя работы было раза в три больше.

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

Питон же — язык с готовым каким-то решением на любой случай жизни. Практичный в бытовом смысле язык. Задача без раздумий и сомнений ложится на код практически один-к-одному, потому что все нужное уже тут. Когда готово, вдруг думаешь — как это получилось? Подозрительно мало я страдал: над выбором библиотек, над мелкой моторикой работы с ними, над микрооптимизациями. Потом к этому ощущению привыкаешь, понимаешь, что так и задумано. И удивляешься, что у других не так: кто-то занят какими-то моноидами, чистотой, системами типов, а на самом деле мясо, скучные бытовые утилиты — они и в промышленности, и для собственного счастья куда важнее. Когда каждой следующей строчкой ты приближаешься к окончательному решению своей задачи (в терминах вход-результат), а не к очередному уточнению используемой абстракции, это больше смысла несет, это важнее. Даже ощущение правильности решения больше. Но это надо попробовать Питон, чтобы понять.

1 Это мое личное, может, в универе меня напугали, но на меня любая строчка кода на C смотрит как партизан, который нет-нет да и выкинет кунштюк, а мне потом неосвобожденная память две ночи снится. В банальной программе
    int* arr = malloc(10);
    arr[0] += 1;
    free(arr);

я не могу избавиться от ощущения, что память тут рано или поздно найдет способ утечь. Это еще и к вопросу о чтении puzzlers на ночь.

(no subject)

Сижу на экзамене. Точнее, нет: сижу на работе. Но сижу я на работе потому, что у меня экзамен. То есть в любой другой день я бы тоже сидел на работе, но уже не потому, что у меня экзамен, потому что экзамен именно сегодня, а не в любой другой день. Возникает, конечно, вопрос: почему я сижу на работе, если у меня экзамен? Вот вам и загадка. Кто ответит -- молодец.

Электронный документооборот -- оборот, в котором документы передаются посредством электронов.