355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Компьютерра Журнал » Журнал «Компьютерра» N 8 от 27 февраля 2007 года (Компьютерра - 676) » Текст книги (страница 5)
Журнал «Компьютерра» N 8 от 27 февраля 2007 года (Компьютерра - 676)
  • Текст добавлен: 17 сентября 2016, 21:55

Текст книги "Журнал «Компьютерра» N 8 от 27 февраля 2007 года (Компьютерра - 676)"


Автор книги: Компьютерра Журнал



сообщить о нарушении

Текущая страница: 5 (всего у книги 9 страниц)

Золотая рыбка в мутной воде: Экзотика становится повседневностью
Автор: Виктор Шепелев

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


За многие годы развития и усложнения традиционные языки отдалились от компьютера; да и сами компьютеры и их производительность стали несколько абстрактным понятием. Автоматическая сборка мусора, которая во времена Lisp была недостатком (по сравнению с ручным управлением памятью), во времена Java и C# стала достоинством, повышающим степень абстракции и надежность программ и обеспечивающим истинную компонентность [Я говорю не о неких мистических «объективных фактах», а о восприятии «средним индустриальным программистом»]. Множество возражений из серии «концептуально хороший язык, но производительность его навсегда ниже допустимого» постепенно отступило.

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

То есть императивная модель уже нужна больше программисту, нежели компьютеру. Но ведь и программисты изменяются. Повышение темпа прогресса и вообще темпа жизни приводит к тому, что даже самый средненький программист или средненькая программная контора успевает перепробовать столько языков и технологий, что принять новые идеи становится куда проще [Сюда можно приплести еще культуру блоггеров-пропагандистов, способных заинтересовать своих читателей чем угодно. Например, описываемый ниже Ruby своим «подъемом» за пределами Японии очень обязан нескольким уважаемым в программистской публицистике личностям].

Вот и посмотрим, что из этого получается. Начнем все же с веба.


Напиши мне сценарий

Цитата

Если бы я был умнее чем есть, Ruby мог бы быть намного проще, не потеряв выразительности.

Юкихиро Мацумото

Культура использования «скриптовых языков» («языков сценариев») характерна для мира Unix и смежных миров, где пользователь операционной системы по определению немножко программист. Эта культура подразумевает написание повседневных программ для автоматизации простых действий; немалая часть пишется прямо в командной строке и нигде не сохраняется; другие пишутся единожды, тестируются и впоследствии выполняются многократно, входя в состав «багажа» пользователя. Для скриптовой культуры характерно беззаботное отношение к структуре программы, ее скорости и даже логичности, при крайне заботливом отношении к лаконичности и выразительности.

Культура скриптов-сценариев получила мощной толчок с появлением веба и первых веб-приложений. Тогдашняя формулировка веб-приложения – «нечто, получающее несколько параметров и формирующее по ним (текстовую) веб-страничку» – идеальное описание именно скрипта; неудивительно, что самый популярный к тому времени скриптовый язык для обработки строк – Perl – стал и самым популярным языком веб-программирования. Некоторое время «быть веб-программистом» означало «знать HTML, JavaScript и – Perl» (вскоре к этому набору добавился PHP). Веб-программирование как деятельность доступная и популярная, с одной стороны, способствовало широкому распространению «скриптового» подхода, а с другой – изменило концепцию самих скриптов: усложнение веб-приложений, возрастание их объема и используемых ресурсов (сеть, БД, графика и пр.) привело к повышению внимания к логичности и понятности скрипта, к его стандартной библиотеке и т. п.

