Re[27]: Язык D - действительно красота и эффективность в одном ф
От: Cyberax Марс  
Дата: 24.04.14 05:10
Оценка: 1 (1)
Здравствуйте, alex_public, Вы писали:

C>>Что значит памяти на 1 байт? Заголовок объектов в Java — это нынче 16 байт. Если объект большой, то это непринципиально.

_>А как у нас дела с контейнерами (массивами и т.п.) при таком раскладе? )
В Java используются контейнеры ссылок. Как и в большинстве софта на D.

C>>D без GC никому не нужен.

_>Я бы с удовольствием пользовался таким. Точнее я на самом деле хотел бы перетаскивания самых модных фич (в основном из области метапрограммирование и т.п.) в C++.
D без GC может называться только "Rust".

C>>Точнее, наоборот — нет возможности сделать граф объектов и после этого работать с ним как с immutable. В Rust — именно это гениальный штрих.

_>А тут вроде уже не так всё страшно. Преобразование в immutable не выглядит особо опасным.
Ну вот я уже тут предложил сделать безопасно дерево со ссылками на родителя на Go. Дырка нашлась сразу же...

Ещё очень важна возможность создания контейнеров объектов. В Rust при желании получаются вполне естественные императивные алгоритмы:
let mut numbers = vec![1, 2];
numbers.push(3);
numbers.push(4);

numbers.pop();
for n in numbers.iter()
{
   numbers.pop(); //Ошибка - мутируем список во время итерации по нему
}
numbers.pop(); //Снова всё ОК, не осталось borrowed-ссылок

let numbers_immut = numbers; //Теряем мутирующего владельца

numbers.pop(); //Ошибка
numbers_immut.pop(); //Ошибка


Все ошибки — времени компиляции.
Sapienti sat!
Re[23]: Язык D - действительно красота и эффективность в одном ф
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 24.04.14 05:30
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>
I>>void getDocument(Callback<Document> cnt, Callback<Error> errCnt);
I>>


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

I>>
I>>Document getDocument() throws Error;
I>>


I>>Ну например


I>>
I>>Promise<Document> getDocument();
I>>


I>>Валяй, показывай чудеса метапрограммирования — одной строчкой подключил либу и всё палит само. Ручное написание всех сортов врапперов и тд оставь детям. Короче, покажи, наконец "тривиально реализуется обычными способами".


_>Ты тут путаешь разные вещи. Давай я перечислю все возможные варианты, а ты укажешь что ты конкретно хочешь. Значит имея подобный асинхронный api можно использовать его следующими способами:


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


_>1. Собственно асинхронный вызов (обработка результатов происходит в контексте вызывающего). Т.е. код у нас будет вида:

_>
_>getDocument([](Document d){
_>    process(d);
_>}, [](int code){
_>    error(code);
_>});
_>

_>Кстати, замечу, что в том же JS как раз наиболее популярен именно этот вариант.

Замечу, что твоя задача была избавиться от колбеков, а у тебя они в полный рост. В JS это делается на раз и я уже показал как будет выглядеть.
От тебя требуется вызвать вот так:
auto f = getDocument();


сигнатуры смотри выше

Фейл.

_>2. Сделать из асинхронного вызова синхронный. Т.е. код вида:

_>
_>promise<Document> p;
_>auto f=p.get_future();
_>getDocument([&](Document d){
_>    p.set_value(d);
_>}, [&](int code){
_>    p.set_exception(exception(code));
_>});//весь код выше можно преобразовать в красивый вариант вида auto f=sync(getDocument);
_>process(f.get());//в get имеем блокировку
_>


Нет, надо ровно то что я просил:

auto f = getDocument();


Фейл.

_>3. Асинхронный вызов с продолжением. Т.е. что-то вроде:

_>
_>promise<Document> p;
_>auto f=p.get_future();
_>getDocument([&](Document d){
_>    p.set_value(d);
_>}, [&](int code){
_>    p.set_exception(exception(code));
_>});//опять же можно упрятать весь код выше в функцию
_>f.then([](future<Document> d){
_>    process(d.get());
_>    return to_string(d.get());
_>}).then([](future<string> s){
_>    cout<<s.get();
_>});
_>

_>Как видно, здесь можно образовывать цепочки исполнения произвольной длины.

Ты увлекся похоже. От тебя требовалось избавиться от этих спагетти с помощью метапрограммирования.

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

_>4. Асинхронный код, выглядящий как синхронный. Такое уже делается только с помощью сопрограмм и мы подробно разбирали подобный код. Он выглядит (изнутри — понятно, что при нормальном использование мы маскируем все эти вещи в удобные макросы) приблизительно так:

_>
_>coroutine __c([](){//маскируем под что-то типа ASYNC(...) - выделение блока асинхронного кода
_>Document doc;
_>int __error=0;
_>getDocument([&](Document d){
_>    doc=d;
_>    __c.go();
_>}, [&](int code){
_>    __error=code;
_>    __c.go();
_>});
_>__c.break();
_>if(__code) throw exception(__code);//маскируем весь кусок досюда под что-то типа Document doc=await_async(getDocument);
_>process(doc);
_>});
_>

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

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

то есть, цепочка функций с колбеками вида function x(arg1,argN, success, error) {}
вызывается вот так

var result = x1(arg1,arg2).x2(arg3,arg4)...xN(argi, argk);

все промисы, замыкания и прочие вещи, которые ты расписывал в 4х примерах не надо писать, все делается подключением ровно одной либы а дальше всё палит само.

В твоем случае есть только один выход — олдскульная кодогенерация, то есть генерация промежуточного слоя АПИ, который сделает преобразование интерфейса, то есть для каждого метода вида
void getDocument(Callback<Document> cnt, Callback<Error> errCnt);


будет сгенерирован правильный лифтинг, то есть


Document getDocument()
{
  return Document.wrap((succeed, error) => {

     baseLib.getDocument(succeed, error);
  });
}

сам документ это навроде
class Document:Promise<baseLib:Document>{
}


В противном случае ты не сможешь вызывать вот так x().y().z()


Итого — ты привел ажно 4 примера и все мимо. Эпик фейл

_>Да, ну и так с реализацией какого из этих 4-ёх вариантов у тебя есть какие-то вопросы?


С учетом того, что ты не осилил то, чего требовалось ...

I>>Ты утверждал, "для реализации подобного метапрограммирование не требуется. Это тривиально реализуется обычными способами"


_>Ну да. А что, есть сомнения? )


Конечно, и даже сильнее чем раньше.
Re[26]: Язык D - действительно красота и эффективность в одном ф
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 24.04.14 12:01
Оценка: 10 (1)
Здравствуйте, Cyberax, Вы писали:

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

_>>Снимать immutable — это вообще выглядит ненормально. Я ещё понимаю снятие shared...
C>Точнее, наоборот — нет возможности сделать граф объектов и после этого работать с ним как с immutable. В Rust — именно это гениальный штрих.

А вот есть такой гениальный штрих в D:
если написать так
int[] make() { return [1,2,3]; }

void main(string[] argv)
{
    immutable xs = make();
}

То выдается ожидаемая ошибка Error: cannot implicitly convert expression (make()) of type int[] to immutable(int[]).
Но если сделать так
int[] make() pure { return [1,2,3]; }

То все компиляется и работает. Результат чистой функции может быть легально переведен из мутабельного в иммутабельный, т.к. чистота подразумевает, что лишних ссылок на эти данные мы не сделали. Вот и решение не хуже этого вашего Раста.
Re[28]: Язык D - действительно красота и эффективность в одном ф
От: alex_public  
Дата: 24.04.14 20:58
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>В Java используются контейнеры ссылок. Как и в большинстве софта на D.


Так это же ещё хуже. Кроме оверхеда на java-заголовок объекта в памяти, получаем расход ещё и на ссылки. А вообще я намекал на подобные http://vanillajava.blogspot.ru/2011/07/java-how-much-memory-do-different.html цифры — часть их них ужасает. )

C>D без GC может называться только "Rust".


Rust пока не тянет даже на замену C++, максимум на замену C. Просто по набору возможностей. Хотя их естественно можно нарастить в будущем, если заложен хороший базис. Но на данный момент ситуация именно такая.

C>Ещё очень важна возможность создания контейнеров объектов. В Rust при желании получаются вполне естественные императивные алгоритмы:

C>...
C>Все ошибки — времени компиляции.

Ну так если не считать запрета на мутацию массива внутри итерации по нему, то всё остальное точно так же работает и на D и на C++.
Re[24]: Язык D - действительно красота и эффективность в одном ф
От: alex_public  
Дата: 24.04.14 21:26
Оценка: -1
Здравствуйте, Ikemefula, Вы писали:

