Здравствуйте, alex_public, Вы писали:
_>Речь не про убогое ФП, а про чистый код. Да, я помню, что вы считаете код внутри монад равноправным обычному коду в Хаскеле. Но на мой взгляд это совсем не так. И не только на мой (могу привести цитаты из хороших книг по Хаскелю).
Еще раз. Если вам что-то не нравится (например IORef), это не значит, что этого нет. А вся ваша аргументация и тут и в ветке про UFP как раз и построена на том, что IORef прочего не существует.
На самом деле в ФП есть средства работы с мутабельностью никак принципам ФП не противоречащие.
_>Не, это не то совсем. Вот хорошая скрытая мутабельность реализуется например при превращение рекурсии в цикл.
Непонятно, почему ленивость как скрытая мутабельность — это не то, а превращение рекурсии в цикл, как скрытая мутабельность — то. Первое встречается гораздо чаще второго, и позволяет оптимизировать гораздо более широкий спектр рекурсивного кода.
K>>Конкретный пример — это код. K>>Я же говорю, оптимизации, которые устраняют промежуточные массивы, списки и т.д. в комбинации функций, каждая из которых по по отдельности копирует, а не меняет по месту существуют и вполне работают. Как и все оптимизации, работают они не всегда, но объем копирования существенно сокращают. Т.е. компилятор оптимизирующий код вида: K>>... K>>существует. Понятно, что без таких оптимизаций было бы затруднительно комбинировать комбинаторы более-менее безнаказанно.
_>Ну ок, пускай будет код. Мне интересно, в коде типа такого _>
Что-то подобное вполне можно оптимизировать так, чтоб память выделялась один раз. Правда, типичные подходы к дефорестации/фьюжену минимизируют проходы (плюс они ориентированы на оптимизацию конвееров, в которых типы на входе и выходе функций обычно отличаются), так что полученный код будет проверять наличие n функций для каждого элемента в течении одного прохода по выделенной памяти, а не ходить по этой памяти n раз. Впрочем, правила переписывания для того же GHC это библиотечный код, все эти оптимизации не захардкодили в компилятор, а написали авторы библиотек, с которыми они (оптимизации) и поставляются. Так что можно и преобразования нужные вам описать — никакой принципиальной проблемы тут нет.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[52]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
_>Исходные коды, из которых генерируется бинарный код, полностью типизированы.
Ну так я же не утверждаю, что конкретный, специализированный код нетипизирован? Он, конечно, типизирован. Нетипизирован обобщенный.
_>А то, что копилятор не обращает внимания на куски исходников, не используемые для генерации бинарного кода, никак не снижает уровень типизации.
Т.е. отсутствие проверки типов для какого-то кода не снижает уровень типизации? Вообще-то снижает. В случае отсутствия проверки, снижает до нуля.
_>Ну так это же опять не компиляция в исполняемый код (как и в том случае в Хаскелем при соответствующей оптимизации), а просто некое переформатирование исходников. )))
Это вполне решает те проблемы, для решения которых раздельная компиляция и существует. ну и в случае линктайм кодогенерации, это может быть оптимизация, которая работает именно что с почти готовым исполняемым кодом, который слинкуется и заработает и без этой оптимизации.
_>Что-то вы всё время придумываете некоторые мысли за меня и потом успешно с ними боретесь. ))) Я же чётко противопоставлял скорость обобщённого кода и раздельность компиляции, а не типизированность и раздельность компиляции.
Вы начали обсуждать скорость обобщенного кода как оправдание и даже причину нетипизированности обобщенного кода. Хотя обобщенный код, который работает так же как и плюсовые шаблоны вполне можно типизировать.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[56]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
_>Это цена за уникальные возможности.
И что это за не имеющие аналогов возможности? Тут рядом я давал ссылку на сравнение разных методов обобщенного программирования, которое показывает, что возможности вовсе не уникальны. Так что едва ли это можно рассматривать как цену уплаченную за какие-то уникальные возможности — оплачивается экономия умственных усилий разработчиков языка.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[30]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
_>Он может стать чистым где-то далеко выше, при применение чего-то типа runSt для отрезания данной области от остального кода. А так это не нормальный код на хаскеле, а императивный монадный подъязык.
Он всегда является чистым. IO/ST как раз это и обеспечивают. Это нормальный код на хаскеле, который преимущественно из использования разнообразных "молнадных подъязыков" и состоит.
_>Реализации различные, а результат один.
Нет, не один.
K>>А если мы возвращаем пару или вовсе список замыканий? _>Да без проблем. Какая разница сколько объектов перемещать? )
Объект один. А ссылки на него во всех возвращаемых замыканиях. Какое тут может быть перемещение?
_>Про циклы не понял о чём вообще речь.
Циклические ссылки.
_>Насчёт выбора и т.п... Ну C++ как бы не самый простой язык и вообще не очень ориентирован на новичков. Однако думаю что уж не Хаскелю что-то говорить на эту тему — в нём не меньше всяческих нюансов, просто они совсем из другой области.
На хаскеле просто писать высокоуровневый код, а низкоуровневый — сложно. На плюсах легко писать низкоуровневый код, а высокоуровневый — сложно.
_>Кстати, сам то код функции с ссылкой выглядит не так уж и страшно. Только вот это уже не та функция (по сравнению с C++ аналогом) — в ней мы имеем дело уже не int'ом, а с некой другой сущностью, не имеющей его свойств (в отличие от int& в большинстве императивных языков). И вследствие этого, код использующий данную функцию будет уже выглядеть совсем адски.
Вот так всегда. Какой монадически-ужасный код вам не покажи — всякий раз оказывается, что ничего страшного в нем нет, но вот другой, пока еще не показанный — вот это ужас-ужас-ужас.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[30]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Так это и есть работающий код:
tail -n 6 main.cpp
Ядерный реактор условно не показан.
Все же можно посмотреть полный код, который можно скомпилировать и запустить?
EP>Вот только смысла так писать нет — итеративная версия будет и проще и быстрее. EP>Но если нужна действительно быстрая версия, то посыпание синтаксическим сахром ничем не поможет — нужно использовать подходящий алгоритм, типа ((1,1),(1,0))^n*(1,0).
У вас что, есть волшебный рецепт переписывания любого ФП-кода в "итеративный" или вообще "подходящий"? Понятно, что считать числа Фибоначчи именно таким способом бессмысленно. Это просто демонстрация применения ряда идиоматических приемов/языковых средств на минимальном примере.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[30]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>1. Нет встроенных ленивых списков, но они реализуются библиотечно То есть их нет, точно также как нет и встроенных в язык хэштаблиц — хотя std::unodered_map элементарно реализуется средствами самого языка.
Что за встроенные списки? В типе
data [a] = a : [a] | []
есть магические имена конструкторов, но никакими магическими свойствами, по сравнению с типом
data List a = a :> List a | Nil
он не обладает.
А без встроенной ленивости — как вы обеспечите оптимизации описанные в статье? Как вы автоматически будете строгость анализировать? Ну понятно как — написанием языка со встроенной ленивостью.
EP>2. Какого "прочего, более важного" нет?
Решенной UFP.
K>>Ну вот пусть программист решит, где применение ФП себя оправдывает, а где нет. В этом и заключается основная разница между высокоуровневым языком и низкоуровневым.
EP>Разница между высокоуровневым языком и низкоуровневым это наличие ФП? http://rsdn.ru/forum/images/anvaka/wacko.gif
ОК
Ну вот пусть программист решит, где применение высокоуровневых средств себя оправдывает, а где нет. В этом и заключается основная разница между высокоуровневым языком и низкоуровневым.
EP>"обычно небесплатен" — в том то и дело, что он никому не обязан быть "платным".
Как только придумаете небесплатные аналоги — так сразу и будет не обязан. А пока, в данной нам в ощущениях реальности эти средства вполне "платные".
EP>Я говорю что использовать ФП ВЕЗДЕ нет смысла, так как в ряде случаев есть более эффективные и зачастую более понятные техники.
Например прилежание и усидчивость.
EP>Использование ФП там где оно добавляет тормозов на ровном месте, затрудняет понимание и не даёт никаких преимуществ — это и есть "писать ФП ради самого ФП".
Есть смысл использовать ФП везде, где программист решил, что использовать есть смысл. А низкоуровневый коммунизм известен: в колбасе ленивости потребности нет.
EP>Каким образом вы решили что аргумент "писать ФП ради самого ФП — нет смысла" применим только при доказательстве ненужности всего ФП — для меня остаётся загадкой
Ну так ваше "писать ФП ради ФП нет смысла" — это же просто отговорка. Если что-то в плюсах поддерживается слабо — значит это ФП ради ФП — смысла не имеет. А если поддерживается — сразу имеет смысл.
Допустим, ленивость не нужна, гарантии доступности для захваченного в замыкания (а значит и лямбды) не нужны. А что тогда нужно? Вы список какой-нибудь можете составить — какие же ФП-средства нужны, в котором более 0 пунктов?
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[30]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
K>>Тормозит по сравнению с чем? EP>Тормозит по сравнению с простейшей итеративной версией, которую можно объяснить даже ребёнку.
Ну я и говорю. Под поддержкой фп понимается "это все ненужно — можно же написать нетормозящую итеративную версию!".
K>>Вот когда предоставите для сравнения control-structure для связывания комбинаторов с комбинаторами с аналогичной функциональностью (поддержка раннего завершения, циклов, автомемоизации, потокобезопасность и т.д.) тогда и сравним.
EP>Зачем всё это при вычислении простейших задач типа чисел Фибоначчи?
Для более сложных задач. Впрочем подход обычный: поддержка ФП инструментария опять оказалась риторическим вопросом "зачем все это нужно?"
EP>А зачем замена? Ваш пример с числами Фибоначчи с точностью до минимальных синтаксических различий (скобки вместо $, * вместо . , <ap> вместо <*> и т.п.) переписывается на C++: EP>
Вопрос в том, какими средствами это достигается и какими свойствами обладает. Синтаксических претензий у меня, допустим, нет. Вот будет полный, компилирующийся и запускающийся пример — можно будет и обсудить.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[32]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>1. Я вам привёл уже несколько вариантов решения UFP в C++, в том числе GC. О чём тут ещё спорить?
Из которых ни одно решение кроме консервативного GC доступность не гарантирует, а консервативный GC не обладает приемлемыми с практической точки зрения свойствами.
EP>2. Дефолтное средство управление ресурсами, RAII, работает и для памяти и для ресурсов в отличии от GC.
В каком смысле "работает?". UFP не обеспечивает, а prompt finalization обеспечивает. Дефолтное управление с помощью GC наоборот UFP обеспечивает, а prompt finalization — нет. Я согласен, что для дефицитных ресурсов первое лучше, но для обычных языковых сущностей лучше второе.
EP>3. Вариант решения UFP с ресурсами (называйте как хотите — UFP не UFP, но то что проблема подобная это факт) в языках (с позиции которых был наезд "даже Upward Funarg Problem не решена") продемонстрирован не был. Запрет — это не решение.
Я же говорю, уберите скобки-using-и и будет UFP. Скобки нужны для prompt finalization.
EP>Это касается не только возвращения ресурсов в замыканиях, а вообще в любых объектах, что я является нормальной практикой.
Для объектов это нормальная практика, а для дефицитных ресурсов — ненормальная.
EP>Если же требуется запретить передвижение, то делают non-copyable&non-movable.
Вот это уже близкий аналог регионов-скобок.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[42]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
_>Достаточно лидера проекта с правильным стилем, а остальное можно обеспечить с помощью административных стилевых гайдов. Вот тот же Гугл так делает и ещё даже выкладывает свои варианты для публичного использования.
Административные костыли никогда толком не работают. Гугл как раз нетипичный пример, ибо у них средний уровень контингента намного выше чем в среднем по больнице.
Административные костыли перестают работать, когда появляется активный разработчик, еще не очень опытный, но у которого хорошо получается работа. "А я вот так сделаю и это будет работать" — всё, административные костыли перестали работать.
Отсюда ясно, что для административных костылей надо подбирать команду по принципу — один толковый-ответсвенный и толпа послушных управляемых статистов.
К такой модели разработки отношусь очень скептически, ибо видел как такие команды делали только провальные, распильные проекты или мелочовку которая никому не интересна.
I>>Ну вот скажем, у меня бывало так — набираю код на асме около недели, эдакий жосцкий кодинг 8 часов в день и 5 дней подряд, в конце недели запускаю, и все не только компилируется, но и работает без крешей и подвисаний. I>>Личный рекорд — один месяц такого кодинга без промежуточных компиляний и тд и тд. При чем софтина запускалась в прошивке одной железяки для телефонных станций.
_>Сильно. Правда не очень пойму смысл кодинга без компиляции. )
Компиляция, вообще говоря, нужна только для того что бы отдать готовый результат, всё остальное это кривые инструменты или слабые мозги.
I>>Вопрос — ты можешь повторить такое на С++ ?
_>Не пробовал такого. )))
А ты попробуй. Вот там будет очень интересно послушать про самоограничение, стили и соглашения. Получилось — значит язык позволяет то о чем ты говоришь. Не получилось — стало быть ты говоришь про некоторый идеал который для тебя недостижим, и пудозреваю, для большинства разработчиков так же недостижим.
Я например точно понимаю эту разницу, потому как давно утратил способности писать код неделями без ошибок.
Re[60]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
I>>А как мне узнать, как правильно писать свой тип, что бы правильно заюзать вон тот шаблон ? Опаньки ! С учетом того, что мета-информация динамически типизирована, это превращается в небольшой квест.
_>Ты про использование уже готовой библиотеки? А тут то в чём проблема? Подставляешь свой тип в шаблон и если скомпилировалось, то значит всё будет работать.
Если скомпилировалось, то для С++ это значит что только скомпилировалось, а будет ли работать — большой вопрос. Вот для Хаскеля — если скомпилировалось, то с много большей вероятностью будет работать. Вот это и есть типизация.
>А если нет, то компилятор обязательно укажет, определения какой операции не хватает у твоего типа.
Годится, расскажи, как написать код, скажем, статического анализатора ну например на Clang(рядом пример взял), который скажет что bind и unit (другой пример рядом) реализованы неправильно, монадные законы, типы и всё такое.
Программа, разумеется, компилируется.
Второй случай — препроцессор на том же Clang который заменит код эквивалентным, выбрасывая сколь угодно большое количество мусора. Программу так же компилируется.
Ты главное опиши словам, а то мне интересно, как такие фокусы можно делать если типизация шаблонов динамическая. Пудозреваю, если ты решишь эти две задачи, то, внезапно, этот же подход можно будет заюзать для джаваскрипта и питона и динамических языков вообще, да так что скорость работы сравняется с нативным кодом
Re[33]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Klapaucius, Вы писали:
K>Еще раз. Если вам что-то не нравится (например IORef), это не значит, что этого нет. А вся ваша аргументация и тут и в ветке про UFP как раз и построена на том, что IORef прочего не существует. K>На самом деле в ФП есть средства работы с мутабельностью никак принципам ФП не противоречащие.
Так и не существует, вне монад.
Насчёт того, что мне не нравится... В Хаскеле это пожалуй только реализация IO/ST. Т.е. я конечно понимаю, что при данных условиях они не могли сделать по другому. Но можно же было не ставить такие условия, а сделать помягче. Например сделать чистоту не обязательной, а опциональной (как в D). Ленивость кстати при этом можно не убирать полностью — просто она будет работать только для соответствующих мест. Тогда внешний вид программы стал бы как на других функциональных языках, без монадного ужаса. Кстати, саму концепцию монад в Хаскеле как раз стоило бы оставить, как весьма удобную, но уже без IO/ST...
K>Непонятно, почему ленивость как скрытая мутабельность — это не то, а превращение рекурсии в цикл, как скрытая мутабельность — то. Первое встречается гораздо чаще второго, и позволяет оптимизировать гораздо более широкий спектр рекурсивного кода.
Ну так она же не всегда позволяет оптимизировать. )
K>Что-то подобное вполне можно оптимизировать так, чтоб память выделялась один раз. Правда, типичные подходы к дефорестации/фьюжену минимизируют проходы (плюс они ориентированы на оптимизацию конвееров, в которых типы на входе и выходе функций обычно отличаются), так что полученный код будет проверять наличие n функций для каждого элемента в течении одного прохода по выделенной памяти, а не ходить по этой памяти n раз. Впрочем, правила переписывания для того же GHC это библиотечный код, все эти оптимизации не захардкодили в компилятор, а написали авторы библиотек, с которыми они (оптимизации) и поставляются. Так что можно и преобразования нужные вам описать — никакой принципиальной проблемы тут нет.
Так можно всё же получить не некие общие рассуждения, а конкретные ответ:
1. сколько выделений памяти будет в указанном коде?
2. как будет выглядеть на haskell'e код, реализующий тоже самое, но с нулём выделений памяти (размещение исходных данных не считаем)?
Re[53]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Klapaucius, Вы писали:
K>Т.е. отсутствие проверки типов для какого-то кода не снижает уровень типизации? Вообще-то снижает. В случае отсутствия проверки, снижает до нуля.
А то, что компилятор Хаскеля не проверяет исходники какой-нибудь библиотеки на диске, не используемой в данном проекте, случаем не снижает уровень типизации? С точки зрения вашей логики явно должно снижать... )))
Или наоборот. Возьмём шаблонную C++ библиотеку и раскидаем её по заголовочным файлам так, чтобы в каждом файле было ровно по одному шаблону. И соответственно тогда включим в проект, только используемые в нём, заголовочные файлы. После этих магических действий у нас по вашей логике проект резко стал полностью типизированным (т.к. в нём больше нет ни строчки без проверки типов компилятором)?
K>Вы начали обсуждать скорость обобщенного кода как оправдание и даже причину нетипизированности обобщенного кода. Хотя обобщенный код, который работает так же как и плюсовые шаблоны вполне можно типизировать.
Я физически не мог называть скорость обобщённого кода в C++ оправданием нетипизированности, хотя бы потому, что не раз говорил, что не считаю его нетипизированным. Так что ценой за сочетание мощи+скорости шаблонов в C++ является как раз отсутствие раздельной компиляции.
Собственно в Хаскеле всё тоже самое, разве что добавлена возможность получить медленный код с раздельной компиляций.
Re[61]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Ikemefula, Вы писали:
>>А если нет, то компилятор обязательно укажет, определения какой операции не хватает у твоего типа. I>Годится, расскажи, как написать код, скажем, статического анализатора ну например на Clang(рядом пример взял), который скажет что bind и unit (другой пример рядом) реализованы неправильно, монадные законы, типы и всё такое.
AFAIK, монадические законы даже в Haskell не проверяются.
Всё остальное реализуется в языке, без внешнего анализатора — работает и перегрузка (то есть проверка того что передали) и проверка тела шаблона (те операции которые используются). Например смотри Boost.ConceptCheck.
Причём в C++11 с decltype SFINAE стал очень мощным (при таком decltype — концепции это практически синтаксический сахар).
Re[31]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Klapaucius, Вы писали:
K>Он всегда является чистым. IO/ST как раз это и обеспечивают. Это нормальный код на хаскеле, который преимущественно из использования разнообразных "молнадных подъязыков" и состоит.
Чистый снаружи, но не сам по себе.
K>Объект один. А ссылки на него во всех возвращаемых замыканиях. Какое тут может быть перемещение?
Это имеется в виду что-то типа возвращения из функции нескольких разных лямбд, каждая из которых захватывает одну и ту же локальную переменную из нашей функции? Что-то вообще ни разу не попадался мне на практике такой вариант, хотя лямбды использую с удовольствием. Но в любом случае решение тут тоже очевидно — shared_ptr.
K>На хаскеле просто писать высокоуровневый код, а низкоуровневый — сложно. На плюсах легко писать низкоуровневый код, а высокоуровневый — сложно.
Интересная мысль. ) А вот скажем известный набор паттернов проектирования — это высокоуровневый или низкоуровневый код? )
K>Вот так всегда. Какой монадически-ужасный код вам не покажи — всякий раз оказывается, что ничего страшного в нем нет, но вот другой, пока еще не показанный — вот это ужас-ужас-ужас.
Так просто в данном случае весь "ужас ужас ужас" не в самой функции, а в коде её использования (который не был показан). В C++ то нет особой разницы в использование функции int f(int) и void f(int&), а в Хаскеле во втором случае появляется та самая жуть...
Re[61]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Ikemefula, Вы писали:
I>Если скомпилировалось, то для С++ это значит что только скомпилировалось, а будет ли работать — большой вопрос. Вот для Хаскеля — если скомпилировалось, то с много большей вероятностью будет работать. Вот это и есть типизация.
Чего чего? ) Ну покажи мне где там разница... )))
I>Годится, расскажи, как написать код, скажем, статического анализатора ну например на Clang(рядом пример взял), который скажет что bind и unit (другой пример рядом) реализованы неправильно, монадные законы, типы и всё такое. I>Программа, разумеется, компилируется.
Она разумеется не компилируется, если хоть что-то не корректно. )
I>Второй случай — препроцессор на том же Clang который заменит код эквивалентным, выбрасывая сколь угодно большое количество мусора. Программу так же компилируется.
Это я вообще не понял о чём. )
I>Ты главное опиши словам, а то мне интересно, как такие фокусы можно делать если типизация шаблонов динамическая. Пудозреваю, если ты решишь эти две задачи, то, внезапно, этот же подход можно будет заюзать для джаваскрипта и питона и динамических языков вообще, да так что скорость работы сравняется с нативным кодом
Эээээ что? ) Шаблоны C++ работают исключительно во время компиляции. Так что если нам нужно что-то в рантайме, то надо брать уже не шаблоны, а другой инструмент.
Re[43]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Ikemefula, Вы писали:
I>Административные костыли никогда толком не работают. Гугл как раз нетипичный пример, ибо у них средний уровень контингента намного выше чем в среднем по больнице.
Ну так хороший пример для подражания же. Тем более что в небольшой компании этого гораздо проще достичь. )
Re[62]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
I>>Если скомпилировалось, то для С++ это значит что только скомпилировалось, а будет ли работать — большой вопрос. Вот для Хаскеля — если скомпилировалось, то с много большей вероятностью будет работать. Вот это и есть типизация.
_>Чего чего? ) Ну покажи мне где там разница... )))
Это вобщем другими словами примерно следующее "высокоуровневый код писать легко". Но я так понял, ты и с этим будешь спорить ?
I>>Годится, расскажи, как написать код, скажем, статического анализатора ну например на Clang(рядом пример взял), который скажет что bind и unit (другой пример рядом) реализованы неправильно, монадные законы, типы и всё такое. I>>Программа, разумеется, компилируется.
_>Она разумеется не компилируется, если хоть что-то не корректно. )
То есть, ты утверждаешь, что компилятор сумеет отличить правильную с т.з. реализацию математики реализацию bind и неправильную ?
Я правильно тебя понял ?
I>>Второй случай — препроцессор на том же Clang который заменит код эквивалентным, выбрасывая сколь угодно большое количество мусора. Программу так же компилируется.
_>Это я вообще не понял о чём. )
Очень просто — анализируешь мета-код и генеришь эквивалентную замену. Например нашел мега-итераторы и ррррраз, заменил всё более толковым кодом.
I>>Ты главное опиши словам, а то мне интересно, как такие фокусы можно делать если типизация шаблонов динамическая. Пудозреваю, если ты решишь эти две задачи, то, внезапно, этот же подход можно будет заюзать для джаваскрипта и питона и динамических языков вообще, да так что скорость работы сравняется с нативным кодом
_>Эээээ что? ) Шаблоны C++ работают исключительно во время компиляции. Так что если нам нужно что-то в рантайме, то надо брать уже не шаблоны, а другой инструмент.
Шаблоны C++ работают исключительно во время компиляции и при этом они динамически типизированы.
Re[44]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
I>>Административные костыли никогда толком не работают. Гугл как раз нетипичный пример, ибо у них средний уровень контингента намного выше чем в среднем по больнице.
_>Ну так хороший пример для подражания же. Тем более что в небольшой компании этого гораздо проще достичь. )
А в комании из одного человека так и вовсе проблем никаких.
Re[32]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
K>>На хаскеле просто писать высокоуровневый код, а низкоуровневый — сложно. На плюсах легко писать низкоуровневый код, а высокоуровневый — сложно.
_>Интересная мысль. ) А вот скажем известный набор паттернов проектирования — это высокоуровневый или низкоуровневый код? )
Если паттерны высокоуровневые, то код высокоуровневый. Если паттерны низкоуровневые, то код низкоуровневый.
K>>Вот так всегда. Какой монадически-ужасный код вам не покажи — всякий раз оказывается, что ничего страшного в нем нет, но вот другой, пока еще не показанный — вот это ужас-ужас-ужас.
_>Так просто в данном случае весь "ужас ужас ужас" не в самой функции, а в коде её использования (который не был показан). В C++ то нет особой разницы в использование функции int f(int) и void f(int&), а в Хаскеле во втором случае появляется та самая жуть...
Да покаж уже эти ужасы. Уже скоро месяц пугаешь ужасами, я за это время даже Хаскель немного выучить успел но никак ужасов не найду
Re[63]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Ikemefula, Вы писали:
I>Это вобщем другими словами примерно следующее "высокоуровневый код писать легко". Но я так понял, ты и с этим будешь спорить ?
А причём тут это? Ты писал про какие-то различия уровня типизации обобщённого кода на C++ и Haskell'е. Так вот, если мы говорим про некий C++ проект с шаблонами, компилируемый в исполняемый файл (а не шаблонную библиотеку, поставляемую в виде заголовочных файлов), то разницы с Хаскелем нет никакой, в принципе. А именно, компилятор и там и там чётко сообщит о всех некорректностях и просто не скомпилирует проект в случае наличия каких-то ошибок.
I>То есть, ты утверждаешь, что компилятор сумеет отличить правильную с т.з. реализацию математики реализацию bind и неправильную ? I>Я правильно тебя понял ?
Это никакой компилятор не сможет проверить, т.к. для этого надо смотреть не только на прототип функции bind (что компилятор может), но и на её реализацию.
I>Очень просто — анализируешь мета-код и генеришь эквивалентную замену. Например нашел мега-итераторы и ррррраз, заменил всё более толковым кодом.
Ты говоришь про статический анализатор/трансформер исходников что ли? %) Никогда не пользовался такими штуками. И причём он вообще к нашей дискуссии?
I>Шаблоны C++ работают исключительно во время компиляции и при этом они динамически типизированы.
Что-то я тебе вообще перестал понимать. Ты вообще о чём говоришь то? )))