Разное

Декларативные языки: Декларативный язык — это… Что такое Декларативный язык?

Содержание

Язык декларативного программирования XAML | GeekBrains

Где используется XAML, в чём его преимущества и недостатки

https://d2xzmw6cctk25h.cloudfront.net/post/2426/og_image/d456a025d4fb8ca41cfaa66b0d58b214.png

XAML — это язык разметки, разработанный компанией Microsoft. Он используется для инициализации объектов в технологиях на платформе .NET. Это простой декларативный язык, основанный на XML и чем-то похожий на HTML в веб-разработке. С помощью XAML можно легко создавать, инициализировать и устанавливать свойства объектов с иерархическими отношениями. 

XAML в основном используется для разработки графических интерфейсов в технологиях WPF (Windows Presentation Foundation), а также Silverlight. Но сфера применения этим не ограничивается. Данный язык также задействуется в технологиях WCF (Windows Communication Foundation) и WF (Windows Workflow Foundation), где он никак не связан с графическим интерфейсом.

Одна из приятных особенностей XAML — кросс-платформенность. XAML используется не только в WPF, но и в Xamarin.Forms. Это позволяет разработчикам ПО для компьютеров быстро начать создавать мобильные приложения. Можно один раз написать интерфейс — и он будет работать на Android, iOS и UWP (Windows 10). При этом XAML скомпилируется в нативный код для этих платформ.

Как работает XAML

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

Императивные — это известные языки вроде C, C++, C#, Pascal, Basic. В них мы говорим, что нужно сделать, но не уточняем, что должно получиться (обычно это мы описываем и проверяем в unit-тестах).

Декларативные языки, наоборот, позволяют описать состояние, которого мы хотим добиться, но не требуют (и обычно не дают) описать, как прийти к нему. Речь о таких языках, как XAML, XML, HTML, SQL и другие. В случае с XAML за то, как прийти в заданное состояние, отвечает XAML-процессор.

Рассмотрим процесс преобразования XAML-кода в WPF-проекте.

Сначала XAML-код преобразуется процессором XAML для конкретной платформы во внутренний код, который описывает элемент пользовательского интерфейса. Внутренний код и код C# связываются друг с другом посредством частичных классов, и затем компилятор .NET создаёт приложение.

Если наш файл XAML интерпретируется процессором как C#-код, зачем нам вообще нужен XAML? Самое время поговорить о его плюсах.

Преимущества XAML

XAML не является обязательной частью приложения — мы вообще можем обходиться без него, создавая все элементы в файле связанного с ним кода на языке C#. Однако использование XAML всё-таки даёт преимущества:

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

Рассмотрим следующий пример. Допустим, нам нужно отобразить текст «Hello world!»  в элементе TextBlock. Если бы мы делали это на С#, то выглядело бы это так:


TextBlock textBlock = new TextBlock();
textBlock.Text = "Hello world!";

На XAML так:


<TextBlock Text="Hello world!"/>

Как говорится, комментарии излишни. То, как будет обрабатываться XAML-код, нас не волнует — этим занимается XAML-парсер. Использование XAML-кода в GUI-приложениях позволяет отделить графический интерфейс от бизнес-логики программы.

Структура XAML

Новый проект WPF по умолчанию содержит файлы с кодом XAML. Например, дефолтный файл MainWindow.xaml в проекте будет иметь следующую разметку:


<Window x:Class="XamlApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas. microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:XamlApp"
        mc:Ignorable="d"
        Title="MainWindow">
    <Grid>
 
    </Grid>
</Window>

Подобно структуре веб-страницы на HTML, здесь есть иерархия элементов. Элемент верхнего уровня — Window, это окно приложения. Кроме него есть ещё два элемента верхнего уровня: Page и Application.

Window имеет вложенный пустой элемент Grid, а также, подобно HTML-элементам, ряд атрибутов (Title, Width, Height). Они задают заголовок, ширину и высоту окна соответственно.

Чтобы задействовать элементы в XAML, мы также подключаем пространства имён. Вторая и третья строчки как раз и представляют собой такие пространства, подключаемые в проект по умолчанию. А атрибут xmlns необходим, чтобы определять пространства имён в XML.

  • Так, пространство имён http://schemas. microsoft.com/winfx/2006/xaml/presentation содержит описание и определение большинства элементов управления. 
  • http://schemas.microsoft.com/winfx/2006/xaml — это пространство имён, которое определяет некоторые свойства XAML, например Name или Key. 

Префикс x в определении xmlns:x означает, что те свойства элементов, которые заключены в этом пространстве имён, будут использоваться с префиксом x — x:Name или x:Key. Это же пространство имён используется уже в первой строчке x:Class=»XamlApp.MainWindow» — здесь создаётся новый класс MainWindow и соответствующий ему файл кода, куда будет прописываться логика для этого окна приложения.

Элементы и их атрибуты

XAML может просто определять элементы и их свойства. Каждый элемент должен иметь открытый и закрытый тег, как в случае с Window:


<Window></Window>

Либо элемент может иметь сокращённую форму с закрывающим слешем в конце, наподобие:


<Window />

Каждый элемент в XAML соответствует определённому классу C#. Например, элемент Button соответствует классу System.Windows.Controls.Button. Добавим кнопку в разметку окна:


<Window x:Class="XamlApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:XamlApp"
        mc:Ignorable="d"
        Title="MainWindow">
    <Grid x:Name="grid1">
        <Button x:Name="button1"  Content="Кнопка" />
    </Grid>
</Window>

Сначала идёт элемент высшего уровня — Window. Затем вложенный элемент Grid — контейнер для других элементов. И в нём уже определён элемент Button, представляющий кнопку.

Для кнопки мы можем определить свойства в виде атрибутов. Здесь заданы атрибуты x:Name (имя кнопки), Width, Height и Content. Определив разметку XAML, запускаем проект — и видим весь код XAML в графике, то есть нашу кнопку:

Недостатки XAML

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


<Style x:Key="SendButton">
    <Style.Setters>
        <Setter Property="Border.Margin" Value="1" />
        <Setter Property="Border.Background" Value="#333" />
        <Setter Property="TextBlock.Foreground" Value="#fff" />
        <Setter Property="TextBlock.FontWeight" Value="DemiBold"/>
        <Setter Property="TextBlock.VerticalAlignment" Value="Center"/>
        <Setter Property="TextBlock.TextAlignment" Value="Center"/>
        <Setter Property="Border.Padding" Value="10, 5" />
        <Setter Property="Button.Template">
            <Setter. Value>
                <ControlTemplate>
                    <Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Border.Padding}">
                        <TextBlock Text="{TemplateBinding Button.Content}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style.Setters>
    <Style.Triggers>
        <Trigger Property="Control.IsMouseOver" Value="true">
            <Setter Property="Button.Background" Value="#444"/>
        </Trigger>
    </Style.Triggers>
</Style>

В то же время на CSS это можно было сделать намного проще:


.button
{
	background: #333;
}
 
.button:hover
{
	background: #444;
}

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

  • неправильно указана привязка;
  • не указан DataContext;
  • передаётся пустой объект; 
  • и так далее.

Возможно, освоив XAML для WPF, вы захотите перейти к разработке Xamarin.Forms. Но там используется немного другой XAML: у некоторых элементов другие имена (StackLayout вместо StackPanel). Привязка данных создаётся тоже по-другому, не так, как вы привыкли в WPF. 

Заключение

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

Декларативное программирование — Declarative programming

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

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

Декларативное программирование часто рассматривает программы как теории формальной логики и вычисления в качестве вычетов в этом логическом пространстве. Декларативное программирование может значительно упростить написание параллельных программ .

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

Определение

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

Эти определения существенно пересекаются.

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

На чистом функциональном языке , таком как Haskell , все функции не имеют побочных эффектов , а изменения состояния представлены только как функции, которые преобразуют состояние, которое явно представлено в программе как объект первого класса . Хотя чистые функциональные языки не являются императивными, они часто предоставляют возможность описать действие функции в виде серии шагов. Другие функциональные языки, такие как Lisp , OCaml и Erlang , поддерживают сочетание процедурного и функционального программирования.

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

Подпарадигмы

Декларативное программирование — это общий термин, который включает в себя ряд наиболее известных парадигм программирования .

Ограниченное программирование

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

Доменные языки

Хорошо известные примеры декларативных предметно-ориентированных языков (DSL) включают язык ввода генератора синтаксического анализатора yacc , QML , язык спецификации сборки Make, язык управления конфигурацией Puppet , регулярные выражения и подмножество SQL (запросы SELECT, например, ). Преимущество DSL в том, что они полезны, но при этом не обязательно должны быть полными по Тьюрингу , что упрощает использование чисто декларативного языка.

Многие языки разметки, такие как HTML , MXML , XAML , XSLT или другие языки разметки пользовательского интерфейса , часто являются декларативными. HTML, например, описывает только то, что должно отображаться на веб-странице — он не определяет ни поток управления для визуализации страницы, ни возможные взаимодействия страницы с пользователем.

По состоянию на 2013 год некоторые программные системы объединяют традиционные языки разметки пользовательского интерфейса (например, HTML) с декларативной разметкой, которая определяет, что (но не как) системы внутреннего сервера должны делать для поддержки заявленного интерфейса. Такие системы, обычно использующие доменное пространство имен XML , могут включать абстракции синтаксиса базы данных SQL или параметризованные вызовы веб-служб с использованием передачи репрезентативного состояния (REST) ​​и SOAP .

Гибридные языки

Make-файлы, например, декларативно определяют зависимости, но также включают обязательный список действий, которые необходимо предпринять. Точно так же yacc декларативно определяет контекстно-свободную грамматику, но включает фрагменты кода с основного языка, что обычно является обязательным (например, C ).

Логическое программирование

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

Моделирование

Модели или математические представления физических систем могут быть реализованы в компьютерном коде, который является декларативным. Код содержит ряд уравнений, а не императивных присваиваний, которые описывают («декларируют») поведенческие отношения. Когда модель выражается в этом формализме, компьютер может выполнять алгебраические манипуляции, чтобы наилучшим образом сформулировать алгоритм решения. Математическая причинность обычно накладывается на границы физической системы, в то время как описание поведения самой системы является декларативным или акаузальным. Языки и среды декларативного моделирования включают Analytica , Modelica и Simile .

Смотрите также

Ссылки

