Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Передача параметров по имени в языке Algol



Читайте также:
  1. TAНК ИМЕНИ МАЯКОВСКОГО
  2. V2: Формула Эйлера для критической силы сжатого стержня и пределы ее применимости
  3. VI. Раскройте скобки, используя соответствующие местоимения
  4. VII. В 4-5 предложениях расскажите о новой европейской валюте на французском языке.
  5. VII. В 4-5 предложениях сообщите на французском языке о пользе леса для человека и для окружающей среды.
  6. VII. В 4-5 предложениях сообщите на французском языке о проблеме климата.
  7. А 3. В каких предложениях допущена ошибка в употреблении имени числительного?

Процедуры и параметры в языке Algol обладали намного большей общностью, чем в более ранних языках, таких как Fortran. В частности, параметры выглядели так, как полагается в традиционной математике функций, где действительный параметр текстуально замещает формальный параметр [2]. Например, при наличии объявления

real procedure square(x); real x; square:= x * x

вызов square(a) должен точно интерпретироваться как a*a, а вызов square(sin(a)*cos(b)) - как sin(a)*cos(b) * sin(a)* cos(b). Для этого требуется вычислять синус и косинус дважды, что, весьма вероятно, не соответствует желанию программиста. Для предотвращения этого часто встречающегося, вводящего в заблуждение случая разработчики языка Algol постулировали вторую разновидность параметра - параметр-значение. Это означало, что должна была выделяться локальная переменная x' и инициализироваться значением действительного параметра x. При наличии объявления

real procedure square(x); value x;

real x; square:= x * x

приведенный выше вызов интерпретировался бы как

x':= sin(a) * cos(b); square:= x' * x',

что позволяло избежать двойного вычисления действительного параметра. В действительности передача параметров по имени является наиболее гибким средством, что показывает следующий пример.

Пусть имеется объявление

real procedure sum(k, x, n);

integer k, n; real x;

begin real s; s:= 0;

for k:= 1 step 1 until n do s:= x + s;

sum:= s

end

Тогда сумма a1 + a2 +: + a100 записывается просто как sum(i, a[i], 100), внутреннее произведение векторов a и b - как sum(i, a[i]*b[i], 100), а гармоническая функция - как sum(i, 1/i, n).

Но за общность, которая может оборачиваться элегантностью и усложненностью, нужно платить. Рефлексия показывает, что каждый параметр, передаваемый по имени, должен быть реализован как безымянная процедура без параметров. Чтобы избежать скрытых накладных расходов, в искусно разработанных компиляторах некоторые случаи можно оптимизировать. Но обычно возникает неэффективность, которую можно было бы легко избежать.

Мы могли бы просто удалить из языка параметры, передаваемые по имени. Однако эта мера была бы слишком решительной и поэтому является неприемлемой. Например, это препятствовало бы присваиванию параметрам для возврата результатов вызвавшей процедуре. Однако это соображение привело к замене в более поздних языках Algol W, Pascal и Ada средства передачи параметров по имени на средство передачи параметров по ссылке. Сегодня идея звучит следующим образом: относитесь скептически к чрезмерно сложным средствам и возможностям. В самом крайнем случае их стоимость должна быть известна пользователям до выпуска, публикации и распространения языка. Эта стоимость должна быть соразмерна преимуществам, получаемым при включении в язык данного средства.

Лазейки (loopholes)

Я рассматриваю лазейки как одно из наихудших средств, хотя сам заразил этим убийственным вирусом Pascal, Modula и даже Oberon. Лазейка позволяет программисту взломать проверку типов компилятора и сказать: "Не вмешивайтесь. Я умнее правил". У лазеек имеется много форм. Наиболее распространены функции явного изменения типа, такие как

Mesa: x:= LOOPHOLE[i, REAL]

Modula: x:= REAL(i)

Oberon: x:= SYSTEM.VAL (REAL, i)

Но они могут маскироваться под спецификации абсолютных адресов или под записи с вариантами, как в языке Pascal. В предшествующих примерах внутреннее представление целого значения i должно интерпретироваться как число с плавающей точкой x. Это можно делать только при наличии знания о представлении чисел, что не должно требоваться при работе на уровне абстракции, обеспечиваемом языком.

В Pascal и Modula [3] лазейки, по крайней мере, демонстрируются открытым образом. В языке Oberon они представлены только через небольшое число функций, инкапсулированных в псевдокод, называемый SYSTEM, который должен импортироваться и, таким образом, становиться видимым в заголовке любого модуля, в котором используются такие низкоуровневые возможности.

Это может звучать как попытка оправдания, но, тем не менее, лазейки являются плохой идеей. Они были введены для обеспечения возможности реализации законченных систем с использованием единственного языка программирования. Например, у менеджера памяти должна иметься возможность представления памяти как плоского массива байт без типов данных. У него должна иметься возможность выделять и освобождать блоки независимо от ограничений типов. Другим примером потребности в лазейках является драйвер устройства. В ранних компьютерах имелись специальные инструкции для доступа к устройствам. Позже программисты присвоили устройствам специальные адреса памяти, отобразили их в память. Поэтому появилась идея разрешить задавать для некоторых переменных абсолютные адреса, как в языке Modula. Но этой возможностью можно злоупотреблять многими нелегальными способами.

Очевидно, что нормальный пользователь никогда не нуждается в программировании менеджера памяти или драйвера устройства, и, следовательно, ему не нужны эти лазейки. Однако - и именно это делает лазейки плохой идеей - лазейки по-прежнему находятся в распоряжении программистов. Опыт показал, что нормальные пользователи не будут избегать использования лазеек, а скорее с энтузиазмом ухватятся за них, как за замечательное средство, которое будет ими использоваться при всякой возможности. Это особенно проявляется, если в руководстве программирования содержатся предостережения по поводу использования лазеек.

Наличие возможности лазеек обычно указывает на недостаточное совершенство языка, показывая, что на языке невозможно выразить некоторые вещи, которые могут оказаться важными. Например, тип ADDRESS в Modula приходилось использовать для программирования структур данных с элементами разных типов. Строгая стратегия статической типизации, которая требовала, чтобы каждый указатель был статически ассоциирован с фиксированным типом и мог ссылаться только на такие объекты, делала это невозможным. Зная, что указатели являются адресами, лазейка в форме невинно выглядящей функции изменения типа обеспечивала эту возможность, позволяя указательным переменным указывать на объект любого типа. Недостаток состоял в том, что никакой компилятор не мог проверить корректность таких присваиваний. Система проверки типов блокировалась и с таким же успехом могла бы вовсе отсутствовать. В языке Oberon [4] было применено чистое решение проблемы расширения типа, называемое в объектно-ориентированных языках наследованием. Теперь стало возможным объявить указатель как ссылающийся на данный тип, и этот указатель мог указывать на любой тип, являющийся расширением данного типа. Это позволяло конструировать неоднородные структуры данных и безопасно использовать их при поддержке надежной системы проверки типов. Реализация требовала проверки во время выполнения только в тех случаях, когда было невозможно произвести проверку во время компиляции.

Программы, представленные на языках 1960-х, были полны лазейками, что делало их весьма подверженными ошибкам. Но тогда отсутствовала какая-либо альтернатива. Тот факт, что разработчики могут использовать язык, подобный Oberon, для программирования без использования лазеек систем целиком, за исключением менеджера памяти и драйверов устройств, характеризует наиболее существенный прогресс в разработке языков за последние 40 лет.


Дата добавления: 2015-07-10; просмотров: 109 | Нарушение авторских прав






mybiblioteka.su - 2015-2024 год. (0.006 сек.)