Учебник. Часть 1




НазваниеУчебник. Часть 1
страница1/28
ТипУчебник
rykovodstvo.ru > Руководство эксплуатация > Учебник
  1   2   3   4   5   6   7   8   9   ...   28


http://Common-Lisp.net

Practical Common Lisp

Учебник. Часть 1.




Peter Seibel

[Выберите дату]




[Введите аннотацию документа. Аннотация обычно представляет собой краткий обзор содержимого документа. Введите аннотацию документа. Аннотация обычно представляет собой краткий обзор содержимого документа.]


Оглавление


1.Введение 3

2.Знакомство с реализацией Лиспа 16

3.Практикум: Простая база данных 35

4.Синтаксис и семантика 74

5.Функции 100

6. Переменные 125



  1. Введение


Сначала я писал на Perl, изучив его достаточно, чтобы создать форум для сайта журнала Mother Jones, после этого я работал над большими (по тем временам) сайтами, такими, как, например, сайт компании Nike, запущенный к олимпийским играм 1996 года. После этого я перешёл на Java, будучи одним из первых разработчиков в WebLogic (теперь эта компания — часть BEA). После WebLogic я участвовал в другом стартапе, где был ведущим программистом по построению транзакционной системы обмена сообщениями на Java. Со временем мои основные интересы в программировании позволили мне использовать как популярные языки, такие, как C, C++ и Python, так и менее известные, такие, как Smalltalk, Eiffel и Beta.

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

Например, в одном из отпусков, имея около недели на опыты с Lisp, я решил попробовать написать версию программы, написанной мною на Java в начале программистской карьеры. Эта программа применяла генетические алгоритмы для игры в Го. Даже с моими зачаточными знаниями Common Lisp написание всего-лишь основных функций было намного продуктивнее, чем если бы я решил переписать всё на Java заново. Для написания программы на Java потребовалось несколько лет работы с этим языком.

Похожий эксперимент привёл к созданию библиотеки, о которой я расскажу в главе 24. В начале моей карьеры в WebLogic я написал библиотеку наJava для разбора java-классов (файлов *.class). Она работала, но код был запутан, и его трудно было изменить или добавить новую функциональность. В течение нескольких лет я пытался переписать библиотеку, думая, что смогу использовать мои новые знания в Java и не увязнуть в куче дублирующегося кода, но так и не смог. Когда же я попробовал написать её на Common Lisp, это заняло всего 2 дня, и я получил не просто библиотеку для разбора java-классов, но библиотеку для разбора любых двоичных файлов. Вы увидите, как она работает, в главе24, и воспользуетесь ею в главе 25 для разбора тэгов ID3 в MP3-файлах.

Сложно объяснить на нескольких страницах введения, почему пользователи языка любят какой-то конкретный язык, ещё сложнее объяснить, почему вы должны тратить своё время на его изучение. Личный пример не слишком убеждает. Может быть, я люблю Lisp, потому что какая-то цепь в моём мозгу замкнулась. Это может быть даже генетическим отклонением,так как мой отец похоже тоже имел его. Так что прежде, чем вы погрузитесь в изучение языка Lisp, вполне естественным покажется желание узнать, что это вам даст, какую выгоду принесёт.

Для некоторых языков выгода очевидна. Например, если вы хотите писать низкоуровневые программы для Unix, то должны выучить C. Или если вы хотите писать кросс-платформенные приложения, то должны использовать Java. И большое число компаний до сих пор использует C++, так что если вы хотите получить работу в одной из них, то должны знать C++.

Тем не менее, для большинства языков выгоду не так просто выделить. Мы имеем дело с субъективными оценками того, насколько язык удобно использовать. Защитники Perl любят говорить, что он "делает простые вещи простыми, а сложные - возможными" и радуются факту, озвученному в девизе Perl - "Есть более чем один способ сделать это".1) С другой стороны, фанаты языка Python думают, что Python –прозрачный и простой язык, и код на Python проще понять, потому что, как гласит их лозунг, "Есть лишь один способ сделать это".

