OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Воскресенье, 28 Апрель, 2024 21:57

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 42 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: Вирт: О стилях программирования
СообщениеДобавлено: Понедельник, 28 Апрель, 2008 05:45 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Не заметил, чтобы сообщалось:

Вирт выложил свои текстики:
http://www.inf.ethz.ch/personal/wirth/A ... index.html
http://www.inf.ethz.ch/personal/wirth/A ... onARM.html

В частности, забавная страничка
<b>On Programming Styles </b>
http://www.inf.ethz.ch/personal/wirth/A ... Styles.pdf
против локальных процедур/за функциональный стиль:

"... A better option is to allow access to strictly local and to
strictly global objects. The latter are typically state variables and they retain the notion of state.
Apart from them, the recommended style becomes predominantly functional. With the adoption of these rules, also the nesting of procedures (of scopes) essentially becomes irrelevant.

The first system disallowing access to not strictly local objects was the Algol compiler for the Burroughs B-5000 computer in 1964. The reason then, however, was a simplification of the compiler rather than a methodological one. We have introduced the same restriction in the revision of the language Oberon in 2007.

In summary, the new rule of good style is: Avoid nesting of procedures and use global variables sparingly! Of course this is no dogma, and rules allow for justified exceptions."

То-то Темный Джек порадуетца 8))

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 28 Апрель, 2008 08:02 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1429
Как раз функциональщики очень любят локальные процедуры.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 28 Апрель, 2008 09:55 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Непонятно, что у вас за проблемы с локальными процедурами. Полезнейшая вещь, что бы не засорять глобальное пространство имён... А если они ещё и анонимные в нужном месте с удобным синтаксисом -- вообще самое то...

Сколько разрабатывается компилятор Зоннона, до сих пор там не реализованы эти самые локальные процедуры... Что-то в консерватории не так?

Оберон всё дальше и дальше возвращается к своему самому недостойному противнику -- Си...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 28 Апрель, 2008 12:08 
Аватара пользователя

Зарегистрирован: Суббота, 19 Ноябрь, 2005 15:59
Сообщения: 803
Откуда: Зеленоград
Info21 писал(а):
Впрочем, я тоже удовлетворен: в лекциях правило избегать локальных процедур было с самого начала.

Почему?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Апрель, 2008 09:28 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Trurl писал(а):
Как раз функциональщики очень любят локальные процедуры.


Имелась в виду фраза "the recommended style becomes predominantly functional."


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Апрель, 2008 09:36 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
AVC писал(а):
Info21 писал(а):
Впрочем, я тоже удовлетворен: в лекциях правило избегать локальных процедур было с самого начала.

Почему?

Вчера оборвался инет, где уже заранее был ответ :-)

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

2) глобальное пространство имен отнюдь не загромождается, т.к. процедуры остаются спрятаны в модулях (а выкрики Geniepro стали уже утомительны).

3) "Разделяй и управляй". По умолчанию применяется сей Первый Принцип. Локальная процедура -- "средство оптимизации", вторая очередь.

Если можно без особого труда вынести локальную процедуру, то такое вынесение однозначно улучшает изоляцию частей, устраняет вероятности появления каких-то плюх и т.п.
-----------
А если "почему?" относится к "с самого начала", то конкретно вспоминается борьба с алгебраическими сортировками, где по сравнению с обычными добавляется один уровень рекурсии (на корреткную обработку сокращения членов без дополнительного прохода по данным), и я там наигрался вволю.
Алг. сортировки и точные целые -- две sine qua non вещи для симв. алгебры, числа я тогда достаточно тупо по Кнуту сделал, а с сортировками пришлось разбираться (до сих пор немножко).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Апрель, 2008 11:23 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
А у меня "распознаватель = сканер + парсер" языка Component Pascal целиком содержится внутри одной процедуры Cp2cRecognizer.Do, а парсер модуля целиком содержится внутри вложенной в Cp2cRecognizer.Do процедуры Module:

Код:
MODULE Cp2cRecognizer;
   ...
   PROCEDURE Do (context: Context)
      VAR
         ch: CHAR;
         symbol: INTEGER;
         symbolPos, currentPos: Position;
         charValue: CHAR;
         intValue: LONGINT;
         realValue: REAL;
         stringValue: String;
         dict: Dictionary;
 
      ...

      PROCEDURE GetSymbol;
      ...
      END GetSymbol;

      PROCEDURE Module;
         VAR name, libName: String;
         
         PROCEDURE^ TypeDefinition;
         PROCEDURE^ Expression;
         PROCEDURE^ Designator;
         PROCEDURE^ StatementSequence;
         PROCEDURE^ FormalParameters;

         PROCEDURE Import;
         BEGIN
         ...
         END Import;

         ...

      BEGIN (* Module *)
         ASSERT(symbol = symModule, 100);
         GetSymbol; Check(symIdent);
         IF symbol = symIdent THEN
         ...
         END
      END Module;

   BEGIN (* Do *)
      ASSERT(context # NIL, 20);
      dict := context.Dictionary();
      ASSERT(dict # NIL, 20);
      ch := chSpace; symbol := 0;
      symbolPos.pos := 0; symbolPos.row := 0; symbolPos.col := 0;
      currentPos.pos := 0; currentPos.row := 0; currentPos.col := 0;
      charValue := 0X; intValue := 0; realValue := 0;
      stringValue := dict.empty;
      GetSymbol; Check(symModule);
      IF symbol = symModule THEN Module END
   END Do;

END Cp2cRecognizer.


Вместе с процедурами генерирующими текстовые сообщения об ошибках Cp2cRecognizer содержит менее 1400 строчек.

Так что вложенные процедуры использованные по назначению рулят неописуемо.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Апрель, 2008 11:43 
Аватара пользователя

Зарегистрирован: Воскресенье, 08 Июль, 2007 00:38
Сообщения: 778
Откуда: Москва
А что, конечный автомат сложно реализовать в локальной процедуре? Насколько я понял, Вирт оставил глобальные переменные только ради него.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Апрель, 2008 12:21 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Все локальные переменные инициализируются каждый раз, когда запускается процедура. Значения пропадают после завершения работы процедуры. Есть два способа сохранения состояния, доступных непосредственно исполняющейся программе: рекурсия и глобальные переменные.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Апрель, 2008 13:25 
Аватара пользователя

Зарегистрирован: Воскресенье, 08 Июль, 2007 00:38
Сообщения: 778
Откуда: Москва
Valery Solovey писал(а):
Все локальные переменные инициализируются каждый раз, когда запускается процедура. Значения пропадают после завершения работы процедуры.
...

А зачем завершать и вновь запускать процедуру? Пусть себе работает - 99% времени находится в ожидании в цикле и генерит новые состояния - до окончания работы программы. Это же не функция, которая завершается сразу после возврата значения в точку вызова.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Апрель, 2008 18:16 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Info21 писал(а):
2) глобальное пространство имен отнюдь не загромождается, т.к. процедуры остаются спрятаны в модулях
А это абсолютно неважно -- внутримодульное пространство является глобальным для процедур, определённых в нём, и засорять его также нехорошо.

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

Локальные процедуры (для меня лично) всегда были преимуществом паскалевского семейства перед сишным (пусть и не с самым удачным синтаксисом), ну что ж, скоро и этого преимущества не останется...
Правда всё-таки так и не понятно, зачем нужно снижать и без того не очень высокий уровень языка...

Info21 писал(а):
(а выкрики Geniepro стали уже утомительны).
Ну что ж поделать, любая критика утомительна...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Апрель, 2008 18:31 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Сергей Прохоренко писал(а):
Valery Solovey писал(а):
Все локальные переменные инициализируются каждый раз, когда запускается процедура. Значения пропадают после завершения работы процедуры.
...

А зачем завершать и вновь запускать процедуру? Пусть себе работает - 99% времени находится в ожидании в цикле и генерит новые состояния - до окончания работы программы. Это же не функция, которая завершается сразу после возврата значения в точку вызова.

Такая функция называется итератором... Эта идея появилась ещё в середине 70-х, в языке CLU, но только сейчас стала появляться в современных языках. Паскалевское семейство эту идею, конечно же, обошло незамечанием...

Итераторы, кстати, также можно симитировать бесконечными ленивыми списками, как это принято в функциональном программировании.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Апрель, 2008 23:28 
Аватара пользователя

Зарегистрирован: Воскресенье, 08 Июль, 2007 00:38
Сообщения: 778
Откуда: Москва
Geniepro писал(а):
Сергей Прохоренко писал(а):
Valery Solovey писал(а):
Все локальные переменные инициализируются каждый раз, когда запускается процедура. Значения пропадают после завершения работы процедуры.
...

А зачем завершать и вновь запускать процедуру? Пусть себе работает - 99% времени находится в ожидании в цикле и генерит новые состояния - до окончания работы программы. Это же не функция, которая завершается сразу после возврата значения в точку вызова.

Такая функция называется итератором... Эта идея появилась ещё в середине 70-х, в языке CLU, но только сейчас стала появляться в современных языках. Паскалевское семейство эту идею, конечно же, обошло незамечанием...

Итераторы, кстати, также можно симитировать бесконечными ленивыми списками, как это принято в функциональном программировании.


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

См. [url]http://ru.wikipedia.org/wiki/Итератор[/url]

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 30 Апрель, 2008 01:16 
Аватара пользователя

Зарегистрирован: Суббота, 19 Ноябрь, 2005 15:59
Сообщения: 803
Откуда: Зеленоград
Valery Solovey писал(а):
Есть два способа сохранения состояния, доступных непосредственно исполняющейся программе: рекурсия и глобальные переменные.

В принципе, когда-то еще были сопрограммы. :?:


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 30 Апрель, 2008 09:33 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Geniepro писал(а):
Info21 писал(а):
2) глобальное пространство имен отнюдь не загромождается, т.к. процедуры остаются спрятаны в модулях
А это абсолютно неважно -- внутримодульное пространство является глобальным для процедур, определённых в нём, и засорять его также нехорошо.