внешние ссылки

SoftCraft: Декларативное программирование





[
Содержание
| 1
| 2
| 3
| 4
| 5
| 5.1
| 5.2
| 5. 3
| 5.4
| 5.5
| 5.6
| 5.7
| 5.8
| 5.9
| 6
| 6.1
| 6.2
| 6.3
| 6.4
| 6.5
| 7
| 7.1
| Литература
]



© 2003 И.А. Дехтяренко


3. Инструменты.



Инструменты, которые мы применяем, оказывают глубокое
(и тонкое) влияние на наши способы мышления и следовательно на нашу
способность мыслить.

Эдсгер Дейкстра.

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

С точки зрения функционального программирования программа — функция,
применяемая к вводу и возвращающая вывод.


        output = program(input)



Логическая программа — отношение между вводом и выводом.


        program(input, output)


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

Имеется, однако, более серьёзные отличия. Функции в функциональных языках
«однонаправлены». Они получают аргументы и возвращают результат. В
логических языках разница между вводом и выводом условна. Мы можем указать
желаемый вывод и получить ввод, который его обеспечит. Другое важное отличие
— недетерминизм логических языков. Результат в них не обязательно
определяется однозначно.

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




Функциональная программа

Логическая программа


area(Eurasia) = 55
area(Africa) = 29
area(NorthAmerica) = 20
area(SouthAmerica) = 18
area(Australia) = 7
area(Antarctica) =14


area(Eurasia,55)
area(Africa,29)
area(NorthAmerica,20)
area(SouthAmerica,18)
area(Australia,7)
area(Antarctica,14)

Теперь к функциональной программе можно обратиться, например, с запросом
area(Eurasia) и получить ответ 55.

Запросы к логической программе разнообразнее: area(Eurasia,a)
выдаст ответ {a = 55}, а area(m,29) — {m=Africa}. Запрос
area(m,a) выдаст любую из шести возможных пар, но, добавляя
ограничения, мы можем сузить область допустимых результатов.
Возможные ответы на area(m,a),a>20 -
{m=Eurasia,a=55}и {m=Africa, a=29}, а на
area(m,a),a>20,a<40 получим единственно
возможный ответ: {m=Africa, a=29}.
Этот по выражению Хоара «ангельский недетерминизм» и составляет
главную силу логического программирования.

Предпринимаются попытки объединить эти два стиля. Один из подходов -
«функционально-логическое программирование», в котором отношения
задаются функциями, но запросы выполняются как в логических языках. То есть
допускаются обращения вида area(m) = 20 —> {m = NorthAmerica}.

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

Другая характеристика языка — используемая в нём система типов данных.
Вообще, для декларативных языков характерен «декларативный» подход
и к организации данных. То есть понятие структуры данных никак не связано с
её представлением в памяти компьютера. Напрочь отсутствует такое понятие как
указатель. Редко встречаются и массивы. Наиболее распространенные структуры -
списки и деревья.

Некоторые языки полностью игнорируют понятие типа данных. Имена
переменных в них не связываются по умолчанию с каким-либо типом — все объекты
образуют единое универсальное пространство. Такие языки называют бестиповыми,
а также «языками с динамической типизацией» или «языками со
скрытыми типами». Наиболее радикальны в этом плане Лисп и Пролог. Формы
представления программ и данных в них одинаковы — символьные выражения. Это
позволяет программе обрабатывать и преобразовывать другие программы и даже
саму себя.

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

Еще одно важное свойство языков — поддержка модульности. Ранние языки
слабо развиты в этом отношении. Они имеют «плоское» пространство
имён в духе Си. Наиболее развита система модулей у SML и OCAML, но многие
считают её чересчур сложной. Возможно «золотую середину»
представляют Haskell, Mercury и т.п., использующие простой модульный механизм
в стиле Модулы-2. Для практических нужд этого вполне достаточно.

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


Функциональные языки.


Лисп
остаётся наиболее широко используемым функциональным языком. За долгую
историю своего развития язык Лисп породил множество диалектов. Несмотря на
то, что почти все из них носят названия вида «Some Lisp», разница
между ними бывает значительной, не меньше, чем между Алголом и Паскалем или
между C и C++. Так что правильнее считать их разными языками.

Предпринимались попытки
стандартизировать язык. Наиболее
известная из них — стандарт ANSI

Common Lisp
(см. также CLtL2).
К сожалению, язык получился слишком сложным. Его описание содержит более 1000
страниц.

Доступны как коммерческие (
Allegro,
Harlequin,
Corman),
так и бесплатные (
GnuCL,
CLISP,
CMUCL) реализации.

ISLISP — очень компактный диалект Лиспа, принятый в качестве
международного стандарта
(ISO).
Доступны реализации
OpenLisp ,
TISL,
OKI ISLISP.

EuLisp
разрабатывается группой европейских пользователей Лиспа в надежде создать
развитую систему программирования, но не такую громоздкую как Common Lisp.
Язык всё ещё в стадии разработки, но уже существует несколько реализаций (
EuScheme,
Feel,
Youtoo)
включающие TELOS (The Eulisp Object System — аналог CLOS) .

Scheme — римейк Лиспа, более простой
и даже элегантный язык. Активно используется в исследовательских работах и
для обучения. Сторонники Scheme любят подчёркивать, что объем «сообщения
о языке» (

R4RS,

R5RS
~50 страниц) меньше чем объем указателя к описанию Common Lisp.

Существует более 50 реализаций Scheme (см.
список).
Некоторые имеют интегрированные среды (
DrScheme,
WinScheme48,
3DScheme и EdScheme).
Есть довольно эффективные компиляторы (
Gambit,
Bigloo).

Для обучения и экспериментов
подойдут Scheme48,
WinScheme48,
XLISP,
MzScheme,
DrScheme.

Успеху Scheme значительно способствовала книга Абельсона и Сусмана
[20]. Это не учебник функционального программирования, но
одна из лучших книг по программированию. Очень жаль, что не переводилась на
русский.
Функциональное подмножество Лиспа используется в учебнике
Хендерсона [2]. На русском издано несколько книг по
Лиспу [3,4,
5].
Ему же посвящён курс лекций М.Н Морозова [6].


Erlang
интересный язык, разработанный компанией Ericsson. Подобно Лиспу бестиповый,
но имеет очень выразительный синтаксис, основанный на сопоставлении с
образцом и несколько напоминающий Пролог. Это делает его более легким в
освоении. Специфика языка — ориентация на параллельное программирование
систем реального времени. Язык включает средства для описания
взаимодействующих процессов, близкие к нотации CSP Хоара
[19]. Реализация содержит богатую библиотеку и довольно
активно развивается.


Два языка из семейства ML: Standard ML и CAML (Categorical
Abstract Machine Language). Функциональные языки с «энергичной»
стратегией вычислений. Развитая система типов и модулей. Есть и типично
императивные средства: присваивания, циклы, обработка исключений. Различия
между двумя диалектами в основном синтаксичские.


Standard ML


  • Moscow ML — популярный компилятор, созданный на основе CAML Light.
    Благодаря ему SML стал широко доступным.

  • Poly/ML также неплохой инструмент
    для экспериментов с SML. Предлагается библиотека графического
    интерфейса, но она пока недостаточно стабильна (по крайней мере Windows
    версия).

  • SML/NJ (Standard
    ML of New Jersey) — классическая реализация SML. Хорошо оптимизирующий,
    но довольно громоздкий компилятор.
  • MLton обладает примерно теми же
    достоинствами и недостатками, что и SML/NJ.
  • MLj — компилятор в
    байт-код JavaVM. Реализует подмножество SML и не очень качественно.
  • SML.NET -
    Великий и Ужасный не мог обойти вниманием SML.

Сравнение производительности некоторых систем можно посмотреть
здесь.

CAML

  • Objective CAML
    содержит компилятор в байт-код и оптимизирующий компилятор для
    объектно-ориентированного расширения CAML.
  • CAML Light
    — компилятор в байт-код. В связи с появлением OCAML может считаться
    устаревшим, но продолжает развиваться. Широко применяется в учебных
    заведениях, поскольку очень быстр и нетребователен к ресурсам.
  • F#
    — ещё один диалект ML, созданный на основе CAML специально для .NET.

Классическим учебником по SML считается
Programming in Standard ML
Роберта Харпера. Есть перевод ранней версии книги [7].
Очень краткое сравнение
SML vs Ocaml.


Haskell
— быстро набирающий популярность язык. Разрабатывается международным
комитетом как чисто функциональный «индустриальный» язык
программирования. Язык довольно строгий и выразительный, хотя и может
показаться и сложным. Главные особенности: строгая функциональность
(отсутствуют императивные операторы), ленивые вычисления, полиморфная система
типов и классы типов — попытка ввести в функциональное программирование
некоторые концепции ООП.

  • Hugs
    интерпетатор Haskell. Для обучения лучше всего выбрать именно его.

  • GHC
    (Glasgow Haskell Compiler) — наиболее эффективный компилятор, но медленный
    и весьма требователен к ресурсам.

  • nhc98
    не столь эффективен как ghc, зато предьявляет гораздо меньшие требования к
    компьютеру.

  • HBC
    похоже заброшен авторами. Включает компилятор с Lazy ML. Самая интересная
    особенность — библиотека декларативного программирования пользовательских
    интерфейсов Fudgets. Сейчас она переносится на ghc.

  • Mondrian
    позволяет компилировать код Haskell в MSIL для .NET.

На www.haskell.org
есть описание Haskell и
учебные материалы.
По-русски введение в язык можно найти в лекциях Романа Душкина
[8], а описание  Hugs в его же пособии
[9].

На основе Haskell создано уже немало языков. В основном это расширения языка
параллельными
(DFH,
GPH,
pH,
Goffin,
Eden)
или императивными (Mondrian)
средствами. Есть попытки добавить возможности ООП (
O’Haskell) или
другими способами повысить выразительность системы типов
(PolyP,
Cayenne).

Очень похожий на Haskell язык
Clean
разработан в Неймегенском университете. Эффективный компилятор и неплохая
библиотека (в частности графического интерфейса) делают его вполне пригодным
для решения реальных задач.


Hope — очень простой язык и в то же время содержит все важные
особенности функциональных языков. Широкого применения не имеет, используется
для обучения функциональному программированию.
На страничке Роса Патерсона (
Hope) можно найти описание
языка и исходный текст ленивого интерпретатора.
Существует ещё довольно старый и неудобный интерпретатор для DOS
ichope.
Можно выполнять программы и через
WEB интерфейс.

