Оператор присваивания

Проектирование и разработка идеального средства программирования.

Модератор: Модераторы

Оператор присваивания

Сообщение Bonart » 23.10.2007 09:42:38

Казалось бы, нет ничего лучше традиционного Паскалевского оператора присваивания. Однако прогресс на месте не стоит и к настоящему времени есть ряд хороших расширений.
1. Использование для совмещения определения переменных с инициализацией.
переменная[:тип] := выражение
Если тип опущен, то он выводится компилятором.
Так можно избегать громозких секций описания и определять локальные переменные прямо в ходе. Опасность - опечатка при переприсваивании с возможностью опустить тип ведет к описанию новой переменной, т.е. синтаксическая ошибка становится семантической, что не есть хорошо.
Поэтому для присваиваний, совмещенных с описаниями есть резон сделать указание типа обязательным.
2. Использование для определения констант.
константа[:тип] ::= выражение
Кто сказал, что константы обязаны вычисляться только во время компиляции?
Константы - это то, что нельзя переприсваивать, а не только то, что вычислено еще до выполнения.
Такая возможность (аналог const в C++) позволяет обнаруживать ошибки переприсваивания того, что по логике алгоритма не должно обновляться. Вдобавок такой оператор позволяет компилятору сильно оптимизировать код.
Для констант необязательность указания типа логична и целессобразна - их никто переприсваивать не будет.
Почему именно ::=? Во-первых не будет коллизиии с операцией сравнения, во-вторых это сочетание знаков в БНФ означает "определено как".
3. Использование структур в левой части оператора присваивания.
Например, вот пример с кортежем:
(i, x) := (1, 1)
Это позволяет сделать код более лаконичным и прозрачным, выделяя логически связанные присваивания, а также позволяет лучше оптимизировать (а то и распараллелить!) код - порядок присваивания элементов внутри структуры не определен.
Bonart
новенький
 
Сообщения: 81
Зарегистрирован: 29.06.2007 11:47:40

Сообщение bw » 23.10.2007 10:33:59

> переменная[:тип] := выражение
Так я считаю лучше:
Код: Выделить всё
var переменная: тип = выражение;

А почему у тебя тип в кв. скобках? Ты думаешь что его объявление не всегда нужно? Мне кажется что тип указывать нужно обязательно. По ходу кода должно быть понятно, с переменной какого типа мы имеем дело.

> константа[:тип] ::= выражение
Код: Выделить всё
const константа: тип = выражение;


> Во-первых не будет коллизиии с операцией сравнения
Код: Выделить всё
if константа == 1 then ...


..bw
Аватара пользователя
bw
постоялец
 
Сообщения: 359
Зарегистрирован: 01.12.2005 11:36:23
Откуда: Усть-Илимск

Сообщение Bonart » 23.10.2007 11:14:54

bw
bw писал(а):А почему у тебя тип в кв. скобках? Ты думаешь что его объявление не всегда нужно?

Думаю, да. Тип переменной=тип выражения инициализации. Его в большинстве случае видно невооруженным глазом.
В большинстве случаев это даст лаконичность без потери прозрачности.
bw писал(а):Так я считаю лучше:

А зачем var? Указание типа переменной - уже ясно видимый признак определения, а не переприсваивания.
bw писал(а): Во-первых не будет коллизиии с операцией сравнения

От двойного равенства меня тошнит ;) Да и в математике равенство принято обозначать одиночным знаком.
Bonart
новенький
 
Сообщения: 81
Зарегистрирован: 29.06.2007 11:47:40

Сообщение bw » 23.10.2007 12:40:30

> А зачем var? Указание типа переменной - уже ясно видимый признак определения, а не переприсваивания.
У тебя вроде как указание типа не обязхательно :-). Так что не всегда будет понятно, что к чему, а с var однозночно ясно. Врядли использование var сильно снизит скорость написания кода, зато при отладке поможет сильно. Я бы даже ввел (наверное) оператор "del":
Код: Выделить всё
var I: Integer = 0;
...
del I;
...
WriteLn(I);  {компилятор матюгнется}


Хотя с другой стороны я не поощраю функции таких размеров где жизненный цикл переменной не прозрачен. Собственно по этому и объявление переменных я считаю должно быть в одном месте, до начала кода. Если же начинает смущать то что объявление переменной в одном месте, а инициализация (и использование) намного дальше - значит пока разбивать метод на два или большее число методов :-).

..bw
Аватара пользователя
bw
постоялец
 
Сообщения: 359
Зарегистрирован: 01.12.2005 11:36:23
Откуда: Усть-Илимск

Сообщение alexs » 23.10.2007 12:53:04

bw писал(а):Если же начинает смущать то что объявление переменной в одном месте, а инициализация (и использование) намного дальше - значит пока разбивать метод на два или большее число методов

Золотые слова :-)
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Сообщение Bonart » 23.10.2007 13:24:28

bw писал(а):У тебя вроде как указание типа не обязхательно

Ага :) Но цель-то в большей лаконичности. Если не хочется давать компилятору генерить определения из опечаток - то лучше сделать указание типа переменной обязательным.
bw писал(а):Я бы даже ввел (наверное) оператор "del"

Незачем. У нас уже есть операторные скобки - переменная видна только на том уровне где определена и ниже.
bw писал(а):Хотя с другой стороны я не поощраю функции таких размеров где жизненный цикл переменной не прозрачен.

