Русский
Русский
English
Статистика
Реклама

Выбор языка программирования

Из песочницы Практическое применение Kotlin в стартапах и энтерпрайзе

13.06.2020 16:21:14 | Автор: admin

Disclaimer: Я не имею никакого отношения к JetBrains, не получаю денег от продвижения Kotlin или от написания данной статьи. Весь материал это лишь отражение моего личного опыта.


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



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


В этой публикации я собираюсь объяснить свою позицию, а заодно опишу некоторые особенности перехода с Java на Kotlin как в условиях стартапа, так и в условиях крупного энтерпрайз-проекта.


Kotlin против Java


Можно было бы привести список из десятков-сотен преимуществ языковых конструкций в Kotlin против таких же конструкций в Java, но основной выигрыш от применения языка находится гораздо глубже.


На мой взгляд, Java зародилась как мощный ответ прежде всего C++. Поэтому в ней чувствуется сильное его влияние со всеми его недостатками. Проблема в том, что за 25 лет существования Java, она продемонстрировала значительную консервативность по сравнению с другими языками. В то время как множество языков экспериментировали с ключевыми словами типа async, с пунктуацией языка (точки с запятой, скобки и пр.), Oracle хранила исключительную верность "традиционным принципам", что привело лишь к моральному устареванию самого языка.


Печально то, что разрыв лишь нарастает, не смотря на попытки его сократить со стороны Oracle. Например, дата-классы в Kotlin появились в самых ранних версиях, а некий их аналог в Java появился лишь в 14 версии, полагаю, как раз под давлением конкуренции с JetBrains.


Kotlin, напротив, стремился вобрать в себя все самые передовые практики от всех других языков разработки, при этом поддерживая интероперабельность с Java. Поэтому, сравнивая Java и Kotlin, мне приходит на ум аналогия со старым добрым и надежным паровозом с его чугунными поршнями (Java) и автомобилем с его персональной аудиосистемой, противоугонкой, хромированными ручками дверей и прочими "наворотами" (Kotlin).


Если вам в вашем проекте требуется "возить лес в Сибири" вдали от селений и с полным отсутствием бензина, то, вероятно, паровоз вам действительно подойдет лучше. Но большинство проектов все же находятся не в столь экзотических условиях. Поэтому тот факт, что на Kotlin проект получается раза в 2-3 компактнее, более легкочитаемый, более надежный в плане защиты от NullPointerException, должен стать серьезным аргументом. Именно эти особенности и позволяют Kotlin снижать в 2 раза время разработки и количество багов, а в итоге, стоимость создания и владения программным продуктом.


Я лишь вкратце перечислю те преимущества, которые Kotlin предлагает из коробки, но которые с трудом достигаются в традиционном Java.


  1. Множество элементов, сокращающих бойлерплейт: data class, getters&setters в разы сокращает количество кода.


  2. Более продуманная и юзабельная структура классов: вместо HashMap, например, Map (иммутабельный) и MutableMap (мутабельный) позволяет с легкостью входить в язык новичкам и концентрироваться на бизнесовой постановке, а не на способах реализации.


  3. Прямо из коробки идут различные защиты, например от null:


    var str: String = ""str = null // Здесь будет ошибка компиляции, а не runtimevar nullableStr: String? = null // а так можно
    

    что приводит к значительным сокращениям ошибок в программах и снижению стоимости поддержки.


  4. На уровне языка идет поддержка асинхронных операций, которые существуют в Python и JS ES6 приводит к упрощению работы с асинхронными и многопоточными операциями по сравнению с Java.


  5. Kotlin Multiplatform возможность компиляции программ на Kotlin одновременно для JVM, JS, Native (C/C++, Object C) допускает снижение дублирования кода, более легкую интеграцию с фронтендами и более оптимальную разработку в архитектуре Serverless.


  6. Domain Specific Language (DSL) дает компактную и легкочитаемую замену билдерам.



Проблемы перехода на Kotlin