Чушь. Глобальное пространство не контролируется разработчиком, поэтому там возможны неприятные конфликты. Внутримодульное -- обозримо (кроме интерфейсных модулей для WinApi :-)) и контролируется (несколько утрируя) одним разработчиком.

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

Geniepro писал(а):
Info21 писал(а):
(а выкрики Geniepro стали уже утомительны).
Ну что ж поделать, любая критика утомительна...
Это не критика. В критике не бывает заведомой дезинформации и субъективных оценочных суждений. Это если по-научному. Если же по-простому, то к вашей "критике" можно смело применять обозначение "лай".


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 30 Апрель, 2008 09:36 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Geniepro писал(а):
... но только сейчас стала появляться в современных языках. Паскалевское семейство эту идею, конечно же, обошло незамечанием...


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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 30 Апрель, 2008 15:57 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Info21 писал(а):
Еще одна глупость. Интеракторы -- как и многие другие подобные высокоуровневые вещи


Итераторы... Приведенная ссылка на википедию, хотя и на русском языке, дает весьма смутное понимание (а упоминание глагола/оберона там вообще не в тему). Посмотрите лучше английский вариант:
http://en.wikipedia.org/wiki/Iterators

Функция-генератор, о которой говорил Geniepro, в разделе "Generators".


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 30 Апрель, 2008 17:19 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Info21 писал(а):
Еще одна глупость. Интеракторы -- как и многие другие подобные высокоуровневые вещи -- допускают такое многообразие в деталях реализации, что вмораживать конкретные формы в язык будет только человек, не понимающий законов эволюции языков на длинных временах. Короче, только молодой человек, озабоченный тем, чтобы доказать, какой он крутой и остроумный.
Ага, расскажите это Барбаре Лисков. Она хоть и менее известна, чем Вирт, но тем не менее тоже внесла немалый вклад в развитие надёжного (защитного) программирования... Язык Эйфель с предусловиями/постусловиями на языковом уровне появился на десятилетие позже CLU...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 30 Апрель, 2008 17:25 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Барбара Лисков это делала давно. И была первопроходцем в абстрактной типизации, за что её все помнят и уважают (вместе с CLU). Но, факт есть факт, удачная реализация CLU - задачка из той же оперы, что Алгол-68... Реализации по пальцам пересчитать (одна из успешных и полных вроде на Эльбрусах была ленинградцами сделана).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 30 Апрель, 2008 19:45 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Выдержки из главы 6 книги Барбары Лисков и Джона Гатэга "Использование абстракций и спецификаций при разработке программ" (MIT Press 1986, "Мир" 1989):
__________________________________________

