вторник, 22 октября 2013 г.

Joker

Сходил 15 октября на конференцию Joker. Было хорошо, организация на 5- (минус за грустного чувака в костюме бетменовского джокера, Леджер негодует с того света), подбор докладов на 4. Далее краткий обзор докладов на которых я присутствовал.

"Факты и заблуждения о Java-сериализации" Хороший доклад, я так понимаю ничего что нельзя прочитать в спеке сказано не было... Но ктож её читал. Достаточно компактно рассказано о основных возможностях стандартной джавовской сериализации, и случаях когда не надо искать ей замену. По крайней мере для меня было познавательно.

"Парадигмы ООП, основы здравого дизайна и архитектуры Java приложений" Не очень понравился. Рассказывал какой-то коуч, так что представление было бодрым. Но и рассказ согласно званию автора был про очевидные вещи вроде SOLID и DRY. Много ссылок на "авторитеты" вместо рассмотрения каки-то конкретных решений и их последствий. Много проталкивания одной позиции в давних холиварах вроде interface vs. abstract class или setters/getters vs. public field.

"Компромиссы, или Как проектируются языки программирования" Неплохо. Но в основном содержание свелось к "В Kotlin всё збс.". Я пару раз попробовал набросить на тему что хаки в компиляторе склонные выявляться в самые интересные моменты. Мне сказали что встроили аккуратно но крепко, никто ничего не заметит. Ага...

"Платформа для Видео сроком в квартал" Хороший доклад от техлида Одноклассников. Рассказ был про их хостинг видео. Всё кратко и по делу. Вопросы не отставали от доклада. Очень понравилось. Не так часто разрабы сервисов такого уровня делятся архитектурными решениями и цифрами. Яндекс вон всё больше норовит мап-редьюс фреймворк какой заопенсурсить.

"The (not so) dark art of Performance Tuning" Откровенная муть. Какие-то эмпирические правила на тему что смотреть при проблемах с производительностью и куда крутить когда что-то увидели. Мало описания смысла циферок в табличках, мало идей на тему как искать проблему когда она не на поверхности. Долгое и непонятное демо в конце.

"Разработка API в Java-проекте: как оказывать влияние на людей и не приобрести врагов" Попытка обобщить хорошие практики в дизайне API на джаве. Много очевидных вещей, но зато автор не ленился приводить альтернативы и трэйд-оффы. Подача мягко говоря хромала, очень монотонная без намёка на акценты речь. Каких-то новых для себя идей не заметил, но как обобщение пойдёт.

"JDK8: Stream style" Хороший технический доклад от ораклового инженера. Довольно кратко и по делу. После него достаточно понятно становится чего ждать от 8го релиза джавы. Были приведены кое-какие интересные детали дизайна. Докладчик опытный, подача на отл. Рекомендуется к просмотру.

"В поисках Tommy Hilfiger" Интересный рассказ про внутренности Lucene. Немного дизайна немного алгоритмов, много задачек ушло в зал, на что-то я даже ответил. Докладчик молодец что (а) выбрал техническую тему, без лирики, (б) с самого начала наладил взаимодействие с аудиторией. Если Кормен на полке покрылся пылью то рекомендуется к просмотру с паузами на вопросах в зал.

UPD: вставил ссылки на записи докладов.

среда, 16 октября 2013 г.

ГЭБ

Прочитал сабж. Ещё буду выборочно перечитывать, по крайней мере доказательства...

Что можно сказать?... Автор неимоверно крут. Что бы по науке, технике или искусству вы сейчас не читали - бросайте, читайте эту книгу. Всё-рано после неё захочется перечитать и передумать заново...

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

Ладно хватит абстрактной воды, пора немного рассказать о чём книга. В предисловии Хофштадтер приводит мнения разных людей о том про что эта книга. Так вот, дочитав до конца я понял что очень важного предположения там не хватает. Эта книга - о сложности!

Действительно одна из центральных концепций книги - "странные петли". Системы с обратной связью, но только между всеми уровнями, без начала. Про этакие гармошки свёрнутые в бублик. Про проблемы которые можно начать изучать откуда угодно и и никогда не закончить. Про всю эту жуть которая пугает технаря со стажем, так же как пугала всех математиков ещё 100 лет назад. А может и им до сих пор страшновато?

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

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

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

понедельник, 7 октября 2013 г.

Несколько простых идей по улучшения кода на Scala

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

Самое очевидное, но и самое часто забытое - for. Альтернативой ему обычно выступают цепочки из map, filter, collect, flatMap, foreach. for имеет смысл использовать почти всегда когда нужна манипуляция с составом коллекции. Во-первых он существенно легче читается при росте длины. Цепочка из 3-4 преобразующих методов находится уже на грани понимания, при записи в for-нотации эта грань ещё далеко. Во-вторых for позволяет существенно читабельнее выписывать типы связанных переменных, а компилятор частенько от нас этого требует. Например сравните:
sessions.foreach((s: Session) => mngr.cancel(s.id))
и
for (s: Session <- sessions) mngr.cancel(s.id)

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

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

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

def hostedOn(host: Host)(node: Node) = host.addresses.contains(node.address)

def handleFailure(failed: Host) = {
    val affectedNodes = allNodes filter hostedOn(failed)
    ...
}

Удачно сочетая методы стандартного API с именами и сигнатурами своих функций можно строить очень читабельные и производительные DSL просто на ровном месте. Там где в джаве обычно получаются циклы с телами на 200 строк.

Третья недоиспользованная возможность языка - case classes. Во-первых они позволяют с разумной перегрузкой по синтаксису создавать новые типы данных. Тип данных из 3 полей это не 50 строк кода, а одна! Их можно и нужно создавать всякий раз когда они нужны, каждый модуль на 100 строк может позволить себе иметь 10 внутренних типов с собственными именами и именами их полей и при этом быть читабельным. Во-вторых они могут быть использованы в паттерн-матчинге без дополнительных усилий.

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

try {
    ...
} catch {
    case NoDataReceivedException =>
        channel.close()
        showError("No data received.")
    case PartialDataReceivedException =>
        if (confirmDataLoss(session.received()))
            channel.close()
}
и
try {
    ...
} catch {
    case TimeoutException(received) if received == 0 =>
        channel.close()
        showErrorDialog(received)
    case TimeoutException(received) =>
        if (confirmDataLossDialog(received))
            channel.close()
}

В какую сторону изменится выбрасывающий исключения код предлагаю додумать самостоятельно.
В завершение хочу поделиться вот этой вот замечательной книжкой: Scala By Example Раньше она висела на главной документации по языку, но сейчас почему-то исчезла оттуда. Если вы начали изучать Scala с какого-то мудрёного доклада на конференции или вводной на какой-то user group - скорее всего забыть всё услышанное и начать с этой книжки будет отличной идеей. Она является действительно кратким и очень целостным введением в язык, при этом просто полна идеями как с помощью самых простых средств писать очень выразительные программы на Scala.