Re[38]: Язык D - действительно красота и эффективность в одном ф
От: DarkEld3r  
Дата: 29.04.14 11:14
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Если мне хотелось бы изгибаться — я бы взял динамический язык.

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

C>В Расте есть перегрузка операторов. А явное указание трейтов позволяет, например, разделять публичный интерфейс и реализацию.

Не понял. Можно мысль развернуть?

C>Так что не нужно включать в каждый файл пару миллионов строк Буста.

C>В результате, код на Rust'е строится что-то в 20 раз быстрее С++-ного.
Буст тут вообще к чему? И зачем его в каждый файл включать?
А для ускорения помогает модульность, а не "указание трейтов".

C>Это игрушка, где настоящее-то? С поддержкой полной форматной строки. В теории оно возможно, но что-то мне подсказывает, что компиляторы это пока ниасиливают.

Нашел несколько реализаций. Признаюсь, глубоко не копал. В стандарте нет, да. Но что значит "компиляторы не осиливают"?
Они (некоторые, по крайней мере) даже стандартный принтф проверять осилили.

C>Уже можно. Хотя не очень понятно зачем. Ну и макросы действуют только в пределах файла при явном их импорте, так что не стоит преувеличивать их глобальность.

Понятно зачем. Чтобы это был нормальный языковый инструмент, а не как в С, где макросам префикс либы лепят.

C>А какие реальные плюсы от их необязательности?

По моему, мы ходим по кругу. Ну не "наследует"/реализует тип нужный трейт, но нужные операции там имеются. Всё могло бы работать, но не в расте. Только не надо рассказывать, что одноимённые функции/операторы могут делать совсем разные вещи в разный трейтах. Могут, но это бывает ещё реже, а уж чтобы создавало проблемы с темплейтами так вообще редкость.

C>Нет, высказвалось мнение, что шаблоны С++ лучше за счёт того, что делают вычисления во времени компиляции. В С++ это единственный метод.

Во первых, не единственный (constexpr ещё).
Во вторых, мнение высказывал не я.
В третьих, не собираюсь отрицать, что сложные вычисления выглядят страшно и нормальные макросы лучше. Но шаблоны не только для этого.

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

В смысле пусть функция возвращает Ани а там будет или результат или "исключение"? Ну это коряво и не слишком естественно.
"Стандартные" Option/Result куда лучше в этом плане.

C>Но и не особо много.

Но есть.

C>Возможная неоднозначность и изменение поведения. Т.е.:

C>
C>//int frob(int a);
C>int frob(float a);
C>int frob(double a);

C>int res = frob(11);
C>

C>Какая функция вызовется? А если раскомментировать первую (в одном из включаемых файлов)?
В первом случае, я бы предпочёл неоднозначность и ошибку на этапе компиляции. В С++ так и происходит.
Если раскомментировать, то понятно что вызовется. И почему это удивительно? В конце концов, в коде типа такого тоже совершенно непонятно, что будет делать вызов (мало ли кто и что там переопределил!):
void test(some_interface *i)
{
  i->do_work();
}

И точно так же новый код может "поломать" старый.

C>Необязательно. Первый параметр в Rust может указываться вручную, как и в Питоне. Так что этот вызов будет аналогичен: Ord::min(a, b). Если нужна конкретная спецификация, то можно так: f64::min(11, 12).

С питоном слабо знаком, можно чуть подробнее? "Ord" тут имя класса или неймспейс? И чем второй вызов отличается?

C>Именно так. И потому 90% возможностей С++ стоит выкинуть нафиг, оставив только то, что реально нужно.

Это только твоё мнение. Из Pаста тоже многое можно повыкидывать и без ущерба к надёжности. Если фантазировать, то из С++ было бы отлично повыкидывать всякие кривости имеющиеся из-за обратной совместимости. А вот возможности (модули, нормальные макросы, рефлексию и т.д.) наоборот добавить неплохо было бы.

Да и если на другие языки посмотреть — они тоже развиваются и увеличивают количество фич. Тот же С# скоро по "сложности" догонит С++ (если уже не обогнал).

C>С каждой фичей матрица их взаимодействий растёт квадратично. В результате, сейчас С++ полностью не может знать никто.

Ложное утверждение. Во первых, не все фичи взаимодействуют. Во вторых, в Расте фич гораздо больше, чем в С. Тем не менее язык получается "надёжнее" и удобнее.

C>И тех, которые могут заменить С++? Таких не знаю.

Не прикидывайся, что не понял. (Практически?) любую фичу можно выкинуть и язык всё равно может быть успешным.

C>То есть? GNOME написан на стандартном чистом C. Там объектная модель сделана полностью на ручных vtbl.

Изначально ты говорил про расширения языка. Они — непереносимы.
"Рукопашные реализации" без расширений переносимы, но имеют другие недостатки.

C>Что "ну-ну"? ООП на чистом С делается без проблем — это совершенно неоспоримый факт.