Учебник Филда и Харрисона [1], использующий
этот язык — одна из лучших книг по функциональному программированию и,
безусловно, лучшая изданная на русском.


Логические языки.


Пролог — практически единственный широко используемый логический
язык. Имеется множество реализаций.

  • Две коммерческие системы
    Quintus Prolog и
    SICStus Prolog сейчас развиваются
    и поддерживаются SICS (Swedish Institute of Computer Science). Среды
    разработки с большим набором инструментов и очень обширными библиотеками.
    Большинство разработчиков используют SICStus.

  • Strawberry Prolog
    хорошо подходит для знакомства с Прологом и создания небольших программ для
    Windows, но обладает слишком низкой производительностью для серьезных
    задач.

  • SWI Prolog -
    довольно популярная система, в основном благодаря удобной среде и
    переносимой библиотеке для создания графического интерфейса.

  • B-Prolog
    — самая быстрая из реализаций, основанных на байт-коде. Включает некоторые
    расширения: ограничения на конечных доменах CLP(FD) и запоминание
    результатов (tabling) — техника известная в функциональном программировании
    как мемоизация (memoiazation).

  • XSB
    — развитие некогда популярного Stony Brook Prolog. Также поддерживает
    tabling. Интересная особенность — возможность использования языка второго
    порядка HiLog.

  • GNU Prolog
    — компилятор в двоичный код. По скорости совсем немного уступает SICStus.

Книга Стерлинга и Шапиро [12] — лучший
учебник по Прологу и отличное введение в логическое программирование.
Представление о языке можно получить из курса лекций М.Н Морозова
[16]. Теории логического программирования
посвящены [10] и [11].


Visual Prolog
— продукт датской фирмы Prolog Development Center. Ранее распространялся под
названием Turbo Prolog (Borland) и PDC Prolog. Несмотря на своё название это -
не реализация Пролога, а совершенно особенный язык со строгим контролем типов.
К сожалению, отсутствие полиморфизма делает систему типов маловыразительной. В
последних версиях появилась поддержка ООП.

Книги по Турбо-Прологу [17,
18] безнадёжно устарели, но полезную информацию можно
получить на сайте фирмы
Пролог-Софт.

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

Godel
— экспериментальный логический язык со строгим контролем типов. Попытка
создать декларативную альтернативу Прологу. Значительное внимание уделено
средствам метапрограммирования. Замечательное средство для изучения
логического программирования. К сожалению, поддержки для Windows нет и не
планируется.


«Мультипарадигматические» языки.


Curry
— функционально-логический язык, созданный на основе Haskell. Наследует
большинство его свойств, но добавляет логические особенности. Всё ещё в стадии
разработки.

Escher
— ещё один функционально-логический язык. Первоначально создавался на основе
Godel, добавлением функциональных свойств, но затем значительно изменился.
Сейчас очень похож на Curry и отличается в основном стратегией вычислений.

Oz — попытка объединить главные особенности различных парадигм в
рамках одного языка. Он включает классы, наследование, активные объекты,
функции высшего порядка, недетерминированные вычисления. В настоящее время
несколько исследовательских групп объединились в разработке среды
программирования Mozart .

Poplog — пример объедининения разных
парадигм путём создания многоязычной среды программирования. Включает
компиляторы языков Pop-11, Common Lisp, Standard ML и Prolog.


Литература

  1. Филд А., Харрисон П.
    Функциональное программирование. М., Мир, 1993.

  2. Хендерсон П.
    Функциональное программирование. Применение и реализация. М., Мир, 1983.

  3. Маурер У.
    Введение в программирование на языке Лисп. — М.: Мир, 1976.

  4. Лавров С., Силагадзе Г.
    Автоматическая обработка данных. Язык Лисп и его реализация. — М.: Наука,
    1978.

  5. Хювенен Э., Сеппянен Й.
    Мир Лиспа. В 2-х т. — М.: Мир, 1990.

  6. Морозов М.Н.

    Функциональное программирование — курс лекций
    (700Kzip).

  7. Харпер Р.
    Введение в Стандартный ML. (
    pdf
    ps)

  8. Душкин Р.В.

    Лекции по функциональному программированию.
    (в формате doc)

  9. Душкин Р.В.
    Лабораторный
    практикум по функциональному программированию.(
    в формате doc)

  10. Ковальски Р.
    Логика в решении проблем. М.:Наука,1990.

  11. Хоггер К.
    Введение в логическое программирование. — М.: Мир, 1988.

  12. Стерлинг Л.,
    Шапиро Э.
    Искусство программирования на языке Пролог. — М.: Мир, 1990.

  13. Клоксин У., Меллиш К.
    Программирование на языке Пролог. — М.: Мир, 1987.

  14. Братко И.
    Программирование на языке Пролог для искусственного интеллекта. — М.: Мир,
    1990.

  15. Малпас Дж.
    Реляционный язык Пролог и его применение. — Новосибирск: Наука,1990

  16. Морозов М. Н.

    Логическое программирование — курс лекций .

  17. Ин Ц., Соломон Д.
    Использование Турбо-Пролога. — М.: Мир, 1993.

  18. Янсон А.
    Турбо-Пролог в сжатом изложении. — М.: Мир, 1991.

  19. Хоар Ч.
    Взаимодействующие последовательные процессы. — М.: Мир, 1989.

  20. Abelson H., Sussman G.

    Structure and Interpretation of Computer Programs.
    — MIT Press, Boston, 1986.


[
Содержание
| 1
| 2
| 3
| 4
| 5
| 5.1
| 5.2
| 5.3
| 5. 4
| 5.5
| 5.6
| 5.7
| 5.8
| 5.9
| 6
| 6.1
| 6.2
| 6.3
| 6.4
| 6.5
| 7
| 7.1
| Литература
]












Декларативное программирование — Карта знаний

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

    Наиболее близким к «чисто декларативному» программированию является написание исполнимых спецификаций (см. соответствие Карри — Ховарда). В этом случае программа представляет собой формальную теорию, а её выполнение является одновременно автоматическим доказательством этой теории, и характерные для императивного программирования составляющие процесса разработки (проектирование, рефакторинг, отладка и др.) в этом случае исключаются: программа проектирует и доказывает сама себя.

    К подвидам декларативного программирования также зачастую относят функциональное и логическое программирование — несмотря на то, что программы на таких языках нередко содержат алгоритмические составляющие, архитектура в императивном понимании (как нечто отдельное от кодирования) в них также отсутствует: схема программы является непосредственно частью исполняемого кода.

    На повышение уровня декларативности нацелено языково-ориентированное программирование.

    «Чисто декларативные» компьютерные языки зачастую не полны по Тьюрингу — так как теоретически не всегда возможно порождение исполняемого кода по декларативному описанию. Это иногда приводит к спорам о корректности термина «декларативное программирование» (менее спорным является «декларативное описание решения» или, что то же самое, «декларативное описание задачи»).

Источник: Википедия

Связанные понятия

Функциона́льное программи́рование — раздел дискретной математики и парадигма программирования, в которой процесс вычисления трактуется как вычисление значений функций в математическом понимании последних (в отличие от функций как подпрограмм в процедурном программировании).

Грамотное программирование (ГП; англ. Literate Programming) — концепция, методология программирования и документирования, в которой программа состоит из прозы на естественном языке вперемежку с макроподстановками и кодом на языках программирования. Термин и саму концепцию предложил Дональд Кнут в 1981 году при разработке системы компьютерной вёрстки TeX.

Обобщённое программирование (англ. generic programming) — парадигма программирования, заключающаяся в таком описании данных и алгоритмов, которое можно применять к различным типам данных, не меняя само это описание. В том или ином виде поддерживается разными языками программирования. Возможности обобщённого программирования впервые появились в виде дженериков (обобщённых функций) в 1970-х годах в языках Клу и Ада, затем в виде параметрического полиморфизма в ML и его потомках, а затем во многих объектно-ориентированных…

Язык спецификаций — формальный язык, предназначенный для декларативного описания структуры, связей, свойств данных и способов их преобразований, (в отличие от активных языков) без явного упоминания порядка выполняемых действий и использования конкретных значений данных.

Аппликативное программирование — один из видов декларативного программирования, в котором написание программы состоит в систематическом осуществлении применения одного объекта к другому. Результатом такого применения вновь является объект, который может участвовать в применениях как в роли функции, так и в роли аргумента и так далее. Это делает запись программы математически ясной. Тот факт, что функция обозначается выражением, свидетельствует о возможности использования значений-функций — функциональных…

Пролог (англ. Prolog) — язык и система логического программирования, основанные на языке предикатов математической логики дизъюнктов Хорна, представляющей собой подмножество логики предикатов первого порядка.

Сема́нтика в программировании — дисциплина, изучающая формализации значений конструкций языков программирования посредством построения их формальных математических моделей. В качестве инструментов построения таких моделей могут использоваться различные средства, например, математическая логика, λ-исчисление, теория множеств, теория категорий, теория моделей, универсальная алгебра. Формализация семантики языка программирования может использоваться как для описания языка, определения свойств языка…

В информатике отражение или рефлексия (холоним интроспекции, англ. reflection) означает процесс, во время которого программа может отслеживать и модифицировать собственную структуру и поведение во время выполнения. Парадигма программирования, положенная в основу отражения, называется рефлексивным программированием. Это один из видов метапрограммирования.

Подробнее: Рефлексия (программирование)

Аспектно-ориентированная разработка программного обеспечения — развивающаяся технология разработки программного обеспечения, которая ищет новые способы разбиения на модули программного обеспечения, чтобы изолировать вторичные или вспомогательные функции от бизнес-логики основной программы. АОРПО позволяет реализовать отдельно различные проблемы и автоматически объединять их в работоспособные системы.

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

Предметно-ориентированный язык (англ. domain-specific language, DSL — «язык, специфический для предметной области») — язык программирования, специализированный для конкретной области применения (в противоположность языку общего назначения, применимому к широкому спектру областей и не учитывающему особенности конкретных сфер знаний). Построение такого языка и/или его структура данных отражают специфику решаемых с его помощью задач. Является ключевым понятием языково-ориентированного программирования…

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

Язык программи́рования — формальный язык, предназначенный для записи компьютерных программ. Язык программирования определяет набор лексических, синтаксических и семантических правил, определяющих внешний вид программы и действия, которые выполнит исполнитель (обычно — ЭВМ) под её управлением.

Языково-ориентированное программирование (ЯОП) (англ. Language Oriented Programming), также Расходящаяся разработка (англ. middle out development), также метаязыковая абстракция, также Разработка, опирающаяся на предметно-специфичный язык (англ. DSL-Based Development) — парадигма программирования, заключающаяся в разбиении процесса разработки программного обеспечения на стадии разработки предметно-ориентированных языков (DSL) и описания собственно решения задачи с их использованием. Стадии могут…

Концептуальное программирование — подход к программированию, описанный Э.Х. Тыугу в одноименной книге . К. программирование предполагает оперирование понятиями (концептами), описанными в терминах предметной области, что позволяет использовать ЭВМ на этапе постановки задачи. Достаточно точное описание задачи позволяет ЭВМ автоматически составлять программы для её решения. Характерными особенностями концептуального программирования являются также использование языка предметной области и использование…

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

Комбинато́рное программи́рование (англ. function-level programming) — парадигма программирования, использующая принципы комбинáторной логики, то есть не требующая явного упоминания аргументов определяемой функции (программы) и использующая вместо переменных комбинаторы и композиции. Является особой разновидностью функционального программирования, но, в отличие от основного его направления, комбинаторное программирование не использует λ-абстракцию).

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

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

Неявная типизация, латентная типизация или утиная типизация (англ. Duck typing) — в ООП-языках — определение факта реализации определённого интерфейса объектом без явного указания или наследования этого интерфейса, а просто по реализации полного набора его методов.

В информатике типобезопасность (англ. type safety) языка программирования означает безопасность (или надёжность) его системы типов.

Семанти́ческие веб-се́рвисы (англ. Semantic Web Services, SWS; иногда Semantic Web Web Services, SWWS) — законченные элементы программной логики с однозначно описанной семантикой, доступные через Интернет и пригодные для автоматизированного поиска, композиции и выполнения с учетом их семантики. В тематической литературе часто называются «динамической составляющей семантической паутины».

Объе́ктно-ориенти́рованное программи́рование (ООП) — методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определённого класса, а классы образуют иерархию наследования.

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

Процеду́рное программи́рование — программирование на императивном языке, при котором последовательно выполняемые операторы можно собрать в подпрограммы, то есть более крупные целостные единицы кода, с помощью механизмов самого языка.

Абстра́ктный тип да́нных (АТД) — это математическая модель для типов данных, где тип данных определяется поведением (семантикой) с точки зрения пользователя данных, а именно в терминах возможных значений, возможных операций над данными этого типа и поведения этих операций.

Компонентно-ориентированное программирование (англ. component-oriented programming, COP) — парадигма программирования, существенным образом опирающаяся на понятие компонента — независимого модуля исходного кода программы, предназначенного для повторного использования и развёртывания и реализующегося в виде множества языковых конструкций (например, «классов» в объектно-ориентированных языках программирования), объединённых по общему признаку и организованных в соответствии с определёнными правилами. ..

Мультиме́тод (англ. multimethod) или мно́жественная диспетчериза́ция (англ. multiple dispatch) — механизм, позволяющий выбрать одну из нескольких функций в зависимости от динамических типов или значений аргументов. Представляет собой расширение одиночной диспетчеризации (виртуальных функций), где выбор метода осуществляется динамически на основе фактического типа объекта, для которого этот метод был вызван. Множественная диспетчеризация обобщает динамическую диспетчеризацию для случаев с двумя или…

Логика разделения, сепарационная логика (англ. separation logic) в информатике — формальная система, предназначенная для верификации программ, содержащих изменяемые структуры данных и указатели, расширение логики Хоара. Разработана Джоном Рейнольдсом (англ. John C. Reynolds), Питером О’Хирном (англ. Peter O’Hearn), Самином Иштиаком (англ. Samin Ishtiaq) и Хонсёком Яном (англ. Hongseok Yang) на основе работ Рода Бёрстола (англ. Rod Burstall). Язык утверждений логики разделения является специальным…

Контрактное программирование (design by contract (DbC), programming by contract, contract-based programming) — это метод проектирования программного обеспечения. Он предполагает, что проектировщик должен определить формальные, точные и верифицируемые спецификации интерфейсов для компонентов системы. При этом, кроме обычного определения абстрактных типов данных, также используются предусловия, постусловия и инварианты. Данные спецификации называются «контрактами» в соответствии с концептуальной метафорой…

Шаблон проектирования или паттерн (англ. design pattern) в разработке программного обеспечения — повторяемая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках некоторого часто возникающего контекста.

Теория языков программирования (англ. programming language theory, PLT) — раздел информатики, посвящённый вопросам проектирования, анализа, определения характеристик и классификации языков программирования и изучением их индивидуальных особенностей. Тесно связана с другими ветвями информатики, результаты теории используются в математике, в программной инженерии и лингвистике.

Формальная верификация или формальное доказательство — формальное доказательство соответствия или несоответствия формального предмета верификации его формальному описанию. Предметом выступают алгоритмы, программы и другие доказательства.

Неуточняемое поведение (англ. unspecified behavior) или поведение, определяемое реализацией (англ. implementation-defined behavior) — поведение компьютерной программы, которое может различаться на разных платформах и компиляторах поскольку спецификация языка программирования предлагает несколько допустимых вариантов реализации некой языковой конструкции. В отличие от неопределённого поведения, программа с неуточняемым поведением с точки зрения соответствия спецификации языка не считается ошибочной…

Станда́рт оформле́ния ко́да (станда́рт коди́рования, стиль программи́рования) (англ. coding standards, coding convention или programming style) — набор правил и соглашений, используемых при написании исходного кода на некотором языке программирования. Наличие общего стиля программирования облегчает понимание и поддержание исходного кода, написанного более чем одним программистом, а также упрощает взаимодействие нескольких человек при разработке программного обеспечения.

Металингвистическая абстракция в информатике — это процесс решения сложных проблем путём создания нового языка или словарного запаса, чтобы лучше понять проблему пространства. Этот вопрос подробно описан в учебнике МТИ «Структура и интерпретация компьютерных программ», который рекомендует использовать язык Scheme как основу для создания новых языков.

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

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

Правило одного определения (One Definition Rule, ODR) — один из основных принципов языка программирования C++. Назначение ODR состоит в том, чтобы в программе не могло появиться два или более конфликтующих между собой определения одной и той же сущности (типа данных, переменной, функции, объекта, шаблона). Если это правило соблюдено, программа ведёт себя так, как будто в ней существует только одно, общее определение любой сущности. Нарушение ODR, если оно не будет обнаружено при компиляции и сборке…

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

По одной из классификаций, языки программирования неформально делятся на сильно и слабо типизированные (англ. strongly and weakly typed), то есть обладающие сильной или слабой системой типов. Эти термины не являются однозначно трактуемыми, и чаще всего используются для указания на достоинства и недостатки конкретного языка. Существуют более конкретные понятия, которые и приводят к называнию тех или иных систем типов «сильными» или «слабыми».

Подробнее: Сильная и слабая типизация

Синтаксический сахар (англ. syntactic sugar) в языке программирования — это синтаксические возможности, применение которых не влияет на поведение программы, но делает использование языка более удобным для человека.

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

Клу (англ. Clu, CLU) — объектно-ориентированный язык программирования, одним из первых реализовавший концепцию абстрактных типов данных и парадигму обобщённого программирования. Создан группой учёных Массачусетского технологического института под руководством Барбары Лисков в 1974 году, широкого применения в практике не нашёл, однако многие его элементы использованы при создании таких языков, как Ада, C++, Java, Sather, Python, C#.

Декларативные (описательные) языки программирования

Предназначены для решения задач
искусственного интеллекта, к ним относят
такие языки, которые способны в зависимости
от набора исходных данных модифицировать
алгоритм работы, т.е. «на ходу» менять
программу.

Функциональные языки. В их основе
лежит понятие функции как «черного
ящика», имеющего вектор параметров
(аргументов)на входе и результатr(скаляр) на
выходе:

(7.1)

В функциональных языках программирования
отсутствуют операторы: все действия, в
том числе и управляющие конструкции,
выполняются при помощи вызовов функций.
Поскольку каждая функция возвращает
значение, ее можно подставить в качестве
аргумента другой функции, что позволяет
записывать сложные выражения в
функциональной форме. Одним из первых
функциональных языков стал интерпретируемый
язык LISP(Лисп), созданный в конце
50-х гг.

Логические языки. Логическое
программирование представляет собой
попытку возложить на программиста
только постановку задачи, а поиски путей
ее решения предоставить транслятору.
Язык этой группыProlog(Пролог) был
создан в начале 70-х годов Аланом Колмероэ.
В его основу положена математическая
модель теории исчисления предикатов.
Программа на этом языке строится из
последовательности фактов и правил, а
затем формулируется утверждение, которое
Пролог будет пытаться доказать с помощью
введенных правил. Человек только
описывает структуру задачи, а внутренний
«мотор» Пролога сам ищет решение с
помощью методов поиска и сопоставления.

Объектно-ориентированные языки программирования

Это направление стало разрабатываться
в середине 70-х гг. Керниганом и Риччи.
Представляет собой отображение объектов
реального мира, их свойств (атрибутов)
и связей между ними при помощи специальных
структур данных (классов). Начало
реализации положили ОО-версии языков
Си и Паскаль,.

Object Pascal.
Объектно-ориентированное расширение
языкаPascal.

C++ (Си++).Объектно-ориентированное
расширение языка Си, созданное Бьярном
Страуструпом в 1980 году.

Java (Джава, Ява).
Этот язык был создан компаниейSunв начале 90-х годов на основе Си++. Он
призван упростить разработку приложений
на основе Си++ путем исключения из него
всех низкоуровневых возможностей. Но
главная особенность этого языка –
компиляция не в машинный код, а в
платформно-независимый байт-код (каждая
команда занимает один байт). Этот байт-код
может выполняться с помощью интерпретатора
– виртуальнойJava-MaшиныJVM(JavaVirtualMachine), версии которой
созданы для любых платформ. Благодаря
наличию множестваJava-машин
программы наJavaможно
переносить не только на уровне исходных
текстов, но и на уровне двоичного
байт-кода, поэтому язык Ява стал очень
популярным. Особое внимание в развитии
этого языка уделяется двум направлениям:
поддержке всевозможных мобильных
устройств и микрокомпьютеров, встраиваемых
в бытовую технику (технологияJini)
и созданию платформно-независимых
программных модулей, способных работать
на серверах в глобальных и локальных
сетях с различными операционными
системами (технологияJavaBeans). Пока основной
недостаток этого языка – невысокое
быстродействие, так как язык Ява
интерпретируемый.

Smalltalk(Смолток). Интерпретируемый
язык, созданный в корпорации XEROX в 1980
году. Синтаксис языка очень компактен
и базируется исключительно на понятии
объекта. В этом языке отсутствуют
операторы или данные. Все, что входит в
Смолток, является объектами, а сами
объекты общаются друг с другом
исключительно с помощью сообщений
(например, появление выражения I+1 вызывает
посылку объекту I сообщения «+», то есть
«прибавить», с параметром 1, который
считается не числом-константой, а тоже
объектом). Больше никаких управляющих
структур, за исключением «оператора»
ветвления (на самом деле функции,
принадлежащей стандартному объекту),
в языке нет, хотя их можно очень просто
смоделировать. Сегодня версия VisualAge for
Smalltalk активно развивается компанией
IBM.

Императивная и декларативная парадигмы программирования — Студопедия

Существуют две парадигмы программирования: императивная и декларативная. Основной (традиционной) парадигмой программирования является императивное (процедурное) программирование. В рамках императивной парадигмы рассматривается класс языков программирования, в которых программа явно указывает способ получения результата, не определяя ожидаемых свойств результата. Процедура получения результата имеет вид последовательности операций. Отсюда следуют характерные черты императивной программы:

• указание логики управления в программе;

• определение порядка выполнения операций;

• наличие операторов присваивания, выполняющих разрушающее присваивание.

Императивная парадигма основана на «фон-неймановской» вычислительной модели, основными параметрами которой являются:

• программа состоит из набора команд, которые выполняются последовательно;

• поименованные области памяти (концепция переменных как областей памяти, к которым можно обращаться по имени).

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



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

Императивные языки программирования характеризуются следующими особенностями:

• необходимостью явного управления памятью, в частности описанием переменных;

• малой пригодностью для символьных вычислений;

• отсутствием строгой математической основы;

• высокой эффективностью реализации на традиционных ЭВМ.

Одним из важнейших классификационных признаков процедурного языка является его уровень. Уровень языка программирования определяется семантической (смысловой) емкостью его конструкций и степенью его ориентации на программиста. Язык программирования частично ликвидирует разрыв между методами решения различного рода задач человеком и вычислительной машиной. Чем более язык ориентирован на человека, тем выше его уровень. К императивным языкам программирования относятся ассемблеры и хорошо распространенные языки программирования высокого уровня, например такие, как Фортран, Паскаль, Си.


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

Декларативная парадигма программирования реализуется с помощью одного из двух стилей программирования: функционального или логического программирования.

императивных и декларативных языков запросов: в чем разница?

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

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

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

В этой серии блогов Graph Databases for Beginners я расскажу вам об основах графической технологии, предполагая, что у вас мало (или нет) опыта в этой области. В последние недели мы обсуждали, почему будущее за графической технологией, почему связанные данные имеют значение, основы (и подводные камни) моделирования данных и почему язык запросов к базам данных имеет значение в первую очередь.

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

Языки императивных запросов: определение и пример

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

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

Некоторые хорошо известные языки общего императивного программирования включают Python, C и Java.

В мире технологий графовых баз данных не существует строго императивных языков запросов. Однако и Gremlin, и Java API (для Neo4j) включают обязательные функции. Эти два варианта предоставляют вам более подробную власть над выполнением своей задачи.Если все написано правильно, никаких сюрпризов — вы получите именно то, что хотите.

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

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

Чтобы лучше проиллюстрировать различия, представьте, что у вас двое детей: Изабель и Дункан. Isabel представляет собой императивный язык запросов, а Duncan — декларативный язык запросов.

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

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

Окончательный результат будет очень похож на результат Дункана (или, возможно, точно так же). В конце процесса обоим детям заправляют кровати.

Языки декларативных запросов: определение и примеры

Слишком часто декларативные языки запросов определяются как любой язык запросов к базе данных, который является обязательным , а не .Однако давать такое определение было бы слишком широко.

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

Некоторые хорошо известные общие декларативные языки программирования включают Ruby, R и Haskell.SQL (язык структурированных запросов) — это декларативный язык запросов, который является отраслевым стандартом для реляционных баз данных.

В экосистеме технологии графов декларативными считаются несколько языков запросов: Cypher, SPARQL и Gremlin (который также включает некоторые обязательные функции, как упоминалось выше).

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

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

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

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

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

Заключение

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

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

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

Вы новичок в мире графических технологий?
Нажмите ниже, чтобы получить бесплатную копию книги O’Reilly Graph Databases и узнать, как использовать графические базы данных для вашего приложения или проекта.

Получить книгу

Познакомьтесь с остальной частью серии «Графические базы данных для начинающих»:

Императивные и декларативные языки | theburningmonk.com

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

Определение:

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

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

Как они сравнивают:

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

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

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

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

Декларативное программирование

В информатике декларативное программирование — это парадигма программирования, которая выражает логику вычисления без описания его потока управления. [1] Многие языки, применяющие этот стиль, пытаются минимизировать или устранить побочные эффекты, описывая, что должна выполнять программа, а не , как делать это. [2] Это контрастирует с императивным программированием, которое требует явно заданного алгоритма.

Декларативное программирование часто рассматривает программы как теории формальной логики, а вычисления — как выводы в этом логическом пространстве. Декларативное программирование в последнее время стало особенно интересным, поскольку оно может значительно упростить написание параллельных программ. [3]

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

Определение

Декларативное программирование часто определяется как любой стиль программирования, который не является обязательным.Существует ряд других общих определений, которые пытаются дать этому термину определение, отличное от простого противопоставления его императивному программированию. Например:

Эти определения существенно пересекаются.

Подпарадигмы

Декларативное программирование — это общий термин, который включает ряд наиболее известных парадигм программирования.

Программирование ограничений

Основная статья: программирование в ограничениях

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

Программирование с ограничениями часто используется как дополнение к другим парадигмам: функциональному, логическому или даже императивному программированию.

Доменные языки

Основная статья: предметно-ориентированный язык

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

Многие языки разметки, такие как HTML, MXML, SVG, XAML, XSLT или другие языки разметки пользовательского интерфейса, часто являются декларативными. HTML, например, описывает только то, что должно отображаться на веб-странице, и не указывает возможные взаимодействия с ним.

Некоторые программные системы теперь сочетают традиционные языки разметки пользовательского интерфейса, такие как HTML, с декларативной разметкой, которая определяет, что (но не как) системы внутреннего сервера должны делать для поддержки заявленного интерфейса.Такие системы, обычно использующие доменное пространство имен XML, включают абстракции синтаксиса базы данных SQL или параметризованные вызовы веб-служб с использованием REST и SOAP.

Функциональное программирование

Основная статья: Функциональное программирование

Функциональное программирование и, в частности, чисто функциональное программирование, пытается минимизировать или устранить побочные эффекты, и поэтому считается декларативным. Однако большинство функциональных языков, таких как Scheme, Objective Caml и Unlambda, на практике допускают побочные эффекты.

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

Гибридные языки

Например, файлы Makefile

декларативно определяют зависимости, [5] , но также включают обязательный список действий, которые необходимо предпринять.Точно так же yacc декларативно определяет контекстно-свободную грамматику, но включает фрагменты кода с основного языка, что обычно является обязательным (например, C).

Логическое программирование

Основная статья: Логическое программирование

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

См. Также

Список литературы

Внешние ссылки

