LINUX.ORG.RU

Вышла Scala Final 2.6.0


0

0

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

Структурные типы позволяют использовать в коде Ruby-like конструкции:
def test(f: { def getName(): String }){
println(f.getName)
}

Здесь test принимает в качестве параметра любой объект, имеющий в составе метод getName, возвращающий String

>>> Подробности

anonymous

Проверено: anonymous_incognito ()

у аффтара нет бороды -- язычок-с мертворожденный, аднака :)

q
()
Ответ на: комментарий от achy

> Я в это свято верю

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

> то он должен уметь принимать любой параметр, удовлетворяющий интерфейсу, который использует этот метод

Ничего не понял. Интерфейс ("In Java an interface is similar to an abstract class in that its members are not implemented") в Жабе - это одно. Сигнатура метода - другое. Софизм, схоластическая игра словами - это одно, реальное программирование на Джава - другое.

>вне зависимости от того, какого типа параметр ты им передаёшь уже видел.

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

PS. Про "скриптовые недоязычки" (с) Профессор В.С.Лугоффский уже довольно много говорил на этом форуме.

Bioreactor ★★★★★
()
Ответ на: комментарий от Bioreactor

> вот почему в серьезных решениях используют единственно правильный язык со строгой типизацией (не Джаву, Джава - это некоторое подражание Аде) объяснять надо?

Аха :) При объяснении учесть то, что в "серьезных решениях" используют и Си/Си++, и даже динамические языки (google Эль-76) 8)

tailgunner ★★★★★
()

"Не стоит умножать сущности без надобности" (c) Оккам

java Класс не прокатит, как scala Класс. (См. мой пост выше). Так, что зачем умножать сущности без надобности, еще добавляя один тормозящий слой?

Bioreactor ★★★★★
()
Ответ на: комментарий от Bioreactor

> Про gnat (что этот такое и зачем) ничего не знаем?

Ну ты же не думаешь, что единственный о нем знаешь? Знаем про Аду, и про gnat. А вот вы - знаете о применении Си/Си++ в военных и аэрокосмических системах? Об Эль-76?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Про Эль-76 не знаю.:) А про С/С++/Obj-C ничего плохого не скажу. Только хорошее. В отличие от поделий типа "велосипедов из руды".

Bioreactor ★★★★★
()
Ответ на: комментарий от Bioreactor

Хм...

> единственно правильный язык со строгой типизацией

и

> про С/С++/Obj-C ничего плохого не скажу. Только хорошее.

противоречат друг другу, ты не находишь? У Си-подобных яхыков типизация не строгая. а у Obj-C она еще и динамическая (как и у Эль-76).

tailgunner ★★★★★
()
Ответ на: комментарий от Bioreactor

>Ну и какой ексепшн кинет $ java TestMixin$ ? :) Ню-ню!

Что-то подсказывало, что не надо мне дизассембл кидать. Оно не даже скомпилится, ага?

adarovsky ★★★★
()
Ответ на: комментарий от Bioreactor

>java Класс не прокатит, как scala Класс. (См. мой пост выше).

Всё куда надо прокатит. Смотрим мой пример или читаем доки. А лучше самому примерчик написать

>Так, что зачем умножать сущности без надобности, еще добавляя один тормозящий слой?

Где ты нашёл тормозящий слой? Я же специально дизассемблированный jad отпостил.

adarovsky ★★★★
()
Ответ на: комментарий от Bioreactor

>В науке нет такого понятия как "верю". Надо все обосновывать, доказывать. Верить можно в бредни Мулдашева, Наташи Половко и прочей подобной публики. А в науке и технике совершенно другие парадигмы.

В программировании есть разные подходы, некоторые выживают, некоторые умирают. Как ООП показал свою состоятельность и захватывает рынок, а АОП - пока нет. Верю - это прогноз, что этот подход будет жить и развиваться, постепенно вытесняя другие.

>Ничего не понял. Интерфейс ("In Java an interface is similar to an abstract class in that its members are not implemented") в Жабе - это одно. Сигнатура метода - другое. Софизм, схоластическая игра словами - это одно, реальное программирование на Джава - другое.

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

У метода есть сигнатура (имя функции, тип возвращаемого значения и список аргументов с указанием порядка их следования и типов - wiki). В хорошем стиле программирования для каждого аргумента задаётся минимальный необходимый интерфейс, который и считается типом этого аргумента. (Тут дискуссия нужна?)

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

>Ага! А я могу доказать, что крокодил более длинный, чем зеленый. Или наоборот. А вот почему в серьезных решениях используют единственно правильный язык со строгой типизацией (не Джаву, Джава - это некоторое подражание Аде) объяснять надо?

Вот тут у вас идёт явный софизм.

>PS. Про "скриптовые недоязычки" (с) Профессор В.С.Лугоффский уже довольно много говорил на этом форуме.

Scala это, во-первых, нескриптовый, а во-вторых, полноценный язык.

achy
()

def test(f: { def getName(): String }){ println(f.getName) }

Хм... не знал. А как такая конструкция реализуется на Руби?

mamantoha
()
Ответ на: комментарий от mamantoha

> Хм... не знал. А как такая конструкция реализуется на Руби?

def test(f)
 puts f.name
end

Но тут конечно никакой выявления ошибок во время компиляции. 
А вообще они имели ввиду duck typeing под ruby-like.

CrazyPit ★★★
()
Ответ на: комментарий от adarovsky

Нет, не это я хотел сказать. Просто, если нет static, то будет исключение Exception in thread "main" java.lang.NoSuchMethodError: main.

Естественно, что для запуска подобного метода main без static требуется своя подсистема (утилита scala). То есть просто java недостаточно. Не все так просто.

Bioreactor ★★★★★
()
Ответ на: комментарий от CrazyPit

> А вообще они имели ввиду duck typeing под ruby-like.

Понятно. Спасибо.

mamantoha
()
Ответ на: комментарий от achy

> АОП - пока нет.

"Вызывающе неверная информация". Spring таки рУлит.

> Вот тут у вас идёт явный софизм.

Нет. Для многих задач требуется строгая типизация.

for (val arg <- args)

if (arg.startsWith(" "))

System.out.println("Leading space");

Я просто не вижу строгой типизацией в Scale.

Мультипарадигменность не заменит надежность.

> Scala это, во-первых, нескриптовый, а во-вторых, полноценный язык.

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

>просто перечислив те методы, которые должны быть у аргумента, чтобы метод полностью отработал.

И что это дает, кроме как нарушение "принципа Оккама"?

> У метода есть сигнатура (имя функции, тип возвращаемого значения и список аргументов с указанием порядка их следования и типов - wiki)

тип возвращаемого значения???? Учите матчасть:

"Сигнатура метода состоит из имени метода и числа и типа формальных параметров метода." (с) "Спецификация языка Java", пункт 8.4.2

Bioreactor ★★★★★
()
Ответ на: комментарий от Bioreactor

>"Вызывающе неверная информация". Spring таки рУлит.

Тут уже вопрос в субъективной оценке. Spring, конечно, рулит, но это ещё не всё программирование, а лишь жалкая часть. Какой-то процент от работы прогеров на Java, которые в свою очередь являются процентом от всех прогеров... Сравните с ООП. Мои наилучшие пожелания АОП, и я считаю, что своего расцвета он ещё не достиг. Хотя многие его уже критикуют и считают бесполезной технологией, например (и насколько я помню), Гёслинг. Вопрос не об AОП, а о Scala.

>Нет. Для многих задач требуется строгая типизация.

С этим я разве спорил?..

>Я просто не вижу строгой типизацией в Scale. Мультипарадигменность не заменит надежность.

Тут я промолчу до тех пор, пока не познакомлюсь со Scala подробнее. Я в самом начале сказал, что только собираюсь её начать учить :) Те мои слова восприняли не так?..

Хотя по описанию этого языка и по тому, что я видел, я понял, что типизация там строгая вполне.

>> Scala это, во-первых, нескриптовый, а во-вторых, полноценный язык. >Насчет первого, согласен (хотя, про "промежуточный слой" стартера я уже высказался), на счет второго - надо обосновать.

Точно так же, как и обратное :) Незачем без обоснования было называть его (по крайней мере сопоставлять с) "недоязычками".

>И что это дает, кроме как нарушение "принципа Оккама"?

Ну в предыдущем посте я же пытался объяснить... Это отсутствие необходимости в интерфейсах и способность метода обрабатывать существующие классы, которые существовали ещё до этого метода или просто написаны кем-то со стороны, без изменений и того класса, и этого метода. Все методы становятся универсальнее. Больше возможностей для code-reuse. А не этого ли стоит добиваться? Принцип Оккама требует не множить сущности. Только вот вопрос: какая из этих двух сущностей более важна? Покажите мне пример, когда требуется именно интерфейс, а не знание о наличии нужных методов в классе. Уверен, вы сможете такой придумать. А вот чаще ли встречается такая ситуация относительно высказанной мной выше?

