Файл: Классификация языков программирования. Критерии выбора среды и языка разработки программ..pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 26.06.2023

Просмотров: 82

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Примеры недостатка ортогональности в языках: [9]

1. В языке Pascal функции могут возвращать значения только скалярного или указательного типов, а в языках C и C++ — значения всех типов, за исключением массивов (трактовка массивов в этих языках отличается от трактовки остальных типов). В функциональных языках, языках Ada и Python этот недостаток ортогональности устранен.

2. В языке C локальные переменные могут быть определены только в начале блока (составного оператора), а в C++ переменные определяются в любом месте блока (но, конечно, перед использованием).

3. В языке Java величины скалярных типов (символьного, целого, вещественного и т. д.) не являются объектами, а величины всех остальных типов считаются объектами. Скалярные типы называют примитивными типами, а типы объектов — ссылочными типами. Примитивные типы используют семантику значения (значение копируется во время присваивания). Ссылочные типы используют семантику ссылки (присваивание формирует две ссылки на один и тот же объект). Кроме того, в языке Java коллекции объектов и коллекции примитивных типов трактуются по-разному. Среди коллекций в Java только массивы могут содержать примитивные значения. Примитивные значения могут вставляться в коллекции других типов лишь в капсулах объектов- оболочек. В языках Smalltalk и Python, напротив, все величины являются объектами, а все типы — ссылочными типами. Таким образом, в этих языках применяется лишь семантика ссылки и все коллекции объектов создаются в ортогональном стиле.

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

Структурированность потока управления в программе. Порядок передач управления между операторами программы должен быть удобен для чтения и понимания человеком. Речь идет об ограниченном использовании оператора безусловного перехода goto и применении специальных структур управления.

2.3. Легкость создания программ

Легкость создания программ (Writability) [10]отражает удобство языка для написания программ в конкретной предметной области. Поскольку в каждой предметной области программы имеют свою специфику, очень важно выбирать язык, который ее учитывает. Например, если речь идет об исследовании искусственного интеллекта, следует использовать язык Prolog или LISP, а при решении задач научных вычислений — язык Fortran.


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

Концептуальная целостность языка. Концептуальная целостность языка включает в себя три взаимосвязанных аспекта: простоту, ортогональность и единообразие понятий. Простота языка предполагает использование минимального числа понятий. Ортогональность позволяет комбинировать любые языковые конструкции по определенным правилам. Единообразие понятий требует согласованного, единого подхода к описанию и использованию всех понятий.

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

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

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

Ортогональность приемлема в разумных пределах. Чрезмерная степень ортогональности усложняет применение языка. Если разрешена любая комбинация элементарных конструкций, то логические ошибки программы могут просто остаться незамеченными, их не сможет выявить компилятор. [11]

Естественность для приложений. Синтаксис языка должен способствовать легкому и прозрачному отображению в программах алгоритмических структур предметной области. Любой из типовых алгоритмов (последовательный, разветвляющийся, циклический, параллельный) имеет естественную структуру, которая должна поддерживаться программными операторами реализующего языка. Язык должен предоставлять структуры данных, операции и структуры управления, адекватные решаемой задаче. Естественность — это одна из важнейших причин популярности того или иного языка. Язык, ориентированный на характерные черты предметной области, может сильно упростить создание для нее программных приложений. Приведем примеры языков с очевидной направленностью на решение конкретных классов задач: Prolog (поддерживает дедуктивные рассуждения), Perl (предназначен для записи различных сценариев).


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

Выразительность.[12] Выразительность языка может характеризовать две возможности. С одной стороны, она означает наличие очень мощных средств для представления структур данных и действий, описывающих большой объем вычислений с помощью очень маленькой программы (языки APL, Snobol, Icon, SETL). С другой стороны, выразительность позволяет записывать вычисления в более удобной и компактной форме. Например, в языке С запись х++ удобнее и короче записи х = х + 1. Аналогично, булевы операции and then и or else в языке Ada позволяют указать сокращенное вычисление булевых выражений. В языке Pascal циклы с известным количеством повторений проще создавать с помощью оператора for, чем с помощью оператора while. Несомненно, что все эти возможности облегчают разработку программ.

2.4. Надежность

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

