В Java реализована динамическая диспетчеризация, которая "сама" решает непосредственно во время выполнения программы, какую реализацию метода запускать. Узнать это с помощью статической типизации невозможно.
В чистых функциональных языках вместо интерфейсов предлагается концепция тайп-классов, рассказывал:
Тайп-классы и алгебраические структуры
Тайп-классы
Своим названием однако эта концепция только запутывает. Просто знайте, что тайп-класс имеет очень мало общего с "типом" или "классом".
Если интерфейс в языках ООП говорит "этот класс может выполнить этот метод", то тайп-класс говорит, что "существует нечто, что может выполнить этот метод на этом классе" (где понятие класса совсем абстрактно). Интерфейс обычно "прошивается" в коде в заголовке класса, а экземпляр тайп-класса существует как отдельная "физическая" сущность -- реализация метода не привязывается к "классу рантайма". Компилятор вытаскивает нужный экземпляр тайп-класса, основываясь на эксплицитном типе в исходном коде, а не на конкретном типе во время выполнения. Этот подход конечно не так гибок, как динамическая диспетчеризация в ООП, но имеет то безусловное преимущество, что просто посмотрев на код, мы можем точно сказать, какая реализация метода будет выполнена.
Да, но как тогда мы можем рассуждать о коде в Java на третьем логическом уровне, если не знаем точно, какой код будет выполняться? На помощь приходит принцип подстановки Лисков (точнее, его идеология). Подробнее эту тему разбираю для курсантов в материале "LSP с т.зр. ФП".
Вкратце, абстракция LSP гласит: разработчик! не удивляй своих коллег! )))
В чистых функциональных языках вместо интерфейсов предлагается концепция тайп-классов, рассказывал:
Тайп-классы и алгебраические структуры
Тайп-классы
Своим названием однако эта концепция только запутывает. Просто знайте, что тайп-класс имеет очень мало общего с "типом" или "классом".
Если интерфейс в языках ООП говорит "этот класс может выполнить этот метод", то тайп-класс говорит, что "существует нечто, что может выполнить этот метод на этом классе" (где понятие класса совсем абстрактно). Интерфейс обычно "прошивается" в коде в заголовке класса, а экземпляр тайп-класса существует как отдельная "физическая" сущность -- реализация метода не привязывается к "классу рантайма". Компилятор вытаскивает нужный экземпляр тайп-класса, основываясь на эксплицитном типе в исходном коде, а не на конкретном типе во время выполнения. Этот подход конечно не так гибок, как динамическая диспетчеризация в ООП, но имеет то безусловное преимущество, что просто посмотрев на код, мы можем точно сказать, какая реализация метода будет выполнена.
Да, но как тогда мы можем рассуждать о коде в Java на третьем логическом уровне, если не знаем точно, какой код будет выполняться? На помощь приходит принцип подстановки Лисков (точнее, его идеология). Подробнее эту тему разбираю для курсантов в материале "LSP с т.зр. ФП".
Вкратце, абстракция LSP гласит: разработчик! не удивляй своих коллег! )))
👍8😁2❤1✍1
Пятница -- отличный день, чтобы сломать прод.
🔥23👌7😁6🐳6🫡1
Кстати да
В 90-е знакомый ставил банкам "опердень", который переставал работать через 90 дней, если ему не заплатили. Один банк не заплатил, а на 91-й день к нему приехали суровые пацаны с разбитыми кулаками, и жёстко потребовали, чтобы опердень у них быстро заработал. На его возгласы что не заплатили, они сказали, что это твои проблемы, решай с бухгалтерией.
Пришлось запускать...
Через несколько месяцев этот банк к нему уже вежливо обратился с просьбой обновить на новую версию, сделать доработки, ну он запросил двойную цену, и те согласились.
А потом на этот рынок пришли взрослые интеграторы-автоматизаторы, и это уже совсем другая история (разборки были на порядок круче)...
В 90-е знакомый ставил банкам "опердень", который переставал работать через 90 дней, если ему не заплатили. Один банк не заплатил, а на 91-й день к нему приехали суровые пацаны с разбитыми кулаками, и жёстко потребовали, чтобы опердень у них быстро заработал. На его возгласы что не заплатили, они сказали, что это твои проблемы, решай с бухгалтерией.
Пришлось запускать...
Через несколько месяцев этот банк к нему уже вежливо обратился с просьбой обновить на новую версию, сделать доработки, ну он запросил двойную цену, и те согласились.
А потом на этот рынок пришли взрослые интеграторы-автоматизаторы, и это уже совсем другая история (разборки были на порядок круче)...
✍14👍4🐳3🔥1🫡1
LLMs эффективно убивают своих оппонентов, мастерски обманывают других, создают тщательно продуманное алиби и перекладывают вину на других. Речь про игру Hoodwinked, напоминающую Мафию, статья университета Южной Калифорнии. Это в тему странных споров, сможет ли грядущий AI, умнее нас в 100 раз, обманывать человечков ))) уже.
Вы можете поиграть в Hoodwinked по ссылочке из этой статьи.
Напомню, что интеллект AI в конкретных задачах потрясающий: в Go (значительно сложнее шахмат) AI научилось играть на топовом уровне за три дня, просто играя миллионы партий само с собой. И, пока по слухам, мета обещает выложить грядущую GPT-5 (лламу-4 ?), которую можно крутить локально, в опенсорс (я только за :).
Shane Legg (Google DeepMind's Chief AGI Scientist) даёт 30% вероятности, что AGI (сильный ИИ) появится в ближайшие 3 года. И даже главный AGI-скептик Gary Marcus даёт 35% шанса, что оный явится в ближайшие 13 лет.
Однако пока автоматизация разработки ПО с помощью AI -- это в основном производство ещё более дерьмового и практически не сопровождаемого кода :) Никаким переосмыслением и демократизацией производства программного обеспечения тут совсем не пахнет.
Вы можете поиграть в Hoodwinked по ссылочке из этой статьи.
Напомню, что интеллект AI в конкретных задачах потрясающий: в Go (значительно сложнее шахмат) AI научилось играть на топовом уровне за три дня, просто играя миллионы партий само с собой. И, пока по слухам, мета обещает выложить грядущую GPT-5 (лламу-4 ?), которую можно крутить локально, в опенсорс (я только за :).
Shane Legg (Google DeepMind's Chief AGI Scientist) даёт 30% вероятности, что AGI (сильный ИИ) появится в ближайшие 3 года. И даже главный AGI-скептик Gary Marcus даёт 35% шанса, что оный явится в ближайшие 13 лет.
Однако пока автоматизация разработки ПО с помощью AI -- это в основном производство ещё более дерьмового и практически не сопровождаемого кода :) Никаким переосмыслением и демократизацией производства программного обеспечения тут совсем не пахнет.
🤔11👍4🔥3✍1😇1
Маск на днях заявил, что новая версия Tesla V12 содержит единичные тысячи строк кода по сравнению с предыдущей версией в 300 тыс. строк кода — за счёт активного использования AI.
"drop >300k lines of C++ control code by ~2 orders of magnitude"
Что-то крайне подозрительно.
Лет 10 назад Toyota была оштрафована на $1,2 миллиарда за баг в софте автомобилей, насчитывавшего тогда около миллиона строк кода. Получилось около $1200 за 1 строку кода -- дороже, чем стоило ПО тех времён в самых дорогих американских космических проектах.
К сожалению, в мэйнстриме сегодня вполне достаточно писать код, который "просто работает", и получать за это 300k/s.
"drop >300k lines of C++ control code by ~2 orders of magnitude"
Что-то крайне подозрительно.
Лет 10 назад Toyota была оштрафована на $1,2 миллиарда за баг в софте автомобилей, насчитывавшего тогда около миллиона строк кода. Получилось около $1200 за 1 строку кода -- дороже, чем стоило ПО тех времён в самых дорогих американских космических проектах.
К сожалению, в мэйнстриме сегодня вполне достаточно писать код, который "просто работает", и получать за это 300k/s.
🤔15😁4👍2🫡1
В этом году в Вышку на "программную инженерию" конкурс был 305 баллов из 300. Напомню в этой связи, с трека "Элитный программист", что
"Люди поступают в университет не для того, чтобы получить какие-то новые навыки. Практически всё, чему учат в университете, можно получить бесплатно в интернете, или на гораздо более дешёвых и компактных в сравнении с университетом курсах профессиональной переподготовки, как мои. Люди идут в университет прежде всего для того, чтобы погрузиться в определённую социальную среду. В элитных университетах существуют закрытые университетские братства, состоящие в которых потом всю жизнь помогают друг другу. И именно эта особенность делает университетское образование таким ценным."
Как это всё правильно использовать в карьере, рассматриваем на ЭП подробно.
"Люди поступают в университет не для того, чтобы получить какие-то новые навыки. Практически всё, чему учат в университете, можно получить бесплатно в интернете, или на гораздо более дешёвых и компактных в сравнении с университетом курсах профессиональной переподготовки, как мои. Люди идут в университет прежде всего для того, чтобы погрузиться в определённую социальную среду. В элитных университетах существуют закрытые университетские братства, состоящие в которых потом всю жизнь помогают друг другу. И именно эта особенность делает университетское образование таким ценным."
Как это всё правильно использовать в карьере, рассматриваем на ЭП подробно.
👍19😁5🫡4👏2🐳1
Случайно наткнулся на "I've been trying to code up the Eilenberg-Moore category for a monad in Haskell."
Я не математик, очень слабо к сожалению в этом разбираюсь, но вот подумал, что если мы сделаем DSL по заветам метапрограммиста Алана Кэя, в котором все типы будут моноидами, то для всех них соответственно будут определены моноидные операции. И тогда мы сможем писать код, как если бы мы находились в категории моноидов Эйленберга-Мура (наверное).
"Eilenberg–Moore Monoids and Backtracking Monad Transformers"
Я не математик, очень слабо к сожалению в этом разбираюсь, но вот подумал, что если мы сделаем DSL по заветам метапрограммиста Алана Кэя, в котором все типы будут моноидами, то для всех них соответственно будут определены моноидные операции. И тогда мы сможем писать код, как если бы мы находились в категории моноидов Эйленберга-Мура (наверное).
"Eilenberg–Moore Monoids and Backtracking Monad Transformers"
🤯8👍5🔥2✍1⚡1
Жить надо так, чтобы вы с гордостью могли сказать, что за последние 10 лет программирования в вашем коде ни разу не возникла ошибка.
⚡15🔥2🤯2👍1🫡1
"Надо помнить и о том, что на сегодняшний день нам пока не удалось нащупать "потолок" в какой-либо области человеческой деятельности. С развитием обучающих методик появляются все новые рекорды, и люди из самых разных сфер все более совершенствуются в своем деле. И пока что незаметно никаких признаков того, что это когда-нибудь прекратится. С каждым новым поколением горизонт человеческого потенциала отодвигается все дальше."
"Максимум. Как достичь личного совершенства с помощью современных научных открытий"
-- Андерс Эрикссон
Я знаю пару ребят, совершенно фантастических программистов, а по жизни они реально сильные PhD в математике, и им пока 35 лет!
Увы, в России их больше нету.
"Максимум. Как достичь личного совершенства с помощью современных научных открытий"
-- Андерс Эрикссон
Я знаю пару ребят, совершенно фантастических программистов, а по жизни они реально сильные PhD в математике, и им пока 35 лет!
Увы, в России их больше нету.
🔥14🤔6🫡4❤3🏆2
От девушки, занимающейся на одном из начальных курсов (занятие по знакомству с системами отслеживания тикетов):
"Ранее на работе я сталкивалась уже с джирой, в принципе, идея ясна. Разве что скажу честно, что обычно там не задачи на 2-3 часа, а такие что делаются по несколько дней. Наверное тогда лучше дробить их, но обычно сотрудникам не охота расписывать каждое действие."
Именно так: если вы сеньор или тимлид, и ваши подчинённые всеми фибрами души сопротивляются дроблению их тикетов по точности до 2 часов (идеальная точность -- до получаса), значит, дела с успешной сдачей проектов в срок и в бюджет в вашей конторе весьма печальны :)
Вполне типична ситуация, когда разработчик мычит "ннну... дня три потребуется на эту фичу...". В таких случаях просите/требуйте декомпозировать тикет на более простые.
Подзадача на 4 часа максимум -- это предел в любой ситуации.
Некоторые задачи действительно трудно сперва оценить, ну значит пусть человек оформляет тикет на 0,5-1 час для предварительного изучения темы, насколько будет трудоёмко.
При этом совершенно ничего страшного, если люди будут ошибаться в оценках. Накосячить в 2-3 раза дольше вполне нормально, и ругать за это ни в коем случае нельзя. Просто фиксируйте себе буферный коэффициент по каждому из разработчиков.
Но есть нюанс...
"Ранее на работе я сталкивалась уже с джирой, в принципе, идея ясна. Разве что скажу честно, что обычно там не задачи на 2-3 часа, а такие что делаются по несколько дней. Наверное тогда лучше дробить их, но обычно сотрудникам не охота расписывать каждое действие."
Именно так: если вы сеньор или тимлид, и ваши подчинённые всеми фибрами души сопротивляются дроблению их тикетов по точности до 2 часов (идеальная точность -- до получаса), значит, дела с успешной сдачей проектов в срок и в бюджет в вашей конторе весьма печальны :)
Вполне типична ситуация, когда разработчик мычит "ннну... дня три потребуется на эту фичу...". В таких случаях просите/требуйте декомпозировать тикет на более простые.
Подзадача на 4 часа максимум -- это предел в любой ситуации.
Некоторые задачи действительно трудно сперва оценить, ну значит пусть человек оформляет тикет на 0,5-1 час для предварительного изучения темы, насколько будет трудоёмко.
При этом совершенно ничего страшного, если люди будут ошибаться в оценках. Накосячить в 2-3 раза дольше вполне нормально, и ругать за это ни в коем случае нельзя. Просто фиксируйте себе буферный коэффициент по каждому из разработчиков.
Но есть нюанс...
👍26😁4✍2⚡1🔥1
...Если вы будете пытаться измерять "продуктивность" разработчиков, отслеживая количество закомиченных строк кода, число исправленных ошибок, среднее число комментариев по каждой правке кода и т.д., то люди сосредоточатся на игре в такую систему, чтобы набирать в ней баллы, вместо того чтобы учиться правильным вещам и делать свою работу хорошо.
играть в глупые игры, выигрывать глупые призы...
играть в глупые игры, выигрывать глупые призы...
✍16👍9🔥4🫡4
Синхронизм двух отчётов курсантов :)
"Первые трудности были связаны с установкой фаззера на рабочий MacBook (хотел протестировать рабочий код).
Для установки требуется полноценный Clang, который содержит libFuzzer (как понял на Mac стоит урезанная версия Apple Clang).
Для решения данного вопроса потребовалось установить LLVM. Установить с первого раза не удалось. Потребовалось несколько вечеров, чтобы настроить окружение для установки Atheris."
"Вообще сложности возникли только с макбуком, который я неданво получил и все ещё настраиваю. Пришлось собирать из исходников clang; потому что apple поставляет огрызок llvm без libFuzz."
=
Никогда не понимал, зачем разработчику макбук. За такую цену можно взять куда более мощный ноут с линуксом, и быть вечно счастливым.
"And no, I do not have last Tuesday’s list of what is and isn’t supported under Linux, nor do I have next Tuesday’s list, which will in all probability be a different list."
-- Terry Lambert
отец FreeBSD, написавший в Apple 6% OS X kernel
"Первые трудности были связаны с установкой фаззера на рабочий MacBook (хотел протестировать рабочий код).
Для установки требуется полноценный Clang, который содержит libFuzzer (как понял на Mac стоит урезанная версия Apple Clang).
Для решения данного вопроса потребовалось установить LLVM. Установить с первого раза не удалось. Потребовалось несколько вечеров, чтобы настроить окружение для установки Atheris."
"Вообще сложности возникли только с макбуком, который я неданво получил и все ещё настраиваю. Пришлось собирать из исходников clang; потому что apple поставляет огрызок llvm без libFuzz."
=
Никогда не понимал, зачем разработчику макбук. За такую цену можно взять куда более мощный ноут с линуксом, и быть вечно счастливым.
"And no, I do not have last Tuesday’s list of what is and isn’t supported under Linux, nor do I have next Tuesday’s list, which will in all probability be a different list."
-- Terry Lambert
отец FreeBSD, написавший в Apple 6% OS X kernel
🤔11🤝4❤1👍1
Нужно ли в случае проблем выбрасывать исключение в конструкторе?
Это спорная тема, по которой высказывается даже Microsoft Learn.
Это спорная тема, по которой высказывается даже Microsoft Learn.
Anonymous Poll
57%
нужно
43%
не нужно
🤔17✍2🤯1
Ко вчерашнему опросу, посмотрите, противоположные взгляды разделились примерно поровну. Попробую немного пояснить.
Исключения -- это по сути современные GOTO (динамическая типизация, скрытая в статической типизации). Когда конструктор выбрасывает исключение, он пытается вернуть что-то, отличное от явно запрошенного типа.
Начинающие часто делают такую ошибку: надо написать функцию, возвращающую сумму значений из набора файлов, а если там возникнет любая ошибка (от отсутствия файла до записанного в него нечислового значения), то что с ней делать? выбрасывать своё исключение? что-то "ошибочное" (null/None) возвращать в качестве результата?
Отсюда мы плавно переходим к фабрикам и монадам :)
Но есть нюанс: что делать, если некоторые данные в конструкторе недоступны сразу, и должны быть получены с помощью асинхронного вызова (что само по себе не здорово, но вот такой легаси-код вам достался)?
Это особенно актуально при активном использовании IoC-контейнеров, которые так любимы в мэйнстриме: если мы ждём отложенного поступления данных, а затем строим поведенческий класс, то у нас нет других вариантов, кроме явного вызова конструктора -- который ярые сторонники IoC как раз отвергают сходу.
Расскажу дальше чуть подробнее.
Исключения -- это по сути современные GOTO (динамическая типизация, скрытая в статической типизации). Когда конструктор выбрасывает исключение, он пытается вернуть что-то, отличное от явно запрошенного типа.
Начинающие часто делают такую ошибку: надо написать функцию, возвращающую сумму значений из набора файлов, а если там возникнет любая ошибка (от отсутствия файла до записанного в него нечислового значения), то что с ней делать? выбрасывать своё исключение? что-то "ошибочное" (null/None) возвращать в качестве результата?
Отсюда мы плавно переходим к фабрикам и монадам :)
Но есть нюанс: что делать, если некоторые данные в конструкторе недоступны сразу, и должны быть получены с помощью асинхронного вызова (что само по себе не здорово, но вот такой легаси-код вам достался)?
Это особенно актуально при активном использовании IoC-контейнеров, которые так любимы в мэйнстриме: если мы ждём отложенного поступления данных, а затем строим поведенческий класс, то у нас нет других вариантов, кроме явного вызова конструктора -- который ярые сторонники IoC как раз отвергают сходу.
Расскажу дальше чуть подробнее.
✍13🤔5🫡4👍1🤯1
...Основная засада в том, что большинство систем типов (даже самые академические!) терпят неудачу в ситуациях вроде исключения в конструкторе. Мы хотели бы стереть с помощью типов грань между временем выполнения и временем компиляции, но это требует от системы типов наличия условий и итераций (зависимостей от значений), тьюринговой полноты, и тут в любом случае возникают большие сложности применения типизации к значениям в рантайме.
Вообще, это большая тема, насколько активно и как правильно использовать конструкторы.
Универсального ответа, что делать с исключением в конструкторе, у меня нету :) Если язык достаточно продвинутый, на сегодня в мэйнстриме это наверное только TypeScript (что немудрено, его автор Хейлсберг ранее придумал Delphi и C#), тогда можно например задать тип конструктора как
Dwarf | ValidationException
Если же в случае ошибки вы хотите возвращать null, то тогда используйте фабричный метод, который выдаст Dwarf | null
В общем случае, проблема не в поведении времени выполнения, а в том, насколько соответствующий исходный код типизирован и выразителен.
В Python например вы не используете new, и конструктор там выглядит как функция, что очень здорово :)
dwarf = Dwarf()
И как раз за счёт своей гибкости Python позволяет (как и TS) наглядно записывать типы-объединения (PEP 604), поэтому мы можем конструктор и фабричный метод типизировать совершенно по-разному, и это просто великолепно.
Dwarf | None
Self | None
Тут можно строить очень интересные паттерны, сравнимые с продвинутыми фабричными методами, в том числе "умные конструкторы", которые скрывают недостатки исходного конструктора и принуждают использовать более тонкие подходы. Python, Kotlin, Swift, Go, Rust -- список нонконформистов можно продолжать. Например, в Kotlin есть extension methods, которые отнюдь не синтаксический сахар или эквивалент статическим методам Java. Наверно, можно даже сказать, что это в некотором смысле тайп-классы из ФП, или монады из LINQ...
Ладно, больше не буду морочить вам голову :)
Вообще, это большая тема, насколько активно и как правильно использовать конструкторы.
Универсального ответа, что делать с исключением в конструкторе, у меня нету :) Если язык достаточно продвинутый, на сегодня в мэйнстриме это наверное только TypeScript (что немудрено, его автор Хейлсберг ранее придумал Delphi и C#), тогда можно например задать тип конструктора как
Dwarf | ValidationException
Если же в случае ошибки вы хотите возвращать null, то тогда используйте фабричный метод, который выдаст Dwarf | null
В общем случае, проблема не в поведении времени выполнения, а в том, насколько соответствующий исходный код типизирован и выразителен.
В Python например вы не используете new, и конструктор там выглядит как функция, что очень здорово :)
dwarf = Dwarf()
И как раз за счёт своей гибкости Python позволяет (как и TS) наглядно записывать типы-объединения (PEP 604), поэтому мы можем конструктор и фабричный метод типизировать совершенно по-разному, и это просто великолепно.
Dwarf | None
Self | None
Тут можно строить очень интересные паттерны, сравнимые с продвинутыми фабричными методами, в том числе "умные конструкторы", которые скрывают недостатки исходного конструктора и принуждают использовать более тонкие подходы. Python, Kotlin, Swift, Go, Rust -- список нонконформистов можно продолжать. Например, в Kotlin есть extension methods, которые отнюдь не синтаксический сахар или эквивалент статическим методам Java. Наверно, можно даже сказать, что это в некотором смысле тайп-классы из ФП, или монады из LINQ...
Ладно, больше не буду морочить вам голову :)
❤12🫡7👍5
Ну, с Днём Программиста!
Хорошая новость-1, что пока цены для новеньких я повышать не планирую (а кто уже занимается, схема цен замораживается навсегда на момент записи на мои курсы),
однако, все тренды идут к этому :) Я жду, например, 110 к октябрю.
Куда ещё теперь вкладывать эти бессмысленные бумажки, как не в собственное развитие?
Хорошая новость-2, что AI научился писать промпты для AI лучше людей.
Процессы самосовершенствования искусственного интеллекта ускоряются в геометрической прогрессии; обратный отсчёт пошёл на месяцы? :)
Хорошая новость-1, что пока цены для новеньких я повышать не планирую (а кто уже занимается, схема цен замораживается навсегда на момент записи на мои курсы),
однако, все тренды идут к этому :) Я жду, например, 110 к октябрю.
Куда ещё теперь вкладывать эти бессмысленные бумажки, как не в собственное развитие?
Хорошая новость-2, что AI научился писать промпты для AI лучше людей.
Процессы самосовершенствования искусственного интеллекта ускоряются в геометрической прогрессии; обратный отсчёт пошёл на месяцы? :)
🎉15🤯7⚡2👏2✍1