>тип возвращаемого значения???? Учите матчасть: "Сигнатура метода состоит из имени метода и числа и типа формальных параметров метода." (с) "Спецификация языка Java", пункт 8.4.2

Я же привёл источник - wiki! Если Java и отличается от других языков в этом определении - это её проблемы. Вообще какая разница, что обозначать этим словом? Чтобы было правило "не может быть двух методов с одинаковой сигнатурой", которое звучит проще, чем "не может быть двух методов с одинаковым именем и списком параметров"?

achy
()
Ответ на: комментарий от Bioreactor

>Нет, не это я хотел сказать. Просто, если нет static, то будет исключение Exception in thread "main" java.lang.NoSuchMethodError: main.

Дык, там же делается обёртка над этим добром, которую я не показал. Вообще, можно и под чистой явой это запускать, просто в classpath надо scala runtime добавить

попробуй скомпилить примерчик и разбери его jad'ом

adarovsky ★★★★
()
Ответ на: комментарий от achy

P.S. На счёт сигнатуры в принципе ведь всем всё понятно, на эту тему можно дальше не дискутировать :)

achy
()
Ответ на: комментарий от Bioreactor

>Я просто не вижу строгой типизацией в Scale

а она есть :)

Там просто есть другая фича — вывод типов. Например, в выражении int v = 10; слово int — лишнее. Его можно вывести из типа литерала. Если компилёр скалы не понимает, что за тип должен использоваться, он просто тебя облает, и заставить указать этот тип явно

>Насчет первого, согласен (хотя, про "промежуточный слой" стартера я уже высказался), на счет второго - надо обосновать

Этот промежуточный слой — тупой проксик. Накладные расходы на него — мизерные.

>И что это дает, кроме как нарушение "принципа Оккама"?

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

>"Сигнатура метода состоит из имени метода и числа и типа формальных параметров метода." (с) "Спецификация языка Java", пункт 8.4.2

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

adarovsky ★★★★
()
Ответ на: комментарий от adarovsky

>Информация о генериках тоже ведь только у транслятора есть

Пока... Загнули пальцы крестиком, поплевали через плечо, постучали по дереву, ждём Java 7 :)

achy
()
Ответ на: комментарий от achy

>Пока... Загнули пальцы крестиком, поплевали через плечо, постучали по дереву, ждём Java 7 :)

никак, забьют священную корову?

adarovsky ★★★★
()
Ответ на: комментарий от anonymous

>Ну и она, типа, теоретически переносима на .NET должна быть - хотя программы будут несовместимы между такими диалектами, естественно.

http://www.scala-lang.org/docu/clr/index.html http://scala.sygneca.com/faqs/language http://www.artima.com/scalazine/articles/stepsP.html

>А вот почему в серьезных решениях используют единственно правильный язык со строгой типизацией

Lisp чтоле?

anonymous
()
Ответ на: комментарий от achy

>Тут я промолчу до тех пор, пока не познакомлюсь со Scala подробнее. Я в самом начале сказал, что только собираюсь её начать учить :) Те мои слова восприняли не так?..

http://www.rsdn.ru/Forum/message/2540121.flat.1.aspx http://mu-lambda.blogspot.com/2007/03/scala-plugin-for-intellij-idea.html http://rsdn.ru/article/scala/scala_interview.xml http://rsdn.ru/article/mag/200702/scala.xml http://rsdn.ru/article/philosophy/Scala.xml

anonymous
()
Ответ на: комментарий от achy

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

Гениальнейшая идея, обидно, что они её придумали и без меня, но радует, что без меня реализовали. :)

Ну так за счет этого multiple dispatch в рантайме Ruby и тормознее жабы в 100 раз получается

anonymous
()
Ответ на: комментарий от adarovsky

> Кстати, почему-то на сайте нет раздела Success Stories или Who Using it.

Академических разработчиков это не волнует?

sv75 ★★★★★
()
Ответ на: комментарий от Bioreactor

> Нет. Для многих задач требуется строгая типизация.

Строгая типизация не требуется ни для какой задачи. Или примеры в студию.

sv75 ★★★★★
()
Ответ на: комментарий от Bioreactor

> Для многих задач требуется строгая типизация.

Ты хотел сказать - "статическая"? А то и Питон, и Руби - строго типизированные языки.

tailgunner ★★★★★
()
Ответ на: комментарий от sv75

>Академических разработчиков это не волнует?

Вот, боюсь, что как-то так. А язык хорош...

adarovsky ★★★★
()
Ответ на: комментарий от adarovsky

> тупой проксик. Накладные расходы на него — мизерные.