При обсуждении проекта с командами, возникают одни и те же вопросы по внедрению Kotlin. Давайте пройдемся по ним.


Где взять Kotlin разработчиков?


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


В любом случае, любой разработчик, знакомый с Java, вполне успешно и быстро переходит на Kotlin (см. следующий вопрос).


Сколько нужно времени для подготовки разработчиков?


Kotlin разрабатывался на базе Java и совместим с ним на 100%. Поэтому для перехода на него не обязательно проходить какие-то специализированные курсы. Начать разрабатывать на Kotlin можно с первого дня. Базовых отличий не так много между языками. Например, if работает и там и там практически одинаково, дополнительно в Kotlin его можно использовать в виде выражения:


val x: Int = if (a == 1) 2 else 3

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


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


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


Как быть с легаси кодом?


Kotlin полностью интеоперабелен с Java, что позволяет прямо в программе на Kotlin использовать код, написанный в Java. Также в саму Intellij Idea включен плагин, который на лету умеет конвертировать куски кода (либо весь файл) из Java в Kotlin. Надо понимать, что качество автоконвертации не сравнится с работой человека, но тем не менее, инструмент очень полезный.


Также Kotlin позволяет писать код одновременно на Java и Kotlin в одном модуле. Для этого можно настроить сборщик либо на расширения, либо на директории, разнеся их в src/main/java и src/main/kotlin. Тут опять нужно знать о нюансах: код из Java легко подхватывается в коде на Kotlin, но для обратной совместимости приходится прилагать определенные усилия. Например, по умолчанию в Kotlin вместо статических методов используются объекты-компаньоны и для экспорта в Java требуется применить аннотацию @JvmStatic.


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


У нас стартап, зачем нам Kotlin?


Довольно часто для стартапов применяется даже не Java, а такие языки как PHP, Python, JavaScript (NodeJS). В каких-то случаях это может быть оправдано, но надо иметь в виду следующее. Перечисленные языки могут себя неплохо показать для прототипирования, но из-за отсутствия строгой типизации, они меньше подходят для долгосрочных, крупных проектов. Просто потому, что строгая типизация позволяет избегать множества ошибок на этапе даже не компиляции, а на этапе написания кода в IDE. Ошибки, допущенные из-за отсутствия проверки типов, выливаются в простои в боевом режиме, приводя к убыткам. Поэтому вам нужно тщательно взвесить все выгоды от быстрой разработки на языках без строгой типизации и убытки от их применения в продуктовом режиме.


Довольно часто бытует мнение, что первую продажу можно сделать на каком-нибудь PHP, а затем мигрировать на Java/Kotlin. Мой опыт говорит, что сделать первую продажу можно вообще без кода хоть на PHP, хоть на Kotlin. Но времени для перехода с одного языка на другой на практике никто не даст при развитии стартапа. Каждый день будут задачи, которые нужно сделать вчера.


Безусловно, на любом языке можно написать плохо. Но PHP, Python, JS дают гораздо больше возможностей для низкокачественного кода, чем Java/Scala/Kotlin. И чем хуже изначально написанный код, тем хуже он поддерживается дальше, приводя к еще большим костылям. Я сталкивался со стартапом, который стартовал нормально, но за 7 лет своей работы получил совершенно нечитаемый и неподдерживаемый код на Python. Ситуация оказалась патовой: его нельзя было просто так закрыть из-за наличия обязательств, и нельзя было продолжить развивать из-за необходимости полностью переписать проект, на что бюджета уже не было.


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


Особенности разработки на Kotlin


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


Ненулевые переменные и свойства класса


Kotlin предоставляет мощнейший элемент защиты от null. Приводит это к тому, что работать с nullable переменными просто неудобно их ведь нужно всегда проверять на null. Хоть такая проверка выполняется очень просто в Kotlin, хочется избегать ее чрезмерного использования. Достигается это тем, что при создании большинства классов я определяю пустой элемент:


data class SomeClass(    var x: String = "",    var y: Int = -1) {    companion object {        val NONE = SomeClass()    }}

, который и используется при инициализации в качестве значения по умолчанию вместо null.


Существует множество случаев, когда нам просто необходимо делать свойства нулевыми. Например, в API или в хранилище мы не можем быть уверенными, что нам придет всегда non-nullable значение. Как раз здесь и играет свою роль DDD (domain driven design). Мы для отправки данных или для сохранения делаем отдельные DTO-классы, которые содержат в себе нулевые поля, а в рабочие модели мы их мапим со всеми проверками:


data class StorableObject(    var id: String? = null,    var data: String? = null) {    // Место размещения конвертера зависит от задачи    constructor(wm: WorkModel): this(        id = wm.id.takeIf { it != -1 }?.toString(),        data = wm.data.takeIf { it.isNotBlank() }    )    // Место размещения конвертера зависит от задачи    fun toWorkModel(): WorkModel = WorkModel(        id = id?.toInt() ?: -1,        data = data ?: ""    )}

Таким образом, простое использование Null-safety в Kotlin стимулирует нас применять практику DDD, что в свою очередь делает наш код более гибким, защищенным от изменений API или внутренней логики.


Kotlin Multiplatform (KMP)


KMP это довольно мощное средство и его стоит использовать в проектах при интеграции с JS и Native компонентами системы. На практике, KMP вполне неплохо себя показывает при описании API для потребления Single Page Application (SPI) типа React, Angular, Vue, а также мобильными приложениями под Android и iOS.


Но лично я предпочитаю разрабатывать фронтенд на Dart/Flutter, а с этим фреймворком простой интеграции через KMP пока не существует. Интеграцию между бэкендом на Kotlin и фронтендом на Dart можно реализовать с использованием OpenAPI, AsyncAPI, gRPC и других кодогенераторов.


На бэкенде KMP может быть применен, например, при использовании Serverless архитектуры, в том числе Google Cloud Functions, Yandex Cloud Functions, AWS Lambda и др. аналогов. Особенность бессерверных архитектур в том, что в них важна скорость старта приложения. Поэтому код на Python или NodeJs может показывать гораздо более низкое время отклика, чем на JVM. Использование KMP позволяет компилировать код в JavaScript или в Native executable, что вполне решает проблему быстрого старта.


Недостатки Kotlin


Наверное есть какие-то недостатки более бытового характера. Но для меня самым существенным недостатком является отсутствие фронтенд-фреймворка для Kotlin. Ktor, при всех его преимуществах, не достиг уровня фронтенд-фреймворка. Я как-то видел набор в Jetbrains фронт-разработчиков и думаю, что вскорости такой фреймворк будет анонсирован. Однако, на сегодняшний день на фронтенде я предпочитаю использовать Google Flutter, который использует язык Dart. Возможно для кого-то окажется более приемлемым переход на Dart как на фронтенде, так и на бэкенде вместо Котлина.


Заключение


В заключении хочу кратко суммировать основные утверждения настоящей статьи.