За указателями можно самому следить и "килер-фича" раста "не нужна" — неоспоримый факт такого же уровня.
Хватит передёргивать и выдирать из контекста. Давай ещё раз — хочешь спорить с тем, что встроенные в язык решения не лучше/удобнее/проще непонятных реализаций? Особенно если в языке отсутствуют инструменты упрощающие такие вещи (типа макросов).
Re[39]: Язык D - действительно красота и эффективность в одном ф
От: Cyberax Марс  
Дата: 29.04.14 11:47
Оценка:
Здравствуйте, DarkEld3r, Вы писали:

C>>В Расте есть перегрузка операторов. А явное указание трейтов позволяет, например, разделять публичный интерфейс и реализацию.

DE>Не понял. Можно мысль развернуть?
В С++ компилятор _обязан_ иметь полное тело шаблона при каждом его инстанцировании. Так как ошибка может возникнуть в любом месте шаблона, если у его параметра не окажется нужного метода.

В Rust каждый generic может компилироваться отдельно — всё что нужно сделать компилятору, это просто подставить адреса реальных функций, реализующих trait'ы. В этом Rust похож на C#, где то же самое делается на уровне байт-кода.

C>>Так что не нужно включать в каждый файл пару миллионов строк Буста.

C>>В результате, код на Rust'е строится что-то в 20 раз быстрее С++-ного.
DE>Буст тут вообще к чему? И зачем его в каждый файл включать?
Ну вот подключил ты тот же самый Boost.Xpressive — и сразу же затянулось примерно 100000 строк include'ов. В Rust'е у меня подтянется только внешний модуль из пакета regex (300 строк, не считая пустых и комментариев).

DE>А для ускорения помогает модульность, а не "указание трейтов".

Каким образом модульность будет помогать с шаблонами С++? Эксперимент с "extern template" показал, что сильно шаблоны ускорить таким образом нельзя.

DE>Нашел несколько реализаций. Признаюсь, глубоко не копал. В стандарте нет, да. Но что значит "компиляторы не осиливают"?

DE>Они (некоторые, по крайней мере) даже стандартный принтф проверять осилили.
Стандартный printf проверяется в качестве специального случая, в виде магии компилятора. А вот полный разбор форматной строки и проверка совпадения типов параметров — пока нигде не делается.

C>>Уже можно. Хотя не очень понятно зачем. Ну и макросы действуют только в пределах файла при явном их импорте, так что не стоит преувеличивать их глобальность.

DE>Понятно зачем. Чтобы это был нормальный языковый инструмент, а не как в С, где макросам префикс либы лепят.
В С макросы часто попадают во внешний интерфейс, т.е. если я объявлю макрос min, использую его в .h-файле (пользуясь случаем, хочу передать привет windows.h), то все пользователи .h-файла будут материться. В Rust это исключено — макрос будет действовать на уровне единицы трансляции.

Возможно столкновение имён макросов, но на практике маловероятно. Нет фундаментальных причин, запрещающих делать namespace для макросов, просто оно пока разработчикам не нужно.

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

DE>В смысле пусть функция возвращает Ани а там будет или результат или "исключение"? Ну это коряво и не слишком естественно.
Нет, можно ловить fail по Any.

C>>Какая функция вызовется? А если раскомментировать первую (в одном из включаемых файлов)?

DE>В первом случае, я бы предпочёл неоднозначность и ошибку на этапе компиляции. В С++ так и происходит.
Не всегда происходит. В случае с double/float — да. А вот в случае с раскомментированием int — нет.

DE>Если раскомментировать, то понятно что вызовется. И почему это удивительно? В конце концов, в коде типа такого тоже совершенно непонятно, что будет делать вызов (мало ли кто и что там переопределил!)

DE>И точно так же новый код может "поломать" старый.
Нет. В случае с виртуальной функцией код поломается, если изменится именно реализация виртуальной функции. Это нормально. В случае с добавлением реализации frob() сломается совершенно посторонний код.

Далее, в Rust серьёзно относятся к модульной компиляции. Предположим, что у нас есть модуль clink. Он использует модуль bling, внутри которого определена функция "frob(double)". Послезавтра в модуль bling добавили "frob(int)" — нужно ли в этом случае перекомпилировать clink? Если нужно, то как это обнаружить? А что если этот модуль binary-only?

C>>Необязательно. Первый параметр в Rust может указываться вручную, как и в Питоне. Так что этот вызов будет аналогичен: Ord::min(a, b). Если нужна конкретная спецификация, то можно так: f64::min(11, 12).

DE>С питоном слабо знаком, можно чуть подробнее? "Ord" тут имя класса или неймспейс? И чем второй вызов отличается?
Ord — это имя трейта ('Ordered'). Второй вариант — это вызов непосредственной реализации.

C>>Именно так. И потому 90% возможностей С++ стоит выкинуть нафиг, оставив только то, что реально нужно.