< прим. Предыдущие главы назывались "Процедурная абстракция", "Абстракции данных" и "Исключительные ситуации" >

6. Абстракция итерации

В этой главе обсуждается наш последний механизм абстракции -- абстракция итерации, или, коротко, итератор. Итераторы являются некоторым обобщением итерационных методов, имеющихся в большинстве языков программирования. Они позволяют пользователям выполнять итерации для произвольных типов данных удобным и эффективным способом.

...

6.3. Примеры

В этом разделе приводится несколько примеров итераторов. Первый пример, приведённый на рис. 6.7, -- это простой "фильтр". он называется фильтром потому, что удаляет некоторые элементы, выданные другим итератором, и выдаёт только остальные элементы в процедуру, которая к нему обращается.
Код:
filter = iter (s: intset, els: itertype (intset) yields (int),
               pred: proctype (int) returns (bool))  yields (int)
         requires чтобы s не модифицировалась в теле цикла.
         effects  Выдаёт в произвольном порядке все элементы, выданные операцией els (s),
                  которые удовлетворяют условию, заданному в pred.

filter = iter (s: intset, els: itertype (intset) yields (int),
               pred: proctype (int) returns (bool))  yields (int)
    for e: int in els (s) do
        if pred (e) then yield (e) end
        end
    end filter
Рис. 6.7. Фильтр.

Например, если операция odd выдаёт значение true, только если её целый аргумент является нечётным числом, то фильтр

filter (s, intset$elements, odd)

выдаёт нечетные числа из набора s.

...

6.5. Обзор главы

В этой главе рассматривается проблема полноты типов данных, которые являются совокупностью объектов. Поскольку совокупность, вообще говоря, используется для выполнения некоторого действия над её элементами, нам необходим некоторый способ доступа ко всем элементам. Этот способ должен быть эффективным в смысле времени и пространства, удобным для использования и не должен разрушать данную совокупность. Кроме того, он должен обеспечивать абстракцию через спецификацию.

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

Итераторы эффективны для исполнения. Выдача из итератора аналогична обращению к процедуре. К телу цикла for "обращаются" из итератора. Возобновление работы итератора аналогично возврату из процедуры. Тело цикла "возвращает" управление в итератор. Следовательно, затраты на использование итераторов состоят максимум из одного обращения к процедуре на выполнение тела цикла. Такие затраты могут быть меньше из-за оптимизаций компилятора.

Итераторы полезны сами по себе, как это имело место в примерах permutations и primes. Однако их основным применением являются операции над типами данных. В конце книги мы рассмотрим другие примеры их использования.

< конец цитаты >
__________________________________________

Приведённый в этом примере итератор filter можно, конечно, реализовать в виде обычной процедуры, возвращающей отфильтрованный набор элементов, но это хуже тем, что не так удобно в использовании (нужно заводить специальную переменную для хранения этого набора после вызова такой процедуры), а так же эти элементы в случае использования итератора будут вычисляться только когда они действительно нужны (своего рода ленивые вычисления в энергичном языке), а если вдруг часть этих элементов не нужна, то они и вычисляться не будут, тогда как в случае с процедурой (энергичной) все эти элементы будут в любом случае обработаны и вычислены (создавая заметную ненужную паузу), и если их слишком много или они требуют много ресурсов, то это может стать просто неприемлемым вариантом.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 42 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 3 часа


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

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


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB