Оператор присваивания
Модератор: Модераторы
Оператор присваивания
Казалось бы, нет ничего лучше традиционного Паскалевского оператора присваивания. Однако прогресс на месте не стоит и к настоящему времени есть ряд хороших расширений.
1. Использование для совмещения определения переменных с инициализацией.
переменная[:тип] := выражение
Если тип опущен, то он выводится компилятором.
Так можно избегать громозких секций описания и определять локальные переменные прямо в ходе. Опасность - опечатка при переприсваивании с возможностью опустить тип ведет к описанию новой переменной, т.е. синтаксическая ошибка становится семантической, что не есть хорошо.
Поэтому для присваиваний, совмещенных с описаниями есть резон сделать указание типа обязательным.
2. Использование для определения констант.
константа[:тип] ::= выражение
Кто сказал, что константы обязаны вычисляться только во время компиляции?
Константы - это то, что нельзя переприсваивать, а не только то, что вычислено еще до выполнения.
Такая возможность (аналог const в C++) позволяет обнаруживать ошибки переприсваивания того, что по логике алгоритма не должно обновляться. Вдобавок такой оператор позволяет компилятору сильно оптимизировать код.
Для констант необязательность указания типа логична и целессобразна - их никто переприсваивать не будет.
Почему именно ::=? Во-первых не будет коллизиии с операцией сравнения, во-вторых это сочетание знаков в БНФ означает "определено как".
3. Использование структур в левой части оператора присваивания.
Например, вот пример с кортежем:
(i, x) := (1, 1)
Это позволяет сделать код более лаконичным и прозрачным, выделяя логически связанные присваивания, а также позволяет лучше оптимизировать (а то и распараллелить!) код - порядок присваивания элементов внутри структуры не определен.
1. Использование для совмещения определения переменных с инициализацией.
переменная[:тип] := выражение
Если тип опущен, то он выводится компилятором.
Так можно избегать громозких секций описания и определять локальные переменные прямо в ходе. Опасность - опечатка при переприсваивании с возможностью опустить тип ведет к описанию новой переменной, т.е. синтаксическая ошибка становится семантической, что не есть хорошо.
Поэтому для присваиваний, совмещенных с описаниями есть резон сделать указание типа обязательным.
2. Использование для определения констант.
константа[:тип] ::= выражение
Кто сказал, что константы обязаны вычисляться только во время компиляции?
Константы - это то, что нельзя переприсваивать, а не только то, что вычислено еще до выполнения.
Такая возможность (аналог const в C++) позволяет обнаруживать ошибки переприсваивания того, что по логике алгоритма не должно обновляться. Вдобавок такой оператор позволяет компилятору сильно оптимизировать код.
Для констант необязательность указания типа логична и целессобразна - их никто переприсваивать не будет.
Почему именно ::=? Во-первых не будет коллизиии с операцией сравнения, во-вторых это сочетание знаков в БНФ означает "определено как".
3. Использование структур в левой части оператора присваивания.
Например, вот пример с кортежем:
(i, x) := (1, 1)
Это позволяет сделать код более лаконичным и прозрачным, выделяя логически связанные присваивания, а также позволяет лучше оптимизировать (а то и распараллелить!) код - порядок присваивания элементов внутри структуры не определен.
- bw
- постоялец
- Сообщения: 359
- Зарегистрирован: 01.12.2005 10:36:23
- Откуда: Усть-Илимск
- Контактная информация:
> переменная[:тип] := выражение
Так я считаю лучше:
А почему у тебя тип в кв. скобках? Ты думаешь что его объявление не всегда нужно? Мне кажется что тип указывать нужно обязательно. По ходу кода должно быть понятно, с переменной какого типа мы имеем дело.
> константа[:тип] ::= выражение
> Во-первых не будет коллизиии с операцией сравнения
..bw
Так я считаю лучше:
Код: Выделить всё
var переменная: тип = выражение;А почему у тебя тип в кв. скобках? Ты думаешь что его объявление не всегда нужно? Мне кажется что тип указывать нужно обязательно. По ходу кода должно быть понятно, с переменной какого типа мы имеем дело.
> константа[:тип] ::= выражение
Код: Выделить всё
const константа: тип = выражение;> Во-первых не будет коллизиии с операцией сравнения
Код: Выделить всё
if константа == 1 then .....bw
bw
Думаю, да. Тип переменной=тип выражения инициализации. Его в большинстве случае видно невооруженным глазом.
В большинстве случаев это даст лаконичность без потери прозрачности.
А зачем var? Указание типа переменной - уже ясно видимый признак определения, а не переприсваивания.
От двойного равенства меня тошнит
Да и в математике равенство принято обозначать одиночным знаком.
bw писал(а):А почему у тебя тип в кв. скобках? Ты думаешь что его объявление не всегда нужно?
Думаю, да. Тип переменной=тип выражения инициализации. Его в большинстве случае видно невооруженным глазом.
В большинстве случаев это даст лаконичность без потери прозрачности.
bw писал(а):Так я считаю лучше:
А зачем var? Указание типа переменной - уже ясно видимый признак определения, а не переприсваивания.
bw писал(а): Во-первых не будет коллизиии с операцией сравнения
От двойного равенства меня тошнит
- bw
- постоялец
- Сообщения: 359
- Зарегистрирован: 01.12.2005 10:36:23
- Откуда: Усть-Илимск
- Контактная информация:
> А зачем var? Указание типа переменной - уже ясно видимый признак определения, а не переприсваивания.
У тебя вроде как указание типа не обязхательно
. Так что не всегда будет понятно, что к чему, а с var однозночно ясно. Врядли использование var сильно снизит скорость написания кода, зато при отладке поможет сильно. Я бы даже ввел (наверное) оператор "del":
Хотя с другой стороны я не поощраю функции таких размеров где жизненный цикл переменной не прозрачен. Собственно по этому и объявление переменных я считаю должно быть в одном месте, до начала кода. Если же начинает смущать то что объявление переменной в одном месте, а инициализация (и использование) намного дальше - значит пока разбивать метод на два или большее число методов
.
..bw
У тебя вроде как указание типа не обязхательно
Код: Выделить всё
var I: Integer = 0;
...
del I;
...
WriteLn(I); {компилятор матюгнется}
Хотя с другой стороны я не поощраю функции таких размеров где жизненный цикл переменной не прозрачен. Собственно по этому и объявление переменных я считаю должно быть в одном месте, до начала кода. Если же начинает смущать то что объявление переменной в одном месте, а инициализация (и использование) намного дальше - значит пока разбивать метод на два или большее число методов
..bw
bw писал(а):У тебя вроде как указание типа не обязхательно
Ага
bw писал(а):Я бы даже ввел (наверное) оператор "del"
Незачем. У нас уже есть операторные скобки - переменная видна только на том уровне где определена и ниже.
bw писал(а):Хотя с другой стороны я не поощраю функции таких размеров где жизненный цикл переменной не прозрачен.
Такой вывод следует из неявного (и очень сильного!) предположения, что локализация переменной должна быть той же, что и локализация алгоритма в виде процедуры.
На практике это не так - для переменной оптимальная область видимости много меньше подпрограммы (о чем хорошо знают разработчики оптимизаторов) Самый наглядный пример - параметр цикла, нафиг не нужный (в том числе физически!) за его пределами, хотя сам цикл отдельной подпрограммы достоин далеко не всегда.
Или переменные в пределах одной из альтернатив условного оператора - если управление не попадает на соответсвующую ветку, то им даже память можно не выделять! Такая возможность критична для эффективной реализации рекурсивных алгоритмов.
- bw
- постоялец
- Сообщения: 359
- Зарегистрирован: 01.12.2005 10:36:23
- Откуда: Усть-Илимск
- Контактная информация:
> Самый наглядный пример - параметр цикла
С этим в соседнюю ветку, так что как пример не катит.
> то им даже память можно не выделять!
Ну
. Ну будешь же ты динамически под каждый "байт" (переменную) выделять память. Это делается иначе, и ты знаешь как.
Все же я остаюсь против возможности объявления переменной в теле функции.
p.s. Мы сильно в оффтоп ушли, не думаешь
? Я думаю пора отделить часть сообщений в тему "Переменные" или что-нибудь такоё.
..bw
С этим в соседнюю ветку, так что как пример не катит.
> то им даже память можно не выделять!
Ну
Все же я остаюсь против возможности объявления переменной в теле функции.
p.s. Мы сильно в оффтоп ушли, не думаешь
..bw
bw писал(а):Ну будешь же ты динамически под каждый "байт" (переменную) выделять память. Это делается иначе, и ты знаешь как.
Знаю
Но экономия есть: если в одной из альтернатив нам нужна переменная x, а в другой - y, то при определении на уровне подпрограммы расход памяти будет sizeof x+sizeof y, а при определении на уровне блока - max(sizeof x,sizeof y) - если выделять память на стеке при входе в подпрограмму.
Но что меня в свое время поразило - в рекурсивных подпрограммах экономия памяти за счет локализации переменных на более низком, чем подпрограммы, уровне давала возможность расширить рабочий (без переполнекния стека) диапазон параметров в несколько раз.
Кстати, вот такая иллюстрация:
Код: Выделить всё
begin
t ::= a
a := b
b := t
end;
Зачем нужна t за пределами этого блока?
Зачем нужно явно указывать ее тип?
- Deepthroat
- постоялец
- Сообщения: 144
- Зарегистрирован: 06.09.2007 00:21:34
- Откуда: Outer Heaven
- Контактная информация:
Я тоже думаю, что хорошо бы указывать тип. Это позволит избежать ошибок. Например, так очень даже ничего:
Здесь t - целое, и это мы наем точно. Но что, если тип не указан, а мы где-то вверху ошиблись в типе? Тем более, что описание a находится не сверху, а где-то внутри кода, т.е. надо долго и упорно искать это описание. Да если там еще и тип не указан, то вообще вешайся - ищи описание переменных (всех - вдруг одна из трех-пяти-десяти имеет тип real!), через которые описана a. А каждая переменная описана х.з. где, да еще и не у каждой тип указан. Т.е. для определения типа всех переменных, через которые описана a, надо определить тип всех переменных, через которые описаны все переменные, через которые описана a.
Ну вы поняли, да? К чему ведет необязательность объявления типа...
Код: Выделить всё
begin
var t: integer := a;
a := b;
b := t;
end;
Здесь t - целое, и это мы наем точно. Но что, если тип не указан, а мы где-то вверху ошиблись в типе? Тем более, что описание a находится не сверху, а где-то внутри кода, т.е. надо долго и упорно искать это описание. Да если там еще и тип не указан, то вообще вешайся - ищи описание переменных (всех - вдруг одна из трех-пяти-десяти имеет тип real!), через которые описана a. А каждая переменная описана х.з. где, да еще и не у каждой тип указан. Т.е. для определения типа всех переменных, через которые описана a, надо определить тип всех переменных, через которые описаны все переменные, через которые описана a.
Ну вы поняли, да? К чему ведет необязательность объявления типа...
Deepthroat писал(а): Например, так очень даже ничего:
Так - плохо.
Во-первых var - лишнее, т.к. явное указание типа уже признак определения, а не переприсваивания.
Во-вторых temp изменять никто не собирается, а значит это не переменная, а константа.
В-третьих, при изменении типов a и b придется менять и тип t, что в данном случае явно лишняя работа.
Deepthroat писал(а):Т.е. для определения типа всех переменных, через которые описана a, надо определить тип всех переменных, через которые описаны все переменные, через которые описана a.
Ну и что? Компилятор с этим справится быстрее чем мы с набиванием пары символов.
alexs писал(а):А ещё лучше
А swap что такое?
Процедура, макрос, оператор?
Для всех ли типов работает?
Может ли подставляться в код или генерит дорогостоящий вызов?
Можно ли написать свой аналог этого SWAP и каков будет его исходный текст?
Я всего лишь проиллюстрировал преимущество объявления констант и необязательность указания типа.