декларативный язык — это … Что такое декларативный язык?

  • декларативный язык — deklaratyvioji kalba statusas T sritis informatika apibrėžtis ↑ Programavimo kalba, kai programos kuriamos nusakant kurios nors apibrėžtos srities faktus ir ryšja irzvaduso išvaduso is. Deklaratyviosiomis…… Enciklopedinis kompiuterijos žodynas

  • декларативный язык — язык программирования, предназначенный для декларативных операторов (операторов, которые предназначены для компилятора, а НЕ являются частью реальной программы, такой как DDL)… Современный английский словарь

  • Простой декларативный язык — Простой декларативный язык — это кроссплатформенный декларативный компьютерный язык, используемый для определения базовых структур данных, таких как списки, карты и деревья типизированных данных в компактном, удобном для чтения представлении.Простой API позволяет читать,…… Wikipedia

  • Декларативное программирование — Парадигмы программирования Агентно-ориентированные на основе автоматов На основе компонентов На основе потоков Конвейерные конкатенативные параллельные вычисления… Википедия

  • Декларативная память — (иногда называемая явной памятью) является одним из двух типов долговременной памяти человека. Это относится к воспоминаниям, которые можно вспомнить сознательно, например к фактам и знаниям. [1] Его аналог известен как недекларативная или процедурная память,…… Wikipedia

  • Декларативная ссылочная целостность — (DRI) — это один из методов в языке программирования баз данных SQL для обеспечения целостности данных.Содержание 1 Значение в SQL 2 Значение продукта 3 Ссылки 4… Wikipedia

  • язык — / lang gwij /, n. 1. совокупность слов и системы их использования, общие для людей, которые принадлежат к одному сообществу или нации, одному географическому региону или одной и той же культурной традиции: два языка Бельгии; язык банту; французы…… Универсал

  • Языковые поэты — Языковые поэты (или поэты L = A = N = G = U = A = G = E, в честь журнала, носящего это название) являются авангардной группой или тенденцией в поэзии Соединенных Штатов, которая возникла в конце 1960-х — начале 1970-х гг.Развивая свою поэтику, члены…… Wikipedia

  • Язык программирования, ориентированный на данные — определяет категорию языков программирования, где основной функцией является управление данными и манипулирование ими. Язык программирования, ориентированный на данные, включает встроенные примитивы обработки для доступа к данным, хранящимся в наборах, таблицах, списках и…… Wikipedia

  • Mercury (язык программирования) — Автокод Меркурия см. В разделе Автокод.Парадигма (и) Меркурия Логика, функционал Появился в 1995 г. Разработан Zoltán Somogyi… Wikipedia

  • Глоссарий терминов унифицированного языка моделирования — Этот глоссарий терминов унифицированного языка моделирования охватывает все версии UML. Отдельные записи будут указывать на любые различия, существующие между версиями. A * Аннотация Индикатор, применяемый к классификатору (например, субъекту, классу, варианту использования) или к некоторым… Wikipedia

  • императивных и декларативных языков запросов: в чем разница?

    История языков программирования восходит к истокам вычислений, когда новые языки создаются для каждой вариации и парадигмы.Когда дело доходит до баз данных, две хорошо известные парадигмы включают императивный и декларативный языки запросов.

    Слишком часто последний в широком смысле определяется как любой язык запросов к базе данных, который является обязательным , а не . Однако давать такое определение было бы слишком широко.

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

    Императивные языки запросов

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

    Некоторые хорошо известные языки общего императивного программирования включают Python, C и Java.В мире графовых баз данных нет чисто императивных языков запросов. Однако и Gremlin, и Java API (для Neo4j) включают обязательные функции. Эти два варианта предоставляют вам более подробную власть над выполнением своей задачи. Если все написано правильно, никаких сюрпризов — вы получите именно то, что хотите.

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

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

    Чтобы лучше проиллюстрировать различия, представьте, что у вас двое детей: Иззи и Дункан. Иззи представляет императивный язык запросов, а Дункан — декларативный язык запросов.

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

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

    Окончательный результат будет почти таким же, как у Дункана (или, возможно, точно таким же). В конце процесса обоим детям заправляют кровати.

    Языки декларативных запросов

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

    Некоторые хорошо известные общие декларативные языки программирования включают Ruby, R и Haskell. SQL (язык структурированных запросов) — это декларативный язык запросов, который является отраслевым стандартом для реляционных баз данных. В экосистеме графовой базы данных декларативными считаются несколько языков запросов: Cypher, SPARQL и Gremlin (который также включает некоторые обязательные функции).

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

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

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

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

    Заключение

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

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

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

    Очаровательный Python: создание декларативных мини-языков

    Очаровательный питон

    Программирование как утверждение, а не инструкция

    Дэвид Мертц
    Опубликовано 27 февраля 2003 г.

    Контент серии:

    Этот контент является частью # из серии: Charming Python

    https: // www.ibm.com/developerworks/library/?series_title_by=**auto**

    Следите за дополнительными материалами этой серии.

    Этот контент является частью серии: Charming Python

    Следите за дополнительными материалами из этой серии.

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

    Позвольте мне перечислить несколько языков, которые попадают в различные категории.Многие читатели использовали
    многие из этих инструментов, не обязательно задумываясь о категориальных различиях
    среди них. Python, C, C ++, Java, Perl, Ruby, Smalltalk, Fortran, Basic, xBase — это
    все явно императивные языки программирования. Некоторые из них являются объектом
    ориентированы, но это просто вопрос организации кода и данных, а не
    фундаментальный стиль программирования. На этих языках вы управляете
    программа для выполнения последовательности инструкций: поместите некоторые данные в
    переменная; извлечь данных обратно из переменной; петля через
    блок инструкций с по удовлетворяет какое-то условие; сделай что-нибудь
    , если верно.Что хорошо во всех этих языках:
    что о них легко думать в рамках знакомых временных метафор. Обыкновенный
    жизнь состоит в том, чтобы делать одно дело, делать выбор, а затем делать другое, может быть
    используя некоторые инструменты по ходу дела. Легко представить себе компьютер, на котором
    программа как повар, или каменщик, или водитель автомобиля.

    Языки, такие как Prolog, Mercury, SQL, XSLT, грамматики EBNF и даже конфигурация
    файлы различных форматов, все декларируют , что что-то не так, или что
    применяются определенные ограничения.Функциональные языки (такие как Haskell, ML, Dylan,
    Ocaml, Scheme) похожи, но с большим упором на определение внутренних
    (функциональные) отношения между объектами программирования (рекурсия, списки и т. д.). Наши
    обычная жизнь, по крайней мере в ее повествовательном качестве, не дает прямого аналога
    программные конструкции этих языков. Для решения этих проблем вы, естественно, можете
    описать на этих языках, однако декларативные описания гораздо более краткие,
    и намного менее подвержены ошибкам , чем обязательные решения.Например,
    рассмотрим систему линейных уравнений:

     10x + 5y - 7z + 1 = 0
    17x + 5y - 10z + 3 = 0
    5x - 4y + 3z - 6 = 0 

    Это довольно элегантное сокращение, обозначающее несколько отношений между объектами.
    (x, y и z). В реальной жизни вы можете встретить эти факты по-разному, но
    на самом деле «решение для x» карандашом и бумагой — это вопрос беспорядочных деталей, склонных
    к ошибке. Написание шагов на Python, вероятно, даже хуже от отладки
    перспектива.

    Пролог — это язык, который приближается к логике или математике. В нем вы просто
    напишите утверждения, которые, как вы знаете, являются правдой, затем попросите приложение вывести
    последствия для вас. Заявления составляются без определенного порядка (как линейные
    уравнения не имеют порядка), и вы, программист / пользователь, понятия не имеете, какие шаги
    принимаются для получения результатов. Например:

     / * Взято из образца по адресу:
    
    Это приложение может ответить на вопросы о сестринстве и любви, например:
    # Алиса - сестра Гарри?
    ? -сестра (Алиса, Гарри)
    # Кто из сестер Алисы любит вино?
    ? -сестра (X, Алиса), любовь (X, вино)
    * /
    isterof (X, Y): - родители (X, M, F),
                        женский (X),
                        родители (Y, M, F).
    родители (Эдвард, Виктория, Альберт).
    родители (Гарри, Виктория, Альберт).
    родители (алиса, виктория, альберт).
    женщина (алиса).
    любит (гарри, вино).любит (Алиса, вино). 

    Не совсем идентична, но похожа по духу EBNF (Расширенная форма Бэкуса-Наура)
    декларация грамматики. Вы можете написать несколько объявлений, например:

     word: = alphanums, (wordpunct, alphanums) *, сокращение?
    буквенные обозначения: = [a-zA-Z0-9] +
    wordpunct: = [-_]
    сокращение: = "'", ("clock" / "d" / "ll" / "m" / "re" / "s" / "t" / "ve") 

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

    В качестве еще одного декларативного примера рассмотрим объявление типа документа,
    описывает диалект допустимых XML-документов:

     
    
    
    
     

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

    Python как интерпретатор против Python
    в качестве среды

    Библиотеки Python могут использовать декларативные языки на одном из двух довольно разных
    способами. Возможно, более распространенным методом является анализ и обработка не-Python
    декларативные языки как данные. Приложение или библиотека могут читать во внешнем
    источник (или строка, определенная внутри, но просто как «капля»), а затем определить набор
    императивных шагов для выполнения, которые в некотором роде соответствуют этим внешним
    декларации.По сути, эти типы библиотек представляют собой системы, управляемые данными; там
    концептуальный и категориальный разрыв между декларативным языком и тем, что Python
    приложение делает для выполнения или использования своих деклараций. На самом деле довольно часто
    библиотеки для обработки этих идентичных объявлений также реализованы для других
    языки программирования.

    Все приведенные выше примеры относятся к этой первой технике. Библиотека
    PyLog — это реализация системы Prolog на языке Python.Читается
    Файл данных Prolog, как в примере, затем создает объекты Python для модели
    Объявления пролога. В примере EBNF используется конкретный вариант
    SimpleParse — библиотека Python, преобразующая эти
    объявления в таблицы состояний, которые может использовать mx.TextTools .
    mx.TextTools сама по себе является библиотекой расширений для Python, которая использует
    базовый движок C для запуска кода, хранящегося в структурах данных Python, но имеющего мало
    делать с Python как таковой .Python — отличный клей для этих задач,
    но склеенные вместе языки сильно отличаются от Python. Самый Пролог
    реализации, кроме того, написаны на языках, отличных от Python, как и
    большинство парсеров EBNF.

    DTD аналогичен другим примерам. Если вы используете проверяющий парсер, например
    xmlproc , вы можете использовать DTD для проверки диалекта XML
    документ. Но язык DTD не является Pythonic, и xmlproc просто
    использует его как данные, которые необходимо проанализировать.Более того, проверяющие парсеры XML были
    написано на многих языках программирования. Преобразование XSLT снова похоже, оно
    не зависит от Python, и такой модуль, как ft. 4xslt , просто использует Python как
    клей.

    Пока нет ничего неправильного с вышеуказанными подходами и инструментами
    упомянутого выше (я использую их все время), он мог бы быть более элегантным, а в некоторых
    способов более выразительно — если бы сам Python мог быть декларативным языком.Если
    ничего больше, библиотеки, которые способствовали этому, не заставили бы программистов думать
    о двух (и более) языках при написании одного приложения. Иногда это естественно
    и мощный, чтобы опираться на интроспективные возможности Python для реализации «родных»
    декларации.

    Магия самоанализа

    Анализаторы Spark и PLY позволяют пользователям объявлять значения Python
    в Python , затем используйте магию, чтобы позволить среде выполнения Python
    действовать как конфигурация синтаксического анализа.Например, давайте посмотрим на PLY
    эквивалент предыдущей грамматики SimpleParse . Spark есть
    аналогично примеру:

     токенов = ('ALPHANUMS', 'WORDPUNCT', 'CONTRACTION', 'WHITSPACE')
    t_ALPHANUMS = r "[a-zA-Z0-0] +"
    t_WORDPUNCT = г "[-_]"
    t_CONTRACTION = r "'(часы | d | ll | m | re | s | t | ve)"
    def t_WHITESPACE (t):
        r "\ s +"
        t.value = ""
        вернуть т
    импортный лекс
    lex.lex ()
    lex.input (некоторый текст)
    а 1:
        t = lex.token ()
        если не t: break 

    Я написал о PLY в моей будущей книге Обработка текста в
    Python
    , и в этом столбце написано о Spark (ссылки см. В разделе Ресурсы).Не вдаваясь в
    подробности библиотек, вы должны заметить, что это Python
    сами привязки, которые настраивают синтаксический анализ (фактически лексирование / токенирование в этом
    пример). Модуль PLY просто знает достаточно о Python.
    среда, в которой он работает, чтобы действовать в соответствии с этими объявлениями шаблонов.

    Просто , как PLY знает, что делает, включает в себя довольно причудливые
    Программирование на Python.На первом уровне программист среднего уровня поймет, что
    можно исследовать содержимое глобальных переменных () и locals ()
    словари. Было бы хорошо, если бы стиль объявления был немного другим.
    Например, представьте, что код больше похож на:

     import basic_lex as _
    _.tokens = ('АЛФАНУМЫ', 'РАБОТА', 'КОНТРАКЦИЯ')
    _.ALPHANUMS = r "[a-zA-Z0-0] +"
    _.WORDPUNCT = r "[-_]"
    _.CONTRACTION = r "'(часы | d | ll | m | re | s | t | ve)"
    _.lex () 

    Этот стиль не был бы менее декларативным, и модуль basic_lex
    гипотетически может содержать что-то простое, например:

     def lex ():
        для t в токенах:
            print t, '=', globals () [t] 

    Это даст:

    % python basic_app.py
    АЛФАНУМЫ = [a-zA-Z0-0] +
    WORDPUNCT = [-_]
    CONTRACTION = '(clock | d | ll | m | re | s | t | ve) 

    PLY удается проникнуть в пространство имен импортирующего модуля, используя
    информация о кадре стека.Например:

     import sys
    попробуйте: поднять RuntimeError
    кроме RuntimeError:
        e, b, t = sys.exc_info ()
        caller_dict = t.tb_frame.f_back.f_globals
    def lex ():
        для t в caller_dict ['токены']:
            print t, '=', caller_dict ['t _' + t] 

    Это дает тот же результат, что и в примере basic_app.py , но
    с объявлениями, использующими предыдущий стиль t_TOKEN .

    В самом модуле PLY больше волшебства.Мы видели, что
    токены, названные шаблоном t_TOKEN , на самом деле могут быть либо строками
    содержащие регулярные выражения или функции, содержащие как регулярные выражения
    docstrings вместе с кодом действия. Некоторая проверка типов допускает полиморфное поведение:

     # ... определить caller_dict с помощью RuntimeError ...
    из импорта типов *
    def lex ():
        для t в caller_dict ['токены']:
            t_obj = caller_dict ['т _' + т]
            если тип (t_obj) равен FunctionType:
                напечатайте t, '=', t_obj.__doc__
            еще:
                print t, '=', t_obj 

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

    Магия наследования

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

    Модуль gnosis.xml.validity представляет собой основу для создания классов, которые
    сопоставление непосредственно с продукцией DTD. Любой класс gnosis.xml.validity может
    только можно создать с аргументами, подчиняющимися допустимости диалекта XML
    ограничения. На самом деле это не совсем так; модуль также сделает вывод о правильном
    типы из более простых аргументов, когда есть только один однозначный способ «поднять»
    аргументы правильных типов.

    Поскольку я написал модуль gnosis.xml.validity , я склоняюсь к
    думать, что его цель сама по себе интересна. Но в этой статье я просто хочу
    посмотрите на декларативный стиль, в котором создаются классы достоверности. Набор
    правила / классы, соответствующие предыдущему образцу DTD, состоят из:

     из gnosis.xml.validity import *
    фигура класса (ПУСТО): пройти
    class _mixedpara (Или): _disjoins = (PCDATA, рисунок)
    абзац класса (Некоторые): _type = _mixedpara
    название класса (PCDATA): пройти
    class _paras (Некоторые): _type = paragraph
    глава класса (Seq): _order = (title, _paras)
    класс диссертация (Некоторые): _type = chapter 

    Вы можете создать экземпляры из этих объявлений, используя:

     ch2 = LiftSeq (chapter, («1st Title», «Validity is important»))
    ch3 = LiftSeq (chapter, («2-й заголовок», «Декларация - это весело»))
    дисс = диссертация ([ch2, ch3])
    print dis 

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

    Обратите внимание, что эти классы, хотя и созданы с использованием стандартного синтаксиса Python, являются
    необычный (и более краткий) отсутствие методов или данных экземпляра. Классы
    определяется исключительно для наследования от некоторой структуры, где эта структура сужается
    атрибут единого класса.Например, — это последовательность
    другие теги, а именно </code>, за которым следует один или несколько<br /> <code> <параграф> </code> тегов. Но все, что нам нужно сделать, чтобы гарантировать<br /> ограничение соблюдается в случаях <em> объявить </em> главой <code> </code><br /> класс в такой простой манере.</p><p> Основная «уловка», связанная с программированием родительских классов, таких как<br /> <code> гнозис.xml.validity.Seq </code> — посмотреть на <code> .__ class__ </code><br /> атрибут экземпляра <em> </em> во время инициализации. Класс<br /> Глава <code> </code> не имеет собственной инициализации, поэтому ее родительский<br /> <code> __init __ () вызывается метод </code>. Но <code> сам </code> перешел на<br /> родительский элемент <code> __init __ () </code> является экземпляром <code> главы </code>, и он<br /> знает это. Чтобы проиллюстрировать, это часть реализации<br /> <code> гнозис.xml.validity.Seq </code>:</p><pre data-widget="syntaxhighlighter"> класс Seq (кортеж): def __init __ (self, inittup): если не hasattr (self .__ class__, '_order'): поднять NotImplementedError, \ «Дочерний элемент абстрактного класса Seq должен указывать порядок» если не isinstance (self._order, tuple): поднять ValidityError, "Seq должен иметь кортеж в порядке" self.validate () self._tag = self .__ class __.__ name__ </pre><p> Как только программист приложения пытается создать экземпляр <code> chapter </code>,<br /> код создания экземпляра проверяет, что глава <code> </code> была объявлена ​​с требуемым<br /> <code>._order </code> атрибут класса, и что этот атрибут является необходимым<br /> объект кортежа. Метод <code> .validate () </code> выполняет некоторые дополнительные проверки, чтобы<br /> убедитесь, что объекты, которыми был инициализирован экземпляр, принадлежат<br /> соответствующие классы, указанные в <code> ._order </code>.</p><h3><span class="ez-toc-section" id="i-46"> Когда объявлять </span></h3><p> Декларативный стиль программирования <em> почти всегда </em> более прямой способ<br /> установление ограничений, чем является императивным или процедурным.Конечно не все<br /> проблемы программирования связаны с ограничениями — или, по крайней мере, это не всегда<br /> натуральный состав. Но проблемы систем, основанных на правилах, таких как грамматика и<br /> Системами логического вывода гораздо легче управлять, если их можно описать декларативно.<br /> Императивная проверка грамматики быстро превращается в спагетти-код и требует<br /> сложно отлаживать. Формулировки шаблонов и правил могут оставаться намного проще.</p><p> Конечно, по крайней мере в Python, проверка или соблюдение заявленных правил<br /> всегда будет сводиться к процедурным проверкам. Но подходящее место для такой процедурной<br /> check — это хорошо проверенный библиотечный код. Отдельные приложения должны полагаться на<br /> более простые декларативные интерфейсы, предоставляемые такими библиотеками, как <code> Spark </code> или<br /> <code> PLY </code> или <code> gnosis.xml.validity </code>. Другие библиотеки, например<br /> <code> xmlproc </code>, <code> SimpleParse </code> или <code> фут.4xslt </code> также<br /> включить декларативные стили, но не объявления <em> в Python </em> (который<br /> подходит для их доменов, конечно).</p><h5><span class="ez-toc-section" id="i-47"> Ресурсы для загрузки </span></h5><h5><span class="ez-toc-section" id="i-48"> Связанные темы </span></h5><p>.</p><div class='yarpp-related yarpp-related-none'><p>No related posts.</p></div></div><div class="entry-footer is-start"> <b>Share :</b><ul class="post-share"><li><a target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=https://wwwoldi.ru/raznoe/deklarativnye-yazyki-deklarativnyj-yazyk-eto-chto-takoe-deklarativnyj-yazyk.html"><i class="fab fa-facebook-f"></i></a></li><li><a target="_blank" href="http://twitter.com/share?text=Декларативные%20языки:%20Декларативный%20язык%20—%20это…%20Что%20такое%20Декларативный%20язык?&url=https://wwwoldi.ru/raznoe/deklarativnye-yazyki-deklarativnyj-yazyk-eto-chto-takoe-deklarativnyj-yazyk.html"><i class="fab fa-twitter"></i></a></li><li><a target="_blank" href="http://pinterest.com/pin/create/button/?url=https://wwwoldi.ru/raznoe/deklarativnye-yazyki-deklarativnyj-yazyk-eto-chto-takoe-deklarativnyj-yazyk.html&media=&description=Декларативные%20языки:%20Декларативный%20язык%20—%20это…%20Что%20такое%20Декларативный%20язык?"><i class="fab fa-pinterest"></i></a></li><li> <a target="_blank" href="http://www.linkedin.com/shareArticle?mini=true&title=Декларативные%20языки:%20Декларативный%20язык%20—%20это…%20Что%20такое%20Декларативный%20язык?&url=https://wwwoldi.ru/raznoe/deklarativnye-yazyki-deklarativnyj-yazyk-eto-chto-takoe-deklarativnyj-yazyk.html"><i class="fab fa-linkedin"></i></a></li></ul></div></div></article></div><nav class="navigation post-navigation" aria-label="Записи"><h2 class="screen-reader-text">Навигация по записям</h2><div class="nav-links"><div class="nav-previous"><a href="https://wwwoldi.ru/php/php-goto-goto-rukovodstvo-po-php.html" rel="prev"><span class="nav-subtitle">Previous:</span> <span class="nav-title">Php goto: goto | Руководство по PHP</span></a></div><div class="nav-next"><a href="https://wwwoldi.ru/server/luchshie-mediaservery-7-luchshih-prilozhenij-dlya-mediaservera.html" rel="next"><span class="nav-subtitle">Next:</span> <span class="nav-title">Лучшие медиасерверы: 7 лучших приложений для медиасервера</span></a></div></div></nav><aside class="related-posts"><h2 class="section-heading">Related Post</h2><div class="row"><div class="rpl-xl-4 rpl lg-6"><article class="related-post hentry post"><div class="post-wrapper"><div class="main-entry-content"><header class="entry-header"><h4><a href="https://wwwoldi.ru/raznoe/kak-ochen-bystro-pisat-ruchkoj-kak-bystro-nauchitsya-pisat.html">Как очень быстро писать ручкой: Как быстро научиться писать?</a></h4></header></div></div></article></div><div class="rpl-xl-4 rpl lg-6"><article class="related-post hentry post"><div class="post-wrapper"><div class="main-entry-content"><header class="entry-header"><h4><a href="https://wwwoldi.ru/raznoe/chto-v-videokarte-glavnoe-dlya-igr-videokarta-dlya-igr-pomoshh-v-vybore.html">Что в видеокарте главное для игр: Видеокарта для игр: помощь в выборе</a></h4></header></div></div></article></div><div class="rpl-xl-4 rpl lg-6"><article class="related-post hentry post"><div class="post-wrapper"><div class="main-entry-content"><header class="entry-header"><h4><a href="https://wwwoldi.ru/raznoe/funkcziya-v-int-python-funkczii-int-python.html">Функция в int python: Функции int() | Python</a></h4></header></div></div></article></div></div></aside></main><div id="comments" class="comments-area"><div id="respond" class="comment-respond"><h3 id="reply-title" class="comment-reply-title">Добавить комментарий <small><a rel="nofollow" id="cancel-comment-reply-link" href="/raznoe/deklarativnye-yazyki-deklarativnyj-yazyk-eto-chto-takoe-deklarativnyj-yazyk.html#respond" style="display:none;">Отменить ответ</a></small></h3><form action="https://wwwoldi.ru/wp-comments-post.php" method="post" id="commentform" class="comment-form" novalidate><p class="comment-notes"><span id="email-notes">Ваш адрес email не будет опубликован.</span> <span class="required-field-message">Обязательные поля помечены <span class="required">*</span></span></p><p class="comment-form-comment"><label for="comment">Комментарий <span class="required">*</span></label><textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" required></textarea></p><p class="comment-form-author"><label for="author">Имя <span class="required">*</span></label> <input id="author" name="author" type="text" value="" size="30" maxlength="245" autocomplete="name" required /></p><p class="comment-form-email"><label for="email">Email <span class="required">*</span></label> <input id="email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-notes" autocomplete="email" required /></p><p class="comment-form-url"><label for="url">Сайт</label> <input id="url" name="url" type="url" value="" size="30" maxlength="200" autocomplete="url" /></p><p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="Отправить комментарий" /> <input type='hidden' name='comment_post_ID' value='13333' id='comment_post_ID' /> <input type='hidden' name='comment_parent' id='comment_parent' value='0' /></p></form></div></div></div><div class="rpl-lg-4 secondary" id="sidebar-secondary"><aside id="secondary" class="sidebar"><section id="categories-3" class="widget sidebar-widget widget_categories"><div class="sidebar-title"><h3 class="widget-title">Рубрики</h3></div><ul><li class="cat-item cat-item-8"><a href="https://wwwoldi.ru/category/jquery">Jquery</a></li><li class="cat-item cat-item-5"><a href="https://wwwoldi.ru/category/mysql">Mysql</a></li><li class="cat-item cat-item-4"><a href="https://wwwoldi.ru/category/php">Php</a></li><li class="cat-item cat-item-9"><a href="https://wwwoldi.ru/category/dlya-chajnikov">Для чайников</a></li><li class="cat-item cat-item-3"><a href="https://wwwoldi.ru/category/raznoe">Разное</a></li><li class="cat-item cat-item-7"><a href="https://wwwoldi.ru/category/server">Сервер</a></li><li class="cat-item cat-item-1"><a href="https://wwwoldi.ru/category/sovety">Советы</a></li><li class="cat-item cat-item-6"><a href="https://wwwoldi.ru/category/ustanovka">Установка</a></li></ul></section><section id="calendar-5" class="widget sidebar-widget widget_calendar"><div id="calendar_wrap" class="calendar_wrap"><table id="wp-calendar" class="wp-calendar-table"><caption>Март 2024</caption><thead><tr><th scope="col" title="Понедельник">Пн</th><th scope="col" title="Вторник">Вт</th><th scope="col" title="Среда">Ср</th><th scope="col" title="Четверг">Чт</th><th scope="col" title="Пятница">Пт</th><th scope="col" title="Суббота">Сб</th><th scope="col" title="Воскресенье">Вс</th></tr></thead><tbody><tr><td colspan="4" class="pad"> </td><td>1</td><td>2</td><td>3</td></tr><tr><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td></tr><tr><td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td></tr><tr><td>18</td><td>19</td><td>20</td><td>21</td><td>22</td><td>23</td><td>24</td></tr><tr><td>25</td><td>26</td><td>27</td><td>28</td><td id="today">29</td><td>30</td><td>31</td></tr></tbody></table><nav aria-label="Предыдущий и следующий месяцы" class="wp-calendar-nav"> <span class="wp-calendar-nav-prev"><a href="https://wwwoldi.ru/2021/11">« Ноя</a></span> <span class="pad"> </span> <span class="wp-calendar-nav-next"> </span></nav></div></section><section id="archives-11" class="widget sidebar-widget widget_archive"><div class="sidebar-title"><h3 class="widget-title">Архивы</h3></div><ul><li><a href='https://wwwoldi.ru/2021/11'>Ноябрь 2021</a></li><li><a href='https://wwwoldi.ru/2021/10'>Октябрь 2021</a></li><li><a href='https://wwwoldi.ru/2021/09'>Сентябрь 2021</a></li><li><a href='https://wwwoldi.ru/2021/08'>Август 2021</a></li><li><a href='https://wwwoldi.ru/2021/07'>Июль 2021</a></li><li><a href='https://wwwoldi.ru/2021/06'>Июнь 2021</a></li><li><a href='https://wwwoldi.ru/2021/05'>Май 2021</a></li><li><a href='https://wwwoldi.ru/2021/04'>Апрель 2021</a></li><li><a href='https://wwwoldi.ru/2021/03'>Март 2021</a></li><li><a href='https://wwwoldi.ru/2021/02'>Февраль 2021</a></li><li><a href='https://wwwoldi.ru/2021/01'>Январь 2021</a></li><li><a href='https://wwwoldi.ru/2020/12'>Декабрь 2020</a></li><li><a href='https://wwwoldi.ru/2020/11'>Ноябрь 2020</a></li><li><a href='https://wwwoldi.ru/2020/10'>Октябрь 2020</a></li><li><a href='https://wwwoldi.ru/2020/09'>Сентябрь 2020</a></li><li><a href='https://wwwoldi.ru/2020/08'>Август 2020</a></li><li><a href='https://wwwoldi.ru/2020/07'>Июль 2020</a></li><li><a href='https://wwwoldi.ru/2020/06'>Июнь 2020</a></li><li><a href='https://wwwoldi.ru/2020/05'>Май 2020</a></li><li><a href='https://wwwoldi.ru/2020/04'>Апрель 2020</a></li><li><a href='https://wwwoldi.ru/2020/03'>Март 2020</a></li><li><a href='https://wwwoldi.ru/2020/02'>Февраль 2020</a></li><li><a href='https://wwwoldi.ru/2020/01'>Январь 2020</a></li><li><a href='https://wwwoldi.ru/2019/12'>Декабрь 2019</a></li><li><a href='https://wwwoldi.ru/2019/11'>Ноябрь 2019</a></li><li><a href='https://wwwoldi.ru/2019/10'>Октябрь 2019</a></li><li><a href='https://wwwoldi.ru/2019/09'>Сентябрь 2019</a></li><li><a href='https://wwwoldi.ru/2019/08'>Август 2019</a></li><li><a href='https://wwwoldi.ru/2019/07'>Июль 2019</a></li><li><a href='https://wwwoldi.ru/2019/06'>Июнь 2019</a></li><li><a href='https://wwwoldi.ru/2019/05'>Май 2019</a></li><li><a href='https://wwwoldi.ru/2019/04'>Апрель 2019</a></li><li><a href='https://wwwoldi.ru/2019/03'>Март 2019</a></li><li><a href='https://wwwoldi.ru/2019/02'>Февраль 2019</a></li><li><a href='https://wwwoldi.ru/2019/01'>Январь 2019</a></li><li><a href='https://wwwoldi.ru/2018/12'>Декабрь 2018</a></li><li><a href='https://wwwoldi.ru/2018/11'>Ноябрь 2018</a></li><li><a href='https://wwwoldi.ru/2018/10'>Октябрь 2018</a></li><li><a href='https://wwwoldi.ru/2018/09'>Сентябрь 2018</a></li><li><a href='https://wwwoldi.ru/2018/08'>Август 2018</a></li><li><a href='https://wwwoldi.ru/2018/07'>Июль 2018</a></li><li><a href='https://wwwoldi.ru/2018/06'>Июнь 2018</a></li><li><a href='https://wwwoldi.ru/2018/05'>Май 2018</a></li><li><a href='https://wwwoldi.ru/2018/04'>Апрель 2018</a></li><li><a href='https://wwwoldi.ru/2018/03'>Март 2018</a></li><li><a href='https://wwwoldi.ru/2018/02'>Февраль 2018</a></li><li><a href='https://wwwoldi.ru/2018/01'>Январь 2018</a></li><li><a href='https://wwwoldi.ru/1970/02'>Февраль 1970</a></li><li><a href='https://wwwoldi.ru/1970/01'>Январь 1970</a></li></ul></section></aside></div></div></div></div><footer class="site-footer is-bg"><div class="footer-in"><div class="container"><div class='row'><div class="rpl-xl-12 rpl-md-6 rpl-sm-12 footer-widget-item"></div></div></div></div><div class="site-info"><div class="container"><div class="siteinfo-text"> 2024 © Все права защищены. Карта сайта</div></div></div></footer> <noscript><style>.lazyload{display:none}</style></noscript><script data-noptimize="1">window.lazySizesConfig=window.lazySizesConfig||{};window.lazySizesConfig.loadMode=1;</script><script async data-noptimize="1" src='https://wwwoldi.ru/wp-content/plugins/autoptimize/classes/external/js/lazysizes.min.js'></script> </div> <script defer src="https://wwwoldi.ru/wp-content/cache/autoptimize/js/autoptimize_b6fa92f1bccfa39b7cc8912552ddbb27.js"></script></body></html><script src="/cdn-cgi/scripts/7d0fa10a/cloudflare-static/rocket-loader.min.js" data-cf-settings="8e2ea031f566f32ec41a0d58-|49" defer></script>