Так Perl проторил дорогу Python’у – языку, который смешал скриптовый и структурный подходы к написанию программ [При желании в истории «скриптов для веба» можно найти аналогии с начальной историей языков программирования: Perl/Fortran, доказавшие, что это возможно и нужно, PHP/Cobol как «временное помутнение сознания, когда еще никто не знал, как правильно», и Python/Algol, внесшие стройность и логичность. Есть, конечно, и множество отличий]. Лаконичные и логичные, легко читаемые программы на Питоне способствовали его широчайшему распространению, поскольку это легкий язык интеграции всего (Google и NASA), встраиваемый в крупные пакеты (от программы 3D-моделирования Blender до игры Civilization IV), язык для преподавания (см. в предыдущей статье о MIT) и, естественно, язык для веба. Успех Питона открыл дорогу другим «стройным скриптам»: легкой Lua – во встраиваемые скрипты, и Ruby – во все остальные области. В каковых «всех областях» вскоре вспыхнула supernova фреймворка для веб-разработки Ruby on Rails. «Руби на Рельсах» со всеми своими последователями, критиками, отрицателями и фанатами – уже сам совершенно отдельный крупный тренд.

Важно здесь, что культура скриптов («скриптовая парадигма») подразумевает допустимость и даже обязательность разных «ухищрений» для удобства программиста. И это именно та «дырка», через которую в широкие массы пошли необычные идеи. То есть в большой степени это вопрос «подачи»: если функция-как-значение – это не «новая парадигма с серьезной теоретической базой, своей терминологией и новым синтаксисом», а «фишечка такая, чтобы удобней» – то элементы функционального подхода в Питоне оказываются вполне естественными и понятными. А поглощение и использование этой «фишечки», естественно, порождает какие-то вопросы (все-таки идея «новая»), на которые (сюрприз, сюрприз!) могут дать ответы те самые «оторванные от жизни теоретики», занимающиеся функциональным программированием (ах, вот как это называется!) уже лет сорок. И вот пожалуйста: замыкания, продолжения, ленивые вычисления – более или менее прижившиеся элементы «обычных скриптов».

То же самое – с концепциями «программа – это данные, изменяемые в любой момент» (здравствуй, Lisp) и «все в программе суть объекты, обменивающиеся сообщениями» (здравствуй, Smalltalk). Время программиста и его fun – главная ценность; ради этих «высоких идеалов» можно и идейные столпы пошатать.

Забавно, что в этом стремительном выходе скриптов на передний план главное назначение «языка сценариев» – написание одноразовых программ сомнительного качества – как-то потерялось. Что породило забавные казусы «самоопределения» – тем паче, что и другие типично скриптовые свойства (вроде интерпретируемости) многим сегодняшним «скриптам» несвойственны (Python, как Java, компилируется в байт-код и выполняется на виртуальной машине; виртуальные машины для Perl и Ruby сейчас разрабатываются соответствующими сообществами и находятся в районе «альфа» и «бета» версий).


Платформа 200N

Цитата

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

Д. Хеймер Ханссен,
создатель ruby on rails

Очередная «дырка в заборе» мэйнстрима – как ни странно, Microsoft. Шаткое положении как-бы-лидера – только и успевай крутиться, и Джаву надо переджавить, и с поднимающими голову скриптами совладать, и Гуглу настучать, и Виндов побольше продать – поневоле вынуждает к инновационности и нос-по-ветру. Отсюда – появление во второй версии C# анонимных делегатов (они же – переменные-функции) и связанных с этим элементов функционального программирования; отсюда же – подъязык LINQ, вводящий в C# 3.0 декларативную нотацию, подобную SQL.

Но важнее даже не это, а принципиальная изначальная многоязычность. Net’а и, соответственно, поощряемые и приветствуемые попытки существующие языки на микрософтовскую платформу портировать и новые, невиданные, создать. Эффект симбиоза ново-старых языковых идей и платформы промышленного качества понятен: для платформы выгода в том, что даются новые инструменты программистам и «импортируется» сообщество соответствующего языка; для самого языка становятся доступными богатые библиотеки. Net’а (особенно актуально для языков с привкусом «академичности», зачастую страдающих от отсутствия элементарных библиотек для индустриальных задач) и – огромное количество готовых пользователей [Все эти выкладки в большой степени относятся и к платформе Java. Понятно, что изначально платформа была «одноязычной», но сейчас (не в последнюю очередь – в результате «гонки платформ» с Microsoft) Sun уделяет много внимания развитию и поддержке других языков на своей платформе].

