Yoda писал(а):
Код:
int72 operator + (int72 a, int72 b) {
int128 t = a.l + b.l;
Result.l = int64(t);
Result.h = a.h + b.h + t>>64;
}
Сергей, я в недоумении. Куда опять дели байт?
Yoda писал(а):
В данном случае ТеХ - это язык программирования, а визивиги - среды разработки. Таким образом, собственно языком является неудобоваримое текстовое представление.
Что ж, верно. Тогда давайте я перестану смешивать собственно язык и среду программирования. Мне трудно представить полностью графический язык программирования, непонятно, как лексический анализатор должен будет распознавать всякие «многоэтажные» математические записи. Язык должен быть plain-text, а отображение должно быть привычным для математика, а удобными для программирования должны быть оба этих инструмента. Вот, пока у меня именно такое мнение. Так можно делать в Maple, переключаться меду режимами, если что.
Yoda писал(а):
А я почём знаю? Я даже не уверен, что изменения не могут затронуть первые 32 символа. Я бы по крайней мере, попробовал бы там тоже навести какое-то подобие порядка. Пожалуй, можно утверждать, что точно устоялись символы с кодами 10, 32-126. Даже символ с кодом 13 - порождение зла, его то с одной стороны приткнут, то с другой, то вообще выкинут, то изобретают специальные моды открытия файла для работы с ним.
Печально. Я вот хотел бы отказаться от многих ключевых слов типа for, if, заменив их разными визуальными символами. Видимо, от идеи придётся отказаться пока.
Yoda писал(а):
Это нереально и единственно, к чему может привести, это к куче негативных отзывов. С моей точки зрения было бы правильней стандартизировать: табуляция - это ВСЕГДА 8 позиций. Но даже в этом случае обязательно будут недоразумения.
Я вот тут не согласен. Можно взять и запретить, и наплевать на отзывы. Конечно, тут можно возразить, дескать, я не авторитет, чтобы решать данный вопрос. Но есть вещи, которые нужно отрубать жёстко. Ещё вариант: отступы в языке делать ТОЛЬКО символом tab и никаким больше. Пробел в начале строки будет синтаксической ошибкой. Но блин, это не сработает, так как многие редакторы настраиваются их пользователями так, чтобы tab сразу заменялся на пробелы (у меня это 2 пробела и чхать на всё : ) ) Мы здесь приходим к неоднозначности, в моей концепции (которую я пытаюсь продумать) сказано, что не должно быть никаких неоднозначностей. И здесь вопрос ребром: либо запрещаем tab, либо создаём какие-то совершенно однозначные правила его использования. Современный tab в отступах - это такое же недоразумение, как возврат каретки. Имхо.
Yoda писал(а):
16-битные целые числа к 32-битным тоже явно приводить?
Нет, можно, как было предложено, создать чёткую иерархию и правила преобразования.
Yoda писал(а):
А если есть типы, определённые пользователем, с тем же видом отношений между ними?
Пользователь должен прописать правила преобразования (по сути, эту задачу решает конструктор, который нужно указывать явно)
Yoda писал(а):
А если есть необъемлющие типы, которые было бы удобно приводить автоматически? Например, функция вывода сообщений ожидает указатель на константную строку символов, а у вас собственный тип данных строк, нужно ли позволить неявное приведение или каждый раз надо писать:
Код:
cout << static_cast <const char *>(mystr);
?
Оператор «<<» для ostream придётся прописать для нашей собственной строки, раз мы её определяем.
Yoda писал(а):
А если учесть, что результатом умножения всегда является удвоенный размер, нужно ли явно приводить результат к тому же типу после умножения?
Нет, оператор умножения должен возвращать тот размер, который определён в его коде. Если прописано, что возвращается удвоенный размер, значит возвращается удвоенный, если нет, то нет. Умножение чисел с бесконечной точностью, например, не возвращает удвоенный по размеру тип, а возвращает тот же тип. Если мы пишем, c=a*b, значит компилятор должен понять, что вернуть нужно тип decltype(с), либо ошибку (если нет такого оператора умножения). На самом деле, это непростой вопрос, заставлять компилятор из контекста определять тип результата. Например, программист может от выражения a*(b*c) хотеть, чтобы в скобках тип на время или навсегда стал удвоенным, чтобы случилось переполнение и отрезание старшей половины, чтобы тип стал не удвоенным, а утроенным. Я не думаю, что эту проблему можно оставить на откуп компилятору. Лучше прописать явно, чего мы хотим. Например,
Код:
int64 a, b, c;
a*int128(b*c) // явно хотим, чтобы b*c имело удвоенный тип.
a*(b*c) // явно хотим, чтобы b*c имело тот же тип.
int128(a*(b*c)) // явно хотим, чтобы b*c имело тот же тип, а умножение на a уже удвоенный.
У Вас имеется более удачный вариант решения проблемы? Я считаю, что приводить тип к int128, а затем выполнять умножение – это пустая трата ресурсов.
Yoda писал(а):
А если вспомнить, что даже операции с плавающей точкой как правило приводят к потере точности (а то и к переполнению), нужно ли после каждой операции над числами типа float приводить результат к float?
Если это не следует из контекста, то да. Если написана команда float=float*float, то умножаем как есть с одинарной точностью. Если написано double = float*float, значит нужно обеспечить умножение с удвоенной точностью. Это непривычно для программиста на C++, как и предыдущие примеры, но я лучше не придумал.
Yoda писал(а):
Моя точка зрения состоит в том, что константы не должны иметь точно указанного размера, как например 1ULL в C/C++, т.к. они всегда используются только в каком-то контексте. Любые константные вычисления компилятор должен производить с бесконечной точностью и по результату приведения к конечному требуемому типу выдавать ОШИБКУ, если число выходит за целевой диапазон значений.
Вот, да, я согласен. Если мы вводим встроенный тип бесконечной точности (а такой должен быть), то проблема решается очень просто.
Yoda писал(а):
А суффиксы - это зло, они усложняют логику и вынуждают программиста явно держать в голове не только сами расчёты, но и размер результатов после каждой операции.
А я так и постарался описать суффиксы, чтобы они были ещё больше похожи на зло.
Yoda писал(а):
Разумное объяснение: запись типа .5 усложняет лексический анализ, т.к. при встрече символа "." в потоке требуется проверка следующего символа, не число ли. Если язык допускает нумерованные поля, то потребуются ещё более сложные телодвижения для анализа, необходимо ли трактовать a.5 как пятое поле структуры "a" или переменную "a", за которой следует константа с плав.тчк.
Хорошо, Ваша точка зрения ясна, но она лежит в области программирования транслятора. Возможно, мало кого из пользователей будет волновать, что транслятор будет чуть сложнее. Моё неприятие подобной записи скорее эмоционально-эстетическое. Плюрализм на способы записи одного и того же выражения здесь создаёт у меня какой-то внутренний дискомфорт. Возникает необходимость задумываться над тем, как мне «вот здесь» написать – «0.5» или «.5», а как «вот здесь», а как мне написать число «0»? Написать «0.» или «.0» или просто «.»? И т. д.. Тут же появляется несколько сторонников того и другого лагеря, они начинают устраивать холивар на пустом месте, провоцируется драка, создаются разные ветки языка, обиды и негодования друг на друга и т. д. и т. п.
Yoda писал(а):
Всё верно. А префиксную запись типа 0xABCD я бы запретил. Да и восьмеричную систему счисления тоже запретил бы. Только два суффикса - b и h.
У Вас есть исследования, которые позволяли бы столь смело выбрасывать восьмеричную систему? Я ни разу за 15 лет ей не воспользовался в реальной программе (если не считать тупых университетских задач, придуманных, видимо, для детей младше 3-х лет). Но я – это я, моя категоричность иногда бесит людей, поэтому я стараюсь прислушиваться к ним, если они говорят достаточно аргументированно.
Yoda писал(а):
Никаких апострофов перед суффиксами. Неоднозначность решается просто, - любое число должно начинаться с цифры. 0ABCDh - число, ABCDh - переменная.
Если честно, то это некрасиво : ) хотя и проще для анализа. И с апострофом тоже не очень. Видимо, придётся пожертвовать здесь красотой.
Yoda писал(а):
Лирическое отступление по поводу типизации. Дэн Гроссман, ведущий на курсере курс "Языки программирования" от Вашингтонского университета, считает (и я в этом с ним полностью согласен), что деление на слабую и сильную типизацию некорректно, ибо нет чёткого определения такого разделения. В каждом языке есть свои правила приведения типов, что можно приводить неявно, а что нельзя. С/С++ являются не слабо, а плохо типизированными языками. Например, в С проблемой является не смешение целочисленного и булевого типов, а отсутствие булевого.
Ну так я согласен, сам так думаю, просто придерживаюсь принятой сейчас в обществе терминологии, чтобы меня понимали. Меня также не устраивает деление языков на типы: функциональный, императивный, декларативный. Это как делить людей на сангвиников, флегматиков, меланхоликов и холериков, а затем делать из этого далеко идущие выводы о поведении людей, постоянно ошибаясь и навешивая на них пустые ярлыки. Всегда имеем либо смесь парадигм программирования в одном языке, либо плохой язык программирования. Типизация не должна быть сильной или слабой, она должна быть просто. Если Вы тоже так считаете, то с этого момента я не буду говорить «сильная типизация», а буду считать, что типизация есть и небезопасное преобразование типов, а также смешивание логики в процессе преобразования запрещены.