Так почему же Common Lisp? Здесь нет такой очевидной выгоды, как для C, Java или C++ (конечно, если вы не являетесь счастливым обладателем Lisp-машины). Выгоды от использования Lisp заключены в переживаниях и впечатлениях от его использования. В остальной части книги я буду показывать отличительные черты языка, так что вы сможете по себе оценить, на что эти впечатления похожи. Сейчас я попытаюсь показать смысл философии Lisp.

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

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

Common Lisp — это также прекрасный язык для исследовательского программирования (прототипирования?), когда вам неизвестно достоверно,как ваша программа должна работать. Common Lisp предоставляет некоторые возможности, помогающие вам вести инкрементальную интерактивную разработку.

Интерактивный цикл read-eval-print, о котором я расскажу в следующей главе, позволяет вам непрерывно взаимодействовать с вашей программой во время её разработки. Пишете новую функцию. Тестируете её. Меняете её. Пробуете другие подходы к реализации. Вам не приходится останавливаться для длительной компиляции3).

Другими особенностями, которые поддерживают непрерывный, интерактивный стиль программирования, являются динамическая типизация Lisp и система обработки условий в Lisp. Первое позволяет вам тратить меньше времени на убеждение компилятора в том, что вам можно запустить программу, и больше времени на её действительный запуск и работу с ней4). Последнее позволяет интерактивно разрабатывать даже код обработки ошибок.

Другим следствием того, что Lisp — "программируемый язык" является то, что, кроме возможности вносить мелкие изменения в язык, которые позволяют легче писать программы, есть возможность без труда отражать в языке значительные, новые понятия, касающиеся общего устройства языков программирования. Например, первоначальная реализация Common Lisp Object System (CLOS) — объектной системы Common Lisp, была библиотекой, написанной на самом Common Lisp. Это позволило Lisp программистам получить реальный опыт работы с возможностями, которые она предоставляла, еще до того момента, когда библиотека была официально включена в состав языка.

Какая бы новая парадигма программирования ни появилась, Common Lisp, скорее всего, без труда сможет впитать её без изменений в ядре языка. Например, один программист на Lisp недавно написал библиотеку AspectL, которая добавляет Common Lisp поддержку аспектно-ориентированного программирования (AOP)5). Если будущее за AOP, то Common Lisp сможет поддерживать его без изменений в базовом языке и без дополнительных препроцессоров и прекомпиляторов6).

Common Lisp – современный потомок языка программирования Lisp, придуманного Джоном Маккарти (John McCarthy) в 1956 году. Lisp был создан для"обработки символьных данных"7) и получил своё имя от одной вещи, в которой он был очень хорош: обработки списков (LISt Processing). Много воды утекло с тех пор, и теперь Common Lisp обогащён набором современных типов данных, которые вам только могут понадобиться, а также системой обработки ситуаций, которая, как вы увидите в главе 19,предоставляет уровень гибкости, отсутствующий в системах обработки исключений таких языков, как C++, Java, Python; мощной системой объектно-ориентированного программирования; несколькими особенностями, которых нет ни в одном другом языке. Как такое возможно? Что, скажите, обусловило превращение Lisp в такой богатый язык?

Маккарти был (и является до сих пор) исследователем в области искусственного интеллекта, и многие особенности, которые он заложил в первую версию, сделали этот язык замечательным инструментом для программирования искусственного интеллекта. Во время бума ИИ в 80-е Lisp оставался излюбленным языком для решения сложных проблем, как то: автоматическое доказательство теорем, планирование и составление расписаний, компьютерное зрение. Это были проблемы, требующие сложных программ, для написания которых нужен был мощный язык, так что программисты ИИ сделали Lisp таковым. Помогла и Холодная война, т.к. Пентагон выделял деньги Управлению перспективных исследовательских программ(DARPA), часть этих денег попадала к людям, занимающимся моделированием крупных сражений, автоматическим планированием и интерфейсами на естественных языках. Эти люди также использовали Lisp и продолжали совершенствовать его, чтобы язык полностью удовлетворял их потребностям.

