А почему макросам не радуются?
Nov. 7th, 2012 08:03 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Макросы - это признание поражения. "Наш язык оказался недостаточно хорошо, нам придется генерировать программы на нём, чтобы продолжать притворяться, что мы пишем на нём".
Во-первых, тут явно подразумевается, что кодогенерация является чем-то плохим и доказывает несостоятельность языка, как средства для написания программ. Из моего ежедневного: редактировать форму мне удобней в графическом дизайнере, просматривать схему базы данных и редактировать связи между таблицами опять же удобней в графическом представлении. По-моему, очевидно, что если существуют разные способы выполнить одну работу, то надо выбирать самый удобный. И либо у нас есть серебряная пуля, либо для каждой задачи существует свой самый удобный инструмент. А чтобы это все как-то между собой взаимодействовало о совмещалось, надо приводить к одному знаменателю. Например, к текстовому представлению в виде кода на определенном языке программирования. Этот способ не единственный, но, на мой взгляд, достаточно практичный и удобный.
Во-вторых, языки развиваются и видоизменяются. При этом во время компиляции многие известные мне языки сначала рассахариваются в некоторое подмножество языковых конструкцию, после чего код на этом подможестве преобразуется в AST и поехало. Специальный синтаксис для монад (linq query syntax в C#, do-нотация в Haskell), asyc/await в C#, сахар для стрелок в том же Haskell, препроцессоры OCaml и множество других примеров. Интересно, нормально ли после каждого релиза с подобными изменениями, упрекать авторов в том, что их язык оказался недостаточно хорош?
В-третьих, существуют расширения компилятора. Для Haskell'а они активно используются и даже можно встретить мнения, что часть этих расширений пора включить в стандарт. Для C# делается некий проект Roslyn, который должен позволить пилить аналогичным образом расширения для главного языка дотнетов. На мой взгляд, это свидетельсво того факта, что разные люди по-разному видят развитие инструмента и работают в соответствующем направлении. Расширение его возможностей или наоборот специализация - это нормально. Но можно, например, заявить про признание поражения.
На мой взгляд, имеет место быть "ваша пуля не серебряная", а это как-то не серьезно.
Код с макросами очень трудно отлаживать.
Этот пойт я не понял. Я пишу на Немерле, и код с использованием макросов в отладке ни чем не отличается от кода без них. Откуда могут быть проблемы? Было выражение, потом на этапе компиляции оно раскрылось в другое выражение. И итоге получается простой линейный код с нормальными именами переменных. Проблемы - это когда стираются имена аргументов, когда стейт шарится между кучей объектов, когда стектрейс растягивается на два экрана, когда куча всего вычисляется лениво и ошибки этих вычислений экранируются и игнорируются или пихаются в стейт, когда все это вычисляется в нескольких потоках наступает ад. Макросы ничего в этот список не привносят. Есть еще отладка самих макросов, но это дело скорее неудобное чем сложное, по крайней мере, применительно к Немерле.
Практически деткам в руки дали не спички, а сразу тротиловые шашки. Представляю, что на этом могут построить наши индийские братья по разуму.
Во-первых, всем всем равно, чем занимается контингент именуемый здесь "индийские братья по разуму". Сколько лет я программирую, столько лет слышу эти рассказы, иногда вижу какие-то подтверждения. Если человек склонен к превращению кода в ад, он это сделает. Они этим занимались на Lisp, занимались на Си, занимаются на Java, будут заниматься на любом другом языке. (Я считаю, что в той или иной мере мы все к этому склонны, просто не всегда рядом есть кто-то, способный увидеть сумасшествие и указать на это, как и не всегда есть желание обсуждать подобное. А вопрос как раз и состоит в постоянном развитии и совершенствовании. И приоритеты в этом развитии могут быть разными).
Во-вторых, я не вижу, чтобы слабые программисты лезли использовать мощные и сложные средства. То есть существует некий контингент постоянно стремящийся интегрировать в проекты НОВЬЕ из последнего выпуска журнала Хакер или статей на Хабре, но там либо старшие товарищи останавливают, либо все желание пропадает, пока новатор разбирается с новой игрушкой. А те программисты, которые ничем не интересуются, пишут на небольшом примитивных подмножестве языка, мирно делаю свои велосипеды и никому жизнь портить не пытаются. (Всегда забавляет эта ежемесячная статья на Хабре "Что такое атрибуты в дотнете и зачем они нужны" и куча комментариев вроде "интересно, спасибо, прочитал") А макросы в статически типизируемом языке с негомоиконичным синтаксисом - штука сложна, очень сложная. И вроде,
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Скала очень сложная и без макросов.
- Ребята, я конфетки вам принес
- Не надо, у нас уже есть БАГЕТ. Очень сытный
То есть, я каким-то серьезных аргументов против макросов в Скале пока не увидел. Не хотят люди пользоваться - никто не заставляет. Не знают, какие задачи будут решаться макросами - но ведь никто и не спрашивает. Да и часто не читают про эти самые макросы, то у там С++, то сишка, то рефлексия тормозит.
(no subject)
Date: 2012-11-08 01:50 am (UTC)так уже же
есть scala под llvm, его конечно надо потыкать палочкой что бы убедится что оно живое, но как proof-of-concept вполне годится
(no subject)
Date: 2012-11-08 09:26 am (UTC)А то компилирующаяся в машинный код Scala будет иметь все минусы - и большие накладные расходы, и трудности с библиотеками.
(no subject)
Date: 2012-11-08 10:08 am (UTC)Ленивые значения в Хаскеле как считать - одно значение в районе одного слова или это thunk в районе одного слова+одно значение?
(no subject)
Date: 2012-11-08 11:29 am (UTC)http://hackage.haskell.org/packages/archive/containers/0.1.0.1/doc/html/src/Data-IntSet.html#IntSet
Значение с конструктором Tip займет два слова. Значение с конструктором Bin займёт 5 слов. Bin, как легко понять, вдвое меньше, чем Tip. В среднем, получится 3.5 слов на значение. В Java не получится лучше, чем 4,5 слов на значение.
Сколько слов займут эти два конструктора в Скале?
(no subject)
Date: 2012-11-08 01:08 pm (UTC)Не вижу, почему бы скале быть в этом случае хуже, чем в джаве.
генерирует ничего особенного:
(no subject)
Date: 2012-11-08 01:25 pm (UTC)8 байтов накладных расходов.
http://stackoverflow.com/questions/7060141/what-determines-java-object-size
И это ещё в лучшем случае!
Кстати, я неправильно посчитал расход памяти для Java для полноценного дерева. В случае Java будет 1 дополнительное слово для Bin и два дополнительных слова для Tip. Это приведёт к дополнительным расходам в 1,5 слова на значение. То есть, 5 слов супротив 3,5 на Хаскеле.
(no subject)
Date: 2012-11-08 01:48 pm (UTC)в джаве расход на object header и паддинг полей является implementation specific: IBM JVM на хедер тратит 4 байта, а хотспот 8. В количество памяти на объект также нужно учесть фрагментацию памяти, а это вообще архитектурно-зависимо. В том же хотспоте размер объекта нужно округлить вверх до кратного 8 байтам. При наследовании хотспот поля каждого уровня наследования тоже паддит. Примитивные значения сгруппированы отдельно от указателей. volatile поля выровнены до границы машинного слова. На 64-битных машинах указатели часто 32-битные, зато тратится лишние 2% ЦПУ на конвертацию обратно в 64-битные. Это всё не из-за того, что не могли сделать по-другому в принципе, а потому, что такие design decisions позволяют выиграть какие-то проценты на производительности кэша и GC.
Я думаю, гораздо более интересным сравнением будет глубина применения каких-нибудь unwrap . wrap = id оптимизаций, умение обращаться с мелкими transient объектами. Вот тут Джава может облажаться из-за трудностей escape analysis; до какой-то степени делается, но есть свои но.
(no subject)
Date: 2012-11-08 01:57 pm (UTC)И да, pragma RULES в Скале невозможна.
(no subject)
Date: 2012-11-08 02:39 pm (UTC)А ещё, я думал, это всё означает также, что расход памяти на один объект - это не так важно, как важен расход памяти на единицу бизнес логики. Как один простой пример, если уметь выбросить не нужные unwrap . wrap, которые присутствуют в коде, вы избавитесь от объектов. Второй пример - если суметь reuse место от immutable объектов до GC, опять, избавитесь от объектов.
Например, будет ясно, что тупли Скалы будут соответствовать объектам, которые Джава не сможет распаковать и потому не сможет пользоваться чисто unboxed значениями. Вот если в силу особенностей построения программы на Хаскеле компилятор может делать более глубокий анализ таких паттернов и создавать меньше объектов, чем java, это будет гораздо более ощутимой выгодой, потому что оптимизация создания одного лишнего объекта перекрывает оверхеды от разницы в размерах сразу нескольких объектов меджу этими платформами. Тем более, что чем крупнее объект, тем меньше % эта самая разница, верно?
(no subject)
Date: 2012-11-08 02:46 pm (UTC)Вы про дизайн ByteString читывали ли? А ещё есть short cut deforestation. И та же pragma RULES.
(no subject)
Date: 2012-11-08 02:58 pm (UTC)заметьте, я не говорю, что кто-то круче кого-то. :) я лишь пытаюсь направить обсуждение на более интересную метрику. И привожу примеры с unwrap . wrap только потому, что это что-то, о чём я читал, но сколько из этого происходит на практике я ж не знаю :) вот в джаве - знаю, что unbox+box на бумаге-то есть, но совершенно не следует умение оптимизировать сколь угодно сложные формы boxing или сколь угодно вложенные boxing.
(no subject)
Date: 2012-11-08 03:03 pm (UTC)(no subject)
Date: 2012-11-08 03:23 pm (UTC)(no subject)
Date: 2012-11-08 04:00 pm (UTC)Суперкомпиляция: http://research.microsoft.com/en-us/um/people/simonpj/papers/supercompilation/
Включает в себя inline, deforestation (насколько возможно), склеивание циклов и, наверное, многое другое.
Проверка контрактов: http://gallium.inria.fr/~naxu/research/HaskellContract.pdf
Типа проверка test_Sort = all $ (\xs -> zipWith (<=) xs (tail xs)) $ sort xs на этапе компиляции.
(no subject)
Date: 2012-11-08 04:10 pm (UTC)