Переменная типа

Поделись знанием:
Перейти к: навигация, поиск

В языках программирования и теории типов, переменная типа или ти́повая переменная (англ. type variable) — математическая переменная, которая может принимать значение из множества типов данных.

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

Примечание — в данной статье для явного связывания (explicit binding) ти́повой переменной используется текущий синтаксис, принятый в проекте successor ML[1]: ['a]. Из-за того, что в Haskell этот синтаксис был назначен в качестве синтаксического сахара над типом List, для объявления ти́повых переменных в нём было введено ключевое слово forall.





Наглядный пример

В следующем определении полиморфного типа «список» на языке Standard ML, идентификатор 'a (читается «альфа») является переменной типа:

datatype 'a list = nil | :: of 'a * 'a list

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

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

datatype ('a,'b) t = Single of 'a | Double of 'a * 'a | Pair of 'a * 'b

инстанцировать следующим образом:

type t_ir = (int, real) t

то Single(4), Double(4,5) и Pair(4,5.0) будут допустимыми значениями типа t_ir, а попытка построить значение Single(5.0) приведёт к ошибке типизации, поскольку параметр 'a получил значение «int».

Связывание и квантификация переменных типа

Область действия всякой ти́повой переменной привязывается к определённому контексту[2][3]. В следующем примере идентификатор 'a используется в двух сигнатурах независимо, т.е. не означает требование равенства фактически подставляемых типов между определениями:

val foo: 'a -> 'a
val bar: 'a -> 'a

Это становится наглядным при использовании явного связывания (explicit scoping или explicit bounding) ти́повой переменной:

val foo: ['a] 'a -> 'a
val bar: ['a] 'a -> 'a

Связывание ограничивает область действия данной переменной типа.

В классических диалектах ML явное связывание ти́повых переменных является опциональной возможностью и большинством реализаций не поддерживается за ненадобностью — связывание в них осуществляется неявно при выведении типов, что становится возможным за счёт ограничений ранних версий Хиндли—Милнера. В полной Системе F это объявление записывается как «<math>\Lambda\alpha.~\lambda x^\alpha.~x</math>». Такая запись называется пренексной нормальной формой[en]. Заглавная лямбда в этой записи означает функцию слоя типов (type-level function), параметром которой и является переменная типа. После подстановки в эту переменную конкретного типа, эта функция возвращает мономорфную функцию слоя значений (value-level function). Пренексом называется вынесенное в качестве префикса к сигнатуре типа явное связывание переменной типа. Ранние версии Хиндли—Милнера разрешают только пренексную форму, т.е. требуют, чтобы инстанцирование ти́повой переменной конкретным значением было произведено до необходимости обращения к функции. Это ограничение называется пренексным полиморфизмом — оно не только существенно упрощает механизм проверки согласования типов, но и делает возможным выведение всех или почти всех (в зависимости от диалекта) типов в программе.

Простейшее связывание ти́повых переменных называется их квантификацией. Выделяются два случая:

  • Действие переменной типа распространяется на всё определение типа:
    ['a, 'b] 'a -> 'b -> 'a
    Математически такой тип записывается через универсальный квантор — «<math>\forall a. ~\forall b. ~a \rightarrow b \rightarrow a</math>» — поэтому такая переменная типа называется «универсально квантифицированной», а весь тип — «универсально полиморфным».

На практике, универсально полиморфные типы дают обобщённость типа данных, а экзистенциальные — абстрактность типа данных[5].

В языке Хаскел различают несколько режимов (доступных в виде расширений языка): режим Rank2Types разрешает лишь некоторые формы экзистенциальных типов, открывающие полиморфизм не выше 2-го ранга, для которого выведение типов ещё разрешимо; режим RankNTypes разрешает перемещать универсальный квантор (forall a) внутрь функциональных типов, входящих в состав более сложных сигнатур[6], режим ImpredicativeTypes разрешает произвольные экзистенциальные типы[7].

OCaml реализует поддержку экзистенциальной квантификации посредством решения, названного «локально-абстрактными типами» (locally abstract types)[8].

В спецификации Standard ML для некоторых встроенных операций определена особая квантификация. Её синтаксис не регламентирован и различается в реализациях языка (чаще всего просто скрывается). Например, сигнатура встроенной операции сложения может упрощённо выглядеть примерно следующим образом:

val + : [int, word, real] 'a * 'a -> 'a

Эта семантика реализует примитивную форму ad hoc полиморфизма — объединение нескольких физически различных операций сложения под единым идентификатором «+». Разработчики OCaml отказались от такого решения, полностью убрав ad hoc полиморфизм из языка (в более поздних версиях появились обобщённые алгебраические типы данных).

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

Впервые это расширение было реализовано в основе языка Haskell. Например, операция сравнения на равенство имеет в Хаскеле следующую сигнатуру[en]:

(==) :: (Eq a) => a -> a -> Bool

Проект языка следующего поколения — successor ML[1] — отказывается от необходимости выведения типов, опираясь на явное (манифестное) аннотирование типов[en] (в том числе явное связывание переменных типа), что обеспечивает непосредственную поддержку полной Системы F с полиморфизмом первого класса и рядом расширений, в том числе иерархии подтипов[en] и экзистенциальных типов[1].

Специальные переменные типа

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

Кроме этого, на протяжении истории развития ML выделялись специальные подклассы переменных типа:

  • Переменные типа, допускающего проверку на равенство (или переменные сравниваемого типа, equality type variables) — могут принимать значения из множества всех типов, допускающих проверку на равенство[en] (англ. equality types). Их использование разрешает применение операции сравнения на равенство к объектам полиморфных типов. Обозначаются как «''a» (цифробуквенный идентификатор, всегда начинающийся с двух апострофов). Интересно, что одной из первоначальных целей, ради которых были разработаны классы типов, было именно обобщение таких ти́повых переменных из Standard ML[9]. Они неоднократно подвергалась критике из-за существенного (и спорно оправданного) усложнения определения языка и реализации компиляторов (половина страниц Определения содержат ту или иную поправку на них)[10]. Сложные абстрактные типы данных в принципе не целесообразно проверять на равенство, т.к. такие проверки могут требовать существенных затрат времени. Поэтому из более поздних языков семейства ML поддержка переменных типа, допускающего проверку на равенство, была исключена. В Хаскеле вместо них используется класс типов Eq a.
  • Императивные переменные типа (imperative type variables) представляли собой ad hoc решение проблемы типобезопасности, связанной с наличием побочных эффектов в языке с параметрическим полиморфизмом. Этой проблемы не возникает в чистых языках (Haskell, Clean), но для нечистых языков (Standard ML, OCaml) полиморфизм ссылок представляет угрозу ошибок типизации[2][3]. Императивные переменные типа входили в Определение SML'90, но перестали иметь собственный смысл после того как было придумано «ограничение значениями» (value restriction), ставшее частью Ревизированного Определения SML'97. Синтаксическая поддержка императивных переменных типа в SML'97 была сохранена для обратной совместимости с написанным ранее кодом, но современные реализации трактуют их идентично аппликативным. Обозначаются «'_a» (цифробуквенный идентификатор, всегда начинающийся с апострофа и символа подчёркивания)[2].
  • Слабые переменные типа (weak type variables) использовались в компиляторе SML/NJ[en] в качестве альтернативы императивным переменным типа, предоствляя существенно большие возможности (точнее, меньшие ограничения). Обозначаются «'1a», «'2a» и т.д. (цифробуквенный идентификатор, всегда начинающийся с апострофа и цифры). Цифра, непосредственно идущая за апострофом, показывала градацию «слабости» переменной типа. Как и императивные переменные типа, ныне трактуются идентично аппликативным.[2]

См.также

Напишите отзыв о статье "Переменная типа"

Примечания

  1. 1 2 3 ML2000.
  2. 1 2 3 4 MacQueen - TypeChecking.
  3. 1 2 MLton - Scoping.
  4. haskell_existentials.
  5. Cardelli, Wegner - On Understanding Types.
  6. haskell_rankNtypes.
  7. haskell_impredicative_types.
  8. [caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec228 OCaml extenstions. 7.13 Locally abstract types]
  9. Philip Wadler, Stephen Blott. [homepages.inf.ed.ac.uk/wadler/papers/class/class.ps How to make ad-hoc polymorphism less ad hoc]. — 1988.
  10. Andrew W. Appel [www.cs.princeton.edu/research/techreps/TR-364-92 A Critique of Standard ML]. — Princeton University, revised version of CS-TR-364-92, 1992.

Литература

  • Luca Cardelli, Peter Wegner [lucacardelli.name/Papers/OnUnderstanding.A4.pdf On Understanding Types, Data Abstraction, and Polymorphism]. — ACM Computing Surveys, 1985. — С. 471-523. — ISSN [www.sigla.ru/table.jsp?f=8&t=3&v0=0360-0300&f=1003&t=1&v1=&f=4&t=2&v2=&f=21&t=3&v3=&f=1016&t=3&v4=&f=1016&t=3&v5=&bf=4&b=&d=0&ys=&ye=&lng=&ft=&mt=&dt=&vol=&pt=&iss=&ps=&pe=&tr=&tro=&cc=UNION&i=1&v=tagged&s=0&ss=0&st=0&i18n=ru&rlf=&psz=20&bs=20&ce=hJfuypee8JzzufeGmImYYIpZKRJeeOeeWGJIZRrRRrdmtdeee88NJJJJpeeefTJ3peKJJ3UWWPtzzzzzzzzzzzzzzzzzbzzvzzpy5zzjzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzztzzzzzzzbzzzzzzzzzzzzzzzzzzzzzzzzzzzvzzzzzzyeyTjkDnyHzTuueKZePz9decyzzLzzzL*.c8.NzrGJJvufeeeeeJheeyzjeeeeJh*peeeeKJJJJJJJJJJmjHvOJJJJJJJJJfeeeieeeeSJJJJJSJJJ3TeIJJJJ3..E.UEAcyhxD.eeeeeuzzzLJJJJ5.e8JJJheeeeeeeeeeeeyeeK3JJJJJJJJ*s7defeeeeeeeeeeeeeeeeeeeeeeeeeSJJJJJJJJZIJJzzz1..6LJJJJJJtJJZ4....EK*&debug=false 0360-0300].
  • Dave MacQueen. [www.smlnj.org/doc/Conversion/types.html SML'97 Conversion Guide. 1.1. Types and Type Checking].

Ссылки

  • [wiki.haskell.org/Existential_type Haskell-Wiki: Existential types].
  • [wiki.haskell.org/Rank-N_types Haskell-Wiki: Rank-N types].
  • [wiki.haskell.org/Impredicative_types Haskell-Wiki: Impredicative types].
  • [www.mlton.org/TypeVariableScope Scoping type variables in Standard ML].
  • The ML2000 Working Group. [flint.cs.yale.edu/flint/publications/ml2000.pdf Principles and a Preliminary Design for ML2000]. — 1999.

Отрывок, характеризующий Переменная типа

Предположения о сознании Наполеоном опасности растяжения линии и со стороны русских – о завлечении неприятеля в глубь России – принадлежат, очевидно, к этому разряду, и историки только с большой натяжкой могут приписывать такие соображения Наполеону и его маршалам и такие планы русским военачальникам. Все факты совершенно противоречат таким предположениям. Не только во все время войны со стороны русских не было желания заманить французов в глубь России, но все было делаемо для того, чтобы остановить их с первого вступления их в Россию, и не только Наполеон не боялся растяжения своей линии, но он радовался, как торжеству, каждому своему шагу вперед и очень лениво, не так, как в прежние свои кампании, искал сражения.
При самом начале кампании армии наши разрезаны, и единственная цель, к которой мы стремимся, состоит в том, чтобы соединить их, хотя для того, чтобы отступать и завлекать неприятеля в глубь страны, в соединении армий не представляется выгод. Император находится при армии для воодушевления ее в отстаивании каждого шага русской земли, а не для отступления. Устроивается громадный Дрисский лагерь по плану Пфуля и не предполагается отступать далее. Государь делает упреки главнокомандующим за каждый шаг отступления. Не только сожжение Москвы, но допущение неприятеля до Смоленска не может даже представиться воображению императора, и когда армии соединяются, то государь негодует за то, что Смоленск взят и сожжен и не дано пред стенами его генерального сражения.
Так думает государь, но русские военачальники и все русские люди еще более негодуют при мысли о том, что наши отступают в глубь страны.
Наполеон, разрезав армии, движется в глубь страны и упускает несколько случаев сражения. В августе месяце он в Смоленске и думает только о том, как бы ему идти дальше, хотя, как мы теперь видим, это движение вперед для него очевидно пагубно.
Факты говорят очевидно, что ни Наполеон не предвидел опасности в движении на Москву, ни Александр и русские военачальники не думали тогда о заманивании Наполеона, а думали о противном. Завлечение Наполеона в глубь страны произошло не по чьему нибудь плану (никто и не верил в возможность этого), а произошло от сложнейшей игры интриг, целей, желаний людей – участников войны, не угадывавших того, что должно быть, и того, что было единственным спасением России. Все происходит нечаянно. Армии разрезаны при начале кампании. Мы стараемся соединить их с очевидной целью дать сражение и удержать наступление неприятеля, но и этом стремлении к соединению, избегая сражений с сильнейшим неприятелем и невольно отходя под острым углом, мы заводим французов до Смоленска. Но мало того сказать, что мы отходим под острым углом потому, что французы двигаются между обеими армиями, – угол этот делается еще острее, и мы еще дальше уходим потому, что Барклай де Толли, непопулярный немец, ненавистен Багратиону (имеющему стать под его начальство), и Багратион, командуя 2 й армией, старается как можно дольше не присоединяться к Барклаю, чтобы не стать под его команду. Багратион долго не присоединяется (хотя в этом главная цель всех начальствующих лиц) потому, что ему кажется, что он на этом марше ставит в опасность свою армию и что выгоднее всего для него отступить левее и южнее, беспокоя с фланга и тыла неприятеля и комплектуя свою армию в Украине. А кажется, и придумано это им потому, что ему не хочется подчиняться ненавистному и младшему чином немцу Барклаю.
Император находится при армии, чтобы воодушевлять ее, а присутствие его и незнание на что решиться, и огромное количество советников и планов уничтожают энергию действий 1 й армии, и армия отступает.
В Дрисском лагере предположено остановиться; но неожиданно Паулучи, метящий в главнокомандующие, своей энергией действует на Александра, и весь план Пфуля бросается, и все дело поручается Барклаю, Но так как Барклай не внушает доверия, власть его ограничивают.
Армии раздроблены, нет единства начальства, Барклай не популярен; но из этой путаницы, раздробления и непопулярности немца главнокомандующего, с одной стороны, вытекает нерешительность и избежание сражения (от которого нельзя бы было удержаться, ежели бы армии были вместе и не Барклай был бы начальником), с другой стороны, – все большее и большее негодование против немцев и возбуждение патриотического духа.
Наконец государь уезжает из армии, и как единственный и удобнейший предлог для его отъезда избирается мысль, что ему надо воодушевить народ в столицах для возбуждения народной войны. И эта поездка государя и Москву утрояет силы русского войска.
Государь отъезжает из армии для того, чтобы не стеснять единство власти главнокомандующего, и надеется, что будут приняты более решительные меры; но положение начальства армий еще более путается и ослабевает. Бенигсен, великий князь и рой генерал адъютантов остаются при армии с тем, чтобы следить за действиями главнокомандующего и возбуждать его к энергии, и Барклай, еще менее чувствуя себя свободным под глазами всех этих глаз государевых, делается еще осторожнее для решительных действий и избегает сражений.
Барклай стоит за осторожность. Цесаревич намекает на измену и требует генерального сражения. Любомирский, Браницкий, Влоцкий и тому подобные так раздувают весь этот шум, что Барклай, под предлогом доставления бумаг государю, отсылает поляков генерал адъютантов в Петербург и входит в открытую борьбу с Бенигсеном и великим князем.
В Смоленске, наконец, как ни не желал того Багратион, соединяются армии.
Багратион в карете подъезжает к дому, занимаемому Барклаем. Барклай надевает шарф, выходит навстречу v рапортует старшему чином Багратиону. Багратион, в борьбе великодушия, несмотря на старшинство чина, подчиняется Барклаю; но, подчинившись, еще меньше соглашается с ним. Багратион лично, по приказанию государя, доносит ему. Он пишет Аракчееву: «Воля государя моего, я никак вместе с министром (Барклаем) не могу. Ради бога, пошлите меня куда нибудь хотя полком командовать, а здесь быть не могу; и вся главная квартира немцами наполнена, так что русскому жить невозможно, и толку никакого нет. Я думал, истинно служу государю и отечеству, а на поверку выходит, что я служу Барклаю. Признаюсь, не хочу». Рой Браницких, Винцингероде и тому подобных еще больше отравляет сношения главнокомандующих, и выходит еще меньше единства. Сбираются атаковать французов перед Смоленском. Посылается генерал для осмотра позиции. Генерал этот, ненавидя Барклая, едет к приятелю, корпусному командиру, и, просидев у него день, возвращается к Барклаю и осуждает по всем пунктам будущее поле сражения, которого он не видал.
Пока происходят споры и интриги о будущем поле сражения, пока мы отыскиваем французов, ошибившись в их месте нахождения, французы натыкаются на дивизию Неверовского и подходят к самым стенам Смоленска.
Надо принять неожиданное сражение в Смоленске, чтобы спасти свои сообщения. Сражение дается. Убиваются тысячи с той и с другой стороны.
Смоленск оставляется вопреки воле государя и всего народа. Но Смоленск сожжен самими жителями, обманутыми своим губернатором, и разоренные жители, показывая пример другим русским, едут в Москву, думая только о своих потерях и разжигая ненависть к врагу. Наполеон идет дальше, мы отступаем, и достигается то самое, что должно было победить Наполеона.


На другой день после отъезда сына князь Николай Андреич позвал к себе княжну Марью.
– Ну что, довольна теперь? – сказал он ей, – поссорила с сыном! Довольна? Тебе только и нужно было! Довольна?.. Мне это больно, больно. Я стар и слаб, и тебе этого хотелось. Ну радуйся, радуйся… – И после этого княжна Марья в продолжение недели не видала своего отца. Он был болен и не выходил из кабинета.
К удивлению своему, княжна Марья заметила, что за это время болезни старый князь так же не допускал к себе и m lle Bourienne. Один Тихон ходил за ним.
Через неделю князь вышел и начал опять прежнюю жизнь, с особенной деятельностью занимаясь постройками и садами и прекратив все прежние отношения с m lle Bourienne. Вид его и холодный тон с княжной Марьей как будто говорил ей: «Вот видишь, ты выдумала на меня налгала князю Андрею про отношения мои с этой француженкой и поссорила меня с ним; а ты видишь, что мне не нужны ни ты, ни француженка».
Одну половину дня княжна Марья проводила у Николушки, следя за его уроками, сама давала ему уроки русского языка и музыки, и разговаривая с Десалем; другую часть дня она проводила в своей половине с книгами, старухой няней и с божьими людьми, которые иногда с заднего крыльца приходили к ней.
О войне княжна Марья думала так, как думают о войне женщины. Она боялась за брата, который был там, ужасалась, не понимая ее, перед людской жестокостью, заставлявшей их убивать друг друга; но не понимала значения этой войны, казавшейся ей такою же, как и все прежние войны. Она не понимала значения этой войны, несмотря на то, что Десаль, ее постоянный собеседник, страстно интересовавшийся ходом войны, старался ей растолковать свои соображения, и несмотря на то, что приходившие к ней божьи люди все по своему с ужасом говорили о народных слухах про нашествие антихриста, и несмотря на то, что Жюли, теперь княгиня Друбецкая, опять вступившая с ней в переписку, писала ей из Москвы патриотические письма.
«Я вам пишу по русски, мой добрый друг, – писала Жюли, – потому что я имею ненависть ко всем французам, равно и к языку их, который я не могу слышать говорить… Мы в Москве все восторжены через энтузиазм к нашему обожаемому императору.
Бедный муж мой переносит труды и голод в жидовских корчмах; но новости, которые я имею, еще более воодушевляют меня.
Вы слышали, верно, о героическом подвиге Раевского, обнявшего двух сыновей и сказавшего: «Погибну с ними, но не поколеблемся!И действительно, хотя неприятель был вдвое сильнее нас, мы не колебнулись. Мы проводим время, как можем; но на войне, как на войне. Княжна Алина и Sophie сидят со мною целые дни, и мы, несчастные вдовы живых мужей, за корпией делаем прекрасные разговоры; только вас, мой друг, недостает… и т. д.
Преимущественно не понимала княжна Марья всего значения этой войны потому, что старый князь никогда не говорил про нее, не признавал ее и смеялся за обедом над Десалем, говорившим об этой войне. Тон князя был так спокоен и уверен, что княжна Марья, не рассуждая, верила ему.
Весь июль месяц старый князь был чрезвычайно деятелен и даже оживлен. Он заложил еще новый сад и новый корпус, строение для дворовых. Одно, что беспокоило княжну Марью, было то, что он мало спал и, изменив свою привычку спать в кабинете, каждый день менял место своих ночлегов. То он приказывал разбить свою походную кровать в галерее, то он оставался на диване или в вольтеровском кресле в гостиной и дремал не раздеваясь, между тем как не m lle Bourienne, a мальчик Петруша читал ему; то он ночевал в столовой.
Первого августа было получено второе письмо от кня зя Андрея. В первом письме, полученном вскоре после его отъезда, князь Андрей просил с покорностью прощения у своего отца за то, что он позволил себе сказать ему, и просил его возвратить ему свою милость. На это письмо старый князь отвечал ласковым письмом и после этого письма отдалил от себя француженку. Второе письмо князя Андрея, писанное из под Витебска, после того как французы заняли его, состояло из краткого описания всей кампании с планом, нарисованным в письме, и из соображений о дальнейшем ходе кампании. В письме этом князь Андрей представлял отцу неудобства его положения вблизи от театра войны, на самой линии движения войск, и советовал ехать в Москву.
За обедом в этот день на слова Десаля, говорившего о том, что, как слышно, французы уже вступили в Витебск, старый князь вспомнил о письме князя Андрея.
– Получил от князя Андрея нынче, – сказал он княжне Марье, – не читала?
– Нет, mon pere, [батюшка] – испуганно отвечала княжна. Она не могла читать письма, про получение которого она даже и не слышала.
– Он пишет про войну про эту, – сказал князь с той сделавшейся ему привычной, презрительной улыбкой, с которой он говорил всегда про настоящую войну.
– Должно быть, очень интересно, – сказал Десаль. – Князь в состоянии знать…
– Ах, очень интересно! – сказала m llе Bourienne.
– Подите принесите мне, – обратился старый князь к m llе Bourienne. – Вы знаете, на маленьком столе под пресс папье.
M lle Bourienne радостно вскочила.
– Ах нет, – нахмурившись, крикнул он. – Поди ты, Михаил Иваныч.
Михаил Иваныч встал и пошел в кабинет. Но только что он вышел, старый князь, беспокойно оглядывавшийся, бросил салфетку и пошел сам.
– Ничего то не умеют, все перепутают.
Пока он ходил, княжна Марья, Десаль, m lle Bourienne и даже Николушка молча переглядывались. Старый князь вернулся поспешным шагом, сопутствуемый Михаилом Иванычем, с письмом и планом, которые он, не давая никому читать во время обеда, положил подле себя.
Перейдя в гостиную, он передал письмо княжне Марье и, разложив пред собой план новой постройки, на который он устремил глаза, приказал ей читать вслух. Прочтя письмо, княжна Марья вопросительно взглянула на отца.
Он смотрел на план, очевидно, погруженный в свои мысли.
– Что вы об этом думаете, князь? – позволил себе Десаль обратиться с вопросом.
– Я! я!.. – как бы неприятно пробуждаясь, сказал князь, не спуская глаз с плана постройки.
– Весьма может быть, что театр войны так приблизится к нам…
– Ха ха ха! Театр войны! – сказал князь. – Я говорил и говорю, что театр войны есть Польша, и дальше Немана никогда не проникнет неприятель.