Здравствуйте, samius, Вы писали:
S>А что делать с побочными эффектами, которые могут иметь место в процессе выполнения?
Так ведь у ф-ий нет побочных эффектов по определению ф-ции. А вводить различия между ф-ями и процедурами, (на уровне системы типов, например) это более полезное подразделение. Оно не только для определения того, что можно в компайл-тайм вычислить пригодится.
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
'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
Скажу чего мне нехватает
Покритикуйте или расскажите чего нехватает вам. Ссылки на языки в которых подобная проблема решена будут интересны, но хотелось бы не сильно далеко уходить от мира c++
Мне не так уж и много надо.
1. break [what]; continue [what];
возможность делать break(и continue) из любого скоупа, а не только цикла. Плюс параметризировать.
число говорит сколько скоупов оборвать, а назавание цыкла говорит какой первый встречающийся цикл оборвать. Через запятую перечисление последовательных обрывов.
например если написанно:
Скрытый текст
{
while(true)
{
break 2; // это ведет
}
} // сюдаwhile (true)
{
{
break while; // это ведет
}
} // сюдаdo
{
{
while (true)
{
for (;;)
{
break while, 1; // это ведет
}
}
} // сюда
} while(true);
{
while(true)
{
continue 2; // это ведет
}
// сюда
}
while (true)
{
{
continue while; // это ведет
}
// сюда
}
do
{
{
while (true)
{
for (;;)
{
continue while, 1; // это ведет
}
}
// сюда
}
} while(true);
2. ключевое слово loop (или любое другое имеющее такую же функциональность)
loop auto my_scope_var = get_the_var();
loop string my_scope_string;
Строка инициализации переменной выполняется один раз после входа в loop scope, а деструктор вызывается при выходе из него.
примеры:
Скрытый текст
string s;
ifstream fin("1.txt");
while (getline(fin, s)) // читаем по строкам
{
loop istringstream iss;
loop string s2; // эти переменные объявленны тут только для читабельности,
// их реальное место за пределами цикла, но при этом нет никакой причины чтобы они были бы там видны...
iss.str(s);
while (iss >> s2) // читаем прочитанную строку по словам
{
if (/*some condition*/)
{
continue while, while; // :) goto nextLine;
}
//...
}
nextLine:
}
for (;;)
{
if (not time to begin changes)
continue;
loop lock_t lock(m_mutex);
// допустим что все изменения в данном цикле должные делаться под одним замком,
// однако нет никакой причины закрывать его заранее
}
Здравствуйте, Caracrist, Вы писали:
ZS>> continue while, n; // error not a compile time expresion
Ваш пост огорчает любителей извратиться
Зачем себя искусственно ограничивать?
Здравствуйте, Caracrist, Вы писали:
C>Скажу чего мне нехватает
как немного надо человеку для счастья
C>1. break [what]; continue [what]; C>возможность делать break(и continue) из любого скоупа, а не только цикла. Плюс параметризировать. C>число говорит сколько скоупов оборвать,
лучше — на сколько строк вниз переместиться. нет, лучше машинных инструкций... да, это тяжело. но зато как интересно будет!
C>2. ключевое слово loop (или любое другое имеющее такую же функциональность) C>примеры:
[ccode]
{string s;
string s2;
while (getline(fin, s)) // читаем по строкам
....
}}
[/code]
C>3. goto case; как в C#
Здравствуйте, Caracrist, Вы писали:
C>Скажу чего мне нехватает C>Покритикуйте или расскажите чего нехватает вам. Ссылки на языки в которых подобная проблема решена будут интересны, но хотелось бы не сильно далеко уходить от мира c++
Мне хотя бы constexpr и возможность манипулировать строками (массивами) во времени компиляции.
const int hash_abc = hash("abc"); // compile time :)
Здравствуйте, Mazay, Вы писали:
M>>>Нормальные сообщения об ошибках (полагаю, что с заменой шаблонов на макросы уйдут в прошлое и нечитаемые развертки стэка инстацирования).
BZ>>вообще верит в макросы может только человек которыми ими никогда не пользовался. представь себе хотя бы отладку кода, используюшего макросы....
M>Они же в Немерле как-то отлаживаются. Там какие-то хитрые макросы, не такие как в сишном препроцессоре.
и в C++ как-то отлаживаются шаблоны C++ — это как раз специализированные макросы, которые лишены хотя бы части их недостатков. с макросами будет только хуже. любые идеи универсальных препроцессоров упираются в диагностику и отладку
Здравствуйте, BulatZiganshin, Вы писали:
BZ>Здравствуйте, Mazay, Вы писали:
M>>>>Нормальные сообщения об ошибках (полагаю, что с заменой шаблонов на макросы уйдут в прошлое и нечитаемые развертки стэка инстацирования).
BZ>>>вообще верит в макросы может только человек которыми ими никогда не пользовался. представь себе хотя бы отладку кода, используюшего макросы....
M>>Они же в Немерле как-то отлаживаются. Там какие-то хитрые макросы, не такие как в сишном препроцессоре.
BZ>и в C++ как-то отлаживаются шаблоны C++ — это как раз специализированные макросы, которые лишены хотя бы части их недостатков. с макросами будет только хуже. любые идеи универсальных препроцессоров упираются в диагностику и отладку
Там, ЕМНИП, не простой текстовый препроцессор, а полноценная компайл-тайм логика. в D есть отголосок — компайл-тайм функции.
Вообще же мне не совсем понятно, в какую сторону несёт новый стандарт — вводят какой-то зоопарк сказочных конструкций (как пример — альтернативный typedef и новый формат декларации функций), но при этом выбрасывают такие вещи как концепты. О стандарте на ABI и полноценных модулях остаётся только мечтать.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>для того, чтобы у тебя в шаблонах/макросах не появлялось многоэтажных сообщений об ошибках, нужна типизация. те самые концепты. без них что угодно можно подставить куда попало
Ну это-то понятно. Ему и нужен не текстовый препроцессор, а некий аналог Template Haskell.
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
'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
Здравствуйте, _nn_, Вы писали:
J>>В смысле? Тут надо in_place_factory юзать (если я правильно помню название)
__>Вопрос как надо юзать?
если я правильно помню (под рукой нет документации), у boost::optional просто есть оператор присваивания, который принимает фабрику. Так что в момент присваивания она все там и создаст.
Поправь, если не так.
__>noncopyable в boost::optional
BulatZiganshin,
МС>>Там, ЕМНИП, не простой текстовый препроцессор, а полноценная компайл-тайм логика. в D есть отголосок — компайл-тайм функции.
BZ>новое — это хорошо разрекламированное старое синтаксические макросы хорошо известны с 60-х, как и их недостатки
BZ>для того, чтобы у тебя в шаблонах/макросах не появлялось многоэтажных сообщений об ошибках, нужна типизация. те самые концепты. без них что угодно можно подставить куда попало
Правильно. Но можно без концептов — просто нормальную систему типов, которая бы охватывала не только программы, но и метапрограммы. Например, MetaOcaml хорош тем, что если генератор прошёл проверку типов (well typed), то и сгенерированный код тоже будет проходить проверку типов (тоже будет well typed).
Если речь идёт об отладке сгенерированного кода, то нужен аналог macroexpand-1 (которого кстати нет в C++ и не придвидится). А ходить по шагам в макросе в общем случае (мне кажется) не получится, поскольку самих шагов нет: ведь макрос может строить не только тела функций, а например типы, сами функции вместе с сигнатурами, и вещи типа infixl/infixr. То есть декларативный код, который сгенерирован макросом, вряд ли может быть проверен пошагово, даже если это супер-пупер дебаггер.
Плюс, проблемы появляются, когда метапрограммы перестают быть чистыми функциями, то есть начинают "мараться" об IO, или кидать исключения. В этом случае результат раскрытия макроса начинает походить на сумасшедший микс джокер+покер+нарды с шахматами впридачу.
Однако в последнее время здесь (то есть в исследовании свойств метапрограмм с побочными эффектами) наметился прогресс: Shifting the Stage: Staging with Delimited Control, работа 2009 года. (Олег Киселёв форева).
Тем не менее, несмотря на все сложности с макросами, я не считаю их "слишком большой пушкой"(тм) и лично мне они бы пригодились в ряде мест.
Здравствуйте, Caracrist, Вы писали:
C>1. break [what]; continue [what];
Добавлю тоже предложение по поводу брэйков. Чаще всего break используется для простого выхода из середины цикла, а этот случай легко было бы порешить минимальным изменением грамматики (и семантики), которое сделало бы использование break в этом случае ненужным. А именно меняем в грамматике
Здравствуйте, Caracrist, Вы писали:
C>Мне не так уж и много надо.
C>1. break [what]; continue [what]; C>возможность делать break(и continue) из любого скоупа, а не только цикла. Плюс параметризировать. C>число говорит сколько скоупов оборвать, а назавание цыкла говорит какой первый встречающийся цикл оборвать. Через запятую перечисление последовательных обрывов.
лишние связи в программе. Добавить новый скоуп будет просто нельзя без тотальной проверки внутренностей на предмет таких вот "счетчиков".
C>например если написанно: C>
C>{
C> while(true)
C> {
C> break 2; // это ведет
C> }
C>} // сюда
C>
добавим один if: C>
C>{
C> if (....)
C> {
C> while(true)
C> {
C> break 2; // это ведет
C> }
C> } // сюда
C> }
C>
совсем не то, что ожидалось, не так ли? А если еще и скобок внутри if не поставить — вообще сказка, не так ли?
C>
C>while (true)
C>{
C> {
C> break while; // это ведет
C> }
C>} // сюда
C>
а если так: C>
C>while (true)
C>{
C> while (....)
C> {
C> break while; // это ведет -
C> }// сюда
C>}
C>
то как попасть на метку "сюда?" (выход из двух одинаковых циклов)
и как безболезненно сменить тип цикла while на for без полного пересмотра и правки кода внутри?
C>3. goto case; как в C#
не надо
Здравствуйте, Ligen, Вы писали:
L>Сразу скажу что мне не хватает странного L>Точнее не то чтобы не хватает, но я бы использовал в паре мест такую фичу: было бы круто делать switch на enum, который выдавал бы ошибку компиляции, если case'ами покрыты не все значения enum. Какой нибудь strict_switch.
Я наверно уже всех подзадолбал но в D есть:
enum MyEnum_type { One, Two, Three };
void main()
{
MyEnum_type value;
final switch(value)
{
case MyEnum_type.One:
//.... break;
case MyEnum_type.Two:
//....
}
}
Не скомпилируется с такой ошибкой:
fghhghj.d(8): Error: enum member Three not represented in final switch
Здравствуйте, Mazay, Вы писали:
M>Заменить шаблоны макросами аля Немерл. Остальной сахар реализовать через них.
Поймите правильно, я не предлагаю использовать именно макросы Немерла. Я говорю, что полезной была бы возможность полноценной кастомизации синтаксиса языка на базе C с классами. Остальное будет реализовано в виде библиотек типа буста и stl. В C++ сообществе уже есть успешный опыт по кастомизации синтаксиса с помощью перегрузки операторов, шаблонов. Взгляните на BOOST_FOREACH, SCOPE_EXIT, boost::lambda. Если бы у разработчиков были более удобные инструменты , то эти улучшения было бы также удобно использовать как встроенные операторы. Какими будут эти средства — вопрос обсуждаемый, но макросы Немерла как минимум стоит рассмотреть.
Здравствуйте, Мишень-сан, Вы писали:
МС>Здравствуйте, Мишень-сан, Вы писали:
МС>Кстати, наткнулся как-то на интересную идею (где-то на форуме Nemerle кажется): расширить семантику типа void, в частн. позволить единственное значение этого типа — например (). И соответственно позволить конструкции вида return (); в функциях возвращающих void. Это позволило бы не писать для некоторых случаев делегирования в шаблонах отдельную специализацию.
C>Здравствуйте, dilettante, Вы писали:
D>>Здравствуйте, Caracrist, Вы писали:
C>>> или расскажите чего нехватает вам.
D>>1. Нормальных локальных функций. C>вот так ? C>
C>int main()
C>{
C> for (int i = 0; i < 4; i++)
C> {
C> auto eq = [&i]-> bool (int x)
C> {
C> //...
C> };
C> if (eq(2))
C> {
C> }
C> }
C>}
C>
C>)
D>>2. Блоки-как-выражения. C>вот так ? C>
C>int main()
C>{
C> for (int i = 0; i < 4; i++)
C> {
C> auto eq = [&]-> bool (int x)
C> {
C> //...
C> }(2);
C> }
C>}
C>
C>)
Это я выше по тексту назвал зоопарком сказочных конструкций. Вы не читали, чем товарищи из комитета объясняют извращённый синтаксис с выносом return type в хвост декларации? Якобы тем, что их новенький decltype не сможет, бедняжка, подождать, пока будет прочитан остаток заголовка функции. Это, извиняюсь, всё равно, что ввести обратную польскую запись в плюсы потому, что компилятору легче её разбирать. Не спорю, проще. Но мне от этого ни холодно, ни жарко.
Непосредственно по Вашему сообщению. В C# лямбда выглядит как x => y, в python как lambda x: y. А в С++0x — [&](int x) -> int { return y; }; Некоторый оверхед, не находите?
Здравствуйте, Caracrist, Вы писали:
C>Скажу чего мне нехватает C>Покритикуйте или расскажите чего нехватает вам. Ссылки на языки в которых подобная проблема решена будут интересны, но хотелось бы не сильно далеко уходить от мира c++
Думаю, что предложения ухудшают читабельность кода. Я бы не рекомендовал их использовать в своей команде. Мне видится более благородная цель: придумать, что убрать из C++ для его упрощения, при этом не (сильно) ломая совместимость с существующим кодом.
Интересно было бы иметь аналогов классов из Haskell. А ещё лучше, встроенный в компилятор детектор быдлокода: увидел быдлокод — выдал ошибку
Здравствуйте, Caracrist, Вы писали:
C>Скажу чего мне нехватает C>Покритикуйте или расскажите чего нехватает вам. Ссылки на языки в которых подобная проблема решена будут интересны, но хотелось бы не сильно далеко уходить от мира c++
Из него выкидывать надо, а не добавлять
C>Мне не так уж и много надо.
C>1. break [what]; continue [what]; C>возможность делать break(и continue) из любого скоупа, а не только цикла. Плюс параметризировать. C>число говорит сколько скоупов оборвать, а назавание цыкла говорит какой первый встречающийся цикл оборвать. Через запятую перечисление последовательных обрывов.
Здравствуйте, BulatZiganshin, Вы писали:
VD>>Звучит все складно, как в пвсевдо-научных статьях, но с практиков не коррелирует.
BZ>ты внимательно прочёл?
Вполне.
BZ>я сказал, что 1) нужна проверка типов. которой нет в шаблонах, а не Немерле.
Твоя цитата:
у тебя в шаблонах/макросах не появлялось многоэтажных сообщений об ошибках, нужна типизация
?
BZ>2) что помимо проверки типов нужно много других вещей, которые опять же нужно программировать. к примеру поддержка номеров строк для отладчика
При программировании вообще нужно много программировать, но это же не причина не заниматься программированием?
Если серьезно, то конечно проблемы есть и создание макросов далеко не самое простое занятие. Но дела обстаят не так печально как тебе кажется. Те же номера строк (точнее местоположения) автоматом расставляются для кусков кода которые передаются в качестве параметров макросов, так что вручную их устанавливать приходится крайне редко.
Главное же, что макры (особенно если они хорошо спроектированы и реализованы) позволяют частенько воистину творить чудеса. Так что сложности при разработке макросов с лихвой окупаются тем что они позволяют делать.
Ну, а разговоры о сложности отладки кода использующего макросы — это не более чем досужие домыслы. Отлаженный макрос ничем не отличается от отлаженных фич языка. Да по сути макрос — это и есть часть языка. Разница только в том, что это не обязательная часть языка (ее можно не использовать), и в том, что ты сам можешь написать эту часть.
В общем, те кто провали на практике в 100% случаев расставались с пессимизмом по этому вопросу. Поверь на слово, или проверь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, jazzer, Вы писали:
BZ>>вообще верит в макросы может только человек которыми ими никогда не пользовался. представь себе хотя бы отладку кода, используюшего макросы....
J>Вообще верить в безумную сложность отладки макросов может только человек, которыми ими никогда не пользовался.
Здравствуйте, jamesq, Вы писали:
J>Он не скомпилируется, т.к. поле tt обязательно требует инициализации. J>Visual C++ пишет ошибку: error C2512: 'FieldType' : no appropriate default constructor available
Он не инициализации требует, а требует чтобы был конструктор по умолчанию, который вы сами предварительно скрыли.
Тут ничего нет обязательного.
Здравствуйте, jamesq, Вы писали:
J>Недостатки описанных подходов: J>В первых двух вариантах, память для вынесенного по указателю поля объекта оказывается в стороне от участка J>памяти с самим объектом, что при обращении к полю создает проблемы с кэшированием. Дополнительно, появляются J>проблемы с фрагментацией памяти. Понятно, что лучше один большой учаток памяти на объект и поле в нем, чем два J>отдельных.
J>Во всех вариантах, которые мне приходят в голову, есть еще один недостаток — весь доступ к вынесенному полю J>идет через указатель.
Boost.Optional спасет отца русской демократии. У него нет ни одной из описанных проблем.
Здравствуйте, Caracrist, Вы писали:
C>Скажу чего мне нехватает C>Покритикуйте или расскажите чего нехватает вам. Ссылки на языки в которых подобная проблема решена будут интересны, но хотелось бы не сильно далеко уходить от мира c++
Сразу скажу что мне не хватает странного
Точнее не то чтобы не хватает, но я бы использовал в паре мест такую фичу: было бы круто делать switch на enum, который выдавал бы ошибку компиляции, если case'ами покрыты не все значения enum. Какой нибудь strict_switch.
typedef enum {One, Two, Three} MyEnum_type;
MyEnum_type value;
strict_switch(value)
{
case One:
//.... break;
case Two:
//....
} // <-------- error, case Three not handled
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, jazzer, Вы писали:
J>>Так что иметь концепты, безусловно, было бы здорово, но и без них нормально живется, если приложить к тому усилия.
FR>Все-таки надо было их добавить, хотя бы в урезанном виде, в том же D тоже не осилили всего того, что предлагалось в C++0x, FR>но в результате все-равно очень мощная и симпатичная (практически развитие в сторону паттерн матчинга для шаблонов) FR>штучка получилась:
FR>http://www.digitalmars.com/d/2.0/concepts.html FR>http://www.digitalmars.com/d/2.0/cpp0x.html#concepts
Так может, и добавят в результате.
Эту же версию зарубили из-за того, что она неудобна в использовании.
Может, примут нечто похожее на D.
В конце концов, Уолтер Брайт — член плюсового комитета...
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, _nn_, Вы писали:
__>>Мне хотя бы constexpr и возможность манипулировать строками (массивами) во времени компиляции.
__>>
__>>const int hash_abc = hash("abc"); // compile time :)
__>>
Когда С++ компиляторы научатся собирать всю информацию о типе — имя, функции и т.д.,
в том числе у инстанцированных шаблонов?
И чтобы функцию-член можно было вызвать в рантайме передав строку с ее названием.
Здравствуйте, Caracrist, Вы писали:
C>Скажу чего мне нехватает C>Покритикуйте или расскажите чего нехватает вам. Ссылки на языки в которых подобная проблема решена будут интересны, но хотелось бы не сильно далеко уходить от мира c++
Старый (мега)топик по поводу — "Выйти из двух циклов сразу"
Здравствуйте, bnk, Вы писали:
bnk>Здравствуйте, Caracrist, Вы писали:
C>>Скажу чего мне нехватает C>>Покритикуйте или расскажите чего нехватает вам. Ссылки на языки в которых подобная проблема решена будут интересны, но хотелось бы не сильно далеко уходить от мира c++
bnk>Старый (мега)топик по поводу — "Выйти из двух циклов сразу"
Здравствуйте, Мишень-сан, Вы писали:
МС>Здравствуйте, BulatZiganshin, Вы писали:
МС>Я вместо этих извратов с break-continue предпочёл бы нормальные локальные функции.
а выход через несколько исключениями реализовать, и все необходимое by-ref передавать?
вся идея локальных скоупов в конструкторах/деструкторах, break/continue/loop/if-else и visibility других локальных переменных, можно от них отказаться, но по моему это не правильный путь.
Здравствуйте, Caracrist, Вы писали:
C>Скажу чего мне нехватает C>Покритикуйте или расскажите чего нехватает вам. Ссылки на языки в которых подобная проблема решена будут интересны, но хотелось бы не сильно далеко уходить от мира c++
Заменить шаблоны макросами аля Немерл. Остальной сахар реализовать через них.
Нормальные сообщения об ошибках (полагаю, что с заменой шаблонов на макросы уйдут в прошлое и нечитаемые развертки стэка инстацирования).
Стандарт на объектные файлы.
Здравствуйте, Mazay, Вы писали:
M>Нормальные сообщения об ошибках (полагаю, что с заменой шаблонов на макросы уйдут в прошлое и нечитаемые развертки стэка инстацирования).
и чем же они заменятся?
вообще верит в макросы может только человек которыми ими никогда не пользовался. представь себе хотя бы отладку кода, используюшего макросы....
Здравствуйте, BulatZiganshin, Вы писали:
M>>Нормальные сообщения об ошибках (полагаю, что с заменой шаблонов на макросы уйдут в прошлое и нечитаемые развертки стэка инстацирования).
BZ>и чем же они заменятся?
BZ>вообще верит в макросы может только человек которыми ими никогда не пользовался. представь себе хотя бы отладку кода, используюшего макросы....
Позовите Ви... Влада!
Они же в Немерле как-то отлаживаются. Там какие-то хитрые макросы, не такие как в сишном препроцессоре.
Кстати, наткнулся как-то на интересную идею (где-то на форуме Nemerle кажется): расширить семантику типа void, в частн. позволить единственное значение этого типа — например (). И соответственно позволить конструкции вида return (); в функциях возвращающих void. Это позволило бы не писать для некоторых случаев делегирования в шаблонах отдельную специализацию.
Здравствуйте, Мишень-сан, Вы писали:
BZ>>и в C++ как-то отлаживаются шаблоны C++ — это как раз специализированные макросы, которые лишены хотя бы части их недостатков. с макросами будет только хуже. любые идеи универсальных препроцессоров упираются в диагностику и отладку
МС>Там, ЕМНИП, не простой текстовый препроцессор, а полноценная компайл-тайм логика. в D есть отголосок — компайл-тайм функции.
новое — это хорошо разрекламированное старое синтаксические макросы хорошо известны с 60-х, как и их недостатки
для того, чтобы у тебя в шаблонах/макросах не появлялось многоэтажных сообщений об ошибках, нужна типизация. те самые концепты. без них что угодно можно подставить куда попало
для отладки нужно дать отладчику инофрмацию о том какая строка сейчас выполняется и какие у нас есть переменные. а откуда она возьмётся, если текст подвергся обработке препроцессором? и получаешь ты то же самое, как при отладке в высокоуровневой программы на уровне ассемблера
современная реализация ЯП — это не только трансляция его в низкоуровневый код. это ещё куча средств (рефакторинга, диагностики, навигации, отладки, UI-дизайна и т.д.), облегчающая тебе работу. макросы, создаваемые пользователями, либо должны обеспечивать все те же уровни обработки (что уже становится сравнимо с созданием custom-компилятора), либо они будут оставаться чужеродным фрагментом на теле
Здравствуйте, Klapaucius, Вы писали:
BZ>>для того, чтобы у тебя в шаблонах/макросах не появлялось многоэтажных сообщений об ошибках, нужна типизация. те самые концепты. без них что угодно можно подставить куда попало
K>Ну это-то понятно. Ему и нужен не текстовый препроцессор, а некий аналог Template Haskell.
настолько понятно, что ты ошибаешься
есть три типа макросов: простая текстовая подстановка а-ля #define. синтаксические макросы а-ля TH и C++ templates. и наконец "семантические макросы" а-ля C++ templates with concepts
фишка в том, что TH прверяет типы аргументов только на уровне "здесь должен быть какой-нибудь тип". это откладывает проверки до места фактического использования, получается compile-time dynamic typing. concepts, afair, реализовывали duck typing. а наиболее правильным я считаю, конечно же, static typing — в виде иерархий интерфейсов
и всё это решает только одну проблему макросов, а их множество...
Здравствуйте, BulatZiganshin, Вы писали:
BZ>и всё это решает только одну проблему макросов, а их множество...
Макросы, немакросы. В любом случае очевидно, что необходим более мощный механизм управления компиляцией. Навешивание синтаксических свистоперделок не выход.
Здравствуйте, Caracrist, Вы писали:
C>1. break [what]; continue [what];
Очень редко есть такая необходимость при современном подходе писать множество мелких функций, а тем более при наличии lambda expression.
C>2. ключевое слово loop (или любое другое имеющее такую же функциональность)
Не нужно, уже есть {}
C>3. goto case; как в C#
Не нужно. switch практически используется очень редко.
Зато есть лишее — const. Точнее, не хватет иммутабельности по умолчанию. Но это получится уже другой язык...
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, Mazay, Вы писали:
M>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
Не думаю, что большинству программистов нафик впалось писать для компилятора. Просто если некие сложные расчёты будут проделаны компилятором один раз, при каждом запуске можно будет на халяву пользоваться готовым результатом, а не считать всё заново.
__>>const int hash_abc = hash("abc"); // compile time :)
__>>
M>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
Это, скорее, свидетельство того, что было бы желательно, если бы компилятор вычислял все, что можно вычислить на этапе компиляции. Т.е. если все данные для ф-и hash известны на этапе компиляции, как в данном случае — она на этом этапе и вычисляется. Если данные не известны — на этапе выполнения. А в чем удобство вводить разные сорта ф-ий для этапа компиляции и выполнения не понятно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
'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
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, Mazay, Вы писали:
M>>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
K>Это, скорее, свидетельство того, что было бы желательно, если бы компилятор вычислял все, что можно вычислить на этапе компиляции. Т.е. если все данные для ф-и hash известны на этапе компиляции, как в данном случае — она на этом этапе и вычисляется. Если данные не известны — на этапе выполнения.
А что делать с побочными эффектами, которые могут иметь место в процессе выполнения?
Здравствуйте, BulatZiganshin, Вы писали:
BZ>я вроде описал в чём он заключается
Где описали?
И где еще может проверяться макрос, если не в месте применения? — там ведь будет AST на входе в большинстве случаев. Какими контрактами это AST описывать и, главное, зачем?
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
'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
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, Mazay, Вы писали:
__>>>
__>>>const int hash_abc = hash("abc"); // compile time :)
__>>>
M>>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
K>Это, скорее, свидетельство того, что было бы желательно, если бы компилятор вычислял все, что можно вычислить на этапе компиляции. Т.е. если все данные для ф-и hash известны на этапе компиляции, как в данном случае — она на этом этапе и вычисляется. Если данные не известны — на этапе выполнения. А в чем удобство вводить разные сорта ф-ий для этапа компиляции и выполнения не понятно.
У компиляторов не хватает на это мозгов. Приходится помогать ручками.
Здравствуйте, Мишень-сан, Вы писали:
МС>Здравствуйте, Mazay, Вы писали:
M>>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
МС>Не думаю, что большинству программистов нафик впалось писать для компилятора. Просто если некие сложные расчёты будут проделаны компилятором один раз, при каждом запуске можно будет на халяву пользоваться готовым результатом, а не считать всё заново.
Большинству программистов нафик не брякало использовать boost::mpl и прочую шаблонную магия. Но библиотеками написанными с их помощью пользуются многие с большим удовольствием.
Здравствуйте, dilettante, Вы писали:
D>Здравствуйте, Caracrist, Вы писали:
C>> или расскажите чего нехватает вам.
D>1. Нормальных локальных функций.
вот так ?
int main()
{
for (int i = 0; i < 4; i++)
{
auto eq = [&i]-> bool (int x)
{
//...
};
if (eq(2))
{
}
}
}
D>2. Блоки-как-выражения.
вот так ?
int main()
{
for (int i = 0; i < 4; i++)
{
auto eq = [&]-> bool (int x)
{
//...
}(2);
}
}
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, Mazay, Вы писали:
__>>>
__>>>const int hash_abc = hash("abc"); // compile time :)
__>>>
M>>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
K>Это, скорее, свидетельство того, что было бы желательно, если бы компилятор вычислял все, что можно вычислить на этапе компиляции. Т.е. если все данные для ф-и hash известны на этапе компиляции, как в данном случае — она на этом этапе и вычисляется. Если данные не известны — на этапе выполнения. А в чем удобство вводить разные сорта ф-ий для этапа компиляции и выполнения не понятно.
Функции этапа компиляции могут применяться для того, чтобы управлять генерацией машинного кода и курочить AST. С их помощью можно научить компилятор новым синтаксическим конструкциям, навешать любую метаинформацию, ввести атрибуты для всего, что только можно — полей, методов, классов, блоков кода, переменных и функций и т. д. Сделать тот же выход из двух циклов.
string s;
ifstream fin("1.txt");
{/*loop*/istringstream iss;
/*loop*/ string s2; // эти переменные объявленны тут только для читабельности,
// их реальное место за пределами цикла, но при этом нет никакой причины чтобы они были бы там видны...while (getline(fin, s)) // читаем по строкам
{
iss.str(s);
while (iss >> s2) // читаем прочитанную строку по словам
{
if (/*some condition*/)
{
continue while, while; // :) goto nextLine;
}
//...
}
nextLine:
}
}
Пример с локом переписать могу вот таким способом, хотя понимаю, что это возможно не то (и не понимаю исходный пример)
if ( ... )
{
loop lock_t lock(m_mutex);
for (;;)
{
if (not time to begin changes)
continue;
}
}
Было
for (;;)
{
if (not time to begin changes)
continue;
loop lock_t lock(m_mutex);
// допустим что все изменения в данном цикле должные делаться под одним замком,
// однако нет никакой причины закрывать его заранее - и нельзя, т.к. иначе изменения будут под разными замками// а какие причины держать лок дольше чем надо???
// если условия взятия лока не должны быть защищены этим локом,
// их можно безопасно вынести за цикл по тем же самым причинам
}
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, Мишень-сан, Вы писали:
M>>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
МС>Не думаю, что большинству программистов нафик впалось писать для компилятора. Просто если некие сложные расчёты будут проделаны компилятором один раз, при каждом запуске можно будет на халяву пользоваться готовым результатом, а не считать всё заново.
Тут еще вопрос, что при промышленной разработке дешевле Компилируется-то оно тоже по сто раз на дню...
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Тот кто сидит в пруду, Вы писали:
ТКС>Здравствуйте, Мишень-сан, Вы писали:
M>>>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
МС>>Не думаю, что большинству программистов нафик впалось писать для компилятора. Просто если некие сложные расчёты будут проделаны компилятором один раз, при каждом запуске можно будет на халяву пользоваться готовым результатом, а не считать всё заново.
ТКС>Тут еще вопрос, что при промышленной разработке дешевле Компилируется-то оно тоже по сто раз на дню...
для этого придумали precompiled header и частичную компиляцию
Здравствуйте, Caracrist, Вы писали:
M>>>>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
МС>>>Не думаю, что большинству программистов нафик впалось писать для компилятора. Просто если некие сложные расчёты будут проделаны компилятором один раз, при каждом запуске можно будет на халяву пользоваться готовым результатом, а не считать всё заново.
ТКС>>Тут еще вопрос, что при промышленной разработке дешевле Компилируется-то оно тоже по сто раз на дню...
C>для этого придумали precompiled header и частичную компиляцию
И как, много народа метавычисления в pch пихает?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Caracrist, Вы писали:
C>а выход через несколько исключениями реализовать, и все необходимое by-ref передавать?
Выход через несколько — обычный return, "все необходимое" предается как лексическое замыкание.
Здравствуйте, Мишень-сан, Вы писали:
МС>Это я выше по тексту назвал зоопарком сказочных конструкций. Вы не читали, чем товарищи из комитета объясняют извращённый синтаксис с выносом return type в хвост декларации? Якобы тем, что их новенький decltype не сможет, бедняжка, подождать, пока будет прочитан остаток заголовка функции. Это, извиняюсь, всё равно, что ввести обратную польскую запись в плюсы потому, что компилятору легче её разбирать. Не спорю, проще. Но мне от этого ни холодно, ни жарко. МС>Непосредственно по Вашему сообщению. В C# лямбда выглядит как x => y, в python как lambda x: y. А в С++0x — [&](int x) -> int { return y; }; Некоторый оверхед, не находите?
Можно улучшить код, дать компилятору самому захватить нужные переменные и самому вывести тип.
Оверхед тут возникает от return и от невозможности вывести типы аргументов. А могли бы доделать..
int main()
{
for (int i = 0; i < 4; i++)
{
auto eq = [&] (int x)
{
return i == x;
};
if (eq(2))
{
}
}
}
int main()
{
for (int i = 0; i < 4; i++)
{
auto eq = [&] (int x)
{
return i == x;
}(2);
}
}
Здравствуйте, Mazay, Вы писали:
M>Здравствуйте, _nn_, Вы писали:
__>>Мне хотя бы constexpr и возможность манипулировать строками (массивами) во времени компиляции.
__>>
__>>const int hash_abc = hash("abc"); // compile time :)
__>>
M>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
Если бы были средства для работы с рантаймом как в .Net то можно было бы это обойти сгенерировав код во время выполнения, но в С++ этой возможности нет, а есть возможность генерировать код во время компиляции.
Всего-то нужно немного улучшить текущее положение дел в С++.
P.S.
Мега макросы это хорошо, но лучше улучшать понемногу и пользоваться, чем ждать супер улучшений 12 лет ))
Здравствуйте, BulatZiganshin, Вы писали:
BZ>Здравствуйте, Klapaucius, Вы писали:
BZ>>>для того, чтобы у тебя в шаблонах/макросах не появлялось многоэтажных сообщений об ошибках, нужна типизация. те самые концепты. без них что угодно можно подставить куда попало
K>>Ну это-то понятно. Ему и нужен не текстовый препроцессор, а некий аналог Template Haskell.
BZ>настолько понятно, что ты ошибаешься
BZ>есть три типа макросов: простая текстовая подстановка а-ля #define. синтаксические макросы а-ля TH и C++ templates. и наконец "семантические макросы" а-ля C++ templates with concepts
Я бы сказал так, то что было названо — это три уровня гигиеничности макросов.
А типами (видами) макросов можно назвать следующие две разновидности.
1. Макросы, вводящие новые синтаксические конструкции и трансформирующие их во встроенные конструкции языка. Эти макросы служат только одной цели — позволяют создавать и использовать синтаксический сахар.
2. Макросы, которые используются для трансформации втроенных языковых конструкций в другие конструкции. Например, добавление сериализации, трансформация кода в ленивые или реактивные вычисления и тд, а также возможно анализа кода для каких либо оптимизаций.
BZ>фишка в том, что TH прверяет типы аргументов только на уровне "здесь должен быть какой-нибудь тип". это откладывает проверки до места фактического использования, получается compile-time dynamic typing. concepts, afair, реализовывали duck typing. а наиболее правильным я считаю, конечно же, static typing — в виде иерархий интерфейсов
Хм, то есть TH в этом плане то же, что и шаблоны C++ сейчас? Чем плох duck typing?
BZ>и всё это решает только одну проблему макросов, а их множество...
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, BulatZiganshin, Вы писали:
BZ>>compile-time dynamic typing
K>Мне одному кажется, что это оксюморон?
compile-time потому что подстановки шаблонов выполняются во время компиляции.
dynamic typing потому что эти подстановки шаблонов не типизированы.
То есть получается вычисление типов, где типы не имеют статически определенных типов (чтобы не было повторов слов, можно сказать супертипов или классов типов)
то есть
template<class A, class B>
^
|
не указано, что представляет собой тип, какими свойствами и методами он обладает.
Здравствуйте, Aleх, Вы писали:
BZ>>есть три типа макросов: простая текстовая подстановка а-ля #define. синтаксические макросы а-ля TH и C++ templates. и наконец "семантические макросы" а-ля C++ templates with concepts
A>Я бы сказал так, то что было названо — это три уровня гигиеничности макросов.
нет, гигиеничность — это другое свойство
A>Хм, то есть TH в этом плане то же, что и шаблоны C++ сейчас? Чем плох duck typing?
тем, что функция format в разных классах может делать совсем разные вещи
Здравствуйте, Caracrist, Вы писали:
C>Здравствуйте, Тот кто сидит в пруду, Вы писали:
ТКС>>Здравствуйте, Мишень-сан, Вы писали:
M>>>>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
МС>>>Не думаю, что большинству программистов нафик впалось писать для компилятора. Просто если некие сложные расчёты будут проделаны компилятором один раз, при каждом запуске можно будет на халяву пользоваться готовым результатом, а не считать всё заново.
ТКС>>Тут еще вопрос, что при промышленной разработке дешевле Компилируется-то оно тоже по сто раз на дню...
C>для этого придумали precompiled header и частичную компиляцию
Он не всегда помогает, часто глючит и вообще не сильно ускоряет компиляцию.
Здравствуйте, Klapaucius, Вы писали:
K>А как совмещать продолжения и RAII?
А зачем совмещать продолжения и RAII? Если же речь о вызове деструкторов — то так же, как сейчас — при выходе из блока. Собственно, setcontext/getcontext и в C++ можно использовать.
Здравствуйте, Mazay, Вы писали:
M>Нормальные сообщения об ошибках (полагаю, что с заменой шаблонов на макросы уйдут в прошлое и нечитаемые развертки стэка инстацирования).
Не не уйдет. Проблема в синтаксисе. Он неоднозначен и однозначность достигается уже смантическими средствами (анализом является ли идентификатор типом или нет). Учитывая что шаблоны разбираются только на уровне синтаксиса — эта проблема в С++ практически не устранима.
M>Стандарт на объектные файлы.
Их вообще надо убрать и заменить их на модули (компонентного типа как в Яве, Обероне или дотнете).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>вообще верит в макросы может только человек которыми ими никогда не пользовался. представь себе хотя бы отладку кода, используюшего макросы....
А ты пользовался? Нормальными то? Я вот пользовался. Проблем с отладкой кода не видел. По крайней мере они были не страшнее отладки в языках где макросов нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>и в C++ как-то отлаживаются шаблоны C++ — это как раз специализированные макросы, которые лишены хотя бы части их недостатков. с макросами будет только хуже. любые идеи универсальных препроцессоров упираются в диагностику и отладку
Не, ну, так позориться не стоит. Шаблоны в С++ тоже зло, кстати?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Caracrist, Вы писали:
ТКС>>Тут еще вопрос, что при промышленной разработке дешевле Компилируется-то оно тоже по сто раз на дню...
C>для этого придумали precompiled header и частичную компиляцию
В промышленной разработке precompiled header могут замедлять время сборки. У нас после отключения precompiled headers в проекте время сборки упало почти в 1.5 раза.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>новое — это хорошо разрекламированное старое синтаксические макросы хорошо известны с 60-х, как и их недостатки
Если не изменяет память, макросы в Лиспе появились значительно позже. По крайней мере в том виде в котором их понимают сейчас. В 60-ых появился сам Лисп. Подом был долгий путь к квази-цитированию и выделенному коду трансформации.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Константин, Вы писали:
К>Здравствуйте, Caracrist, Вы писали:
ТКС>>>Тут еще вопрос, что при промышленной разработке дешевле Компилируется-то оно тоже по сто раз на дню...
C>>для этого придумали precompiled header и частичную компиляцию
К>В промышленной разработке precompiled header могут замедлять время сборки. У нас после отключения precompiled headers в проекте время сборки упало почти в 1.5 раза.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>для того, чтобы у тебя в шаблонах/макросах не появлялось многоэтажных сообщений об ошибках, нужна типизация. те самые концепты. без них что угодно можно подставить куда попало
BZ>для отладки нужно дать отладчику инофрмацию о том какая строка сейчас выполняется и какие у нас есть переменные. а откуда она возьмётся, если текст подвергся обработке препроцессором? и получаешь ты то же самое, как при отладке в высокоуровневой программы на уровне ассемблера
Обожаю теоретиков.
Звучит все складно, как в пвсевдо-научных статьях, но с практиков не коррелирует.
На практике все же совсем иначе. Макрос — это программа. И этим все сказано. Эта программа не тупой трансформатор АСТ. Она может и типы проверить. Результат правда будет доступен не во время компиляции макроса, а во время компиляции программы которая использует этот макрос. Но для конечного пользователя-программиста именно это и нужно.
Собственно написать и отладить макрос конечно сложнее нежели просто код, но сложность тут в основном определяется не периодом типизации, а тем что это мета-код, т.е. код высшего порядка (скажем так).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Klapaucius, Вы писали:
BZ>>compile-time dynamic typing
K>Мне одному кажется, что это оксюморон?
Согласен, но если подходить к вопросу несколько мягче, то в его словах действительно можно углядеть нечто рациональное.
Макросы дают статически типизированному языку такую же гибкость и мощь как динамическое метапрограммирование (МП) в динамически-типизированных языках. Разница только в том что в последних МП отрабатывает в рантайме, а в первом в компайлтайме.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Aleх, Вы писали:
A>А типами (видами) макросов можно назвать следующие две разновидности. A>1. Макросы, вводящие новые синтаксические конструкции и трансформирующие их во встроенные конструкции языка. Эти макросы служат только одной цели — позволяют создавать и использовать синтаксический сахар. A>2. Макросы, которые используются для трансформации втроенных языковых конструкций в другие конструкции. Например, добавление сериализации, трансформация кода в ленивые или реактивные вычисления и тд, а также возможно анализа кода для каких либо оптимизаций.
Вообще-то есть и строготипизированные макросы. Так есть MacroML
в котором макросы типизируются. Вот только результат не прижился. Гибкость не та.
Плюс, вы будете смеяться, но примером типизированных макросов является Linq Expressin Tree. Вот только отсутствие квази-цитирования, ограниченность поддержки Expressin Tree в языках и работа этого механизма только в рантйме не позволяет использовать его для метапрограмирования эффективно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Mazay, Вы писали:
M>Поймите правильно, я не предлагаю использовать именно макросы Немерла. Я говорю, что полезной была бы возможность полноценной кастомизации синтаксиса языка на базе C с классами. Остальное будет реализовано в виде библиотек типа буста и stl.
Я даже больше скажу. Можно весь язык сделать одной (большой) библиотекой макросов. Это, кстати, будет проделано в Nemerle 2
).
M>В C++ сообществе уже есть успешный опыт по кастомизации синтаксиса с помощью перегрузки операторов, шаблонов. Взгляните на BOOST_FOREACH, SCOPE_EXIT, boost::lambda.
Я не сказал бы, что этот опыт однозначно положителен. На мой взгляд он провален. Ты верно заметил, что для достижения реального результата нужна другая система макросов.
M>Если бы у разработчиков были более удобные инструменты , то эти улучшения было бы также удобно использовать как встроенные операторы. Какими будут эти средства — вопрос обсуждаемый, но макросы Немерла как минимум стоит рассмотреть.
+1. Особенно те что продумываются для версии 2.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
C>Скажу чего мне нехватает C>Покритикуйте или расскажите чего нехватает вам. Ссылки на языки в которых подобная проблема решена будут интересны, но хотелось бы не сильно далеко уходить от мира c++
Хорошо было бы иметь большую свободу в описании конструкторов объектов.
Сейчас, в первую очередь инициализация в списке инициализации — конструкторы базовых классов, поля,
а потом исполняется тело конструктора.
Зачастую, хочется перед инициализацией из списка инициализации, посчитать что-нить предварительно.
Было бы круто написать что-нибудь вроде
DerivedClass::DerivedClass(mytype arg)
{
// проверка аргументов
// предварительный расчет общих значений для конструкторов, полей и проч.
mytype1 v1 = Calculate1(arg);
mytype2 v2 = Calculate2(arg);
// инициализация базовых классов и полей (синтаксис условен)
:BaseClass(arg, v1);
:MyField1(arg, v1);
:MyField2(arg, v1, v2);
// дальнейшая инициализация
}
Здравствуйте, VladD2, Вы писали:
BZ>>для того, чтобы у тебя в шаблонах/макросах не появлялось многоэтажных сообщений об ошибках, нужна типизация. те самые концепты. без них что угодно можно подставить куда попало
BZ>>для отладки нужно дать отладчику инофрмацию о том какая строка сейчас выполняется и какие у нас есть переменные. а откуда она возьмётся, если текст подвергся обработке препроцессором? и получаешь ты то же самое, как при отладке в высокоуровневой программы на уровне ассемблера
VD>Обожаю теоретиков.
VD>Звучит все складно, как в пвсевдо-научных статьях, но с практиков не коррелирует.
ты внимательно прочёл? я сказал, что 1) нужна проверка типов. которой нет в шаблонах, а не Немерле. 2) что помимо проверки типов нужно много других вещей, которые опять же нужно программировать. к примеру поддержка номеров строк для отладчика
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Mazay, Вы писали:
M>>Нормальные сообщения об ошибках (полагаю, что с заменой шаблонов на макросы уйдут в прошлое и нечитаемые развертки стэка инстацирования).
VD>Не не уйдет. Проблема в синтаксисе. Он неоднозначен и однозначность достигается уже смантическими средствами (анализом является ли идентификатор типом или нет). Учитывая что шаблоны разбираются только на уровне синтаксиса — эта проблема в С++ практически не устранима.
Ну вот в Clang (компилятор С++ под виртульную машину LLVM) вроде бы в отношении сообщений об ошибках много что сделано. M>>Стандарт на объектные файлы.
VD>Их вообще надо убрать и заменить их на модули (компонентного типа как в Яве, Обероне или дотнете).
Кто как думает, плохо (хорошо, пофигу) ли , когда синтаксис неоднозначный.
Минус неоднозначностей в том, что сложнее писать компилятор.
Плюс в том, что пользователю не приходится думать за компилятор, чтобы определить, требуется ли ему подсказка или обойдется.
Код будет более аккуратным и не замусоренным ненужными конструкциями Пример
Здравствуйте, VladD2, Вы писали:
BZ>>новое — это хорошо разрекламированное старое синтаксические макросы хорошо известны с 60-х, как и их недостатки
VD>Если не изменяет память, макросы в Лиспе
Здравствуйте, VladD2, Вы писали:
VD>Макросы дают статически типизированному языку такую же гибкость и мощь как динамическое метапрограммирование (МП) в динамически-типизированных языках. Разница только в том что в последних МП отрабатывает в рантайме, а в первом в компайлтайме.
ну да. ничего, что во время копиляции данных воемени выполнения ещё нет, так что тебе остаётся разве что сгенерить бесконечное число вариантов диспатченного кода
C>Покритикуйте или расскажите чего нехватает вам. Ссылки на языки в которых подобная проблема решена будут интересны, но хотелось бы не сильно далеко уходить от мира c++
Еще круто было бы иметь возможность отключить обязательность инициализированности полей.
Т.е. скажем, есть некий тип FieldType. У него есть конструктор с аргументами, которые обязательно
передавать для инициализации объекта. Ну или пусть даже для инициализации объекта ничего не нужно,
но инициализация присутствует.
Хочется, чтобы можно было бы объявить класс
Здесь, благодаря ключевому слову optional_initialization, не требуется обязательно в конструкторе,
в списке инициализации, инициализировать field. Оно, может остаться неинициализированным.
И при уничтожении объекта, оно автоматически не уничтожится.
Но можно будет field ручками инициализировать через его конструктор, и ручками же уничтожить
(это может делать функция control()).
И в функциях различных, использовать его, разумеется обеспечив, что он существует.
Идея в том, что компилятор заранее выделит память под объект, не нужно будет вместо этого, делать
указатель на объект, и через указатель извращенно к нему докапываться. Можно будет работать с таким
полем, как с обычными полями.
Также это позволит избегать проблем с фрагментацией памяти и кэшем.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>ну да. ничего, что во время копиляции данных воемени выполнения ещё нет, так что тебе остаётся разве что сгенерить бесконечное число вариантов диспатченного кода
Знание значения данных дает мало толку для для тех задач которые обычно решаются метапрограммированием. Обычно достаточно знать их типы и то не всегда. А вот их как раз узнать можно. Знания о них ведь нужны не во время компиляции макроса, а во время его выполнения.
В общем, не стоит обсуждать то что не пробовал на практике.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>>>новое — это хорошо разрекламированное старое синтаксические макросы хорошо известны с 60-х, как и их недостатки
VD>>Если не изменяет память, макросы в Лиспе
BZ>http://en.wikipedia.org/wiki/General_purpose_macro_processor
Здравствуйте, Aleх, Вы писали:
A>Ну вот в Clang (компилятор С++ под виртульную машину LLVM) вроде бы в отношении сообщений об ошибках много что сделано.
Я не утверждаю что сделать ничего нельзя. Я утверждаю, что а) это сложн, и б) во многих случаях просто недостаточно информации (например, при компиляции шаблонов).
A>PS Я уже несколько дней думаю над тем, что же всё таки лучше — однозначный синтаксис или нет.
Еже понятно что чем однозначнее синтаксис тем лучше. Вопрос только в том, чтобы при этом язык удовлетворял потребностям пользователей.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, BulatZiganshin, Вы писали:
K>>>А как совмещать продолжения и RAII?
VD>>GC
BZ>gc не заменяет raii, поскольку не гарантирует вызов деструктора в детерминированный момент времени
Он устраняет необходимость в использовании raii для контроля памяти, а это в С++ 99% случаев использования raii. Оставшиеся копейки легко автоматизируются. Не мне тебе рассказыать, что в языках со встроенным GC особых проблем с управлением ресурсов нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
BZ>>>>новое — это хорошо разрекламированное старое синтаксические макросы хорошо известны с 60-х, как и их недостатки
VD>>>Если не изменяет память, макросы в Лиспе
BZ>>http://en.wikipedia.org/wiki/General_purpose_macro_processor
VD>Ну, и причем тут текстовые макросы?
Здравствуйте, VladD2, Вы писали:
K>>>>А как совмещать продолжения и RAII?
VD>>>GC
BZ>>gc не заменяет raii, поскольку не гарантирует вызов деструктора в детерминированный момент времени
VD>Он устраняет необходимость в использовании raii для контроля памяти, а это в С++ 99% случаев использования raii. Оставшиеся копейки легко автоматизируются
Здравствуйте, VladD2, Вы писали:
VD>Твоя цитата: VD>
VD> у тебя в шаблонах/макросах не появлялось многоэтажных сообщений об ошибках, нужна типизация
VD>?
так ты и написал что в Немерле тип проверить можно
BZ>>2) что помимо проверки типов нужно много других вещей, которые опять же нужно программировать. к примеру поддержка номеров строк для отладчика
VD>При программировании вообще нужно много программировать, но это же не причина не заниматься программированием?
VD>Если серьезно, то конечно проблемы есть и создание макросов далеко не самое простое занятие. Но дела обстаят не так печально как тебе кажется. Те же номера строк (точнее местоположения) автоматом расставляются для кусков кода которые передаются в качестве параметров макросов, так что вручную их устанавливать приходится крайне редко.
VD>Главное же, что макры (особенно если они хорошо спроектированы и реализованы) позволяют частенько воистину творить чудеса. Так что сложности при разработке макросов с лихвой окупаются тем что они позволяют делать.
VD>Ну, а разговоры о сложности отладки кода использующего макросы — это не более чем досужие домыслы. Отлаженный макрос ничем не отличается от отлаженных фич языка. Да по сути макрос — это и есть часть языка. Разница только в том, что это не обязательная часть языка (ее можно не использовать), и в том, что ты сам можешь написать эту часть.
VD>В общем, те кто провали на практике в 100% случаев расставались с пессимизмом по этому вопросу. Поверь на слово, или проверь.
вот что мы имеем:
1. пробовали их ещё десятки лет назад. и тогда же было описано, что макросы — не панацея
2. с тех пор макросы не стали популярней, хотя реализация их по нынешним временам — пустяк
3. сложность компилятора значительно сложнее сложности макропроцессора, а ведь это ещё не единственный компонент, требующий поддержки каждой новой фичи языка
4. на другой чаше весов мы имеем мнение фанатика Немерле
ps: тебе самому отсутствие опыта работы в хаскеле никогда не мешало хаять его фичи, причём даже не на основании чтения умных книг, а "революционного чутья". теперь же наличие опыта работы превратилось в главный критерий, позволяющий судить о вещи. один этот факт говорит о том, что дискутировать с тобой бесполезно
Здравствуйте, BulatZiganshin, Вы писали:
BZ>>>>>новое — это хорошо разрекламированное старое синтаксические макросы хорошо известны с 60-х, как и их недостатки
VD>>>>Если не изменяет память, макросы в Лиспе
BZ>>>http://en.wikipedia.org/wiki/General_purpose_macro_processor
VD>>Ну, и причем тут текстовые макросы?
BZ>текстовые макросы = синтаксические макросы
вот тут я ошибся. синтаксические макросы — это более развитый вариант текстовой подстановки и GPM — одна из систем синтаксических макросов
Здравствуйте, Aleх, Вы писали:
A>compile-time потому что подстановки шаблонов выполняются во время компиляции. A>dynamic typing потому что эти подстановки шаблонов не типизированы.
Тут путаница получается. Dynamic typing — это означает, что типы проверяются на этапе выполнения. Да и они типизированы — утиным способом. И статически.
A>То есть получается вычисление типов, где типы не имеют статически определенных типов (чтобы не было повторов слов, можно сказать супертипов или классов типов)
Они статически определены, просто в виде контракта не записываются — что, конечно, минус. Концепты вообще, по моему мнению, самое полезное из планировавшихся нововведений в C++.
template<class A, class B>
^
|
не указано, что представляет собой тип, какими свойствами и методами он обладает.
Он обладает теми методами, которые используются ниже. Да, типизация утиная, но статическая. Никакой динамики тут нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
'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
Здравствуйте, Mazay, Вы писали:
M>Функции этапа компиляции могут применяться для того, чтобы управлять генерацией машинного кода и курочить AST. С их помощью можно научить компилятор новым синтаксическим конструкциям, навешать любую метаинформацию, ввести атрибуты для всего, что только можно — полей, методов, классов, блоков кода, переменных и функций и т. д.
Это уже макросы. Тут-то явно другой случай. Ф-я, которая вычисляет в компайл-тайм значение времени компиляции из значения времени компиляции. Никакой сложной работы в АСТ тут нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
'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
Здравствуйте, dilettante, Вы писали:
D>А зачем совмещать продолжения и RAII? Если же речь о вызове деструкторов — то так же, как сейчас — при выходе из блока.
При котором выходе из блока? Продолжения позволят выходить из блока сколько угодно раз. И не дают никакой возможности узнать какой выход будет последним в общем случае.
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
'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
Ну ладно, отказались мы от детерминированного освобождения памяти. Тут я не против. Ну а как быть с детерминированным освобождением остальных ресурсов? Продолжения делают любое детерминированное освобождение невозможным — т.е. любой аналог using тоже работать не будет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
'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
Здравствуйте, Klapaucius, Вы писали:
VD>>В общем, не стоит обсуждать то что не пробовал на практике.
K>Вообще — он автор туториалов по Template Haskell.
Влад имеет в виду Немерле, который имеет свои особенности
>Я, собственно, потому и удивился, что он как-то невнятно изъясняется.
Здравствуйте, Klapaucius, Вы писали:
D>>А зачем совмещать продолжения и RAII?
K>При котором выходе из блока? Продолжения позволят выходить из блока сколько угодно раз. И не дают никакой возможности узнать какой выход будет последним в общем случае.
Ну так выход — не использовать локальные объекты, подлежащие уничтожению, в таких блоках. Это однако не означает невозможность использовать RAII с продолжениями в общем случае, например, в википедии, в примере (который на С, но представим, что это С++) можно использовать RAII в любом месте, кроме последнего if (потому что из него программа не выходит).
Здравствуйте, Мишень-сан, Вы писали:
МС>Здравствуйте, Mazay, Вы писали:
M>>Вот, кстати, ещё одно свидетельство того, что программисты хотят программировать не только для компьютера, но для компилятора.
МС>Не думаю, что большинству программистов нафик впалось писать для компилятора. Просто если некие сложные расчёты будут проделаны компилятором один раз, при каждом запуске можно будет на халяву пользоваться готовым результатом, а не считать всё заново.
знаешь, наш предыдущий проект собирался "с нуля" больше чем за сутки у виндовс-товарищей. У нас (линуксоидов) — часа два-три.
Это не проблема, если ты ведешь сборку редко. Но вот если приходился лезть в самые глубины (как-то в мозиллу) — то начинается пересборка чуть не всего проекта. Начинаешь задумываться об оптимизации системы сборки.
Сейчас тоже весело, когда приходится править что-то в библиотеке, которая на шаблонах построена так, что мама не горюй. Любители те еще писали. Разве что НОД не вычисляют на шаблонах.....
Здравствуйте, BulatZiganshin, Вы писали:
BZ>вообще верит в макросы может только человек которыми ими никогда не пользовался. представь себе хотя бы отладку кода, используюшего макросы....
Вообще верить в безумную сложность отладки макросов может только человек, которыми ими никогда не пользовался.
Я этим занимаюсь регулярно, и не с сахарными макросами Немерле, а с кондовым сишным препроцессором (программируемым при помощи Boost.Preprocessor).
И ничего, все замечательно и быстро отлаживается.
Здравствуйте, Мишень-сан, Вы писали:
МС>Вообще же мне не совсем понятно, в какую сторону несёт новый стандарт — вводят какой-то зоопарк сказочных конструкций (как пример — альтернативный typedef и новый формат декларации функций), но при этом выбрасывают такие вещи как концепты. О стандарте на ABI и полноценных модулях остаётся только мечтать.
Ты как-то огульно кучу полезных вещей записал в сказочные конструкции, не очень понятно, с какой целью
Навскидку, не заглядывая в реальный список — auto, rvalue references, variadic templates, variadic macros, memory model, threads, локальные классы как аргументы шаблонов, range-based loop, атрибуты функций/классов/переменных, initializer lists.
Если в список заглянуть — так еще с десяток необходимых вещей наберется.
А концепты не выбросили, их просто признали не готовыми к публикации в этой версии стандарта.
Никто их важности не отрицает, просто фичу такого масштаба сложно встроить в такой огромный язык, как С++, и чтоб при этом ничего не поломалось и чтоб можно было фичей удобно пользоваться.
Это не D и не Python, где один человек принимает все решения и сует в язык каждую понравившуюся ему фичу, а потом чешет репу, глядя на зоопарк несовместимых друг с другом фич, который у него получился, и переписывает все нафиг, делая несовместимые версии языка. Тут люди задумываются над когерентностью языка. С++0x полностью совместим с С++03, с поправкой на неизбежную проблему с новыми ключевыми словами.
В общем, если действительно интересно — читай интервью по поводу выкидывания концепций из _этого_ стандарта.
Здравствуйте, jazzer, Вы писали:
J>Ты как-то огульно кучу полезных вещей записал в сказочные конструкции, не очень понятно, с какой целью J>Навскидку, не заглядывая в реальный список — auto, rvalue references, variadic templates, variadic macros, memory model, threads, локальные классы как аргументы шаблонов, range-based loop, атрибуты функций/классов/переменных, initializer lists.
Названные Вами вещи безусловно полезны. Возможно, я не совсем точно выразил свою точку зрения. Мне не нравится не факт введения новых конструкций, а то, что они перекрывают существующий синтаксис и раздувают его. Хотя, конечно, при обязательном условии совместимости вычистить старьё не удастся.
J>В общем, если действительно интересно — читай интервью по поводу выкидывания концепций из _этого_ стандарта.
Я в курсе, что концепты перенесли в следующий TR (предварительно). Спасибо, поищу, почитаю.
Здравствуйте, Caracrist, Вы писали:
МС>>Я вместо этих извратов с break-continue предпочёл бы нормальные локальные функции.
C>а выход через несколько исключениями реализовать, и все необходимое by-ref передавать? C>вся идея локальных скоупов в конструкторах/деструкторах, break/continue/loop/if-else и visibility других локальных переменных, можно от них отказаться, но по моему это не правильный путь.
Если есть первоклассные функции то циклы не очень то и нужны.
Здравствуйте, Мишень-сан, Вы писали:
МС>Кстати, наткнулся как-то на интересную идею (где-то на форуме Nemerle кажется): расширить семантику типа void, в частн. позволить единственное значение этого типа — например (). И соответственно позволить конструкции вида return (); в функциях возвращающих void. Это позволило бы не писать для некоторых случаев делегирования в шаблонах отдельную специализацию.
Здравствуйте, Caracrist, Вы писали:
C>1. break [what]; continue [what]; C>возможность делать break(и continue) из любого скоупа, а не только цикла. Плюс параметризировать. C>число говорит сколько скоупов оборвать, а назавание цыкла говорит какой первый встречающийся цикл оборвать. Через запятую перечисление последовательных обрывов.
В D можно задавать перед циклом метку и break (или continue) может получить параметром эту метку, что означает выход из помеченного цикла (на произвольную метку при этом перейти нельзя)
Здравствуйте, jazzer, Вы писали:
J>Это не D и не Python, где один человек принимает все решения и сует в язык каждую понравившуюся ему фичу, а потом чешет репу, глядя на зоопарк несовместимых друг с другом фич, который у него получился, и переписывает все нафиг, делая несовместимые версии языка. Тут люди задумываются над когерентностью языка. С++0x полностью совместим с С++03, с поправкой на неизбежную проблему с новыми ключевыми словами.
Да все так, но уже несколько раз когда нужно было делать сложную конструкцию на шаблонах я делал прототип на D а потом переносил на C++ что было на порядок проще чем делать сразу на C++. Совместимость конечно нужно поддерживать, но это может в конце концов просто убить язык из-за слишком большой сложности.
Может быть даже правильнее было бы объявить существующие шаблоны на C++ устаревшими, поддерживать их как есть и ввести новые с не пересекающимся синтаксисом например с таким же синтаксисом как в D, в свое время например борланд в дельфи не постеснялись даже объектную систему полностью поменять, не отменяя при этом поддержку старой.
Здравствуйте, FR, Вы писали:
FR>Да все так, но уже несколько раз когда нужно было делать сложную конструкцию на шаблонах я делал прототип на D а потом переносил на C++ что было на порядок проще чем делать сразу на C++. Совместимость конечно нужно поддерживать, но это может в конце концов просто убить язык из-за слишком большой сложности.
Ну сам понимаешь, это не простой выбор — упростить синтаксис, убив совместимость с бог знает какой горой кода (т.е. фактически сохдав новый язык, со стандартной проблемой нового языка, заключающейся в том, что им никто не пользуется, кроме создателей и фанатов), либо вводить новые фичи аккуратно, тщательно согласуя их с уже имеющимися.
Я думаю, Страуструп тоже был бы не против грохнуть совместимость с С, особенно с наиболее одиозными его частями, но он был мужиком умным и понимал, что без совместимости с С его новый язык нафиг никому нужен не будет.
Народ вон на стандартный С++98/03 переходил лет 10, и до сих пор еще не полностью перешел, куда уж там говорить о несовместимой версии языка.
Здравствуйте, jazzer, Вы писали:
J>Ну сам понимаешь, это не простой выбор — упростить синтаксис, убив совместимость с бог знает какой горой кода (т.е. фактически сохдав новый язык, со стандартной проблемой нового языка, заключающейся в том, что им никто не пользуется, кроме создателей и фанатов),
Тык я же и говорю сделать не убивая совместимость, старые шаблоны останутся как были, но развиваться не будут, новые делать так чтобы они синтаксически не пересекались со старыми и не влияли на совместимость.
J>либо вводить новые фичи аккуратно, тщательно согласуя их с уже имеющимися.
Можно, но в результате накапливается критическая масса после которой это уже становится просто невозможным. C++ по моему уже до нее дошел.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, jamesq, Вы писали:
J>>Еще круто было бы иметь возможность отключить обязательность инициализированности полей.
VD>А она когда-то появлялась?
Вот код:
class FieldType {
public:
FieldType(int);
};
class MyClass {
public:
MyClass() {}
FieldType tt; // Поле обязательно требует инициализации
};
Он не скомпилируется, т.к. поле tt обязательно требует инициализации.
Visual C++ пишет ошибку: error C2512: 'FieldType' : no appropriate default constructor available
Здравствуйте, jamesq, Вы писали:
J>Здравствуйте, VladD2, Вы писали:
VD>>Здравствуйте, jamesq, Вы писали:
J>>>Еще круто было бы иметь возможность отключить обязательность инициализированности полей.
VD>>А она когда-то появлялась?
J>Вот код: J>
J>class FieldType {
J>public:
J> FieldType(int);
J>};
J>class MyClass {
J>public:
J> MyClass() {}
J> FieldType tt; // Поле обязательно требует инициализации
J>};
J>
J>Он не скомпилируется, т.к. поле tt обязательно требует инициализации. J>Visual C++ пишет ошибку: error C2512: 'FieldType' : no appropriate default constructor available
И это правильно.
Здравствуйте, jamesq, Вы писали:
J>Он не скомпилируется, т.к. поле tt обязательно требует инициализации. J>Visual C++ пишет ошибку: error C2512: 'FieldType' : no appropriate default constructor available
А если так попробовать:
class FieldType {
public:
FieldType(int);
};
class MyClass {
public:
MyClass() {}
FieldType* tt;
};
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Если брать код, который я написал, что мы видим:
класс FieldType, для инициализации объектов которого, в конструктор нужно обязательно передать параметр.
конструктор MyClass, в котором в списке инициализации явно не прописана инициализация поля tt.
Если это встретилось, инициализация поля должна быть сгенерирована компилятором неявно, используя
конструктор по умолчанию класса FieldType.
Однако, такого конструктора в коде нет, и поэтому возникла ошибка компиляции.
Если считать класс FieldType зафиксированным, и изменению не поддающимся, то для внедрения в класс MyClass поля
с типом FieldType, придется в конструкторе прописать инициализацию этого поля, с передачей в конструктор объекта поля нужного параметра.
Это я и имел в виду под словами "поле tt обязательно требует инициализации".
Мое предложение в том, чтобы иметь возможность изменить порядок инициализации и уничтожения поля.
Чтобы в конструкторе объекта FieldType не обязательно было бы прописывать инициализацию поля tt
(при условии пометки объявления этого поля специальным словом).
И тогда, при создании объекта FieldType, конструктор для поля tt не вызывался бы, и поле оставалось бы
неинициализированным. Однако, в памяти, выделенной объекту FieldType оставался участок для поля tt.
Его содержимое было бы undefined.
При уничтожении объекта FieldType, деструктор для поля tt тоже бы не вызывался (неявно, после завершения тела деструктора, если бы он был бы прописан в классе FieldType). Сейчас же по правилам C++, они же вызываются, так?
Однако, в коде должна быть возможность ручками где-угодно (хоть в какой-нибудь функции-члене) прописать
инициализацию поле tt, и ручками же его уничтожить (вызовами конструктора и деструктора).
А самое главное, чтобы была бы свободная возможность работать с таким полем, как с любым другим полем.
Т.е. пишем что-нибудь вроде:
void d(FieldType& x){
x.tt.some_func(123); // подразумевается, что в определение класса FieldType добавлена функция some_func()
}
и ура, при вызове d() с любым объектом FieldType, будет попытка вызвать функцию some_func() поля tt.
Причем, компилятору будет пофиг, что tt на момент вызова может быть не инициализировано. Код будет сгенерирован.
Программист должен самостоятельно обеспечить валидность объекта этот момент, ручками проинициализировав его
заранее.
Я понимаю идею. Более того, сейчас, когда мне нужно было ручками управлять существованием полей,
так и поступал: заводил указатели, и выносил поля наружу.
Разумеется, тут могут быть разные вариации: просто указатели, как в приведенном примере,
умные указатели, которые в состоянии автоматически уничтожать объект. Более того, можно
заранее прописывать в объектах буферы, в которые с помощью placement new оператора
создавать объекты.
Недостатки описанных подходов:
В первых двух вариантах, память для вынесенного по указателю поля объекта оказывается в стороне от участка
памяти с самим объектом, что при обращении к полю создает проблемы с кэшированием. Дополнительно, появляются
проблемы с фрагментацией памяти. Понятно, что лучше один большой учаток памяти на объект и поле в нем, чем два
отдельных.
Во всех вариантах, которые мне приходят в голову, есть еще один недостаток — весь доступ к вынесенному полю
идет через указатель.
По-моему, косвенный доступ через адрес в указателе медленее чем прямой, когда относительный адрес может быть вычислен на этапе компиляции. Да и простора для оптимизаций в компиляторе здесь больше: компилятору сложно делать какие-либо предположении о конкретном значении указателя. Это для человека известно, что он указывает все время жизни родительского объекта на один и тот же объект вынесенного поля.
Компилятору вряд ли легко такие факты устанавливать.
Скорее, он будет считать, что значение указателя может поменяться где угодно и когда угодно.
Соответственно, он будет и генерировать код помедленнее.
Здравствуйте, jamesq, Вы писали:
J>и ура, при вызове d() с любым объектом FieldType, будет попытка вызвать функцию some_func() поля tt. J>Причем, компилятору будет пофиг, что tt на момент вызова может быть не инициализировано. Код будет сгенерирован. J>Программист должен самостоятельно обеспечить валидность объекта этот момент, ручками проинициализировав его J>заранее.
Серьезно граблей не хватает?
Это можно было бы вводить если бы C++ поддерживал жесткое разделение на классы и POD структуры и только для
POD структур, но в обычных классах ничего кроме грабель не даст.
Здравствуйте, jamesq, Вы писали:
J>Недостатки описанных подходов: J>В первых двух вариантах, память для вынесенного по указателю поля объекта оказывается в стороне от участка J>памяти с самим объектом, что при обращении к полю создает проблемы с кэшированием. Дополнительно, появляются J>проблемы с фрагментацией памяти. Понятно, что лучше один большой учаток памяти на объект и поле в нем, чем два J>отдельных.
boost::optional посмотри, в нем почти все твои проблемы разрешены, память выделяется сразу и на месте, не инициализируется
пока не попросишь, доступ любым нормальным компилятором оптимизируется до прямого и главное совершенно никаких UB.
Здравствуйте, dilettante, Вы писали:
D>Да. Позволяющее написать например библиотеку легковесных потоков, а-ля Эрланг, распределяющиеся между несколькими реальными тредами.
Библиотеку потрясающе полезных легковестных потоков, внутри которых нельзя использовать RAII. Отличная идея.
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
'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
Здравствуйте, Caracrist, Вы писали:
C>1. break [what]; continue [what]; C>возможность делать break(и continue) из любого скоупа, а не только цикла. Плюс параметризировать. C>число говорит сколько скоупов оборвать, а назавание цыкла говорит какой первый встречающийся цикл оборвать. Через запятую перечисление последовательных обрывов.
Именованные блоки, вот такие:
if(x>0) IfPositiveX
{
while(i != 10) MainIndexLoop
{
for(k=0; k<100; k++) PrepareSpecialDataLoop
{
// ...
// вот так
if(condition1) break MainIndexLoop;
// ...
// или даже так
if(condition2) break IfPositiveX;
}
}
}
Здравствуйте, dilettante, Вы писали:
K>>Библиотеку потрясающе полезных легковестных потоков, внутри которых нельзя использовать RAII. Отличная идея.
D>Разумеется, внутри потоков можно использовать RAII.
в continuations использовать RAII нельзя. а потоки — это только частный случай их применения, поэтому там RAII использовать тоже нельзя, если только вы нне собираетесь делать отдельный анализатор того, как используется библиотека
BulatZiganshin,
K>>>А как совмещать продолжения и RAII?
VD>>GC
BZ>gc не заменяет raii, поскольку не гарантирует вызов деструктора в детерминированный момент времени
RAII не нужен:
bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket acquire release action =
do handle <- acquire
result <- action handle
release handle
return result
и не нужны никакие гарантии никаких мусорщиков. Только FCO
Klapaucius,
VD>>GC
K>Ну ладно, отказались мы от детерминированного освобождения памяти. Тут я не против. Ну а как быть с детерминированным освобождением остальных ресурсов? Продолжения делают любое детерминированное освобождение невозможным — т.е. любой аналог using тоже работать не будет.
Кстати, а флаг isDisposed перед release не поможет? (для bracket, using и аналогов)
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>RAII не нужен: LCR>
LCR>bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
LCR>bracket acquire release action =
LCR> do handle <- acquire
LCR> result <- action handle
LCR> release handle
LCR> return result
LCR>
LCR>и не нужны никакие гарантии никаких мусорщиков. Только FCO
во-первых, это и есть в моём понимании RAII для Haskell. во-вторых, посмотри на стандартный bracket — он защищён от исключений
ну и главное — мы говорим о continuations, где это как раз нельзя использовать. почитай про монаду Cont
Здравствуйте, BulatZiganshin, Вы писали:
BZ>в continuations использовать RAII нельзя. а потоки — это только частный случай их применения, поэтому там RAII использовать тоже нельзя, если только вы нне собираетесь делать отдельный анализатор того, как используется библиотека :)
Т.е. например в системных тредах нельзя использовать RAII? А если можно — почему нельзя использовать в пользовательских потоках, сделанных на продолжениях и обладающей такой же семантикой?
Здравствуйте, dilettante, Вы писали:
D>Здравствуйте, BulatZiganshin, Вы писали:
BZ>>в continuations использовать RAII нельзя. а потоки — это только частный случай их применения, поэтому там RAII использовать тоже нельзя, если только вы нне собираетесь делать отдельный анализатор того, как используется библиотека
D>Т.е. например в системных тредах нельзя использовать RAII? А если можно — почему нельзя использовать в пользовательских потоках, сделанных на продолжениях и обладающей такой же семантикой?
можно поинтересоваться — как вы различаете системные и пользовательские треды? и знакомы ли вообще с тем, как реализуются потоки черех continuations? и хъотя бы даже с тем что такое вообще continuations?
вообще весь этот тред вызван как я понимаю тем, что люди игнорируют непонятное им слово и рассуждают об обычных потоках. вот уже до системных потоков дошли
Здравствуйте, dilettante, Вы писали:
>Т.е. например в системных тредах нельзя использовать RAII? А если можно — почему нельзя использовать в пользовательских потоках, сделанных на продолжениях и обладающей такой же семантикой?
а, я понял, вы под системными тредами понимаете сделанные без continuations? тошда ответ такой — семантика другая. разберитесь наконец в существе вопроса вместо теоретических рассуждений о неизвестном вам предмете
Здравствуйте, BulatZiganshin, Вы писали:
BZ>для того, чтобы у тебя в шаблонах/макросах не появлялось многоэтажных сообщений об ошибках, нужна типизация. те самые концепты. без них что угодно можно подставить куда попало
Которые и сейчас замечательно эмулируются (хотя, конечно, родные концепты были бы удобнее).
Я пишу на работе очень много шаблонов, так вот у меня добрая половина текста каждого шаблона — это проверка параметров и ругань через BOOST_MPL_ASSERT_MSG (http://www.boost.org/libs/mpl/doc/refmanual/assert-msg.html), если что не так. Вывод компилятора становится очень даже читабельным (цепочка звездочек очень хорошо видна и нет проблем ее подсветить/отфильтровать, если ты пропускаешь ругань компилятора через какой-нть процессор, как это делаю я, и/или как-то раскрашиваешь), ибо в нем теперь содержится человеческое описание ошибки (по ссылке есть пример такой ошибки).
Более того, когда этот шаблонный код (и не только шаблонный) генерится макросом, то в проверки можно вставить непосредственно и имена, которые пришли в макрос в виде параметров — тем самым сообщения компилятора становятся совсем замечательными.
Так что иметь концепты, безусловно, было бы здорово, но и без них нормально живется, если приложить к тому усилия.
Здравствуйте, jazzer, Вы писали:
J>Так что иметь концепты, безусловно, было бы здорово, но и без них нормально живется, если приложить к тому усилия.
Все-таки надо было их добавить, хотя бы в урезанном виде, в том же D тоже не осилили всего того, что предлагалось в C++0x,
но в результате все-равно очень мощная и симпатичная (практически развитие в сторону паттерн матчинга для шаблонов)
штучка получилась:
BulatZiganshin,
BZ>во-первых, это и есть в моём понимании RAII для Haskell. BZ>во-вторых, посмотри на стандартный bracket — он защищён от исключений
Да, спасибо, я подумал про это спустя некоторое время.
BZ>ну и главное — мы говорим о continuations, где это как раз нельзя использовать. почитай про монаду Cont.
Да, спасибо, сам догадался (тов. Klapaucius навёл на правильные мысли).
Здравствуйте, BulatZiganshin, Вы писали:
BZ>а, я понял, вы под системными тредами понимаете сделанные без continuations? тошда ответ такой — семантика другая. разберитесь наконец в существе вопроса вместо теоретических рассуждений о неизвестном вам предмете
Мощное заявление. Стоило бы подкрепить фактами, особенно рассуждая о семантике нереализованной и неизвестной вам библиотеки потоков. :)
Здравствуйте, jamesq, Вы писали:
J>А самое главное, чтобы была бы свободная возможность работать с таким полем, как с любым другим полем.
А ничего, что это "всего лишь навсего" нарушение инкапсуляции? Думается что нынешняя ситуация и идеологически и семантически корректная.
За инициализацию объекта должен отвечать сам объект, а не кто-то там.
J>Программист должен самостоятельно обеспечить валидность объекта этот момент, <skip>
— добавив ему конструктор по умолчанию! Кстати, компилятор именно это и говорит
Ну вы даёте... Вы, наверно, смерти желаете С++? Я за молодостью лет не застал язык PL/1, но пишут, что он умер от того, что в нем слишком много всего было.
Вы хотите, чтобы нужно было постоянно держать в голове тысячу особенностей?
Вы хотите, чтобы ежедневное программирование по сложности стало каким-то таким
Название после цикла? Тут нет проблем. Цикл на три страницы — вот это проблема.
Много вложенных циклов? Так избавьтесь от них. Сделайте функцию, а в ней return. Сделайте ее inline.
Ну а в редких случаях (типа обработки n-мерных массивов) поставьте goto. И комментарии. Один оператор goto в пределах функции 50 — 100 строк не испортит вашу карму. И да не падёт на вас проклятье Дийкстры.
Здравствуйте, dmitry_npi, Вы писали:
_>Ну вы даёте... Вы, наверно, смерти желаете С++? Я за молодостью лет не застал язык PL/1, но пишут, что он умер от того, что в нем слишком много всего было.
я как раз считаю, что C++ лучше всего было бы обкорнать. или закопать наконец
_>Вы хотите, чтобы нужно было постоянно держать в голове тысячу особенностей?
нет. я и со времён AT&T 2.0 знаю C++ только частично
_>Название после цикла? Тут нет проблем. Цикл на три страницы — вот это проблема.
я не призываю увеличить C++, просто объясняю человеку общеизвестные вещи из теории ЯП
Здравствуйте, dmitry_npi, Вы писали:
_>Здравствуйте, BulatZiganshin и FR
_>Ну вы даёте... Вы, наверно, смерти желаете С++? Я за молодостью лет не застал язык PL/1, но пишут, что он умер от того, что в нем слишком много всего было.
Я тоже не застал, но говорят что C++ его и так уже догнал
_>Вы хотите, чтобы нужно было постоянно держать в голове тысячу особенностей? _>Вы хотите, чтобы ежедневное программирование по сложности стало каким-то таким
Нет наоборот, чтобы такого не было языку шаблонов не хватает выразительности, чтобы хватало нужно совсем немного добавить, новый стандарт делает правильные, но слишком робкие шаги. Например в том же D в шаблоны уже добавлено практически все что нужно, и писать на шаблонах там на порядок проще чем в C++ и например весь ужас из твоей ссылки заменится простой compile time функцией.
_>Название после цикла? Тут нет проблем. Цикл на три страницы — вот это проблема. _>Много вложенных циклов? Так избавьтесь от них. Сделайте функцию, а в ней return. Сделайте ее inline.
_>Ну а в редких случаях (типа обработки n-мерных массивов) поставьте goto. И комментарии. Один оператор goto в пределах функции 50 — 100 строк не испортит вашу карму. И да не падёт на вас проклятье Дийкстры.
Выход из цикла в D стиле ничего ни добавляет лишнего, все просто и прозрачно и карма не страдает совсем
Здравствуйте, dmitry_npi, Вы писали:
_>Ну вы даёте... Вы, наверно, смерти желаете С++? Я за молодостью лет не застал язык PL/1, но пишут, что он умер от того, что в нем слишком много всего было.
На самом деле, нет. Он ушёл в прошлое вместе с Большими Машинами (tm). Просто в нём было много такого, что не требовалось в языках а-ля C. Например, механизм определения типа переменной по имени. То есть фич-то было много, но на практике они были скорее странными, чем сильно необходимыми. А так, чего там, есть (были, во всяком случае, сейчас лень искать) компиляторы PL/M и для PC.
P.S.: Хотя... Вот, для IBM zSeries, наверное, есть PL/1, который не подозревает о том, что он уже прошлое.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
_>>Ну вы даёте... Вы, наверно, смерти желаете С++? Я за молодостью лет не застал язык PL/1, но пишут, что он умер от того, что в нем слишком много всего было.
ГВ>А так, чего там, есть (были, во всяком случае, сейчас лень искать) компиляторы PL/M и для PC.
pl/m к этой избыточности отнощшения как раз не имеет, это язык на уровне C
Здравствуйте, Caracrist, Вы писали:
C>Скажу чего мне нехватает
4. initialize an array, in the initialization list of a constructor
class A
{
int arr[5];
A() :
arr[i]( (i > 2)?(arr[i-1]+arr[i-2]):1 ) // i represents compiletime const value, can be used as template parameter for example
{}
};
в случае с интом это конечно погоды не сделает,
а вот вызывать дефолтный коструктор у более сложных классов не всегда имеет смысл.
Здравствуйте, Caracrist, Вы писали:
C>Здравствуйте, Caracrist, Вы писали:
C>>Скажу чего мне нехватает
C>4. initialize an array, in the initialization list of a constructor C>class A C>{ C> int arr[5]; C> A() : C> arr[i]( (i > 2)?(arr[i-1]+arr[i-2]):1 ) // i represents compiletime const value, can be used as template parameter for example C> {} C>}; C>в случае с интом это конечно погоды не сделает, C>а вот вызывать дефолтный коструктор у более сложных классов не всегда имеет смысл.
struct Pub
{
static const int dArr[4][i] = i * 2;
typedef int const (&TT)[3];
static TT t;
static TT t2;
};
Pub::TT Pub::t[j](j * j);
const int Pub::t2[4][_](t[_] * _ - 1);
Здравствуйте, jazzer, Вы писали:
J>Есть какие-то специфические проблемы именно с noncopyable? J>Я не помню, использовал ли я optional с noncopyable. Может, и есть какие проблемы.
Есть небольшая особенность, вызванная больше проблемой дизайна и как раз документированая.
В случае использования указателя, вызов new происходит в функции принадлежащей классу, и никаких друзей объявлять не приходится.
В случае с использованием in_place требуется указать всех друзей, конструкторов которых мы вызываем.