Те же силы, что развивали Lisp, также расширяли границы и в других направлениях — сложные проблемы ИИ требуют больших вычислительных ресурсов, как бы вы их ни решали, и если вы примените закон Мура в обратном порядке, то сможете себе представить, сколь скудными эти ресурсы были в 80-е. Так что разработчики должны были найти все возможные пути улучшения производительности их реализаций языка. В результате этих усилий современные реализации Common Lisp часто включают в себя сложные компиляторы в язык, понятный машине. Хотя сегодня, благодаря закону Мура, возможно получить высокую производительность даже интерпретируемых языков, это больше не является проблемой для Common Lisp. И, как я покажу в главе 32, используя специальные(дополнительные) объявления, с помощью хорошего компилятора можно получить вполне приличный машинный код, сравнимый с тем, который выдаст компилятор C.

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

Фактически, к началу 80-х существовало множество Lisp-лабораторий и несколько компаний, каждая со своей реализацией Lisp, их было так много, что люди из DARPA стали высказывать свои опасения о разобщённости Lisp-сообщества. Чтобы достигнуть единства, группа Lisp-хакеров собралась вместе и начала процесс стандартизации нового языка, Common Lisp, который бы впитал в себя лучшие черты существующих диалектов. Их работа запечатлена в книге Common Lisp the Language Гая Стила (Guy Steele, Digital Press, 1984) (CLtL).

К 1986 году существовало несколько реализаций стандарта, призванного заменить разобщённые диалекты. В 1996 организация The American National Standards Institute (ANSI) выпустила стандарт, расширяющий Common Lisp на базе CLtL, добавив в него новую функциональность, такую, как CLOS и систему обработки условий. Но и это не было последним словом: как CLtL до этого, так и стандарт ANSI теперь целенаправленно позволяет разработчикам реализаций экспериментировать с тем, как лучше сделать те или иные вещи: реализация Lisp содержит богатую среду исполнения с доступом к графическому пользовательскому интерфейсу, многопоточности, сокетам TCP/IP и многому другому. В наши дни Common Lisp эволюционирует, как и большинство других языков с открытым кодом: люди, использующие его, пишут библиотеки, которые им необходимы, и часто делают их доступными для всего сообщества. В последние годы, в частности, замечается усиление активности в разработке для Lisp библиотек с открытым кодом.

Так что, с одной стороны, Lisp — один из классических языков в информатике (Computer Science), базирующийся на идеях, проверенных временем8). С другой стороны, Lisp — современный язык общего назначения, с дизайном, отражающим прагматический подход к решению сложных задач с максимальной надёжностью и эффективностью. Единственным недостатком "классического" наследия Лиспа является то, что многие все еще топчутся вокруг представлений о Лиспе, основанных на определенном диалекте этого языка, который они открыли для себя в середине прошлого столетия в то время, когда Маккарти разработал Лисп. Если кто-то говорит вам, что Lisp — только интерпретируемый язык, что он медленный, или что вы обязаны использовать рекурсию буквально для всего, спросите вашего оппонента, какой диалект Lisp'а имеется в видy, и носили ли люди клёш, когда он изучал Lisp9).

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

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

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

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

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

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

Двумя другими распространёнными диалектами Lisp являются ELisp, язык расширений для редактора Emacs, и Autolisp, язык расширений для программы Autodesk AutoCAD. Хотя, возможно, суммарный объём кода, написанного на этих диалектах, перекрывает весь остальной код, написанный на Lisp, оба эти диалекта могут использоваться только в рамках приложений, которые они расширяют. Кроме того, они являются устаревшими по сравнению и с Common Lisp и Scheme. Если Вы использовали один из этих диалектов, приготовьтесь к путешествию на Lisp-машине времени на несколько десятилетий вперёд.

Эта книга для вас, если вы интересуетесь Common Lisp, независимо от того, знаете ли вы его или просто хотите понять, из-за чего вокруг него разгорелась вся эта шумиха.

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