  1. Kotlin это действительно мощный инструмент, который превосходит классическую Java по многим параметрам. Поэтому я ожидаю, что в ближайшие 5 -10 лет произойдет существенное вытеснение им последней с рынка.
  2. Перевод реальных проектов на Kotlin не создаен непреодалимых препятствий, наоборот, его уместно осуществлять как на легаси-проектах, в корпорациях и стартапах.
  3. При том, что переход на Kotlin довольно прост, недостаточный опыт чреват Java-стилем, что неэффективно. Для более полноценного использования этого инструмента, рекомендую получение опыта, привлечение экспертов, либо прохождение практических курсов разработчиками.
  4. Использование Kotlin может заметно влиять на архитектуру проекта, делать ее более стройной, а также позволяет применять техники, которые непименимы в Java, в частности Kotlin Multiplatform.
  5. Пока не существует достаточно мощного фронтенд-фреймворка на Kotlin. Кто-то может предпочесть Котлину Dart, который можно использовать одновременно на всех платформах как на фронтенде, так и на бэкенде.

Подробнее..

Отпусти меня, PHP

14.12.2020 02:16:30 | Автор: admin

Всем привет, меня зовут Коля и я 10 лет пишу на php. Хлоп-хлоп-хлоп, привет, Коля.

Впервые я попробовал PHP в 11 классе, на тот момент были очень популярны сайты для мобилок, и меня это затянуло. Я писал на php на уроках и переменах со своего nokia n73, разбирался с одной из широко известных в узких кругах CMS, и грезил светлым будущим. Вот же оно, я теперь программист, я все понимаю и у меня получается.

Затем была первая работа, брошенный универ, ООП, фреймворки, и первые попытки соскочить. Сначала Java, затем плюсы. Я делал простенькие программки-помощники (трекер времени с автосохранением в jira, десятистрочные плагины для IDE), и среди этих for, if, switch я без проблем плавал как рыба в воде.Но как только требовалось что-то посложнее таймера, сразу начиналось избиение клавиатуры, стола и прочих подручных предметов.

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

Время шло, опыта становилось все больше, паттерны, SOLID, SQRS, DDD. PHP стал совсем понятным, любая ошибка при выполнении скрипта вызывала лишь усмешку и заряженный xdebug, а в мозгу стучало "нет ничего невозможного". Хороший программист может легко разобраться в любом незнакомом языке, а я считал себя хорошим программистом. Java Android, первые table view с данными из интернета, и снова те же грабли. Куча непонятных вещей, вроде передачи параметров между экранами (постоянные краши в этом месте с полотном непонятных ошибок). Сам java уже давно не пугал, классы похожи на PHP, вместо parent - super, а для переопределения нужно писать @override. Приватные классы, переопределение метода прямо при создании объекта wtf??? Снова дядя, задачи, кросс ревью, скрам-митинги, спринты. Снова долгий ящик.

Strict types в php, теперь уже совсем по взрослому, в новых RFC обещают дженерики. Вот это уже настоящий прорыв, теперь мы заживем не хуже всяких java.
Новая попытка, swift, kotlin. И тут, знаете, тот самый момент, когда ты впервые увидел JavaScript.

JavaScript

(код и выводы отсюда)

const f = () => 42;

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

Swiftbook выглядел многообещающе просто: if, for, switch, class struct, enum, tuple(офигеть удобно, почему в php такого нет?). Идея пет-проекта, быстро накиданная на symfony json API.
Красиво написанные в XCode структуры для entities, какая-то либа для дерганья апишки и конвертации json в объекты. И эпик фейл. Я настолько привык к отсутствию проблем с json в php, обкололся symfony serializerами, что полностью зашел в тупик со строгой типизацией в свифт. Моя, как я думал, великолепная апишка возвращала

{success: true, result: {SomeObjectOrArray}} или{success:false, errors: [listErrors]}


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

Еще одна попытка написать что-то, по привычке берем пример из интернетов и настраиваем под себя (на первых порах с PHP всегда прокатывало). Но вы только взгляните на параметры метода (долго искал подходящий пример, нашел не самый сложнопонимаемый, но вот. Код отсюда)

open func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath?, withSender sender: Any?) -> Bool {        guard let indexPath = indexPath else { return false }        return self.presenterForIndexPath(indexPath).canPerformMenuControllerAction(action)    }

Что тут вообще происходит, нижнее подчеркивание, какие-то ключевые фразы перед названием параметров.

Или вот:

if let JSONObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]],    let username = (JSONObject[0]["user"] as? [String: Any])?["name"] as? String {        // There's our username}

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

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

Те вещи, которые делались за считанные минуты и несколько строк кода (давайте возьмем JS, таблица, по клику на строку которой нужно эту строку удалить) теперь почему-то выглядят как пачка классов с непонятного назначения методами и, на первый взгляд, какой-то слишком усложненной логикой. Я видел отрисовку грида на UIKit, и это выглядит как мини-фреймворк. И эта реализация должна быть такой большой, ведь у нас нет умного браузера, который сделает все для вас (сейчас уже есть SwiftUI, который позволяет делать это гораздо короче, но с ним еще не все так просто). Тут нужно глубинное понимание работы, и это не просто "запустился скрипт, построчно выполнился и умер".

Я рад, что жена в свое время выбрала первым языком swift. Знаете, когда я ради интереса сделал за нее небольшое домашнее задание, первым вопросом преподавателя было "что за phpшник это писал?"

Если меня кто-нибудь спросит, какой язык ты посоветуешь для изучения новичку, едва ли я отвечу PHP. PHP язык с нулевым порогом вхождения и нет никаких проблем с его изучением. Десяток ключевых фраз, несколько конструкций, еще щепотка сложных вещей типа генераторов, стрима или замыканий. Пару минут - Hello World, пара часов - ToDo list, пара дней - мини блог. Пара лет, и ты уже Middle/Senior с запросами покруче архитектора, но без всякого понимания, как это работает внутри вида "почему мой алгоритм такой медленный". Но порог "выхода" слишком велик. Можно хорошо писать скрипты, но "взрослые" языки придется постигать почти "с нуля".

Вместо послесловия

Я люблю PHP, а точнее те вещи, которые я могу делать на нем. Люблю чистый и понятный код, который в целом легко пишется на этом языке. Как-то давно на хабре была статья о том, что хороший код и выглядит красиво, все эти отступы и скобочки, лаконичные функции без грамма лишнего. И PHP позволяет писать такой код. На мой взгляд в своей области (создание web-приложений) этот язык отлично подходит, и он должен быть именно таким (ну, или почти таким). Но являюсь ли я хорошим программистом после десятка лет разработки на PHP? Наверное нет.

Подробнее..

Как мы выбираем языки программирования в Typeable

26.04.2021 18:04:48 | Автор: admin

Неоднократно меня спрашивали, почему я предпочитаю использовать такие языки программирования как Haskell и Rust, т.к. они не являются самыми широко используемыми и популярными инструментами. Этот пост написан с целью демистифицировать то, что происходит у меня в голове, когда я думаю о выборе технологии.

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

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

  1. Baseline по скорости работы ПО.
  2. Особенности распространения и эксплуатации программы, например требование интерпретатора или возможность статической линковки.
  3. Экосистема библиотек и компонентов, которые можно переиспользовать. Отмечу что важно не только количество библиотек, но и качество релевантных для вас.
  4. Возможности параллельного/конкурентного/асинхронного исполнения программ, что может быть важным для многих систем.
  5. Сложность обучения людей выбранной технологии, что значительно влияет и на сообщество языка, и на перепрофилирование разработчиков.
  6. Выразительность языка.

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

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

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

  1. Статическая типизация должна поддерживаться языком программирования. Это позволяет сократить длительность для каждой итерации цикла изменения и валидации кода для разработчика. Также это позволяет существенно снизить количество багов, как со стороны функциональных требований, так и безопасности ПО.
  2. Алгебраические типы данных очень сложно переоценить влияние этой фичи, после того, как начинаешь ей пользоваться. Очень доступная и абсолютно необходимая при моделировании инвариантов вещь. Те же типы-суммы настолько незаменимы, что выбрать язык, в котором их нужно моделировать через другие конструкции, это ставить себе преграды уже на первом шаге.
  3. Гибкая возможности для поддержки и исполнения многопоточных программ. Языки с GIL (Global Interpreter Lock) сразу же не удовлетворяют этому требованию. Хочется иметь возможность хорошо утилизировать возможности железа и иметь достаточно высокоуровневые абстракции для работы.
  4. Достаточная экосистема библиотек, оцениваем субъективно их качество в том числе. Не считаем необходимым все подключать в виде библиотек, но наиболее базовые вещи, вроде биндингов к популярным базам данных, должны быть в наличии.
  5. Светлые головы в коммьюнити разработчиков на этом языке программирования. Профиль разработчика, которого бы мы хотели видеть своим сотрудником это заинтересованный в CS и разработке человек. В противопоставлении этому можно поставить статус легких в освоении технологий, которые привлекают людей в IT ради легкой наживы, что сильно размывает рынок спецов.
  6. В нашем распоряжении должны быть языки программирования, которые позволяют реализовывать ПО с жесткими требованиями ко времени обработки и потребления памяти.

В результате всего вышесказанного в нашем ящичке с инструментами есть достаточно блоков, которые позволяют нам занять уверенную позицию во многих проектах. Возвращаясь к шахматной аналогии, это наши принципы, которые позволяют вести позиционную игру. Позиционная игра игра направленная на создание долгосрочной позиции, открывающей игроку возможности и минимизирующей слабости. Она противопоставляется игре атакующей, острой, где есть большая доля риска, а атакующий игрок пытается эту игру завершить до того, как его противник сможет занять хорошую оборонительную позицию. Острая разработка это олимпиадное программирование, MVP для маркетинговых экспериментов, многие задачи в data science, да и зачастую создание ПО, сопровождающее Computer Science публикации. Их объединяет то, что долгой поддержки они зачастую не требуют, им только нужно отработать в определенный момент времени. Позиционная же игра это игра вдолгую, где ключевыми показателями являются поддерживаемость и обновляемость. Именно этим мы и занимаемся, и нам нужен хороший фундамент, для того чтобы быть уверенными в долгосрочной работе ПО, которое мы пишем и обновляем. Такие проекты тоже могут начинаться с MVP, но они делаются с совсем другими предпосылками.

Почему же список соображений для выбора технологий именно такой? Причин тут несколько. Во-первых, желательно исключить вопросы модности и трендовости технологий, для того чтобы увеличить предсказуемость на долгом промежутке времени. Компилятор с долгой историей и активным сообществом это пусть и консервативный, но надежный выбор, в противопоставление новым сверкающим вещам, появляющимся из года в года. Наверняка часть из них перейдет из последней категории в первую, но мы об этом узнаем позже, вероятно, через годы. Вместо трендов мы пытаемся использовать фундаментальный Computer Science и большое количество исследований по этой теме, которые нашли применение в используемых нами языках программирования. Например: теория типов это смежная математике и CS дисциплина, которая занимается фундаментальными вопросами формализации требований. Это ровно то, что нам нужно для написания ПО. К тому же это совокупный опыт других людей, занимающихся точными науками, и как-то глупо, на мой взгляд, этим опытом пренебрегать. Лучше взять за основу такую дисциплину, чем не взять ничего, либо же взять субъективное мнение, основанное на жизненном опыте одного отдельно взятого человека.

Во-вторых, мы ищем реализацию наибольшего количества взятых нами принципов в языках программирования и компиляторах. По этой причине вдобавок к нашему любимому Haskell, в нашем ящичке инструментов стал появляться Rust. С real-time требованиями и жесткими ограничениями на использование памяти нам нужно что-то достаточно низкоуровневое. Строгость типизации в C все же оставляет желать лучшего, поэтому если есть возможность использовать Rust для такой задачи, мы предпочтем это сделать.

Третья причина: мы делаем ПО в первую очередь для наших клиентов, и мы бы хотели, чтобы они были защищены от наших предрассудков. Поэтому при выборе инструмента риск не может превышать некий уровень, который должен быть оговорен с клиентом. Но даже с такими условиями у нас появились довольно маргинальные технологии вроде GHCJS, т.к. при совокупном разборе сильных и слабых сторон картинка все равно была привлекательной для нас и наших клиентов. Про то, как мы пришли к этому решению, мы уже писали: Elm vs Reflex.

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

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru