Здравствуйте, Кодт, Вы писали:
ЗХ>>2) иногда (часто?) между объектами типа определено только отношение равенства, но не порядка. (иногда и наоборот, но это уже клинический случай).
К>Как это?! Если есть порядок, то автоматически есть и равенство.
Это насчет "иногда и наоборот"?
Ну, я могу представить такую ситуацию, когда сортировка объектов возможна (существует отношение порядка), а равенство возможно только в смысле равенства самому себе (identity).
Например, куча non-copiable объектов, которые все существуют в программе в единственном экземпляре; а пользователь оперирует оными объектами через указатели/ссылки. Для проверки равенства самому себе достаточно сравнения указателей; другого равенства заведомо не может быть.
К>Задумку дискредитирует то, что К>- в С++ операторы между собой не связаны К>- а в D, где связь есть, не пошли до конца (скажем, могли потребовать: если определён opCmp, то opEqual определяется автоматически и не подлежит перекрытию)
факт.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>>>2) иногда (часто?) между объектами типа определено только отношение равенства, но не порядка. (иногда и наоборот, но это уже клинический случай).
К>>Как это?! Если есть порядок, то автоматически есть и равенство. ЗХ>Это насчет "иногда и наоборот"? ЗХ>Ну, я могу представить такую ситуацию, когда сортировка объектов возможна (существует отношение порядка), а равенство возможно только в смысле равенства самому себе (identity). ЗХ>Например, куча non-copiable объектов, которые все существуют в программе в единственном экземпляре; а пользователь оперирует оными объектами через указатели/ссылки. Для проверки равенства самому себе достаточно сравнения указателей; другого равенства заведомо не может быть.
Ну и кто мешает в предикате/компараторе делать такую быструю проверку?
bool less(const A& a, const A& b)
{
if(&a == &b) return false;
return deep_less(a,b);
}
int compare(const A& a, const A& b)
{
if(&a == &b) return 0;
return deep_less_or_greater(a,b); // компаратор, от которого не ожидают нуля
}
Здравствуйте, Кодт, Вы писали:
ЗХ>>>>2) иногда (часто?) между объектами типа определено только отношение равенства, но не порядка. (иногда и наоборот, но это уже клинический случай).
К>>>Как это?! Если есть порядок, то автоматически есть и равенство. ЗХ>>Это насчет "иногда и наоборот"? ЗХ>>Ну, я могу представить такую ситуацию, когда сортировка объектов возможна (существует отношение порядка), а равенство возможно только в смысле равенства самому себе (identity). ЗХ>>Например, куча non-copiable объектов, которые все существуют в программе в единственном экземпляре; а пользователь оперирует оными объектами через указатели/ссылки. Для проверки равенства самому себе достаточно сравнения указателей; другого равенства заведомо не может быть.
К>Ну и кто мешает в предикате/компараторе делать такую быструю проверку?
может быть, логика... типа, если они логически не могут быть равны, то и возможности сравнить на равенство — не надо.
Впрочем, это я уже загнул. Спешу напомнить, что мной было сказано:
...определено только отношение равенства, но не порядка. (иногда и наоборот, но это уже клинический случай).
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
FAQ — це мiй ай-кью!
Re[14]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, vdimas, Вы писали:
V>>...либо усложнять блок finally, проверяя, что мы успели создать, а что нет...
СГ>Вы правы, но наполовину. Дело в том, что проверить перед уничтожением объекта был ли он создан, вообще-то, еще ни кому ни когда не вредило в любом случае, не зависимо от того есть finally или нет его.
Подобная проверка зачастую невозможна без нарушений инкапсуляции проверяемого объекта либо усложнения его интерфейса именно для целей проверки. Учитывая всеобщую лень и стремление к минимизации кода, наиболее вероятным представляется первый вариант. Последствия нарушения инкапсуляции могут быть самыми разнообразными, вплоть до катастрофических в "больших" проектах, где функциональность разделена на уровни, а сами программисты — на заказчиков и потребителей функциональности.
Re[3]: ЧАСТЬ 4: синтаксический сахар, синтаксический мусор..
Здравствуйте, VladD2, Вы писали:
M>>*мрачно* Только за это я готов на D перейти. А то как раз ситуевина, млин. Извращаюсь через енумы...
VD>По-моему, кроме С++ все кому не лень позволяют делать свитчи по строкам.
VD>К тому же эмулируется это дело очень просто. Строишь хэш-таблицу ключем которой является строка, а значением функция-обработчик...
"Все кому не лень" делают это по одной простой причине — в языках имеется тип "строка". В C++ такого типа не существует. Следовательно, switch/case по строке невозможен по причине отсутствия самой строки.
C# AFAIK тоже не позволяет писать switch/case по объектам произвольного типа. А как было бы прельстиво:
class Key
{
Key(int i, string s);
. . .
bool operator < (const Key&) ...
};
. . .
switch(Key(i, s))
{
case Key(1, "123"):
case Key(1, "124"):
. . .
}
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[4]: ЧАСТЬ 4: синтаксический сахар, синтаксический мусор..
Здравствуйте, McSeem2, Вы писали:
M>>>*мрачно* Только за это я готов на D перейти. А то как раз ситуевина, млин. Извращаюсь через енумы...
VD>>По-моему, кроме С++ все кому не лень позволяют делать свитчи по строкам.
VD>>К тому же эмулируется это дело очень просто. Строишь хэш-таблицу ключем которой является строка, а значением функция-обработчик...
MS>"Все кому не лень" делают это по одной простой причине — в языках имеется тип "строка". В C++ такого типа не существует. Следовательно, switch/case по строке невозможен по причине отсутствия самой строки.
MS>C# AFAIK тоже не позволяет писать switch/case по объектам произвольного типа. А как было бы прельстиво:
Кстати, да. Первое моё движение, когда я узнал про свич по строкам в Ди — "а по произвольным классам?"
Узнав, что нельзя, "гестапа очень ругалась".
Вопрос: почему нельзя? Что этому мешает? У кого-нибудь есть логичный ответ?
D, оставаясь наследником C++ по духу, все же решает задачу, об которую (по общеизвестным причинам) в свое время обломал зубы Бьярн. Препроцессора нет.
Возникает закономерный вопрос: а что есть и хватает ли этого?
Ответим на этот вопрос по порядку задач, решаемых препроцессором.
Макросы-константы и макросы-"функции"
Проблема решена еще в С++ — обычными константами и инлайновыми функциями (заметим в скобках, что ключевого слова inline в D нет — подстановка функций остается полностью на совести компилятора).
#include
Директива текствого включения исключена за ненадобностью — в D есть модульность.
Определение модуля:
module mymodule; //этого можно не писать. тогда имя модуля совпадет с именем файла, в котором содержится модуль
//еще можно так:
module mypackage.mysabpackage.mymodule; //логическая группировка модулей в "пакеты"
version(UNICODE) //символ, переданный в качестве ключа компилятору
{
....
}
else
{
....
}
Заметим, что в стандарте D заложена дихотомия Debug/Release, то есть следующая кострюхция будет работать без каких-либо дополнительных телодвижений:
version(Debug)
{
...куча дебужного коду...
}
Кроме того, D придает специальный смысл конструкции if(0) — она является аналогом препроцессорного #if(0) в С/С++ — то есть все, что внутри соответствующего блока, не будет компилироваться.
__LINE__, __FILE__ и др.
D предполагает, что единственный смысл использования "особых макросов" — информативность выражения assert. Соответственно, в D выражение assert является не библиотечной функцией, а частью core language, благодаря чему "само" знает, на какой строке и в каком файле приключилось.
#error и static assert
Как слышится, так и пишется
static assert(int.sizeof >= 4);
#pragma
Для некоторых общеупотребительных прагм у D есть свои конструкции (#pragma pack => align), некоторые не нужны вообще (#prgama once). Для всех остальных остается-таки ключевое словечка pragma в core language.
Дальше и дальше...
Дальше — это уже template's & mixin's. О которых — в следующей серии
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
FAQ — це мiй ай-кью!
Re[5]: ЧАСТЬ 4: синтаксический сахар, синтаксический мусор..
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Кстати, да. Первое моё движение, когда я узнал про свич по строкам в Ди — "а по произвольным классам?" ЗХ>Узнав, что нельзя, "гестапа очень ругалась". ЗХ>Вопрос: почему нельзя? Что этому мешает? У кого-нибудь есть логичный ответ?
Ничто не мешает. Традиции мешают и косность мышления
Ну, в C++ еще понятно — четкое разделение самого языка и производных этого языка, AKA классов. А в том же C# или Java, с их IL это сделать вообще раз плюнуть.
Хотя и в C++ проникла некая интеграция языка со стандартной библиотекой. Как, например, реализуется dynamic_cast<reference> с его "throw bad_cast"? Ведь dynamic_cast — это конструкция языка, а bad_cast — это конструкция библиотеки. То же самое с bad_alloc. Получается, что язык знает кое-что о стандартной библиотеке. Так почему бы тогда всю стандартную библиотеку не интегрировать в сам язык?
В том же C# или D можно было бы таких синтаксических конфеток наделать — ухх-ням-ням! Но сделали. Плохие танцоры, наверное — что-то мешает.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Проблема решена еще в С++ — обычными константами и инлайновыми функциями (заметим в скобках, что ключевого слова inline в D нет — подстановка функций остается полностью на совести компилятора).
Вот это плохо. Хотелось бы все-таки неких средств гарантированной оптимизации. То есть, что-то типа MS __forceinline, только еще жестче — функция может быть только inline, она не может иметь собственного адреса, не может быть рекурсивной и т.д. Она может быть только inline. Ну, разумеется, с некими ограничениями по уровню вложенности в случае неявной рекурсии. То есть, если компилятор видит, что "разворачивание" переходит всякие границы (типа 16 или сколько-то там уровней вложенности), то выдает ошибку и не пытается ничего сам решить. Ох, как я не люблю, когда какой-то компилятор вместо меня принимает некое "фундаментальное" решение.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>__LINE__, __FILE__ и др. ЗХ>D предполагает, что единственный смысл использования "особых макросов" — информативность выражения assert. Соответственно, в D выражение assert является не библиотечной функцией, а частью core language, благодаря чему "само" знает, на какой строке и в каком файле приключилось.
Зря он так предполагает
Например, при логировании __FILE__ и __LINE__ здорово помогают. Как и макросы, кстати.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, eao197, Вы писали:
E>>Зря он так предполагает E>>Например, при логировании __FILE__ и __LINE__ здорово помогают. Как и макросы, кстати.
AVK>Еще один важный кусок задач — кодогенераторы.
Да, я тоже хотел об этом сказать. Но поскольку в исходном сообщении ЗХ не было упомянута директива #line, то решил об этом не говорить. К тому же, при желании, кодогенераторы могут сами подсчитывать номера строк в генерируемом коде Хоть это и геморройно.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
К>>Ну и кто мешает в предикате/компараторе делать такую быструю проверку?
ЗХ> может быть, логика... типа, если они логически не могут быть равны, то и возможности сравнить на равенство — не надо. ЗХ>Впрочем, это я уже загнул. Спешу напомнить, что мной было сказано: ЗХ>
ЗХ>...определено только отношение равенства, но не порядка. (иногда и наоборот, но это уже клинический случай).
Действительно, клинический. Порядок сильнее равенства, а равенство сильнее идентичности. То есть, объект сам себе (идентичность истинна) должен быть равен при любом раскладе.
Здравствуйте, McSeem2, Вы писали:
ЗХ>>Проблема решена еще в С++ — обычными константами и инлайновыми функциями (заметим в скобках, что ключевого слова inline в D нет — подстановка функций остается полностью на совести компилятора).
MS>Вот это плохо. Хотелось бы все-таки неких средств гарантированной оптимизации. То есть, что-то типа MS __forceinline, только еще жестче — функция может быть только inline, она не может иметь собственного адреса, не может быть рекурсивной и т.д. Она может быть только inline. Ну, разумеется, с некими ограничениями по уровню вложенности в случае неявной рекурсии. То есть, если компилятор видит, что "разворачивание" переходит всякие границы (типа 16 или сколько-то там уровней вложенности), то выдает ошибку и не пытается ничего сам решить. Ох, как я не люблю, когда какой-то компилятор вместо меня принимает некое "фундаментальное" решение.
mixin есть для таких случаев — гарантированная вставка фрагмента
кода, деклараций и/или классов.
Здравствуйте, c-smile, Вы писали:
ЗХ>>>Проблема решена еще в С++ — обычными константами и инлайновыми функциями (заметим в скобках, что ключевого слова inline в D нет — подстановка функций остается полностью на совести компилятора).
MS>>Вот это плохо. Хотелось бы все-таки неких средств гарантированной оптимизации. То есть, что-то типа MS __forceinline, только еще жестче — функция может быть только inline, она не может иметь собственного адреса, не может быть рекурсивной и т.д. Она может быть только inline. Ну, разумеется, с некими ограничениями по уровню вложенности в случае неявной рекурсии. То есть, если компилятор видит, что "разворачивание" переходит всякие границы (типа 16 или сколько-то там уровней вложенности), то выдает ошибку и не пытается ничего сам решить. Ох, как я не люблю, когда какой-то компилятор вместо меня принимает некое "фундаментальное" решение.
CS>mixin есть для таких случаев — гарантированная вставка фрагмента CS>кода, деклараций и/или классов.
Во! Факт, мною не учтенный.
Кстати, возможно, это более логичный подход: у inline-овых функций есть некая странноватая смысловая нагрузка "выглядит как функция, но на самом деле это просто кусок кода". "Странность" заключается в том, что нет никакой возможности воспользоваться бенефитами реальной подстановки: получить доступ к контексту выполнения. В этом смысле идея миксина как "макроса, только правильного" — возможно, вполне имеет правов на жизнь.
ЗЫ: Пошел спать. Проснусь — распишу-таки преподробно про D-шные templates и mixins. Давно пора было.
Здравствуйте, Зверёк Харьковский, Вы писали:
CS>>mixin есть для таких случаев — гарантированная вставка фрагмента CS>>кода, деклараций и/или классов.
ЗХ>Во! Факт, мною не учтенный. ЗХ>Кстати, возможно, это более логичный подход: у inline-овых функций есть некая странноватая смысловая нагрузка "выглядит как функция, но на самом деле это просто кусок кода". "Странность" заключается в том, что нет никакой возможности воспользоваться бенефитами реальной подстановки: получить доступ к контексту выполнения. В этом смысле идея миксина как "макроса, только правильного" — возможно, вполне имеет правов на жизнь.
Но с другой стороны inline функции более закрыты (вход параметры выход тоже один) а необдуманое использование миксинга может дать малопонятные побочные эффекты, то есть в миксинге сохраняются не только достоинства но и не достатки макросов.
Здравствуйте, FR, Вы писали:
CS>>>mixin есть для таких случаев — гарантированная вставка фрагмента CS>>>кода, деклараций и/или классов.
ЗХ>>Во! Факт, мною не учтенный. ЗХ>>Кстати, возможно, это более логичный подход: у inline-овых функций есть некая странноватая смысловая нагрузка "выглядит как функция, но на самом деле это просто кусок кода". "Странность" заключается в том, что нет никакой возможности воспользоваться бенефитами реальной подстановки: получить доступ к контексту выполнения. В этом смысле идея миксина как "макроса, только правильного" — возможно, вполне имеет правов на жизнь.
FR>Но с другой стороны inline функции более закрыты (вход параметры выход тоже один) а необдуманое использование миксинга может дать малопонятные побочные эффекты, то есть в миксинге сохраняются не только достоинства но и не достатки макросов.
Не готов обсуждать этот вопрос. Пока я только читаю спеку и пишу небольшие тестовые программки. Прелесть/гадость миксинов еще не осознал.