Если вы упёртый прагматик, желающий знать достоинства Common Lispперед другими языками, такими, как Perl, Python, Java, C или C#, эта книга даст вам несколько идей по этому поводу. Или, может быть, вам нет никакого дела до использования Lisp и вы уверены, что он ничуть не лучше языков, которые вы уже знаете, но вам надоели заявления какого-нибудь Lisp-программиста, что вы просто не поняли его как следует. Если так, то в данной книге вы найдёте краткое введение в Common Lisp. Если после чтения этой книги вы по-прежнему будете думать, что Common Lisp ничем не лучше, чем ваши любимые языки, у вас будут веские обоснованные аргументы.

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

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

1)Perl также заслуживает изучения в качестве "изоленты для Internet".

2)К сожалению, нет достоверных исследований продуктивности для разных языков программирования. Один из отчётов, показывающих, что Lisp не уступает C++ и Java в совокупной эффективности программ и труда программистов, находится по адресу http://www.norvig.com/java-lisp.html.

3)Психологи выделяют состояние сознания, называемое потоком (поток сознания?), в котором мы обладаем немыслимой концентрацией и производительностью. Важность данного состояния при программировании была осознана в последние 2 десятилетия, с тех пор, как данная тема была освещена в классической книге о человеческом факторе в программировании "Эффективные проекты и команды" Тома Демарко (Tom DeMarko) и Тимоти Листера (Tim Lister). Два ключевых факта о состоянии потока: требуется около 15минут, чтобы войти в него, и даже короткие прерывания могут вывести из данного состояния, после этого требуется опять 15 минут на вход в него. Демарко и Листер, как и многие последующие авторы, концентрируются на исключении прерываний, разрушающих состояние потока, таких, как телефонные звонки и неподходящие визиты начальника. Меньше внимания обращается на не менее важные вещи — прерывания из-за инструментов, которые мы используем в своей работе. Например, языки, которые требуют долгой компиляции прежде, чем вы сможете запустить ваш код, могут быть не менее губительными для потока, чем надоедливый начальник или звонки по телефону. Lisp может рассматриваться как язык, спроектированный для программирования в состоянии потока сознания.

4)Эта точка зрения противоречит некоторым распространённым мнениям. Статическая типизация против динамической — одна из классических тем для словесных перепалок между программистами. Если Вы пришли из мира С++ или Java (или из мира функциональных языков со статической типизацией, таких, как ML или Haskell) и не представляете жизни без статических проверок типов, можете пока отложить эту книгу. Но прежде чем сделаете это, вам, возможно, будет интересно узнать, что пишут о динамической типизации такие её поборники, как Мартин Фаулер и Брюс Эккель своих блогах —тут и тут. С другой стороны, люди из мира SmallTalk, Python, Perl или Ruby будут чувствовать себя как дома.

5)AspectL — интересный проект, так как его предшественника из мира Java, AspectJ, создал Грегор Кичалес (Gregor Kiczales), один из проектировщиков объектной и метаобъектной системы Common Lisp. Для многих Lisp-программистов AspectJ выглядел как попытка автора портировать идеи Lisp'а в Java. Тем не менее, Паскаль Констанца (Pascal Costanza) — автор AspectL, считает, что в AOP есть интересные идеи, которые будут полезны в Common Lisp. Конечно, он смог реализовать AspectL в виде библиотеки благодаря немыслимой гибкости Common Lisp Meta Object Protocol, разработанного Кичалесом. Для реализации AspectJ пришлось написать отдельный компилятор для компиляции нового языка в Java-код. Страница проекта AspectL находится по адресу http://common-lisp.net/project/aspectl/.

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

7)Lisp 1.5 Programmer's Manual (M.I.T. Press, 1962).

8)Некоторые идеи, впервые реализованные в Lisp: конструкция if-then-else, рекурсивный вызов функций, динамическое распределение памяти, сборка мусора, представление функций как полноценных объектов, лексические замыкания, интерактивное программирование, инкрементальная компиляция и динамическая типизация.