DE>Это только твоё мнение. Из Pаста тоже многое можно повыкидывать и без ущерба к надёжности.
А вот нельзя. Всё что можно выкинуть, уже почти выкинули. Пару лет назад там были зависимые типы, глобальный GC и т.п.

DE>Да и если на другие языки посмотреть — они тоже развиваются и увеличивают количество фич. Тот же С# скоро по "сложности" догонит С++ (если уже не обогнал).

В C# стараются не добавлять кривых фич, чтобы "лишь бы було". И начали с того, что взяли и выкинули 90% C++. И это работает, кстати.

C>>С каждой фичей матрица их взаимодействий растёт квадратично. В результате, сейчас С++ полностью не может знать никто.

DE>Ложное утверждение. Во первых, не все фичи взаимодействуют.
Да ну? Можешь рассказать как будет работать "private virtual blah() volatile const"?

DE>Во вторых, в Расте фич гораздо больше, чем в С. Тем не менее язык получается "надёжнее" и удобнее.

Фундаментальных фич — не так сильно больше.

C>>И тех, которые могут заменить С++? Таких не знаю.

DE>Не прикидывайся, что не понял. (Практически?) любую фичу можно выкинуть и язык всё равно может быть успешным.
В нише системных языков?

C>>То есть? GNOME написан на стандартном чистом C. Там объектная модель сделана полностью на ручных vtbl.

DE>Изначально ты говорил про расширения языка. Они — непереносимы.
Расширения я упоминал только для RAII (__attribute(cleanup)__ из GCC/Clang). Всё остальное делается стандартным C.

DE>Хватит передёргивать и выдирать из контекста. Давай ещё раз — хочешь спорить с тем, что встроенные в язык решения не лучше/удобнее/проще непонятных реализаций? Особенно если в языке отсутствуют инструменты упрощающие такие вещи (типа макросов).

Да, встроенные в язык решения часто хуже библиотечных.
Sapienti sat!
Re[40]: Язык D - действительно красота и эффективность в одном ф
От: DarkEld3r  
Дата: 30.04.14 12:43
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>В Rust каждый generic может компилироваться отдельно — всё что нужно сделать компилятору, это просто подставить адреса реальных функций, реализующих trait'ы. В этом Rust похож на C#, где то же самое делается на уровне байт-кода.

Теперь понял о чём ты. А оптимизироваться/инлайниться при этом будет одинаково?

C>Каким образом модульность будет помогать с шаблонами С++? Эксперимент с "extern template" показал, что сильно шаблоны ускорить таким образом нельзя.

Как минимум, тем что хедеры не будут 100500 раз парситься.
Признаюсь честно — не особо вчитывался в описание модулей в С++. Тем не менее, заявлено ускорение и для темплейтов. Возможно, просто из-за того, что одни и те же инклюды не будут 100500 раз парситься.
В любом случае, я готов платить временем компиляции за производительность в рантайме (и дополнительную гибкость).

C>Возможно столкновение имён макросов, но на практике маловероятно. Нет фундаментальных причин, запрещающих делать namespace для макросов, просто оно пока разработчикам не нужно.

Что-то я не понял. Ты же сам нахваливал растовский принтф, который является макросом? Вполне пример внешнего интерфейса. В таком случае "столкновение имён" просто дело времени.

C>Не всегда происходит. В случае с double/float — да. А вот в случае с раскомментированием int — нет.

И это правильно. Неоднозначности ведь нет.

C>Нет. В случае с виртуальной функцией код поломается, если изменится именно реализация виртуальной функции. Это нормально. В случае с добавлением реализации frob() сломается совершенно посторонний код.

Не вижу существенной разницы.

C>Далее, в Rust серьёзно относятся к модульной компиляции. Предположим, что у нас есть модуль clink. Он использует модуль bling, внутри которого определена функция "frob(double)". Послезавтра в модуль bling добавили "frob(int)" — нужно ли в этом случае перекомпилировать clink? Если нужно, то как это обнаружить? А что если этот модуль binary-only?

В других языках это как-то решают.

C>А вот нельзя. Всё что можно выкинуть, уже почти выкинули. Пару лет назад там были зависимые типы, глобальный GC и т.п.

Да ладно. Если поискать, наверняка, что-то найдётся. К сожалению, с языком практически не знаком, так что сам привести примеры не смогу.

C>В C# стараются не добавлять кривых фич, чтобы "лишь бы було".

Да ладно? Давай заглянем в тему про С#6
Автор: Sinix
Дата: 09.04.14
. Процитирую один из комментариев:

От синтаксического сахара скоро что-нибудь слипнется.
Опасная это тенденция: чем больше всяких разных таких фишек, тем сложнее читать код неподготовленному человеку, тем медленнее изучение языка.
И тем проще написать плохо читаемый и ещё хуже работающий код.
Хотя, некоторые вещи и правда полезные, даже странно, что их сразу не сделали.

Кстати, перегрузка функция в С# есть...