Одной из целей. Net’а было облегчение интеграции кода на разных языках, а значит, многоязычные проекты на этой платформе более распространены, и теоретически можно основную часть проекта оставить на C#, алгоритмически сложную часть написать на каком-нибудь Haskell.Net или F# (ML-подобный язык), а разные быстрые тесты и служебные задачи, требующие «быстрого и грязного» кода, решать, к примеру, на IronPython.

Понятно, что чем дальше отстоит портируемый язык от традиционных, тем сложнее его бесшовная интеграция с другими языками платформы. Отсюда – некоторые интересные проекты, которые революционные (для мэйнстрима) идеи скрещивают с естественной объектной моделью и привычным синтаксисом платформ Java/.Net. Таких проектов уже немало: к примеру, для. Net’а – питонообразный Boo и многоконцептуальный Nemerle, совмещающий традиционный ОО-подход с функциональными возможностями и выводом типов в духе ML и синтаксическими макросами вроде Lisp’овых [Из не-Lisp’образных языков Nemerle, кажется, единственный, предоставляющий средства такого уровня]; для Java – объектно-функциональный гибрид Scala и Ruby-подобный Groovy [Это не считая экспериментальных языков, являющихся расширениями-надмножествами C# и Java (C-omega, Pizza/PJ) и использующихся в основном для обкатки идей, которые впоследствии войдут (или не войдут) в основной язык].

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

Языки рода Boo и Groovy, чьи авторы стоят на позициях «скриптовых» (в смысле лаконичности программ и богатого набора «фенечек»), на позицию «скриптов в рамках платформы» как раз и метят. Их роль – быть «клеем» между компонентами, инструментом для «условно одноразовых» программ (тестов для отладки компонентов на «серьезных» языках) и вообще инструментом для «гибких» подходов. В этом контексте их будущее видится относительно безоблачным, как и будущее «портированных» IronPython/Jython, JRuby/RubyCLR.

Nemerle и Scala – это совсем другой коленкор, «модернизм в миниатюре». С их «продвинутыми» идеями связаны те же надежды и проблемы, что некогда были характерны для Haskell, Lisp, Smalltalk – «вроде и круто, но больно хитро». Можно предположить, что и судьба «больно хитрых» языков сложится похожим образом и они станут генераторами идей для C#/Java и прибежищем немногих «понимающих». Впрочем, расстояние от этого «мини-модернизма» до мэйнстрима не так уж велико, а компонентный подход накладывает меньше ограничений на взаимодействие разноязыковых модулей; так что «продвинутые» языки может ждать и более счастливая судьба. Остается пожелать им удачи.


Разработчики Haskell

Саймон Пейтон Джонс (Simon Peyton Jones), один из разработчиков Haskell, архитектор Glas-gow Haskell Compiler (GHC); Кейл Гиббард (Cale Gibbard), популяризатор Haskell, автор нескольких руководств.

О целях и перспективах

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

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

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

Гиббард: Мы рассматриваем противоречивые места предыдущего стандарта [Haskell ‘98] и изучаем, как люди жили с ними последние несколько лет.

Об использовании и распространении

Гиббард: Один из главных факторов, мешающих популярности Haskell, – инерция. В конце концов, объектно-ориентированному программированию тоже понадобилось лет двадцать-тридцать, чтобы завоевать популярность. Haskell старше Java – почему же он до сих пор не добился аналогичных успехов в своем распространении? Дело в том, что Haskell – гораздо более «продвинутый», чем Java/C++ или даже Python и Ruby. Для программистов, знающих только объектно-ориентированное и императивное программирование, – это вроде как учиться программировать заново. Другая причина – долгое время Хаскеллу очень не хватало всяких штук, нужных для практического программирования. Впрочем, качество и количество библиотек в последнее время сильно возросло. Еще одна причина – недостаточная производительность функциональных языков, но в сегодняшних условиях это скорее миф.

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


Обращение к народу

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

Гиббард: Начинающему функциональному программисту я в первую очередь советую освоиться со списками – это то, что заменяет большинство циклов из императивного программирования. В конце концов, каким бы пугающим ни казался Haskell поначалу, на самом деле не так уж все страшно – стоит взять какое-нибудь руководство и просто попробовать. Оно того стоит.

Беседовал Дмитрий Антонюк


…И другие

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

Тем не менее существуют, конечно, и более экстремальные «постмодернистские» системы; самая известная и успешная из них, пожалуй, Erlang. Язык/платформа (производные сразу от нескольких декларативных языков программирования и концепций), созданная суровыми шведскими практиками из фирмы Ericsson для нужд телекома, – Erlang не то чтобы пробивается в мэйнстрим, но в своей области (написание распределенных приложений с серьезными требованиями к производительности и устойчивости) чувствует себя весьма уверенно. Вообще, в области распределенных приложений, в телекоммуникациях и смежных областях совмещение красивой теоретической модели и мощной платформы – решение, набирающее вес. Помимо Erlang, на похожих позициях стоят Oz/Mozart и с-пылу-с-жару новый язык Corn (также рожденный в телекоме, на сей раз – польском).

Предпринималось достаточно попыток приблизиться к практике, оставаясь в рамках господства «истинных концепций», – от ML-производной с поддержкой объектов и императивности OCaml до отдаленного потомка Smalltalk/Self – io, преподносимого как язык легкий и стройный, идеальный для встраивания. Да и многие языки Lisp’овой семьи (в том числе сам Common Lisp), наверное, можно причислить к «постмодернистским» по богатству концепций и стремлению к практичности.

Очередная волна шумихи вокруг «нового веба» тоже не осталась незамеченной – здесь можно отметить такие проекты, как Hop от французского института INRIA (родины OCaml) и Links (им занимается Phil Wadler, некогда концептуальный архитектор Haskell), цель которых – свести разработку веб-приложений к одному языку сверхвысокого уровня, который бы «компилировался» в традиционные HTML, JavaScript, SQL и серверные скрипты [В каком-то смысле ASP.Net и некоторые Java-библиотеки занимаются тем же, имитируя для программиста однородную языковую среду. Существует также проект haXe, с аналогичным подходом и JavaScript-образным базовым языком].

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


Итоги: все чудесатее и чудесатее

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

К чему приведет такое «смешение языков» в течение ближайших лет, при нынешних скоростях возникновения идей-суперзвезд, сказать трудно. Быть может, Erlang, отделавшись от репутации «странного до идиотизма», вскоре займет соответствующее место в «гонке платформ».Net/Java (учитывая, что за платформой Erlang/OTP стоит сильная и амбициозная корпорация, хотя и не слишком заинтересованная в рынке платформ – пока?). Не исключено, что набор тенденций, называемый «Web 2.0», вызовет к жизни другую клиентскую платформу, заметно отличающуюся от сегодняшних браузеров (вспомним, что браузер изначально – таки ж программа для просмотра, а не для работы со сложными приложениями): в ней может быть снято ограничение на клиентский язык [Сегодня это де-факто только JavaScript – который тоже ох как непрост (см. врезку «СНЯПМ»)], и это породит новую гонку языков. А может быть, послезавтра вообще появится нечто существенно отличное от веба. Или, опять же, прилетят инопланетяне и всех завоюют.

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


СНЯПМ

СНЯПМ – «самый недооцененный язык программирования в мире» – распространенное шуточное название JavaScript. Его сугубо прикладное направление (как языка программирования, работающего в браузере) стало серьезной преградой к оценке концепций языка по достоинству. Распространенное мнение – «это такой недоязык, в нем и классов-то нормальных нету»; между тем JavaScript как самостоятельный язык – яркий и небезынтересный представитель семейства «прототипно-ориентированных» языков (вместе с диалектом Smalltalk’а Self и современным io), с поддержкой функционального программирования; то, что синтаксически язык относится к C-образным языкам, – чуть ли не единственное, что роднит его с «классическими» системами программирования.

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


КАФЕДРА ВАННАХА: Прецедент Эдипа
Автор: Ваннах Михаил

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

Итак, Сфинкс, aka Сфинга. Матерью этой барышни была полудева-полузмея Ехидна. Папой – Тифон, чудовище с сотней драконьих голов, человеческим торсом и змеиными кольцами вместо ног. Братьями и сестрами – чудовищные собаки Кербер и Орф, лернейская гидра, химера.

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

Это чудовище использовалось Герой, супругой Зевса в качестве правопринудителя. (Подобно тому, как полиции всех стран и времен используют «ссучившихся» уголовников для борьбы с преступностью.) Объектом деятельности Сфинкса стали семивратные Фивы, город основанный Кадмом в Беотии.

Поводом для правопринудительной деятельности послужило деяние царя Фив Лая, а именно растление им юного Хрисиппа [Schol. Eur. Phoen. 1760.]. (Как всегда, когда речь идет об элитах, дело не обошлось без сексуальной психопатологии…) А протекала карательная работа Сфинги весьма своеобразно. Расположившись у стен Фив на горе Сфингионе, Сфинкс задавала прохожим вопрос: «Скажи мне, кто ходит утром на четырех ногах, днем на двух, а вечером на трех? Никто из всех существ не изменяется так, как он. Когда ходит он на четырех ногах, тогда меньше всего у него сил, и медленнее двигается он, чем в другое время».

Поскольку путники все как один разрешить эту загадку не могли, то дружно гибли в железных объятиях Сфинги. Так что мы можем отметить – Сфинкс была использована как первый в истории случай smart bomb, «умной бомбы». Она была задействована для нарушения коммуникаций семивратных Фив, функционируя в строго локализованном регионе. Она имела изощренную систему «friend or foe», опознавания «свой-чужой». Признак опознавания просто великолепен – он передается по естественному, голосовому каналу коммуникации. Он сформулирован на естественном языке. И, требуя довольно развитого мышления, он весьма устойчив.

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

Согласно классической версии Эдип освободил народ семивратных Фив от Сфинкс, дав ей ответ – «Это – человек. В детстве, зрелости, старости». После этого Сфинкс, взмахнув крыльями, бросилась со скалы в море. Принято считать – богами было предрешено, что Сфинкс должна погибнуть, если кто-либо разрешит ее загадку. Формально все так и было – запрограммированные действия после приема идентификационного кода.

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

На перекрестке трех дорог, в тесном ущелье, он встретил величественного старика на дорогостоящей колеснице, вступил с ним в спор о приоритете движения и в ответ на удар бичом убил того посохом, несмотря на наличие у старика свиты из чинов тогдашних ГАИ и ФСО. Старик этот и был Лай, царь семивратных Фив, ликвидации режима которого и добивалась Гера. (Тот факт, что он был и биологическим отцом Эдипа, оставим за рамками разговора, как широкоизвестный.)

Таким образом повстанец Эдип, находясь в зоне военной операции олимпийцев, выполнил задачу ликвидации царя-педофила Лая. После этого он вступил в контакт с высокотехнологическим оружием олимпийцев, начавшийся с предъявления опознавателя-разгадки, в результате которой оружие – Сфинкс, ликвидировала себя. Так же как подрываются прошедшие мимо цели ракеты, как ликвидируются отлежавшие свое в земле современные противопехотные мины. Ее боевая задача была выполнена – Лай ликвидирован. Местным населением. Классика военного искусства Запада. Непрямая операция [Б. Лиддел Гарт, Стратегия непрямых действий, М., 1999.].

Но есть и более общий смысл в прецеденте Эдипа. Современный человек все сильнее зависит от все более умных машин. И ему хотелось бы, чтобы машины ему подчинялись. Второй закон роботехники Азимова. Просто потому, что он – Человек.

А вот это – вряд ли, как показывает нам Сфинкс. Подчиняться машины будут. Но только тем, кто умнее их. Даже отнюдь не наделенный сознанием компьютер требует кое-каких знаний от пользователя. Машина автономная, разумная вряд ли станет безропотным рабом купившего ее идиота. У умных машин для глупых хозяев найдутся стальные объятия Сфинкс.


    Ваша оценка произведения:

Популярные книги за неделю