I>Итого — ты привел ажно 4 примера и все мимо. Эпик фейл


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

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

Ну и наконец если сравнивать с JavaScript (кстати, не пойму откуда у наз возникла эта идея, ну да ладно), то я видел в нём реализации моих вариантов 1 и 3. Причём если вариант 2 я просто не видел, но могу изобразить что-то подобное на JS, то как реализовать вариант 4 (это тот самый, который мы давно обсуждали и который есть в C#, тривиально делается в C++ и т.д.) на JS я даже не представляю.

P.S. А вообще я уже что-то потерял нить данной дискуссии — о чём мы вообще спорим сейчас? ) И какое отношение к языку D имеет реализация асинхронности в C++ и JS?
Re[27]: Язык D - действительно красота и эффективность в одном ф
От: Cyberax Марс  
Дата: 24.04.14 21:53
Оценка:
Здравствуйте, D. Mon, Вы писали:

C>>Точнее, наоборот — нет возможности сделать граф объектов и после этого работать с ним как с immutable. В Rust — именно это гениальный штрих.

DM>А вот есть такой гениальный штрих в D:
Не получится, нет borrow-checker'а.

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

Хуже. Чистые функции не могут делать никакого IO, их нельзя распараллеливать и т.д. Фактически, они используются только в метапрограммировании в D.
Sapienti sat!
Re[29]: Язык D - действительно красота и эффективность в одном ф
От: Cyberax Марс  
Дата: 24.04.14 21:58
Оценка:
Здравствуйте, alex_public, Вы писали:

C>>В Java используются контейнеры ссылок. Как и в большинстве софта на D.

_>Так это же ещё хуже. Кроме оверхеда на java-заголовок объекта в памяти, получаем расход ещё и на ссылки.
В D оно ровно так же.

_>А вообще я намекал на подобные http://vanillajava.blogspot.ru/2011/07/java-how-much-memory-do-different.html цифры — часть их них ужасает. )

Бредятина. Строка в 1024 элемента будет занимать примерно 2100 байт, например. Никак не 50Кб.

C>>D без GC может называться только "Rust".

_>Rust пока не тянет даже на замену C++, максимум на замену C. Просто по набору возможностей. Хотя их естественно можно нарастить в будущем, если заложен хороший базис. Но на данный момент ситуация именно такая.
1) Что не так в Rust с возможностями?
2) Чем чистый С хуже по возможностям C++?

C>>Все ошибки — времени компиляции.

_>Ну так если не считать запрета на мутацию массива внутри итерации по нему, то всё остальное точно так же работает и на D и на C++.
Не работает. Я уже примеры даже привёл. В D объекты обязаны сразу создаваться иммутабельными, из-за чего возникает необходимость натянуть презерватив на глобус — создавать их в функциональном стиле в императивном языке.
Sapienti sat!
Re[28]: Язык D - действительно красота и эффективность в одном ф
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 25.04.14 00:36
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Не получится, нет borrow-checker'а.


Уже получилось. В смысле, это не тот же самый штрих, что в расте, но все ж способ легально строить иммутабельные структуры из мутабельных. То, что ты продолжаешь называть невозможным несмотря на уже два продемонстрированных способа.
Re[29]: Язык D - действительно красота и эффективность в одном ф
От: Cyberax Марс  
Дата: 25.04.14 01:07
Оценка:
Здравствуйте, D. Mon, Вы писали:

C>>Не получится, нет borrow-checker'а.

DM>Уже получилось. В смысле, это не тот же самый штрих, что в расте, но все ж способ легально строить иммутабельные структуры из мутабельных. То, что ты продолжаешь называть невозможным несмотря на уже два продемонстрированных способа.
Оба способа дырявые. ЧТД.
Sapienti sat!
Re[30]: Язык D - действительно красота и эффективность в одном ф
От: night beast СССР  
Дата: 25.04.14 05:22
Оценка:
Здравствуйте, Cyberax, Вы писали:

_>>Rust пока не тянет даже на замену C++, максимум на замену C. Просто по набору возможностей. Хотя их естественно можно нарастить в будущем, если заложен хороший базис. Но на данный момент ситуация именно такая.

C>1) Что не так в Rust с возможностями?
C>2) Чем чистый С хуже по возможностям C++?

нет нормальных исключений.
Re[25]: Язык D - действительно красота и эффективность в одном ф
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 25.04.14 08:05
Оценка:
Здравствуйте, alex_public, Вы писали:

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


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

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

Объясняю еще раз — что бы вызвать метод y, x() должен вернуть некоторый враппер. Ты нигде не показал даже необходимость этого враппера.

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

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


Ты сказал про классное метапрограммирование и сказал, что похожий результат в D можно получить обычными средствами. При этом показал пример промисов, но забыл показать, как будет сформирован апи.

На деле оказалось, что метапрограммирование ты понимаешь как копипаст:

"очевидно что соответствующие синхронные обёртки делаются из тех моих примеров банальным копипастом"

А между тем джаваскрипт не требует никакого копипаста.

_>Ну и наконец если сравнивать с JavaScript (кстати, не пойму откуда у наз возникла эта идея, ну да ладно), то я видел в нём реализации моих вариантов 1 и 3.


Ты показал совсем не то что требовалось. Твои примеры даже не функции и ничего не возвращают. А значит и цепочку сорганизовать не выйдет.

_>P.S. А вообще я уже что-то потерял нить данной дискуссии — о чём мы вообще спорим сейчас? ) И какое отношение к языку D имеет реализация асинхронности в C++ и JS?


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

P.S. про копипаст повторяться не нужно.
Re[30]: Язык D - действительно красота и эффективность в одном ф
От: alex_public  
Дата: 26.04.14 11:59
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>В D оно ровно так же.


Нет, там совсем другой расклад с массивами. Уже не говоря о возможности расположения любых данных на стеке. И отсутствие лишней рантайм информации.

C>Бредятина. Строка в 1024 элемента будет занимать примерно 2100 байт, например. Никак не 50Кб.


Одной подобной фразы недостаточно для опровержения серьёзной статьи. Я конечно это сам не измерял, но пока поверю скорее им, а не голословным утверждениям на форуме. )

C>1) Что не так в Rust с возможностями?


Банальная бедность на фичи. Их тут намного меньше чем даже в C++. Что уж говорить про D, который богаче C++.

C>2) Чем чистый С хуже по возможностям C++?


Уууу. ) Странно видеть такой вопрос на этом форуме. Я конечно же могу подробно ответить... Но это будет на много много пунктов, причём мне кажется, что большинство из них тут общеизвестны, так что этот вопрос как-то попахивает троллизмом.

C>Не работает. Я уже примеры даже привёл. В D объекты обязаны сразу создаваться иммутабельными, из-за чего возникает необходимость натянуть презерватив на глобус — создавать их в функциональном стиле в императивном языке.


Создание сразу иммутабельных — это всего лишь один вариант из трёх (см раздел Creating Immutable Data http://dlang.org/const3.html). Можно ещё копировать (кстати, у массивов есть уже готовый метод idup для таких дел). Ну и наконец можно сделать каст — это уже только для профи, которые не опасаются работать без страховки компилятора.
Re[26]: Язык D - действительно красота и эффективность в одном ф
От: alex_public  
Дата: 26.04.14 12:12
Оценка:
Здравствуйте, Ikemefula, Вы писали:

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


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

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

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


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

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


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

Что касается JS, то интересно, есть ли для него хоть одна нормальная реализация сопрограмм? )
Re[31]: Язык D - действительно красота и эффективность в одном ф
От: Cyberax Марс  
Дата: 26.04.14 12:15
Оценка:
Здравствуйте, alex_public, Вы писали:

C>>В D оно ровно так же.

_>Нет, там совсем другой расклад с массивами. Уже не говоря о возможности расположения любых данных на стеке. И отсутствие лишней рантайм информации.
В Java по факту делается escape analysis, так что значительная часть объектов располагается на стеке. Автоматически. И это работает.

C>>Бредятина. Строка в 1024 элемента будет занимать примерно 2100 байт, например. Никак не 50Кб.

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

C>>1) Что не так в Rust с возможностями?

_>Банальная бедность на фичи. Их тут намного меньше чем даже в C++. Что уж говорить про D, который богаче C++.
Каких конкретно фич у него нет?

C>>2) Чем чистый С хуже по возможностям C++?

_>Уууу. ) Странно видеть такой вопрос на этом форуме. Я конечно же могу подробно ответить... Но это будет на много много пунктов, причём мне кажется, что большинство из них тут общеизвестны, так что этот вопрос как-то попахивает троллизмом.
Я серьёзно. Единственная реальная отсутствующая фича — это исключения. Всё остальное есть, даже RAII в виде расширений языка.

C>>Не работает. Я уже примеры даже привёл. В D объекты обязаны сразу создаваться иммутабельными, из-за чего возникает необходимость натянуть презерватив на глобус — создавать их в функциональном стиле в императивном языке.

_>Создание сразу иммутабельных — это всего лишь один вариант из трёх (см раздел Creating Immutable Data http://dlang.org/const3.html).
Я не очень понял где там два остальных метода.
Sapienti sat!
Re[32]: Язык D - действительно красота и эффективность в одном ф
От: DarkEld3r  
Дата: 26.04.14 20:13
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Каких конкретно фич у него нет?

Генерики уступают по мощности плюсовым шаблонам. Нет исключений и перегрузки функций.

C>Я серьёзно. Единственная реальная отсутствующая фича — это исключения. Всё остальное есть, даже RAII в виде расширений языка.

Ну это несерьёзно.
Да и рукопашные "виртуальные функции", например, ужасны.
Re[32]: Язык D - действительно красота и эффективность в одном ф
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 27.04.14 05:30
Оценка: +1
Здравствуйте, Cyberax, Вы писали:

C>>>2) Чем чистый С хуже по возможностям C++?

_>>Уууу. ) Странно видеть такой вопрос на этом форуме. Я конечно же могу подробно ответить... Но это будет на много много пунктов, причём мне кажется, что большинство из них тут общеизвестны, так что этот вопрос как-то попахивает троллизмом.
C>Я серьёзно. Единственная реальная отсутствующая фича — это исключения.

man longjmp

а вообще, это хороший пример того, как можно по-разному определить наличие какой-то возможности.
The God is real, unless declared integer.
Re[33]: Язык D - действительно красота и эффективность в одном ф
От: Cyberax Марс  
Дата: 27.04.14 07:27
Оценка:
Здравствуйте, DarkEld3r, Вы писали:

C>>Каких конкретно фич у него нет?

DE>Генерики уступают по мощности плюсовым шаблонам. Нет исключений и перегрузки функций.
С++-ные шаблоны — не нужны. В Rust'е вместо них нормальные генерики и макросы. К примеру, printf! в Rust реализован в виде макроса и проверяет корректность параметров во время компиляции.

Исключения есть — в виде fail! и Any. Они по своему дизайну могут быть отловлены на границе задачи. Кстати говоря, в язык встроена и модель супервизора задач из Erlang'а.

Чистая перегрузка функций — тоже не нужна. Есть её аналог с помощью impl'ов:
trait to_str { fn to_str(&self) -> str; }

impl to_str for int { fn to_str(&self) -> str { int::to_str(self) } }
impl to_str for str { fn to_str(&self) -> str { self } }
...
132.to_str();
"hello".to_str();


C>>Я серьёзно. Единственная реальная отсутствующая фича — это исключения. Всё остальное есть, даже RAII в виде расширений языка.

DE>Ну это несерьёзно.
Что именно?

DE>Да и рукопашные "виртуальные функции", например, ужасны.

Чем ужасны? Ну кроме жуткого синтаксиса в С для указателей на функции.
Sapienti sat!
Re[33]: Язык D - действительно красота и эффективность в одном ф
От: Cyberax Марс  
Дата: 27.04.14 07:28
Оценка: +1
Здравствуйте, netch80, Вы писали:

C>>Я серьёзно. Единственная реальная отсутствующая фича — это исключения.

N>man longjmp
Это не исключения, так как longjmp никак не связан с деструкторами. Понятно, что на его основе можно сделать SJLJ-исключения, но вот уже DWARF-овые не получится в чистом С.
Sapienti sat!
Re[34]: Язык D - действительно красота и эффективность в одном ф
От: DarkEld3r  
Дата: 27.04.14 11:22
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>С++-ные шаблоны — не нужны. В Rust'е вместо них нормальные генерики и макросы. К примеру, printf! в Rust реализован в виде макроса и проверяет корректность параметров во время компиляции.

С таким же успехом, могу заявить, что "кастрированные генерики не годятся как замена нормальным темплейтам". Типобезопасный принтф в С++ тоже возможен, не говоря уже о том, что компиляторы уже научились форматную строку и обычного принтфа проверять. Нормальные макросы — это отлично, но они темплейтам не замена.
Единственный минус темплейтов — длинные и "сложные" сообщения об ошибках. Зато по возможностям, особенно при написании обобщённого кода, они выигрывают.

C>Исключения есть — в виде fail! и Any. Они по своему дизайну могут быть отловлены на границе задачи. Кстати говоря, в язык встроена и модель супервизора задач из Erlang'а.

Вот именно, что "на границе задачи". То есть при необходимости "просто" обработать исключение нельзя.
Насчёт "Any" — можно ссылку на подробное описание?

C>Чистая перегрузка функций — тоже не нужна.

Это не конструктивно.

C>Есть её аналог с помощью impl'ов:

А можно функции типа min/max так изобразить?

Тут меня ещё смущает, что в С++ нормальные макросы когда-то, возможно, и появятся. Вместе с модулями и т.д. А вот в Раст, к примеру, перегрузку функций вряд ли добавят. Именно потому что кто-то решил, что она "не нужна".

DE>>Ну это несерьёзно.

C>Что именно?
Не переносимо.

C>Чем ужасны? Ну кроме жуткого синтаксиса в С для указателей на функции.

По моему, очевидно, что встроенные в язык в 99% случаев удобнее, чем наколеночные реализации. Последние ещё и выглядеть сильно по разному могут, затрудняя чтение кода.
Re[35]: Язык D - действительно красота и эффективность в одном ф
От: Cyberax Марс  
Дата: 27.04.14 15:13
Оценка:
Здравствуйте, DarkEld3r, Вы писали:

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

Тут вопрос — а нафиг нужны темплейты в стиле C++? Необходимость generic'ов абсолютно понятна, а вот необходимость темплейтов с частичной типизацией уже не очень.

DE>Типобезопасный принтф в С++ тоже возможен, не говоря уже о том, что компиляторы уже научились форматную строку и обычного принтфа проверять.

А можно его увидеть?

DE>Нормальные макросы — это отлично, но они темплейтам не замена.

Ну читаем. Что мы видим:
1) Пример с факториалом — в Расте делается с помощью макроса. Намного прямее, чем в С++.

2) Генерики в Расте используют аналог концептов, которые в С++ так и ниасилили. Из-за этого, в частности, ошибки выводятся в месте инстанцирования генерика, а не "во глубине сибирских руд" на пятой странице листинга ошибки.

3) Вычисления во времени компиляции. Раст разрывает "убогий недоязычок" (tm) С++ на мелкие куски. Вот тут пример предкомпиляции регексов: http://blog.burntsushi.net/rust-regex-syntax-extensions Можно увидеть то же самое для С++?

DE>Единственный минус темплейтов — длинные и "сложные" сообщения об ошибках. Зато по возможностям, особенно при написании обобщённого кода, они выигрывают.

Не выигрывают даже близко. И если что, я добавлял свои расширения в Boost.Spirit и Phoenix.

C>>Исключения есть — в виде fail! и Any. Они по своему дизайну могут быть отловлены на границе задачи. Кстати говоря, в язык встроена и модель супервизора задач из Erlang'а.

DE>Вот именно, что "на границе задачи". То есть при необходимости "просто" обработать исключение нельзя.
Задачи в Расте — очень легковесные. Ну и если очень хочется, то есть обёртка try!, которая внутри создаёт задачу.

DE>Насчёт "Any" — можно ссылку на подробное описание?

Вот тут: http://static.rust-lang.org/doc/master/std/any/index.html

На практике, просто делается fail!(<что-то-там>), а на принимающей стороне по нему делается match.

C>>Чистая перегрузка функций — тоже не нужна.

DE>Это не конструктивно.
Какие плюсы от перегрузки функций?

C>>Есть её аналог с помощью impl'ов:

DE>А можно функции типа min/max так изобразить?
Можно.

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

А зачем она нужна? Ну вот реально, какие use-case'ы?

Rust во многом содран с OCaml'а, где перегрузки тоже не было отродясь. И таки прекрасно всё и без неё работает, во вполне реальных программах.

DE>>>Ну это несерьёзно.

C>>Что именно?
DE>Не переносимо.
Что непереносимо? GNOME — вон весь написан в таком стиле, и ничего.

C>>Чем ужасны? Ну кроме жуткого синтаксиса в С для указателей на функции.

DE>По моему, очевидно, что встроенные в язык в 99% случаев удобнее, чем наколеночные реализации. Последние ещё и выглядеть сильно по разному могут, затрудняя чтение кода.
Линксовый VFS с указателями на функции, например, читается сильно лучше, чем 100500 интерфейсов из одной функции.
Sapienti sat!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.