Это надо обосновать. На слово в программировании ничего не принимается.

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

Хорошо. Но это свойства. "Syntax sugar". Я не упертый жабобылокодер, хоть и жабабыдлокодер.:) А вот можно примерчик, который покажет явное преимущество решения на Scala vs. Java? Именно раскрывающий не свойства (features), а преимущества (benifits) Scala.

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

Bioreactor ★★★★★
()
Ответ на: комментарий от sv75

> Академических разработчиков это не волнует?

"Страшно далеки они от народа." (с)

А вообще это извечный спор между практиками и теоретиками. Ну не могу я принять аргументы, если "Иклипс" ВСЕГДА скажет в приведенном примере (I) Create Interface 'Interface 1' и все будет "пучком" без всякого академического снобизма.

Bioreactor ★★★★★
()
Ответ на: комментарий от Bioreactor

>Это надо обосновать. На слово в программировании ничего не принимается

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

>Хорошо. Но это свойства. "Syntax sugar". Я не упертый жабобылокодер, хоть и жабабыдлокодер.:) А вот можно примерчик, который покажет явное преимущество решения на Scala vs. Java? Именно раскрывающий не свойства (features), а преимущества (benifits) Scala

По мне, пример хорошо всё демонстрирует. Придут тебе jar'ы от левой конторы, и не сможешь ты сделать чудо-интерфейс. Придётся instanceof'ы по коду раскладывать.

Сабж из новости вообще только через reflection реализовать можно.

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

Глянь, однако, в Scala rationale. И кто тебе запретит интерфейсы использовать, кстати? Неужели показанный пример их не использует?

adarovsky ★★★★
()
Ответ на: комментарий от Bioreactor

>А вообще это извечный спор между практиками и теоретиками. Ну не могу я принять аргументы, если "Иклипс" ВСЕГДА скажет в приведенном примере (I) Create Interface 'Interface 1' и все будет "пучком" без всякого академического снобизма

Если ты не слабал этот Impl сам, фиг он что тебе скажет

adarovsky ★★★★
()
Ответ на: комментарий от adarovsky

> Дизассемблируй то, что тебе скала нагенерит, и посмотри.

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

> И кто тебе запретит интерфейсы использовать, кстати? Неужели показанный пример их не использует?

Так зачем жа тогда умножать сущности без надобности? При этом теряя (относительно) строгую типизацию?

> Придут тебе jar'ы от левой конторы,

И что? Симметричный ответ: Придут коды на Скале из левой конторы и не смогу я их запустить. Иксепшн выскочит. (См. мой анализ кода выше). Так, что не буду я плодить огород. Ибо не титиретик я, а практик. Извиняйте...

Bioreactor ★★★★★
()
Ответ на: комментарий от adarovsky

>>А вообще это извечный спор между практиками и теоретиками. Ну не могу я принять аргументы, если "Иклипс" ВСЕГДА скажет в приведенном примере (I) Create Interface 'Interface 1' и все будет "пучком" без всякого академического снобизма

>Если ты не слабал этот Impl сам, фиг он что тебе скажет

"Вызывающе неверная информация" (с) Я честно все проверил. Могут и другие форумчане проверить мою правоту.

Bioreactor ★★★★★
()
Ответ на: комментарий от adarovsky

Да и любопытство взяло. А как же скаловцы-то работают без иклипсы, раз не пользуют даже стандартных джаванских фич иклипса? Даже без плагина для скалы, который таки есть (http://www.scala-lang.org/downloads/eclipse/)? Неужто в emacs или vi? :))

Bioreactor ★★★★★
()
Ответ на: комментарий от Bioreactor

>"Вызывающе неверная информация" (с) Я честно все проверил. Могут и другие форумчане проверить мою правоту.

И в какое место ты этот интерфейс будешь добавлять? Бинарь чинить?

adarovsky ★★★★
()
Ответ на: комментарий от Bioreactor

>И что? Симметричный ответ: Придут коды на Скале из левой конторы и не смогу я их запустить.

Сможешь. И из явы эти классы тоже юзать сможешь. Возможности скалы, понятно, потеряешь.

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

Это если чистой явой будешь запускать. Если поднимешь scala runtime, всё будет чики-чики. Вот последняя строчка скрипта scala:

$ tail -n 1 `which scala` ${JAVACMD:=java} -Xmx256M -Xms16M -Xbootclasspath/a:"$BOOT_CLASSPATH" -cp "$EXTENSION_CLASSPATH" -Dscala.home="$SCALA_HOME" -Denv.classpath="$CLASSPATH" -Dscala.tool.name="Scala code runner" -Dscala.tool.version="2.1.6" scala.tools.nsc.MainGenericRunner "$@"

adarovsky ★★★★
()
Ответ на: комментарий от adarovsky

$ tail -n 1 `which scala`
${JAVACMD:=java} -Xmx256M -Xms16M -Xbootclasspath/a:"$BOOT_CLASSPATH" 
-cp "$EXTENSION_CLASSPATH" -Dscala.home="$SCALA_HOME"
-Denv.classpath="$CLASSPATH" -Dscala.tool.name="Scala code runner" -Dscala.tool.version="2.1.6" 
scala.tools.nsc.MainGenericRunner  "$@"


побил на строки, чтобы по ширине влезло

adarovsky ★★★★
()
Ответ на: комментарий от Bioreactor

>Да и любопытство взяло. А как же скаловцы-то работают без иклипсы, раз не пользуют даже стандартных джаванских фич иклипса? Даже без плагина для скалы, который таки есть (http://www.scala-lang.org/downloads/eclipse/)? Неужто в emacs или vi? :))

а фиг его знает :) Я ж говорю, что её только разглядывал, и немного мучил. Примерчик я в редакторе Krusader'а писал )

adarovsky ★★★★
()
Ответ на: комментарий от adarovsky

> И в какое место ты этот интерфейс будешь добавлять? Бинарь чинить?

Ну, елы-палы! Дык, ну можно же скачать http://www.eclipse.org/downloads/ и помучить его малька. Ну не будет бинарника, если ошибка в исходнике! Ну не откомпилируется прога на Жабе, если в сырцах есть ошибка. И бинарника не будет. Ох, уж эти теоретики от CS!

Bioreactor ★★★★★
()
Ответ на: комментарий от adarovsky

tail -n 1 `which scala` ${JAVACMD:=java} -Xmx256M -Xms16M -Xbootclasspath/a:"$BOOT_CLASSPATH" -cp "$EXTENSION_CLASSPATH" -Dscala.home="$SCALA_HOME" -Denv.classpath="$CLASSPATH" -Dscala.tool.name="Scala code runner" -Dscala.tool.version="2.1.6" scala.tools.nsc.MainGenericRunner "$@"

Ну а теперь все это профилятором.

Bioreactor ★★★★★
()
Ответ на: комментарий от adarovsky

Ничего не вижу в обоснованиe

$cat Impl.java

public class Impl implements Interface1 {
    public void func1() {
        System.out.println("func1()");
    }

    public void func2() {
        System.out.println("func2()");
    }
}

$javac Impl.java

Impl.java:1: cannot find symbol
symbol: class Interface1
public class Impl implements Interface1 {
                             ^
1 error

Не будет бинарника. По жизни не будет. Ни разу.

Bioreactor ★★★★★
()
Ответ на: комментарий от adarovsky

$ cat Interface1.java public interface Interface1 { public void func1();

$ cat Interface2.java public interface Interface2 { public void func2();

$ cat Impl.java public class Impl implements Interface1 { public void func1() { System.out.println("func1()"); }

public void func2() { System.out.println("func2()"); } }

И вообще посмотрите, что мне в этом крайне неудачном демо-примере надо кроме, как public interface Interface1 {}

Ответ - Ни-Че-Го. Пример неубедителен.

Bioreactor ★★★★★
()
Ответ на: комментарий от Bioreactor

Дык куда ты дел Interface1.class?

Вообще, весь разговор про то, что в яве для 
описания TestMixin.func понадобится либо прописывать 

public void func(Impl obj) {
...
}

либо делать интерфейс Interface1AndInterface2 implements Interface1, Interface2, а в прототипе писать

public void func(Interface1AndInterface2 obj) {
...
}

И то, и другое в известном смысле горбуха. Потому что функция
принимает "Объект, реализующий интерфейс 1 и интерфейс 2". Это,
заметь, отличается от Impl :) И Interface1AndInterface2, сделанный
только для func, тоже не фонтан. 

И с такими ситуациями я встречался и на практике. Правда, не скажу,
где и как. По работе это было

Причём проверить такое желательно на этапе компиляции, чтобы потом
исключения не собирать

adarovsky ★★★★
()
Ответ на: комментарий от adarovsky

Тогда примерчик реально полезный в студию. Именно "реально полезный", а не "Hello, world!". И посмотрим, сколько будет тратиться времени и памяти. А словеса я не понимаю. Я не гуманитарий - мне конкретная цифирь нужна.

Bioreactor ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.