А то, о чём вы написали, я скорее всего сяду, подумаю, и как-либо обвяжу, чтобы удобно с этим работать из своего кода.
Это вполне конкретный пример из проекта, с которым я имел дело. Проект на С++/Qt. Там объектная модель была полностью динамическая, но нерасширяемая никак. И как раз обвязка была статически типизированная т.к. авторы либы любили ломать что-нибудь даже в патч-релизах. Я не знаю, сколько бы заняла времени ловля подобных багов без статической обвязки.
А я разве где-то сказал, что типизация это панацея? Типы ловят вполне конкретный класс ошибок. Касательно приведённых вами примеров с преимущественно математикой — можно к примеру закодировать типами единицы измерения. Тогда вы сможете гарантировать на этапе компиляции что у вас результат будет м/с^2, а не кг/Н^2. От забытого инкремента или записи не в ту переменную длины это вас конечно не спасёт.
Но давайте представим, что код представляет собой не какой-то вычислительный алгоритм, пусть и сложный. А систему из, скажем, объектной модели документа, представленной сторонней либой. Плюс 3D представление на каком-нибудь OpenSceneGraph со своей иерархией узлов сцены. Плюс несколько панелей виджетов с разными представлениями в модель. Плюс менеджер выбора объектов. И тут у вас в модели документа при апгрейде в каком-то из объектов меняется набор полей… Представьте себе развлекуху отлавливать и править все места, где это используется.
А почему вы не ставите под сомнение необходимость того же JS? Там же куча лишнего — какие-то массивы, объекты, сборка мусора. Писали же раньше люди без всей этой ерунды на ассемблере. Или
… большинство людей тупо разучились (или не умели никогда) писать код и думать головой?
Если же без ехидства, типизация, как и ООП, ФП, сборка мусора призвана перераспределять сложность и снимать часть когнитивной нагрузки с человека, заменяя её автоматизированной машинной проверкой. JS был изначально создан для простеньких эффектов типа снежинок на странице — а не для современных сложных страниц-приложений. Вот как и в случае с ассемблером и к примеру С++, стали делать абстракции над ним, решающие проблему сложности в тех или иных случаях.
По моему скромному опыту, начиная с определённого предела концентрация перестанет вам помогать — область изменений расширится так, что все возможные эффекты перестанут помещаться в голову. На тривиальных примерах динамическая типизация проще, спору нет. Но когда у вас сочленение нескольких нетривиально взаимодействующих систем, вы будете вынуждены полагаться на документацию, тесты и проверку типов в рантайме ассёртами. Иначе на проде вам вполне может радостно прилететь ошибка совершенно не в том месте, которое её вызвало. Причём и документация, и тесты, и ассёрты являются человекозависимыми.
В чём-то аналогичная ситуация с шаблонами С++ для случая параметров-типов. До появления концептов проверять соответствие переданного типа некоему контракту делалось с помощью определённых трюков. Причём реальное использование одного из элементов контракта могло происходить глубоко во вложенных шаблонах. И тогда вы получали длиннющий (несколько десятков, а иногда и сотен строк) и малочитаемый отчёт об ошибке, которая возникла почти наверняка совершенно не в том месте, которое её вызвало.
Так что концентрация не панацея — ресурсы мозга ограничены. Абстракции в виде ООП, ФП или типизации призваны перераспределять сложность, снимая часть когнитивной нагрузки с человека. Если бы всё было так просто, как вы пишете, до сих пор писали бы в машкодах. Чё там, сконцентрируйся — и никакие эти ваши абстракции не нужны.
Как по мне, автор не понимает разницы между слвбой-сильной и статической-динамической типизацией. И в этом и состоит его, автора, проблема. Динамическая типизация имеет и плюсы, и минусы. А вот плюсы слабой типизации мне вообще как-то неочевидны.
Последний раз, когда я смотрел Nim, там не было ни интерфейсов, ни трейтов. Для их эмуляции предлагалось руками собирать структуру из нужных замыканий (найдено в недрах форума, ссылку сейчас не найду). Также несколько странное решение для discriminated unions в виде явно выделенного поля под дискриминант.
Как с этим сейчас?
Справедливости ради, constexpr появились только в 11м стандарте. Более-менее юзабельными они стали только в 14-м, когда разрешили constexpr функции не из одного выражения. Ещё какие-то не слишком приятные ограничения сняли вроде только в 17м, но подробностей уже не упомню.
С одной стороны DSL и все подобные ништяки. С другой стороны тот самый ненавистный прод, на котором авторы некоторых библиотек с лицухами за 5-6 значную сумму не могут нормальную обработку ошибок даже для простого ООПшного АПИ. Не говоря уже о необходимости подсаживать на проект джунов.
Наверное я сейчас просто не готов вести аргументированный спор на эту тему, т.к. никакие статические мета-системы кроме шаблонов С++ нормально не щупал. И да, они мне таки напоминают кастрированный лисп с синтаксисом из злачных кварталов Амстердама.
Siemargl утверждает, что если в языке нельзя, грубо говоря, определить плейсхолдер средствами языка (как пример), то язык костыльный т.к. не умеет в "свободное программирование" (DSL?).
Я утверждаю, что такие вещи должны быть частью языка т.к. требуют хорошей эргономики, в т.ч. краткого и понятного описания ошибок компиляции. В шаблонах С++, к слову, с теми самыми ошибками всё плохо.
Вы говорите о прямой работе с AST, template haskell и других полноценных системах метапрограммирования.
Так о чём говорим дальше? Или где и что я перепутал?
Это по-моему уже немного уклон в философский вопрос — что должно быть частью языка, а что — реализовано в библиотеке.
Приведу немного провокационный пример — концепты. Они ведь, в принципе, реализовывались и до этого. Или те же лямбды, появившиеся в С++11. Был ведь до того boost::lambda.
Тут ведь вопрос в том, насколько легко и удобно будет использовать библиотечную фичу. И — что немаловажно — как трудно будет отлаживать ошибки при её использовании.
И если плейсхолдер из hana сравнительно прост сам по себе, прикиньте, насколько читабельным будет сообщение об ошибке в такой лямбде с хотя бы тремя операторами и участием каких-нибудь шаблонных типов. Вот где-то на этом месте свободное программирование начинает вылазить немного боком. Как экстремальный пример можно привести Perl. А лямбды в составе языка дадут вам при ошибке вменяемое сообщение.
Во-первых хана написана на древних крестах. Во-вторых там там реализовано пол сотни операторов. А то, что там их пол сотни ни о чём не говорит — просто в С++ множество операторов.
костылинг на 14 крестах
Это базовые вещи, которых нету в скриптухе
Никакого отношения эти перегрузки к операциям не имеют
Поциэнт слился успешно
К слову, в других языках все эти вещи есть искаропки, а не реализуются недолиспом с вырвиглазным синтаксисом, коим являются крестовые шаблоны. Учи матчасть, малыш.
Частично уйдёт с поддержкой С++20. В мейнстриме оптимистично уйдёт лет через 5, реалистично лет через 10-15.
Прежде всего простота разработки интерпретатора/компилятора.
И, пожалуй, простота написания простого кода.
Там разве нельзя использовать типы-параметры как маркеры?
Это вполне конкретный пример из проекта, с которым я имел дело. Проект на С++/Qt. Там объектная модель была полностью динамическая, но нерасширяемая никак. И как раз обвязка была статически типизированная т.к. авторы либы любили ломать что-нибудь даже в патч-релизах. Я не знаю, сколько бы заняла времени ловля подобных багов без статической обвязки.
А я разве где-то сказал, что типизация это панацея? Типы ловят вполне конкретный класс ошибок. Касательно приведённых вами примеров с преимущественно математикой — можно к примеру закодировать типами единицы измерения. Тогда вы сможете гарантировать на этапе компиляции что у вас результат будет м/с^2, а не кг/Н^2. От забытого инкремента или записи не в ту переменную длины это вас конечно не спасёт.
Но давайте представим, что код представляет собой не какой-то вычислительный алгоритм, пусть и сложный. А систему из, скажем, объектной модели документа, представленной сторонней либой. Плюс 3D представление на каком-нибудь OpenSceneGraph со своей иерархией узлов сцены. Плюс несколько панелей виджетов с разными представлениями в модель. Плюс менеджер выбора объектов. И тут у вас в модели документа при апгрейде в каком-то из объектов меняется набор полей… Представьте себе развлекуху отлавливать и править все места, где это используется.
А почему вы не ставите под сомнение необходимость того же JS? Там же куча лишнего — какие-то массивы, объекты, сборка мусора. Писали же раньше люди без всей этой ерунды на ассемблере. Или
Если же без ехидства, типизация, как и ООП, ФП, сборка мусора призвана перераспределять сложность и снимать часть когнитивной нагрузки с человека, заменяя её автоматизированной машинной проверкой. JS был изначально создан для простеньких эффектов типа снежинок на странице — а не для современных сложных страниц-приложений. Вот как и в случае с ассемблером и к примеру С++, стали делать абстракции над ним, решающие проблему сложности в тех или иных случаях.
Пожалуй да.
По моему скромному опыту, начиная с определённого предела концентрация перестанет вам помогать — область изменений расширится так, что все возможные эффекты перестанут помещаться в голову. На тривиальных примерах динамическая типизация проще, спору нет. Но когда у вас сочленение нескольких нетривиально взаимодействующих систем, вы будете вынуждены полагаться на документацию, тесты и проверку типов в рантайме ассёртами. Иначе на проде вам вполне может радостно прилететь ошибка совершенно не в том месте, которое её вызвало. Причём и документация, и тесты, и ассёрты являются человекозависимыми.
В чём-то аналогичная ситуация с шаблонами С++ для случая параметров-типов. До появления концептов проверять соответствие переданного типа некоему контракту делалось с помощью определённых трюков. Причём реальное использование одного из элементов контракта могло происходить глубоко во вложенных шаблонах. И тогда вы получали длиннющий (несколько десятков, а иногда и сотен строк) и малочитаемый отчёт об ошибке, которая возникла почти наверняка совершенно не в том месте, которое её вызвало.
Так что концентрация не панацея — ресурсы мозга ограничены. Абстракции в виде ООП, ФП или типизации призваны перераспределять сложность, снимая часть когнитивной нагрузки с человека. Если бы всё было так просто, как вы пишете, до сих пор писали бы в машкодах. Чё там, сконцентрируйся — и никакие эти ваши абстракции не нужны.
Даже с таким супер-профи есть одна мааленькая проблемка. Людям свойственно совершать ошибки.
Как по мне, автор не понимает разницы между слвбой-сильной и статической-динамической типизацией. И в этом и состоит его, автора, проблема. Динамическая типизация имеет и плюсы, и минусы. А вот плюсы слабой типизации мне вообще как-то неочевидны.
Последний раз, когда я смотрел Nim, там не было ни интерфейсов, ни трейтов. Для их эмуляции предлагалось руками собирать структуру из нужных замыканий (найдено в недрах форума, ссылку сейчас не найду). Также несколько странное решение для discriminated unions в виде явно выделенного поля под дискриминант.
Как с этим сейчас?
Справедливости ради, constexpr появились только в 11м стандарте. Более-менее юзабельными они стали только в 14-м, когда разрешили constexpr функции не из одного выражения. Ещё какие-то не слишком приятные ограничения сняли вроде только в 17м, но подробностей уже не упомню.
С одной стороны DSL и все подобные ништяки. С другой стороны тот самый ненавистный прод, на котором авторы некоторых библиотек с лицухами за 5-6 значную сумму не могут нормальную обработку ошибок даже для простого ООПшного АПИ. Не говоря уже о необходимости подсаживать на проект джунов.
Наверное я сейчас просто не готов вести аргументированный спор на эту тему, т.к. никакие статические мета-системы кроме шаблонов С++ нормально не щупал. И да, они мне таки напоминают кастрированный лисп с синтаксисом из злачных кварталов Амстердама.
Это пока такой код не используют в проде хотя бы человек пять :) В этот момент очень хочется половину фич отключить на уровне компилятора :)
Я уже откровенно запутался, что мы тут обсуждаем.
Siemargl утверждает, что если в языке нельзя, грубо говоря, определить плейсхолдер средствами языка (как пример), то язык костыльный т.к. не умеет в "свободное программирование" (DSL?).
Я утверждаю, что такие вещи должны быть частью языка т.к. требуют хорошей эргономики, в т.ч. краткого и понятного описания ошибок компиляции. В шаблонах С++, к слову, с теми самыми ошибками всё плохо.
Вы говорите о прямой работе с AST, template haskell и других полноценных системах метапрограммирования.
Так о чём говорим дальше? Или где и что я перепутал?
Это по-моему уже немного уклон в философский вопрос — что должно быть частью языка, а что — реализовано в библиотеке.
Приведу немного провокационный пример — концепты. Они ведь, в принципе, реализовывались и до этого. Или те же лямбды, появившиеся в С++11. Был ведь до того boost::lambda.
Тут ведь вопрос в том, насколько легко и удобно будет использовать библиотечную фичу. И — что немаловажно — как трудно будет отлаживать ошибки при её использовании.
И если плейсхолдер из hana сравнительно прост сам по себе, прикиньте, насколько читабельным будет сообщение об ошибке в такой лямбде с хотя бы тремя операторами и участием каких-нибудь шаблонных типов. Вот где-то на этом месте свободное программирование начинает вылазить немного боком. Как экстремальный пример можно привести Perl. А лямбды в составе языка дадут вам при ошибке вменяемое сообщение.
Не сказал бы что шелл — хороший пример здесь. Слишком отличается по целой пачке параметров, в том числе и синтаксисом.
Target-san:
yamlevekke:
Поциэнт слился успешно
К слову, в других языках все эти вещи есть искаропки, а не реализуются недолиспом с вырвиглазным синтаксисом, коим являются крестовые шаблоны. Учи матчасть, малыш.
Он тут раньше появлялся под другим виртуалом?
Она творит конкретно вот это:
https://github.com/boostorg/hana/blob/master/include/boost/hana/functional/placeholder.hpp
А твой псевдокод ниочём никого не интересует.
А то, что творит boost.hana чтобы реализовать _ — не страшно? Ну ооок...