Факторы, имеющие сильное влияние на надежность программ:


  1. Проверка типов. Принципиальным средством достижения высокой надежности языка является система типизации данных. В ходе проверки типов анализируется совместимость типов в программе. Разные языки обеспечивают разную полноту проверки типов. Достаточно слабой считают проверку типов в языке С. Языки с динамической типизацией вообще относят эту проверку только к периоду выполнения программы. Наиболее полную проверку гарантирует языка Ada: в процессе компиляции программы проверяются типы практически всех переменных и выражений. Такой подход фактически устраняет ошибки типов при выполнении программы. В языках Pascal, Ada и Java диапазон изменения индексов является частью объявления массива и тоже подвергается проверке. Такая проверка очень важна для обеспечения надежности программы, поскольку индексы, выходящие за пределы допустимого диапазона, часто создают серьезные проблемы.
  2. Обработка исключений. Исключением называют аварийное событие, которое обнаруживается во время выполнения программы (аппаратом исключений). В результате авария устраняется и программа продолжает работу. Подобный механизм значительно повышает надежность вычислений. Языки Ada, C++, C# и Java позволяют обрабатывать исключения, хотя во многих других языках этот механизм отсутствует.
  3. Совмещение имен. Совмещением имен называют наличие нескольких разных имен у одной и той же ячейки памяти. Во многих языках переменным разрешается иметь по паре имен: обычное прямое имя и косвенное имя (на базе указателя). С одной стороны, совмещение имен может приводить к понижению надежности программы. С другой стороны, эта возможность повышает гибкость программирования и компенсирует недочеты жестких схем типизации.

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

2.5. Стоимость

Суммарная стоимость языка программирования складывается из нескольких составляющих.

Стоимость выполнения программы. Она во многом зависит от структуры языка.[14] Язык, требующий многочисленных проверок типов во время выполнения программы, будет препятствовать быстрой работе программы. Взгляды на этот фактор стоимости претерпели существенную эволюцию. В середине прошлого века фактор был решающим в силу высокой стоимости аппаратных средств компьютера и их низкой производительности. Большое значение придавалось применению оптимизирующих компиляторов, эффективному распределению регистров и механизмам эффективного выполнения программ. Сейчас считают, что стоимость (и скорость) выполнения программы существенна лишь для программного обеспечения систем реального времени. Программы реального времени должны обеспечивать быстрые вычисления управляющих воздействий на разнообразные управляемые объекты. Поскольку необходимо гарантировать определенное время реакции, следует избегать языковых конструкций, ведущих к непредсказуемым издержкам времени выполнения программы (например, при сборке мусора в схеме динамического распределения памяти). Для обычных приложений все снижающаяся стоимость аппаратуры и все возрастающая стоимость разработки программ позволяют считать, что скорость выполнения программ уже не столь критична.


Стоимость трансляции программы. Размер этой стоимости зависит от возможностей используемого компилятора. Чем совершеннее методы оптимизации, тем дороже стоит трансляция. В итоге создается эффективный код: резко сокращается размер программы и/или возрастает скорость ее работы.[15]

Стоимость создания, тестирования и использования программы. Этот фактор стоимости удобно проиллюстрировать на примере среды для языка Smalltalk. Данная среда состоит из окон, меню, механизма ввода данных с помощью мыши и набора средств, позволяющих свободно оперировать со Smalltalk-программой. Здесь программное решение может быть спроектировано, закодировано, протестировано, изменено и использовано с минимальными затратами времени и сил программиста. По современным представлениям, наличие в языке развитых конструкций и структур является лишь одним аргументом, влияющим на широту его использования. Наличие же подходящей среды программирования существенно усиливает применимость слабого языка. Прежде всего, в среде программирования должна присутствовать надежная, эффективная и хорошо документированная реализация языка программирования. Специализированные текстовые редакторы, средства моделирования и управления конфигурацией, а также утилиты тестирования, отражающие особенности как самого языка, так и порядка его использования, — это мощные ускорители всех этапов разработки программ. В итоге минимизируются время и затраты, требуемые программисту на решение какой-либо задачи.

Стоимость сопровождения программы. Многочисленные исследования показали, что значительную часть стоимости используемой программы составляет не стоимость разработки, а стоимость сопровождения программы. Сопровождение — это процесс изменения программы после ее поставки заказчику. [16]Сопровождение включает в себя:

1. Исправление ошибок (17% времени и стоимости);

2. Изменения, связанные с обновлением операционного окружения (18% времени и стоимости);

3. Усовершенствование и расширение функций программы (65% времени и стоимости).

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