Такой вывод следует из неявного (и очень сильного!) предположения, что локализация переменной должна быть той же, что и локализация алгоритма в виде процедуры.
На практике это не так - для переменной оптимальная область видимости много меньше подпрограммы (о чем хорошо знают разработчики оптимизаторов) Самый наглядный пример - параметр цикла, нафиг не нужный (в том числе физически!) за его пределами, хотя сам цикл отдельной подпрограммы достоин далеко не всегда.
Или переменные в пределах одной из альтернатив условного оператора - если управление не попадает на соответсвующую ветку, то им даже память можно не выделять! Такая возможность критична для эффективной реализации рекурсивных алгоритмов.
Bonart
новенький
 
Сообщения: 81
Зарегистрирован: 29.06.2007 11:47:40

Сообщение bw » 23.10.2007 14:28:58

> Самый наглядный пример - параметр цикла
С этим в соседнюю ветку, так что как пример не катит.

> то им даже память можно не выделять!
Ну :-). Ну будешь же ты динамически под каждый "байт" (переменную) выделять память. Это делается иначе, и ты знаешь как.

Все же я остаюсь против возможности объявления переменной в теле функции.

p.s. Мы сильно в оффтоп ушли, не думаешь :-) ? Я думаю пора отделить часть сообщений в тему "Переменные" или что-нибудь такоё.

..bw
Аватара пользователя
bw
постоялец
 
Сообщения: 359
Зарегистрирован: 01.12.2005 11:36:23
Откуда: Усть-Илимск

Сообщение Bonart » 23.10.2007 15:05:44

bw писал(а):Ну будешь же ты динамически под каждый "байт" (переменную) выделять память. Это делается иначе, и ты знаешь как.

Знаю :)
Но экономия есть: если в одной из альтернатив нам нужна переменная x, а в другой - y, то при определении на уровне подпрограммы расход памяти будет sizeof x+sizeof y, а при определении на уровне блока - max(sizeof x,sizeof y) - если выделять память на стеке при входе в подпрограмму.
Но что меня в свое время поразило - в рекурсивных подпрограммах экономия памяти за счет локализации переменных на более низком, чем подпрограммы, уровне давала возможность расширить рабочий (без переполнекния стека) диапазон параметров в несколько раз.
Кстати, вот такая иллюстрация:
Код: Выделить всё
begin
  t ::= a
  a := b
  b := t
end;

Зачем нужна t за пределами этого блока?
Зачем нужно явно указывать ее тип?
Bonart
новенький
 
Сообщения: 81
Зарегистрирован: 29.06.2007 11:47:40

Сообщение Deepthroat » 24.10.2007 00:15:00

Я тоже думаю, что хорошо бы указывать тип. Это позволит избежать ошибок. Например, так очень даже ничего:

Код: Выделить всё
begin
  var t: integer := a;
  a := b;
  b := t;
end;


Здесь t - целое, и это мы наем точно. Но что, если тип не указан, а мы где-то вверху ошиблись в типе? Тем более, что описание a находится не сверху, а где-то внутри кода, т.е. надо долго и упорно искать это описание. Да если там еще и тип не указан, то вообще вешайся - ищи описание переменных (всех - вдруг одна из трех-пяти-десяти имеет тип real!), через которые описана a. А каждая переменная описана х.з. где, да еще и не у каждой тип указан. Т.е. для определения типа всех переменных, через которые описана a, надо определить тип всех переменных, через которые описаны все переменные, через которые описана a.

Ну вы поняли, да? К чему ведет необязательность объявления типа...
Аватара пользователя
Deepthroat
постоялец
 
Сообщения: 144
Зарегистрирован: 06.09.2007 00:21:34
Откуда: Outer Heaven

Сообщение Bonart » 24.10.2007 08:00:11

Deepthroat писал(а): Например, так очень даже ничего:

Так - плохо.
Во-первых var - лишнее, т.к. явное указание типа уже признак определения, а не переприсваивания.
Во-вторых temp изменять никто не собирается, а значит это не переменная, а константа.
В-третьих, при изменении типов a и b придется менять и тип t, что в данном случае явно лишняя работа.
Deepthroat писал(а):Т.е. для определения типа всех переменных, через которые описана a, надо определить тип всех переменных, через которые описаны все переменные, через которые описана a.

Ну и что? Компилятор с этим справится быстрее чем мы с набиванием пары символов.
Bonart
новенький
 
Сообщения: 81
Зарегистрирован: 29.06.2007 11:47:40

Сообщение alexs » 24.10.2007 08:25:21

А ещё лучше
Код: Выделить всё
Swap(A,B)

И всё - нет проблем - и налядность на уровне
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Сообщение Bonart » 24.10.2007 08:32:46

alexs писал(а):А ещё лучше

А swap что такое?
Процедура, макрос, оператор?
Для всех ли типов работает?
Может ли подставляться в код или генерит дорогостоящий вызов?
Можно ли написать свой аналог этого SWAP и каков будет его исходный текст?
Я всего лишь проиллюстрировал преимущество объявления констант и необязательность указания типа.
Bonart
новенький
 
Сообщения: 81
Зарегистрирован: 29.06.2007 11:47:40

Сообщение alexs » 24.10.2007 10:29:00

Для эелементарных типо в стандартных библиотеках есть - щас на вскидку не помню, для своих - просто переопредели макросом - и будет тебе счастье :-)
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Сообщение Bonart » 24.10.2007 10:31:54

alexs писал(а):просто переопредели макросом

Макросом? В языке высокого уровня?
Лекарство хуже болезни получается. В худших традициях Си.
"И эти люди запрещают мне опускать тип переменной!"
Bonart
новенький
 
Сообщения: 81
Зарегистрирован: 29.06.2007 11:47:40

Сообщение alexs » 24.10.2007 11:52:13

Bonart писал(а):Макросом? В языке высокого уровня?

Я под макросом подразумевал inline-функцию

а при обявлении перемнной её тип указывать надо! :-)
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

След.

Вернуться в Компилятор / язык программирования

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru