Лекция Определение языков программирования Прежде чем анализировать конкретные парадигмы программирования, рассмотрим задачу определения систем программирования



Скачать 185.86 Kb.
Дата15.01.2013
Размер185.86 Kb.
ТипЛекция

Парадигмы

Лекция 2. Определение языков программирования

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

С этой целью задается отображение конкретного синтаксиса (КС) ЯП в абстрактный (АС), вид которого инвариантен для семейства эквивалентных языков.

КС => АС
Семантика ЯП определяется как универсальная интерпретирующая функция (ИФ), дающая смысл любой программе, представленной в терминах абстрактного синтаксиса. Такая функция использует определенную языком схему команд – языково ориентированную абстрактную машину (АМ), позволяющую смысл программ формулировать без конкретики компьютерных архитектур.
ИФ: АС => АМ
Выбор команд абстрактной машины представляет собой компромисс между уровнем базовых средств языка и сложности их реализации на предполагаемых конкретных машинах (КМ), выбор которых осуществляется на уровне прагматики.
АМ => КМ
Способ такого определения семантики языка программирования с помощью интерпретатора над языково ориентированной абстрактной машиной называют операционной семантикой языка. Принятая в операционной семантике динамика управления обладает большей гибкостью, чем это принято в стандартных системах программирования (СП) компилирующего типа. Это показывает резервы развития СП навстречу современным условиям разработки и применения информационных систем с повышенными требованиями к надежности и безопасности.
Синтаксис программ в языке программирования сводится к правилам представления данных, операторов и выражений языка. Начнем с выбора абстрактного синтаксиса на примере определения небольшого, но функционально полного подмножества языка Лисп.
Конкретный синтаксис языков программирования принято представлять в виде простых БНФ (Формул Бекуса-Наура). Данные языка Лисп - это атомы, списки и более общие структуры из бинарных узлов – пар, строящихся из любых данных:
Пример 2.1. Синтаксис данных языка Лисп



<атом> ::= <БУКВА> <конец_атома>
<конец_атома> ::= <пусто>

| <БУКВА> <конец_атома>

| <цифра> <конец_атома>
<данное> ::= <атом>

| (<данное> ... ) -- списков




Это правило констатирует, что данные - это или атомы, или списки из данных.
/Три точки означают, что допустимо любое число вхождений предшествующего вида объектов, включая ни одного./
Согласно такому правилу () есть допустимое данное. Оно в языке Лисп по соглашению эквивалентно атому Nil.
Такая единая структура данных вполне достаточна для представления сколь угодно сложных программ. Дальнейшее определение языка Лисп можно рассматривать как восходящий процесс генерации семантического каркаса, по ключевым позициям которого распределены семантические действия по обработке программ. Позиции распознаются как вызовы соответствующих семантических функций.
Другие правила представления данных нужны лишь при расширении и специализации лексики языка (числа, строки, имена особого вида и т.п.). Они не влияют ни на общий синтаксис языка, ни на строй его понятий, а лишь характеризуют разнообразие сферы его конкретных приложений.
Абстрактный синтаксис программ является уточнением синтаксиса данных, а именно – выделением подкласса вычислимых выражений (форм), т.е. данных, имеющих смысл как выражения языка и приспособленных к вычислению. Внешне это выглядит как объявление объектов, заранее известных в языке, и представление разных форм, вычисление которых обладает определенной спецификой.
Операционная семантика языка определяется как интерпретация абстрактного синтаксиса, представляющего выражения, имеющие значение. Учитывая исследованность проблем синтаксического анализа и существование нормальных форм, гарантирующих генерацию оптимальных распознавателей программными инструментами типа YACC-LEX, в качестве абстрактного синтаксиса для Лиспа выбрано не текстовое, а списочное представление программ. Такое решение снимает задачу распознавания конструкций языка – она решается простым анализом первых элементов списков. Одновременно решается и задача перехода от конкретного синтаксиса текстов языка к абстрактному синтаксису его понятийной структуры. Переход получается просто чтением текста, строящим древовидное представление программы.
Ниже приведены синтаксические правила для обычных конструкций, к которым относятся идентификаторы, переменные, константы, аргументы, формы и функции. (Правила упорядочены по сложности взаимосвязи формул.)
<идентификатор> ::= <атом>
Идентификатор - это подкласс атомов, используемых при именовании неоднократно используемых объектов программы - функций и переменных. Предполагается, что идентифицируемые объекты размещаются в памяти так, что по идентификатору их можно найти.

Примера 2.2. Синтаксис выражений подмножества языка Лисп



<форма> ::= <константа>

| <переменная>

| (<функция> <аргумент> ... >)

| (IF <предикат> <форма> <форма> )
<константа> ::= (QOUTE <данное>)
<переменная> ::= <идентификатор>
<аргумент> ::= <форма>
<предикат> ::= <форма>




Переменная - это подкласс идентификаторов, которым сопоставлено многократно используемое значение, ранее вычисленное в подходящем контексте. Подразумевается, что одна и та же переменная в разных контекстах может иметь разные значения.

Таким образом, класс форм - это объединение класса переменных и подкласса списков, начинающихся с QUOTE, IF или с представления некоторой функции.
Форма - это выражение, которое может быть вычислено.
Форма, представляющая собой константу, выдает эту константу как свое значение. В таком случае нет необходимости в вычислениях, независимо от вида константы. Константные значения могут быть любой сложности, включая вычислимые выражения. Чтобы избежать двусмысленности, предлагается константы изображать как результат специальной функции QUOTE, блокирующей вычисление. Представление констант с помощью QOUTE устанавливает границу, далее которой вычисление не идет. Константные значения аргументов характерны при тестировании и демонстрации программ.
Если форма представляет собой переменную, то ее значением должно быть данное, связанное с этой переменной до момента вычисления формы. (Динамическое связывание, в отличие от традиционного правила, требующего связывания к моменту описания формы, т.е. статического связывания.)
Третья ветвь определения формы гласит, что можно написать функцию, затем перечислить ее аргументы, и все это как общий список заключить в скобки.
Аргументы представляются формами. Это означает, что допустимы композиции функций. Обычно аргументы вычисляются в порядке вхождения в список аргументов. Позиция "аргумент" выделена для того, чтобы было удобно в дальнейшем локализовать разные схемы обработки аргументов в зависимости от категории функций. Аргументом может быть любая форма, но метод вычисления аргументов может варьироваться. Функция может не только учитывать тип обрабатываемого данного, но и управлять временем обработки данных, принимать решения по глубине и полноте анализа данных, обеспечивать продолжение счета при исключительных ситуациях и т.п.
Последняя ветвь определяет формат условного выражения. Согласно этому формату условное выражение строится из синтаксически различимых позиций для предиката и двух обычных форм. Значение условного выражения определяется выбором по значению предиката первой или второй формы. Первая форма вычисляется при истинном значении предиката, иначе вычисляется вторая форма. Любая форма может играть роль предиката.
Пример 2.3. Синтаксис функций подмножества языка Лисп



<функция> ::= <название>

| (LAMBDA <список_переменных> <форма>)

| (LABEL <название> <функция>)
<список_переменных> ::= (<переменная> ... )
<название> = <идентификатор>



Название - это подкласс идентификаторов, определение которых хранится в памяти, но оно может не подвергаться влиянию контекста вычислений.
Таким образом, класс функций - это объединение класса названий и подкласса трехэлементных списков, начинающихся с LAMBDA или LABEL.
Функция может быть представлена просто именем. В таком случае ее смысл должен быть заранее известен. Функция может быть введена с помощью лямбда-выражения, устанавливающего соответствие между аргументами функции и связанными переменными, упоминаемыми в теле ее определения (в определяющей ее форме). Форма из определения функции может включать переменные, не включенные в лямбда-список, - так называемые свободные переменные. Их значения должны устанавливаться на более внешнем уровне. Если функция рекурсивна, то следует объявить ее имя с помощью специальной функции LABEL.
Используемые в реальных Лисп-системах функции DEFUN или DEFINE, по существу, совмещает эффекты специальных функций LABEL и LAMBDA.
Таблица 2.1. Синтаксическая сводка подмножества языка Лисп.



<форма> ::= <переменная>

| (QOUTE <данное>) --- константа

| (IF <предикат> <форма> <форма>) --- условное выражение

| (<функция> <аргумент> ... <аргумент>) --- вызов функции
<предикат> ::= <форма>

<аргумент> ::= <форма>

<переменная> ::= <идентификатор>
<функция> ::= <название> --- ранее определенная функция

| (LAMBDA <список_переменных> <форма>) --- безымянная функция

| (LABEL <название> <функция>) --- новая именованная функция
<список_переменных> ::= (<переменная> ... )
<название> ::= <идентификатор>

<идентификатор> ::= <атом>





Можно показать, что полученная система правил сводима к нормальным формам, гарантирующим возможность автоматического построения как автомата распознавания текстов, принадлежащих заданному этими формулами языку, так и автомата генерации списочных структур, эквивалентных этому языку. Поэтому приведенное определение может одновременно рассматриваться как определение и множества текстов языка – конкретный синтаксис, и множества структурных представлений программ – абстрактный синтаксис. Это снимает необходимость здесь рассматривать задачу перехода от конкретного синтаксиса к абстрактному.
Согласно Венской методике абстрактный синтаксис языка образуют распознаватели и селекторы для распознавания языковых понятий и выделения значимых позиций, используемых при параметризации семантических обработчиков.
Пусть e – обозначение вычисляемого выражения, а fn – обозначение применяемой функции. Для списочного представления программ на данном подмножестве Лиспа можно задать следующие распознаватели:
(atom e) --- переменная

(eq (car e) 'QUOTE) --- константа

(eq(car e) 'IF) --- условное выражение
(atom fn) --- название известной функция

(eq(car fn)'LAMBDA) --- конструирование безымянной функции

(eq (car fn) 'LABEL) --- конструирование именованной функции
Следует отметить, что полученные БНФ могут рассматриваться лишь как семантический каркас функционального языка программирования. Отсутствует привязка к структурам данных Лиспа и средствам их обработки. Такая обработка обеспечивается набором встроенных базовых функций, смысл которых должен быть заранее определен. Для каждой такой функции интерпретатор должен иметь возможность вычислить результат применения функции к ее аргументам. Набор встроенных функций задает основную область применения языка. Для Лиспа это обработка списочных структур данных:
(eq fn 'CAR) --- вызов функции CAR

(eq fn 'CDR) --- вызов функции CDR

(eq fn 'CONS) --- вызов функции CONS

(eq fn 'ATOM) --- вызов функции ATOM

(eq fn 'EQ) --- вызов функции EQ
Селекторы основных позиций списочного представления программ сводятся к композициям функций обработки списков:
Car

Cdr

Caar

Cadr

Cdar

Caddr
Универсальная функция
Интерпретация или универсальная функция - это функция, которая может вычислять значение любой формы, включая формы, сводимые к вычислению произвольной заданной функции, применяемой к аргументам, представленным в этой же форме, по доступному описанию данной функции. (Конечно, если функция, которой предстоит интерпретироваться, имеет бесконечную рекурсию, интерпретация будет повторяться бесконечно.)
Определим универсальную функцию eval от аргумента expr - выражения, являющегося произвольной вычислимой формой языка Лисп.
Универсальная функция должна предусматривать основные виды вычисляемых форм, задающих значения аргументов, а также представления функций, в соответствии со сводом приведенных выше правил языка. При интерпретации выражений учитывается следующее:

- Атомарное выражение обычно понимается как переменная. Для него следует найти связанное с ним значение. Например, могут быть переменные вида «x», «elem», смысл которых зависит от контекста, в котором они вычисляются.
- Константы, представленные как аргументы функции QUOTE, можно просто извлечь из списка ее аргументов. Например, значением константы (QUOTE T) является атом T, обычно символизирующий значение "истина".
- Условное выражение требует специального алгоритма для предварительного вычисления предиката и выбора нужной ветви. Например, интерпретация условного выражения: 1
(IF (ATOM x) x (first (CAR x) ) )
должна обеспечивать выбор ветви в зависимости от атомарности значения аргумента.
- Остальные формы выражений рассматриваются по общей схеме как список из функции и ее аргументов. Обычно аргументы вычисляются, а затем вычисленные значения передаются функции для интерпретации ее определения. Так обеспечивается возможность писать композиции функций. Например, в выражении (first (CAR x)) внутренняя функция CAR сначала получит в качестве своего аргумента значение переменной x, а потом свой результат передаст как аргумент более внешней функции first.
- Если функция представлена своим названием, то среди названий различаются имена встроенных функций, такие как CAR, CDR, CONS и т.п., и имена функций, введенных в программе, например first. Для встроенных функций интерпретация сама «знает», как найти их значение по заданным аргументам, а для введенных в программе функций - использует их определение, которое находит по имени.
- Если функция использует лямбда-конструктор, то прежде чем его применять, понадобится связывать переменные из лямбда-списка со значениями аргументов. Функция, использующая

лямбда-выражение,
(LAMBDA (x) (COND ((ATOM x) x)

((QUOTE T) (first (CAR x) )) ))

зависит от одного аргумента, значение которого должно быть связано с переменной x. В определении используется свободная функциональная переменная first, которая должна быть определена в более внешнем контексте.
- Если представление функции начинается с LABEL, то понадобится сохранить имя функции с соответствующим ее определением так, чтобы корректно выполнялись рекурсивные вызовы функции. Например, предыдущее LAMBDA-определение безымянной функции становится рекурсивным, если его сделать вторым аргументом специальной функции LABEL, первый аргумент которой – fisrt, имя новой функции.
(LABEL first (LAMBDA (x) (COND ((ATOM x) x)

((QUOTE T) (first (CAR x) )) )))
Таким образом, интерпретация функций осуществляется как взаимодействие четырех подсистем:
- обработка структур данных (cons, car, cdr, atom, eq);

- конструирование функциональных объектов (lambda, label);

- идентификация объектов (имена переменных и названия функций);

- управление логикой вычислений и границей вычислимости (композиции, quote, if, eval).
Прежде чем дать определение универсальной функции, опишем ряд дополнительных функций, полезных при работе с переменными и названиями функций.
PAIRLIS - функция аргументов x, y, al строит список пар соответствующих элементов из списков x и y и присоединяет их к списку al. Полученный список пар, похожий на таблицу с двумя столбцами, называется ассоциативным списком или ассоциативной таблицей. Такой список используется для связывания имен переменных и функций при организации вычислений интерпретатором.
(DEFUN pairlis (x y al) (COND

((null x) al)

((QUOTE T) (CONS (CONS (CAR x)

(CAR Y) )

(pairlis (CDR x)

(CDR y)

al)

)))
(pairlis '(A B C) '(u t v) '((D . y)(E . y))) = ((A . u)(B . t)(C . v)(D . y)(E . y))

ASSOC - функция двух аргументов, x и al. Если al - ассоциативный список, подобный тому, что формирует функция pairlis, то assoc выбирает из него первую пару, начинающуюся с x. Таким образом, это функция поиска определения или значения по таблице, реализованной в форме ассоциативного списка.
(DEFUN assoc (x al) (COND

((equal x (CAAR al)) (CAR al))

((QUOTE T) (assoc x (CDR al))

))
Частичная функция - рассчитана на наличие ассоциации.
(assoc 'B '((A . (m n)) (B . (CAR x)) (C . w) (B . (QUOTE T)))) = (B . (CAR x))

Универсальная функция eval, которую предстоит определить, должна удовлетворять следующему условию: если представленная аргументом форма сводится к функции, имеющей значение на списке аргументов этой же формы, то данное значение и является результатом функции eval.
(eval '(fn arg1 ... argK)) = результат применения fn

к аргументам arg1, ..., argK.
Явное определение такой функции позволяет достичь четкости механизмов обработки Лисп-программ.
(eval ‘((LAMBDA (x y) (CONS (CAR x) y))

‘(A B) ‘(C D) ))

= (A C D)
Вводим две основные функции eval и apply для обработки форм и обращения к функциям, соответственно. Каждая из этих функций использует ассоциативный список для хранения связанных имен - значений переменных и определений функций. Сначала этот список содержит лишь определения встроенных констант.

Вернемся к синтаксической сводке вычислимых форм в таблице 3.1.
Каждой ветви этой сводки соответствует ветвь универсальной функции:
(DEFUN eval (e) (evl e '((Nil . Nil) (T . T))))
Вспомогательная функция evl понадобилась, чтобы в eval ввести накапливающий параметр – ассоциативный список, в котором будут храниться связи между переменными и их значениями и названиями функций и их определениями. При определении evl ранее выбранные распознаватели и селекторы погружаем в более общее ветвление COND и каждому из них сопоставляем свой семантический обработчик, выполняющий действие, соответствующее смыслу распознанной конструкции:2
(DEFUN evl(e a) (COND

( (atom e) (cdr(assoc e a)) )

( (eq (car e) 'QUOTE) (cadr e))

( (eq(car e) 'IF) (evcon(cdr e) a))

( T (apply (car e) (evlis(cdr e) a) a) )) )
(defun apply (fn x a) (COND

((atom fn)(cond

((eq fn 'CAR) (caar x))

((eq fn 'CDR) (cdar x))

((eq fn 'CONS) (cons (car x)(cadr x)) )

((eq fn 'ATOM)(atom (car x)) )

((eq fn 'EQ) (eq (car x)(cadr x)) )

(T (apply (evl fn a) x a)) ) )

)

((eq(car fn)'LAMBDA) (eval (caddr fn)

(pairlis (cadr fn) x a) ))

((eq (car fn) 'LABEL) (apply (caddr fn) x

(cons (cons (cadr fn)(caddr fn)) a)))))
(DEFUN evcon (c a) (COND

((evl (car c) a) (evl (cadr c) a) )

( T (evl (caddr c) a) ) ))
(DEFUN evlis (m a) (COND

((null m) Nil )

( T (cons(evl (car m) a)

(evlis(cdr m) a) )) )
Поясним ряд пунктов этих определений.
Первый аргумент evl - форма. Если она - атом, то этот атом может быть только именем переменной, а значение переменной должно уже находиться в ассоциативном списке.
Если CAR от формы - QUOTE, то она представляет собой константу, значение которой вычисляется как CADR от нее самой.
Если CAR от формы - IF, то форма - условное выражение. Вводим вспомогательную функцию EVCON, которая обеспечивает вычисление предиката и выбор формы, соответствующей значению предиката. Эта форма передается EVL для дальнейших вычислений.
Все остальные случаи рассматриваются как список из функции с последующими аргументами.

Вспомогательная функция EVLIS обеспечивает вычисление аргументов, затем представление функции и список вычисленных значений аргументов передаются функции APPLY.
Первый аргумент apply - функция. Если она - атом, то существует две возможности. Атом может представлять одну из элементарных функций (car cdr cons atom eq). В таком случае соответствующая ветвь вычисляет значение этой функции на заданных аргументах. В противном случае, этот атом - имя ранее заданного определения, которое можно найти в ассоциативном списке, подобно вычислению переменной.
Если функция начинается с LAMBDA, то ее аргументы попарно соединяются со связанными переменными и размещаются в ассоциативном списке, а тело определения (форма из лямбда-выражения) передается как аргумент функции eval для дальнейшей обработки.
Если функция начинается с LABEL, то ее название и определение соединяются в пару, и полученная пара размещается в ассоциативном списке, чтобы имя функции стало определенным при дальнейших вычислениях. Они произойдут как рекурсивный вызов apply, которая вместо имени функции теперь работает с ее определением при более полном ассоциативном списке - в нем уже размещено определение имени функции. Поскольку определение размещается "наверху" стека, оно становится доступным для всех последующих переопределений, то есть работает как локальный объект.
Определение универсальной функции является важным шагом, показывающим одновременно и механизмы реализации, и технику программирования на любом языке.
1) В строгой теории языка программирования все функции следует определять всякий раз, когда они используются. На практике это неудобно. Реальные системы имеют большой запас встроенных функций, известных языку, и возможность присоединения такого количества новых функций, какое понадобится.
2) Для языков программирования характерно большое разнообразие условных форм, конструкций выбора, ветвлений и циклов, практически без ограничений на их комбинирование.
3) В реальных системах программирования обычно поддерживается работа с целыми, дробными и вещественными числами в предельно широком диапазоне, а также работа с кодами и строками. Такие данные, как и атомы, являются минимальными объектами при обработке информации, но отличаются от атомов тем, что их смысл задан непосредственно их собственным представлением.

Приведенное выше самоопределение интерпретации на примере мини-Лиспа является концептуальным минимумом, обеспечивающим постепенность восприятия более сложных методов реализации языков и систем программирования, которые будут иллюстрироваться в дальнейшем. Они будут введены как расширения или уточнения чистого определения универсальной функции.
Составляющие этой формальной системы следующие:
1) Множество символов, называемых списками.
2) Система функциональных обозначений для основных понятий, необходимых при программировании обработки списков.
3) Формальное представление функциональных обозначений в виде списков.
4) Универсальная функция (записанная в виде списка), интерпретирующая обращение произвольной функции, записанной как списка, к ее аргументам.
5) Система базовых функций, обеспечивающих техническую поддержку обработки списков, и специальных функций, обеспечивающих управление вычислениями.
Более интересные и не столь очевидные следствия возникают при варьировании и расширении этой формальной системы, что и будет продемонстрировано в следующих лекциях.
Для полноты картины приведем ряд вспомогательных определений, показывающих механизмы определения обычной, процедурной техники программирования с присваиваниями и глобальными переменными:
APPEND - функция двух аргументов x и y, сцепляющая два списка в один.
(DEFUN append (x y) (COND

((null x) y)

((QUOTE T) (CONS

(CAR x)

(append (CDR x) y)

))))
(append '(A B) '(C D E)) = (A B C D E)
INSERT – вставка z перед вхождением ключа x в список al.
(DEFUN insert (al x z) (COND

((null al) Nil)

((equal (CAR al) x) (CONS z al))

((QUOTE T) (CONS (CAR al) (insert (CDR al) x z)))

))
(insert ‘(a b c) ‘b ‘s) = (a s b c)
ASSIGN – модель присваивания переменным, хранящим значения в ассоциативном списке. Замена связанного с данной переменной в первой паре значения на новое заданное значение. Если пары не было вообще, то новую пару из переменной и ее значения помещаем в конец списка, чтобы она могла работать как глобальная.
(DEFUN assign (x v al) (COND

((Null al) (CONS (CONS x v) Nil ))

((equal x (CAAR al))(CONS (CONS x v) (CDR al)))

((QUOTE T) (CONS (CAR al) (assign x v (CDR al))))

))
(assign ‘a 111 ‘((a . 1)(b . 2)(a . 3))) = ((a . 111)(b . 2)(a . 3))

(assign ‘a 111 ‘((c . 1)(b . 2)(a . 3))) = ((c . 1)(b . 2)(a . 111))

(assign ‘a 111 ‘((c . 1)(d . 3))) = ((c . 1)(d . 3) (a . 111))
Методы верификации программ активно используют структурную и рекурсивную индукцию (Мак-Карти) при доказательстве свойств рекурсивно определенных функций, таких как эквивалентность. Поэтому операционная семантика языка программирования, заданная над списочными структурами и поддерживающая все уровни определения языка от текста до кода, включая моделирование средств различных парадигм программирования, образует технологичную основу для решения актуальных проблем разработки надежных информационных систем. В дальнейших лекциях будут рассмотрены наиболее известные модели различных парадигм программирования. Начиная с низкоуровневого программирования на ассемблере дойдем до суперпрограммирования на языках сверх высокого уровня.

1 Условные выражения были введены в математическую теорию вычислений Маккарти (1963)


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


Похожие:

Лекция Определение языков программирования Прежде чем анализировать конкретные парадигмы программирования, рассмотрим задачу определения систем программирования iconПарадигмы программирования
Цель курса систематизация знаний о возможностях и особенностях разных стилей и методов программирования при решении различных задач...
Лекция Определение языков программирования Прежде чем анализировать конкретные парадигмы программирования, рассмотрим задачу определения систем программирования iconПлан-проспект спецкурса "Математические основы функционального программирования"
Целью курса является приобретение фундаментальных знаний в области построения программных систем с использованием современных языков...
Лекция Определение языков программирования Прежде чем анализировать конкретные парадигмы программирования, рассмотрим задачу определения систем программирования iconЛекция Языки и системы программирования
Понятие о системе программирования, ее основные функции и компоненты. Принципы работы сред программирования. "Операционные" и "модульные"...
Лекция Определение языков программирования Прежде чем анализировать конкретные парадигмы программирования, рассмотрим задачу определения систем программирования iconФилософия Lisp. Понятие о побочном эффекте. Цикл repl
Классификация языков программирования. Способы классификации. Методологии, парадигмы и стили яп. Классификация декларативного программирования....
Лекция Определение языков программирования Прежде чем анализировать конкретные парадигмы программирования, рассмотрим задачу определения систем программирования iconЛекция 3 Инструментальное по
Инструментальное по (или системы программирования, языки программирования) обеспечивают создание всех классов программ: системных,...
Лекция Определение языков программирования Прежде чем анализировать конкретные парадигмы программирования, рассмотрим задачу определения систем программирования iconЭкзаменационные вопросы по информатике
Парадигмы программирования. Основные подходы программирования. Типизация языков. Классификация c и С++ с точки зрения парадигм, подходов...
Лекция Определение языков программирования Прежде чем анализировать конкретные парадигмы программирования, рассмотрим задачу определения систем программирования iconОбзор языков программирования Что такое язык программирования?
Первый вопрос, который обычно задает человек, впервые сталкивающийся с новым языком программирования
Лекция Определение языков программирования Прежде чем анализировать конкретные парадигмы программирования, рассмотрим задачу определения систем программирования iconЛекция 15. Перспективы парадигм программирования
Специфика таких систем еще не нашла достаточно удобных языковых средств, что по-видимому и обуславливает на ближайшее время перспективы...
Лекция Определение языков программирования Прежде чем анализировать конкретные парадигмы программирования, рассмотрим задачу определения систем программирования iconУчебная программа Дисциплины б8 «Языки программирования»
Правила и приемы использования языков программирования, рассмотренные в лекционном курсе, используются в рамках лабораторных занятий...
Лекция Определение языков программирования Прежде чем анализировать конкретные парадигмы программирования, рассмотрим задачу определения систем программирования icon16 марта в 17. 45 аудитория 402 главного корпуса Программа курса Основы программирования
Основы программирования. Методика программирования во Flash. Носители кода. Язык Action Script (AS), история, корни. Окно Actions....
Разместите кнопку на своём сайте:
ru.convdocs.org


База данных защищена авторским правом ©ru.convdocs.org 2016
обратиться к администрации
ru.convdocs.org