C>И начали с того, что взяли и выкинули 90% C++. И это работает, кстати.

Заодно выкинули то из-за чего С++ вообще нужен. Язык получился абсолютно другой.

C>>>С каждой фичей матрица их взаимодействий растёт квадратично. В результате, сейчас С++ полностью не может знать никто.

DE>> Ложное утверждение. Во первых, не все фичи взаимодействуют.
C>Да ну?
Ну да. Не надо вырывать из контекста.

C>Можешь рассказать как будет работать "private virtual blah() volatile const"?

Что конкретно интересует?
В С# "private protected" тоже забавно смотрится.

C>Фундаментальных фич — не так сильно больше.

Тем не менее, больше. Да и сами фичи "более навороченные", по сравнению с простым до примитивности С.

Ну и дальше ты демагогией занимаешься.

DE>>Хватит передёргивать и выдирать из контекста. Давай ещё раз — хочешь спорить с тем, что встроенные в язык решения не лучше/удобнее/проще непонятных реализаций? Особенно если в языке отсутствуют инструменты упрощающие такие вещи (типа макросов).

C>Да, встроенные в язык решения часто хуже библиотечных.
Опять передёргивание. Если в язык встроена нормальная возможность к расширению, то да, предпочтительнее библиотечное решение. Если нет, то рукодельные варианты будут уступать или производительностью или читабельностью или и тем и другим.
Re[41]: Язык D - действительно красота и эффективность в одном ф
От: Cyberax Марс  
Дата: 30.04.14 18:21
Оценка:
Здравствуйте, DarkEld3r, Вы писали:

C>>В Rust каждый generic может компилироваться отдельно — всё что нужно сделать компилятору, это просто подставить адреса реальных функций, реализующих trait'ы. В этом Rust похож на C#, где то же самое делается на уровне байт-кода.

DE>Теперь понял о чём ты. А оптимизироваться/инлайниться при этом будет одинаково?
Да, есть возможность LTO — link time optimization, как и в С/C++.

C>>Каким образом модульность будет помогать с шаблонами С++? Эксперимент с "extern template" показал, что сильно шаблоны ускорить таким образом нельзя.

DE>Как минимум, тем что хедеры не будут 100500 раз парситься.
И всё. Больше улучшений не планируется.

DE>В любом случае, я готов платить временем компиляции за производительность в рантайме (и дополнительную гибкость).

Тут уже есть примеры, когда Rust был быстрее кода на С++ за счёт более умного решения.

DE>Что-то я не понял. Ты же сам нахваливал растовский принтф, который является макросом? Вполне пример внешнего интерфейса. В таком случае "столкновение имён" просто дело времени.

println! — это пример системного макроса (их штук 10 всего), он включается в каждый файл автоматически. Остальные макросы должны подключаться явно самим пользователем.

C>>Нет. В случае с виртуальной функцией код поломается, если изменится именно реализация виртуальной функции. Это нормально. В случае с добавлением реализации frob() сломается совершенно посторонний код.

DE>Не вижу существенной разницы.
Существенная разница в том, что добавление совершенно левого кода ломает не относящийся к нему код.

C>>Далее, в Rust серьёзно относятся к модульной компиляции. Предположим, что у нас есть модуль clink. Он использует модуль bling, внутри которого определена функция "frob(double)". Послезавтра в модуль bling добавили "frob(int)" — нужно ли в этом случае перекомпилировать clink? Если нужно, то как это обнаружить? А что если этот модуль binary-only?

DE>В других языках это как-то решают.
В каких? Я их не знаю. В чистом С нет перегрузки функций. В C#/Java нет раздельной компиляции. Что ещё у нас остаётся?

C>>И начали с того, что взяли и выкинули 90% C++. И это работает, кстати.

DE>Заодно выкинули то из-за чего С++ вообще нужен. Язык получился абсолютно другой.
Ага. А в Rust выкинули так, чтобы всё равно можно было использовать его как системный язык.

C>>Можешь рассказать как будет работать "private virtual blah() volatile const"?

DE>Что конкретно интересует?
Их взаимодействие и что курил автор этого куска Стандарта.

C>>Да, встроенные в язык решения часто хуже библиотечных.

DE>Опять передёргивание. Если в язык встроена нормальная возможность к расширению, то да, предпочтительнее библиотечное решение. Если нет, то рукодельные варианты будут уступать или производительностью или читабельностью или и тем и другим.
Встроенные в язык фичи означают, что у языка недостаточная выразительность, чтобы сделать их удобными библиотечными.
Sapienti sat!
Re[42]: Язык D - действительно красота и эффективность в одном ф
От: DarkEld3r  
Дата: 01.05.14 16:56
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Да, есть возможность LTO — link time optimization, как и в С/C++.

В С++ темплейты всё-таки могут легко инлайнится без привлечения линкера.

C>Тут уже есть примеры, когда Rust был быстрее кода на С++ за счёт более умного решения.

Кодегенерация для регэкспов? Ну да, хороший пример. Только это ведь возможно не из-за дополнительных ограничений генериков, а наоборот за счёт более мощной возможности (макросы).

C>println! — это пример системного макроса (их штук 10 всего), он включается в каждый файл автоматически. Остальные макросы должны подключаться явно самим пользователем.

Подключаться должны именно макросы? Не модули/либы их экспортирующие?
Если второе, то вполне вероятны конфликты. Если первое, то получше так как можно будет обойти, но тоже удобным это сложно назвать.

C>Существенная разница в том, что добавление совершенно левого кода ломает не относящийся к нему код.

Да нет существенной разницы. В худшем случае, оба вараинта вызовут проблемы.
Ну и я ни разу не сталкивался с такой проблемой с перегрузкой. Честно говоря, даже сложно представить когда это может вылезти, да ещё и так, чтобы было не очевидно.

C>Если нужно, то как это обнаружить?

Можно с модулем какие-то метаданные иметь.

C>В C#/Java нет раздельной компиляции.

Разве дотнетовские "сборки" (assembly) — это не то?

C>В чистом С нет перегрузки функций.

В С11 есть _Generic.

C>Их взаимодействие и что курил автор этого куска Стандарта.

Вроде, всё логично: констом ты объявляешь, что не будешь менять состояние класса внутри, а volatile говорит, что оно всё-таки может поменяться извне. Единственная практическая польза, которую вижу — компилятор даст по рукам при попытке всё-таки изменить что-то внутри метода.

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

C>Встроенные в язык фичи означают, что у языка недостаточная выразительность, чтобы сделать их удобными библиотечными.

Тем не менее, совсем без встроенных фич не обойтись. Ну и популярные библиотечные решения часто в стандарт попадают.
Ну и злосчастную перегрузку функций ты вряд ли библиотекой добавишь.
Re[27]: Язык D - действительно красота и эффективность в одном ф
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 12.05.14 13:28
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>Из твоих примеров совершенно не ясно, как получить цепочку вида x().y().z()


_>Так тебе надо цепочку или функцию вида "promise<Document> GetDocument()"? А то ты вроде как заказывал именно её в описание к тому API. Я потому и спрашиваю, что никак не могу понять что ты собственно хочешь увидеть.


Я хочу увидеть аналог x().y().z()

_>Если же говорить про цепочку, то чем тебе не нравится последовательность из .then().then()?


Это не то, что я просил. По существу, сравни две строки

1
x().then(function(xr) {return xr.y()}).then(function(yR){ return yR.z()})


с

2
x().y().z()



1й это очевидный отстой, и я думал, что это не нужно объяснять, но у тебя наверняка своё видение и десятикратное увеличение кода не помеха

Напоминаю, x, y и z в либе объявлены вот так —

function x(success, error) {}


Как видишь, обычные колбеки. а вызвать цепочку надо вот так x().y().z()

I>>Далее, раз дело в метапрограммировании, ты не показал, как же именно будет генерироваться такой код


_>Я же говорил уже, что метапрограммирование не является обязательным для такого кода. Оно позволяет всего лишь перевести динамические вызовы (по виртуальным функциям) в статические, которые оптимизатор может заинлайнить и т.п.


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

I>>Ты сказал, что D классное метапрограммирование. И шота пока не ясно, как же сделать мой пример, который в джаваскрипте работает сам собой.


_>Ну да, в D оно сильнее чем в C++. А уже того, что есть в C++ достаточно для написание того же Sprit'a (который является примером реализации статического похода для подобных цепочек, хотя и не связанных с асинхронностью). Правда в C++ Spirit уже написан, а в D пока нет...


Неинтересный аргумент, это общие слова.


_>Что касается JS, то интересно, есть ли для него хоть одна нормальная реализация сопрограмм? )


Разумеется, как stackless так и stackfull. Осенью ты уже задавал этот же вопрос, кстати говоря. Воспользуйся поиском.
Re: [Язык D] Scott Meyers cегодня в 8 вечера
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 22.05.14 04:42
Оценка:
Сегодня в 8 вечера по Москве Scott Meyers выступит с загадочной речью "The Last Thing D Needs". Онлайн-трансляцию можно будет посмотреть здесь:
http://www.ustream.tv/channel/dconf-2014

Затем будет выступление бородатой женщины про написанный на D JIT-компилятор JS, потом другие акробаты, клоуны и жонглеры.
Это сейчас в логове Фейсбука проходит DConf 2014:
http://dconf.org/2014/schedule/

Я вчера первые три выступления посмотрел, трансляция очень качественно сделана. В онлайне было около 150 зрителей, в аудитории раза в 3-4 меньше.
Все это будет потом на ютюбе, но позже.
Re[42]: Язык D - действительно красота и эффективность в одном ф
От: alex_public  
Дата: 23.05.14 01:27
Оценка:
Здравствуйте, FR, Вы писали:

_>>Так в pdf'ке же вроде весь код есть. Там описан printf, который кидает исключения в случае любых несоответствий строки форматирования аргументам.


FR>Это не то настоящий суровый printf должен практически все ошибки отлавливать во время компиляции, например как в OCaml:

FR>...

Ну так это уже будет совсем другая функция с другим прототипом — там первым параметром должно идти что-то типа constexpr. На D естественно пишется без проблем. Ну а на C++ теоретически тоже можно поизвращаться, но будет очень криво из-за отсутствия возможности передавать строки как параметры шаблонов.
Re[42]: Язык D - действительно красота и эффективность в одном ф
От: alex_public  
Дата: 23.05.14 01:42
Оценка:
Здравствуйте, Cyberax, Вы писали:

_>>Ну я с этим собственно и не спорил, хотя бы уже потому, что не претендую на какие-то знания макросов Rust'a.

C>Ну вот как раз кто-то спорил

Не помню тут критических отзывов о них. )

_>>Так в pdf'ке же вроде весь код есть. Там описан printf, который кидает исключения в случае любых несоответствий строки форматирования аргументам.

C>Там описано, что так сделать можно, но конкретного кода нет. Я в целом вполне верю, что это возможно, но вот на constexpr и шаблонах сделать полный разбор строки printf — совсем нетривиально.

Не, там был как раз конкретный код (на странице 21). Только там разбор то идёт в рантайме (а иначе и не возможно для функции с прототипом как у printf, не переделывая первый параметр на что-то типа constexpr), так что вообще никаких сложностей нет.

А вот сделать разбор во время компиляции на C++ действительно очень не просто из-за его ограничений работы со строками в шаблонах (соответственно на D эта задачка решается элементарно). Однако подобные извращённые решения я тоже видел... Только там строку соответственно надо по странному задавать (макросом например и т.п.), т.е. это не прямая замена нормальному printf'у.

_>>Не очень понятно как это сделать, ведь gettext будет возращать обычную строку, а не что-то вроде constexpr.

C>Будет специальная функция, назовём её "T" с такой сигнатурой: "fn T(initial: str) -> &'static str". Т.е. в программе будет что-то типа: "println!(T("Hello, world"), ...)". Макрос println! будет знать про то, что T будет возвращать исходную строку и для проверки валидности форматной строки просто возьмёт её аргумент. Ну а во время исполнения оно будет работать всё как обычно.

C>Ещё, вместо hard-coded имени T можно сделать специальную аннотацию на функцию.


Хы, модно. Такие вещи уже действительно только макросами делаются (если действительно делаются — я пока не видел сам, а верю на слово), а не метапрограммированием на шаблонах.
Re[43]: Язык D - действительно красота и эффективность в одном ф
От: Cyberax Марс  
Дата: 23.05.14 02:07
Оценка:
Здравствуйте, DarkEld3r, Вы писали:

C>>Да, есть возможность LTO — link time optimization, как и в С/C++.

DE>В С++ темплейты всё-таки могут легко инлайнится без привлечения линкера.
Только вот далеко не всегда это надо. В Rust есть опциональная возможность добавить force_inline аннотацию, кстати.

C>>Тут уже есть примеры, когда Rust был быстрее кода на С++ за счёт более умного решения.

DE>Кодегенерация для регэкспов? Ну да, хороший пример. Только это ведь возможно не из-за дополнительных ограничений генериков, а наоборот за счёт более мощной возможности (макросы).
В Rust нет причин, по которым generics будут сильно тормознее С++. Ну разве что, сейчас в кодогенераторе многое ещё не оптимизировано.

C>>println! — это пример системного макроса (их штук 10 всего), он включается в каждый файл автоматически. Остальные макросы должны подключаться явно самим пользователем.

DE>Подключаться должны именно макросы? Не модули/либы их экспортирующие?
Да, именно макросы. Выглядит так:
//Подключаем макрос из внешней библиотеки на стадию разбора синтаксиса
#[phase(syntax)]
extern crate regex_macros;

В соседнем файле этот макрос может и не подключаться.

C>>Существенная разница в том, что добавление совершенно левого кода ломает не относящийся к нему код.

DE>Да нет существенной разницы. В худшем случае, оба вараинта вызовут проблемы.
Где?

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

Я встречался.

C>>Если нужно, то как это обнаружить?

DE>Можно с модулем какие-то метаданные иметь.
Каким образом? А что если нет исходников?

C>>В C#/Java нет раздельной компиляции.

DE>Разве дотнетовские "сборки" (assembly) — это не то?
Не то.

C>>В чистом С нет перегрузки функций.

DE>В С11 есть _Generic.
Оно работает на заранее перечисленных типах. Это не перегрузка.

DE>Насчёт "что курил автор" — подозреваю просто для полноты добавили, примерно как протектед наследование. Проблемы в этом не вижу. Впрочем, я и просто volatile методы очень редко видел.

Ну вот С++ весь такой. И D тоже приближается к нему.

C>>Встроенные в язык фичи означают, что у языка недостаточная выразительность, чтобы сделать их удобными библиотечными.

DE>Тем не менее, совсем без встроенных фич не обойтись. Ну и популярные библиотечные решения часто в стандарт попадают.
Стандартная библиотека, если она не в виде компиляторной магии, — это не проблема.

DE>Ну и злосчастную перегрузку функций ты вряд ли библиотекой добавишь.

И не надо.
Sapienti sat!
Re[28]: Язык D - действительно красота и эффективность в одном ф
От: alex_public  
Дата: 23.05.14 03:12
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Это не то, что я просил. По существу, сравни две строки


I>1

I>
I>x().then(function(xr) {return xr.y()}).then(function(yR){ return yR.z()})
I>

I>с

I>2

I>
I>x().y().z()
I>

I>1й это очевидный отстой, и я думал, что это не нужно объяснять, но у тебя наверняка своё видение и десятикратное увеличение кода не помеха

Безусловно второй вариант красивее. Однако это единственное их отличие. Т.е. если у нас есть реализация для then, то это полностью решает твою задачу. А все твои претензии сводятся уже не к возможности решения, а к красоте, т.е. по сути синтаксическому сахару.

Что касается синтаксического сахара... На C++ сделать точную копию данного кода конечно не просто. Точнее это легко делается для глобальных функций. Получится что-то вроде "x()|y|z;" (просто переопределяем оператор | для future и засовываем then туда). Однако для функций-членов (как в твоём примере) это будет выглядеть заметно страшнее, типа "x()|XR::y|YR::z;", так что наверное лучше обычным then'ом обойтись и не мутить лишнего сахара.

А вот на D, благодаря наличию в нём перегрузки оператора вызова функции-члена, можно в одну строчку реализовать синтаксический сахар в точности, как ты хочешь.
Re[44]: Язык D - действительно красота и эффективность в одном ф
От: DarkEld3r  
Дата: 23.05.14 08:07
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Только вот далеко не всегда это надо.

А когда это может мешать?
Ну и запретить тоже можно.

C>В Rust есть опциональная возможность добавить force_inline аннотацию, кстати.

И оно заинлайнит, если исходников нет?

C>В Rust нет причин, по которым generics будут сильно тормознее С++. Ну разве что, сейчас в кодогенераторе многое ещё не оптимизировано.

Во первых, "сильно" понятие растяжимое. Так можно заявить, что "нет причин, по которым компиляция С++ кода будет сильно тормознее".
Во вторых, речь шла про возможности, а не скорость.

C>Я встречался.

Можешь рассказать подробнее?
Желательно с уточнением насколько сложно и долго это было обнаружить.

C>Каким образом? А что если нет исходников?

Что-то типа комовских "type libraries", наверное, можно сделать.
Ну и вон с длл-ками либ-файлы тоже нужны. В чём проблема так дополнительную информацию хранить?

C>Не то.

Почему?

C>Оно работает на заранее перечисленных типах. Это не перегрузка.

Ну да. Тем не менее, люди вот так извращаются. И запросто может оказаться, что кто-то "переопределил" таким образом, ты включаешь какой-то файл и поведение меняется.

C>Ну вот С++ весь такой. И D тоже приближается к нему.

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

C>Стандартная библиотека, если она не в виде компиляторной магии, — это не проблема.

Если "компиляторная магия" позволяет сделать что-то удобнее/быстрее, то почему бы и нет.
Да и некоторые фичи являются основными для языка. Скажем, невозможность объявить функцию без подключения (пусть и стандартной) библиотеки выглядит дурацки. Если вдруг забыл, то мы говорили о том хорошо ли что-то "встраивать в язык".

C>И не надо.

Надо или нет — не важно. Факт, что далеко не всё ты сможешь сделать.
Re[29]: Язык D - действительно красота и эффективность в одном ф
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 23.05.14 13:25
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Безусловно второй вариант красивее. Однако это единственное их отличие. Т.е. если у нас есть реализация для then, то это полностью решает твою задачу. А все твои претензии сводятся уже не к возможности решения, а к красоте, т.е. по сути синтаксическому сахару.


начиная с ассемблера всё есть сахар

_>А вот на D, благодаря наличию в нём перегрузки оператора вызова функции-члена, можно в одну строчку реализовать синтаксический сахар в точности, как ты хочешь.


Напомню, мы подключаем внешнюю либу, у ней как глобальные так и все остальные функции сделаны на колбеках.

У кого ты собираешься перегружать оператор вызова?
Re[30]: Язык D - действительно красота и эффективность в одном ф
От: alex_public  
Дата: 23.05.14 21:26
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Напомню, мы подключаем внешнюю либу, у ней как глобальные так и все остальные функции сделаны на колбеках.


I>У кого ты собираешься перегружать оператор вызова?


У future естественно. Так что у него можно будет вызвать произвольную функцию член (и оператор соответственно форвардит этот вызов к внутреннему типу, через then). Т.е. благодаря этой фичи языка D у класса future<XR> будет иметься метод y, который будет возвращать future<YR> (делая при этом внутри вызов настоящего y через then). И всё это ровно в одну строчку и для всех типов сразу.

Но опять же, это всё просто синтаксический сахар, а работающий вариант мы имеем и на C++, просто он выглядит чуть длиннее.
Re[31]: Язык D - действительно красота и эффективность в одном ф
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 24.05.14 12:21
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>У кого ты собираешься перегружать оператор вызова?


_>У future естественно. Так что у него можно будет вызвать произвольную функцию член (и оператор соответственно форвардит этот вызов к внутреннему типу, через then). Т.е. благодаря этой фичи языка D у класса future<XR> будет иметься метод y, который будет возвращать future<YR> (делая при этом внутри вызов настоящего y через then). И всё это ровно в одну строчку и для всех типов сразу.


У тебя решение, как сделать второй и последующие вызовы. А как сделать первый ?

т.е. вместо x(success, error) надо x() и он должен вернуть тот же тип, что приходит в success колбеке.
Re[32]: Язык D - действительно красота и эффективность в одном ф
От: alex_public  
Дата: 24.05.14 23:14
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>У тебя решение, как сделать второй и последующие вызовы. А как сделать первый ?


Ну да. Так вроде мы только на проблеме организации цепочек вложенных асинхронных вызовов и остановились, т.к. с просто вызовами давно всё обсудили. И кстати надо признать, что на C++ организовать цепочку с точно такими фичами, как ты хотел, не выходит. Только несколько более громоздкая выходит на плюсах, хотя по смыслу естественно всё тоже самое. А вот на D уже всё в точности как ты хочешь.

I>т.е. вместо x(success, error) надо x() и он должен вернуть тот же тип, что приходит в success колбеке.


Ну во-первых x() будет возвращать не тот тип, что приходит в success, а future<> от него.

А во-вторых мы же это уже всё обсуждали. Смотри вариант3 здесь http://www.rsdn.ru/forum/philosophy/5574814
Автор: alex_public
Дата: 24.04.14
. Применительно конкретно к нашему случаю, внутри x() будет просто один вызов x(success, error) с лямбдами, в которых будет promise.set_value, ну и соответственно в конце return promise.get_future(). Кстати, этот код вполне универсальный (с точностью до определения нашего асинхронного апи), так что его можно оформить в один шаблон, который будет подходит сразу под все подобные функции (x, y, z).
Re[33]: Язык D - действительно красота и эффективность в одном ф
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 26.05.14 11:51
Оценка:
Здравствуйте, alex_public, Вы писали:

_>А во-вторых мы же это уже всё обсуждали. Смотри вариант3 здесь http://www.rsdn.ru/forum/philosophy/5574814
Автор: alex_public
Дата: 24.04.14
. Применительно конкретно к нашему случаю, внутри x() будет просто один вызов x(success, error) с лямбдами, в которых будет promise.set_value, ну и соответственно в конце return promise.get_future(). Кстати, этот код вполне универсальный (с точностью до определения нашего асинхронного апи), так что его можно оформить в один шаблон, который будет подходит сразу под все подобные функции (x, y, z).


Применительно к нашему случаю — весь код JS будет в либе. Не нужно даже генерировать код. То есть, вообще. Более того, и руками не нужно будет помогать. Так что в целом смотрится очень смешно.

"Кстати, в том же JS я что-то не помню реализации чего-то подобного..."

Re[34]: Язык D - действительно красота и эффективность в одном ф
От: alex_public  
Дата: 26.05.14 19:29
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Применительно к нашему случаю — весь код JS будет в либе. Не нужно даже генерировать код. То есть, вообще. Более того, и руками не нужно будет помогать. Так что в целом смотрится очень смешно.


А что тебе мешает закинуть весь этот код в либу в D? И зачем где-то помогать руками? )
Re[35]: Язык D - действительно красота и эффективность в одном ф
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 27.05.14 10:36
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>Применительно к нашему случаю — весь код JS будет в либе. Не нужно даже генерировать код. То есть, вообще. Более того, и руками не нужно будет помогать. Так что в целом смотрится очень смешно.


_>А что тебе мешает закинуть весь этот код в либу в D? И зачем где-то помогать руками? )


Ты же ни решения, ни набросков не показал
Re[36]: Язык D - действительно красота и эффективность в одном ф
От: alex_public  
Дата: 27.05.14 11:46
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Ты же ни решения, ни набросков не показал


Ээээ что? )Я тебе показал как преобразовать коллбэк в асинхронный вызов (и на C++ и на D одинаково) и как организовать цепочку таких вызовов (красиво на D и чуть пострашнее на C++). Причём всё это в виде шаблонов, так что пишется один раз и закидывается в библиотеку. Чего тебе ещё не хватает то? )
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.