Pull to refresh

Comments 24

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

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

UFO just landed and posted this here
улыбнуло, сама необходимость использовать макросы в супер-пупер навороченном языке высокого уровня говорит очень не в пользу этого языка.

Не развернете вашу мысль? Мне кажется что есть задачи которые удобнее делать на этапе компиляции, а не выполнения и для таких задач раст предлагает макросы.

Вроде бы Страуструп писал однажды. что макросы — это костыли, которые пытаются сгладить проблемы в языке.

Сравните как устроены макросы в Си и Rust. В первом случае на уровне лексера используется автоподстановка, а в случае второго это полноценная модификация AST (не считая аттрибутных, там как раз в стиле си все).
В результате чего макросы гигиенические и не несут опасности для окружающего кода.
А для любителей более сложной кодогенерации есть возможность в build.rs прикрутить что угодно.

varanio исчерпывающе сказал про
  • генерирование избыточного/тривиального кода (boilerplate) вместо его ручного написания.
  • расширение языка перед тем, как будет добавлен новый синтаксис, закрытие пробелов в языке.

То есть:
Если вам в языке что-то надо писать «автоматически», повторять много раз похожий код (нарушая принцип не повторяй себя), или вы видите что часто попадается задача для которой надо «расширить» синтаксис языка, этому языку нужны костыли.
Не костылями будут функции профайлинга, вроде file! line!, принтауты которые используются для тестов, любая функция которая нужна при разработке но отпадает при релизе, их можно переложить на нормальное окружение для теста или дебага.
Ещё макросы часто используются для написания разных вариантов кода для разных платтформ, Раст этим страдает?
При этом при наличии полноценного метаязыка, может даже с полной рефлексией действий компилятора фичи Раста не нужны и язык можно разделить на две компоненты —
язык написания кода и язык управления компилятором. Заново изобретаем С++ с улучшенным механизмом макросов.
и кстати
если разработчик задумает создать свой свой собственный встроенный язык.
то он былдокодер

1) Скажите, а на каком таком языке вы пишете, что у вас нет никакой необходимости в бойлерплейт коде?
2) Чем, например, декораторы выгодно отличаются от макросов? А прочая компайл-тайм рефлексия?

Эдак можно любую фичу языка критиковать.


Например, вот этот аргумент можно использовать для того чтобы доказать что подпрограммы — тоже плохо:


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

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


Если только специально не захардкодить знание, как для format! и других стандартных макросов делают, но это не расширяемый подход, конечно.

Ну кстати, я тут обратил внимание, что всякая фигня, которая через build.rs генерится, превращается во вполне обычные rust модули и вполне себе ide friendly.
В теории это должно работать и с кодогенерацией для процедурных макросов.
А вот в случае с dsl, уже так не получится.

Есть много причин того, что format! реализован как макрос -6-, я же хочу подчеркнуть то, что он может разделить строку на части во время компиляции, проанализировать ее и проверить, является ли обработка переданных аргументов типо-безопасной

Во многих других языках данные ошибки проявились бы во время выполнения

Интересно, а как Си выполняет подобные проверки во время компиляции в printf() и подобных, если там это не макросы?

Уже нашел в приведенной ссылке на вики:


Some compilers, like the GNU Compiler Collection, will statically check the format strings of printf-like functions and warn about problems (when using the flags -Wall or -Wformat). GCC will also warn about user-defined printf-style functions if the non-standard "format" attribute is applied to the function.

То есть, это чисто фича GCC.

Угу. И она никак не дружит с register_printf_function

А как с этим в rust? Можно язык format! расширять?

В каком смысле раширять? Вообще говоря в Rust есть 2 типажа(класса типов) отвечающих за расширение format!: Display и Debug. Реализация этих трейтов для типа T как раз отвечает за отображение этого типа с помощью макроса format!. О таком расширении вы спрашиваете?

В каком смысле раширять?
Хороший вопрос. Например в C register_printf_function может добавить возмость печать число римскими числами. То есть не только распечатать свой тип (тут вы правы — типажи решают проблему), но и распечатать тип, для которого уже есть «канонический» способ печати как-то по другому. Ну и получить несколько аргументов и их перечатать совместно (хотя это уже блажь: glibc так умеет, но на практике я этого ни разу не использовал).
Можно писать обобщённые «типы-обёртки», которые, например, будут брать тип способный конвертироваться в число и реализовывать Display выводящий римские цифры, применение которых будет выглядеть как println!("{}", RomanNum(my_value)).
Это не очень хорошо, так как не позволяет управлять этим процессом локализатору.

Впрочем 99% потребностей то, что есть у rust покрывает, борьба за последний 1% — это уже другая история.

Просто забавно, что после всех десятилетий эволюции самый гибкий вывод текста в стандартной библиотеке — у старого доброго C. Rust пока что чуть позади, а про C++ и говорить не стоит: даже поменять местами два аргумента — проблема.

P.S. А, кстати, как с этим у rust? Такое как делать умеет:

printf(_("Directory \"%s\" does not contain file \"%s\"!"), d, f);

Чтобы при запуске в русской локали оно вывело:

Файл "попа.txt" отсутствует в каталоге "/ай-ай-ай"!


Python и старый добрый C так умеют, а вот C++ — увы…
К сожалению (или к счастью), Rust так тоже не умеет. Но, думаю, вполне возможно написать локализующие аналоги println!, format! и других используя процедурные макросы, которые на данный момент доступны только на Nightly. (есть ещё вариант использовать proc-macro-hack на стабильной ветке, но у него есть существенные ограничения)
Понятно. Может быть когда на rust начнут GUI делать — прикрутят.

Но тут, конечно, вступает в противоречие желание статически всё проверять с одной стороны и локализовать без перекомпиляции — с другой.

Как это грамотно разрулить — я сходу не представляю… В C оно сделано ка и всё в C: если грамотно использовать — то работает быстро и хорошо, а если вы где-то ошиблись… ну дык эта, это ж C, шлем и наколенники в комплекте не идут…
>Может быть когда на rust начнут GUI делать — прикрутят.

Как часть стандартной библиотеки сильно вряд ли. Скорее это будет частью крейта, например, такого как fluent.

>Но тут, конечно, вступает в противоречие желание статически всё проверять с одной стороны и локализовать без перекомпиляции — с другой.

Грамотно написанный макрос будет во время компиляции проверять корректность подтянутых из файлов локализационных строк и переданных аргументов, а так же сообщать об ошибке используя compile_error! с человеко читаемой ошибкой, так что, когда у разработчиков дойдут руки до этого, мы вполне можем получить локализацию на Расте защищённую от выстрелов в ногу, при этом не просто на уровне подстановок, а с «умным» поведением ожидаемым от современных локализационных фреймворков.
Вообще-то не два, а целых 9. Дополняя ответ на изначальный вопрос: кастомные расширения на данный момент создавать нельзя и добавлять их в среднесрочной перспективе не планируется. Реализует ли тип необходимый для форматирования трейт строго проверяется на этапе компиляции.
UFO just landed and posted this here
Sign up to leave a comment.

Articles