9)Один из наиболее распространённых мифов о Lisp гласит, что он мёртв. Хотя Common Lisp, действительно, используется не так широко, как, скажем, Visual Basic или Java, странно называть мёртвым язык, который постоянно приобретает новых пользователей и используется для разработки новых проектов. Несколько последних случаев успешного применения Lisp — проект Viaweb Пола Грэхема,который стал впоследствии Yahoo Store, когда Yahoo купила его компанию; система заказа авиабилетов ITA Software; QPX, используемый компанией Orbitz и другими для продажи билетов он-лайн; игра "Jak and Daxter" компании Naughty Dog для PlayStation 2, написанная на специализированном диалекте Lisp GOAL, компилятор которого, в свою очередь, написан на Common Lisp; Roomba — автоматический робот-пылесос, программная начинка которого написана на L, подмножествеCommon Lisp. Может быть, ещё больше за себя скажут рост объёма и популярности сайтаhttp://Common-Lisp.net, на котором размещаются проекты на Common Lisp с открытым кодом, и стремительно возросшее в последние годы число локальных групп пользователей Lisp.
  1   2   3   4   5   6   7   8   9   ...   28

Похожие:

Учебник. Часть 1 iconСтраницы учебника
Учебник математики. Роль математики в жизни людей и общества. Счёт предметов стр. 3-5 (1 часть)

Учебник. Часть 1 iconВ. И. Добреньков, А. И. Кравченко методы социологического исследования учебник
Д 55 Методы социологического исследования: Учебник. — М.: Инфра-м, 2004. — 768 с. — (Классический университетский учебник)

Учебник. Часть 1 iconУчебник. М., Российское педагогическое агентство. 1996, 374 с
Учебник предназначен для студентов психологических факультетов

Учебник. Часть 1 iconГорбачев Ю. И. Геофизические исследования скважин. Учебник
Основные понятия и определения дисциплины гис. Содержательная часть модулей. Физико-геологические предпосылки каротажа на основе...

Учебник. Часть 1 iconУчебной дисциплины- история Фамилия, имя, отчество преподавателя...
Учебник: История: учебник для учебных заведений спо/ под ред. П. С. Самыгин, 2012

Учебник. Часть 1 iconУчебник по Autocad. Учебник по mathcad. №36 Программирование на sql. №37
Практический курс access xp, версия 0, Серия (Практические курсы по информационным технологиям). №46

Учебник. Часть 1 iconГеологическое задание 8 Общая часть 9 1 Геологическая характеристика...
...

Учебник. Часть 1 iconВиханский О. С. Стратегическое управление: Учебник. 2-е изд., перераб и доп
Учебник предназначен для студентов вузов, слушателей бизнес-школ. Будет полезен руководителям организаций

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

Учебник. Часть 1 iconУчебник. М., Российское педагогическое агентство. 1996, 374 с
Учебник предназначен для студентов психологических факультетов университетов, педагогических вузов и колледжей, а также всех тех,...

Учебник. Часть 1 iconУчебник (курс лекций) для студентов дневного отделения Специальности...
Социокультурный сервис за рубежом. Учебник. – Спб.: Изд-во Спбгусэ, 2007. – 234 с

Учебник. Часть 1 iconУчебник в двух частях Часть 2 2-е издание, исправленное и дополненное...
Федеральное государственное автономное образовательное учреждение высшего образования

Учебник. Часть 1 iconУчебник -3 переработанное издание
Информатика: Учебник -3 переработанное издание / Под ред проф. Н. В. Макаровой М.: Финансы и статистика 1999. 768 с

Учебник. Часть 1 iconМинистерство Российской Федерации по делам гражданской обороны, чрезвычайным...
Организация и ведение аварийно-спасательных работ (учебник). Часть Технология ведения асднр в условиях разрушения зданий и сооружений....

Учебник. Часть 1 iconУчебник нового века
Р31 Психология и педагогика. — Спб.: Питер, 2002. — 432 с.: ил. — (Серия «Учебник нового века»)

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


Руководство, инструкция по применению






При копировании материала укажите ссылку © 2018
контакты
rykovodstvo.ru
Поиск