Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Базарная площадь
  
О разделе

Основная страница

Группы обсуждений


Тематический каталог обсуждений

Архив

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  21:46[Войти] | [Зарегистрироваться]
Обсуждение темы:
Функциональное программирование

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

Исторически функциональное программирование появилось практически вместе с императивным.
Вторым языком после фортрана был лисп.
Но увы, функциональное программирование надолго было уделом исследовательских институтов или специализированных приложений (Искусственный Интеллект)
Конечно не надо считать весь мир дураками из за того что развитие пошло по пути языков Алгол семейства.
Для этого были вполне обьективные причины. Функциональные языки слишком близки к человеку и слишком далеки от машины.
Они сьедают в десятки раз больше рессурсов чем императивные языки.
Вспомните претензии, предявляемые к java - первому императивному языку с виртуальной машиной и сборщиком мусора, толкаемому большими корпорациями в mainstream.
Жутко тормозит, и жрет всю память какая есть. А ведь функциональные языки (далее ФЯ) все без иключения имеют сборщик мусора, виртуальную машину.
Многие из них (семейство лисп) еще и динамические, что только усугубляет положение.
Вполне естественно что появившись более полусотни лет назад они надолго опередилли свое время.

Для широкого распространения ФЯ нужны гигабайты дешевой памяти и гигагерцы дешевых процессоров.
Прошло более 50 лет, прежде чем такие требования к железу стали реальностью.
Это время наступило. СЕЙЧАС.
Добро пожаловать в новую эру программирования.

 Jack Of Shadows

Количество сообщений на странице

Порядок сортировки сообщений
Новое сообщение вверху списка (сетевая хронология)
Первое сообщение вверху списка (обычная хронология)

Перейти на конкретную страницу по номеру


Всего в теме 5502 сообщения

Добавить свое сообщение

Отслеживать это обсуждение


Смотрите также обсуждения:
Средства разработки. Языки программирования.
  • Delphi 4 or Delphi 5
  • Что приобрести в качестве средства разработки?
  • Delphi6
  • Delphi vs PowerBuilder
  • Сравнение компиляторов
  • Вот и вышла Delphi 7... Вы рады?

  • <<<... | 562—553 | 552—543 | 542—533 | ...>>>
    Всего сообщений в теме: 5502; страниц: 551; текущая страница: 496


    № 552   01-08-2006 00:50 Ответить на это сообщение Ответить на это сообщение с цитированием
    http://en.wikipedia.org/wiki/Closure_(computer_science)
    локальная функция может быть closure а может и не быть, зависит от того, имеет ли она доступ к контексту. Навtрное в delphi она не closure (rjulf функция закончится локальные переменный будут убиты - и если функция вернет внутреннюю функцию, то та обломится пытаясь получить доступ к локальным своим переменным ) а в js - closure
    посмотрите здесь пример с аккумулятором:
    http://www.paulgraham.com/icad.html


    № 551   31-07-2006 18:15 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 550« (Geniepro)
    ___________________________
    Согласен со всем сказанным вами.
    Многое из вашего поста уже говорилось здесь причем не раз.

    Жаль что так мало людей, которым дается понимание этой темы. Обычно это программисты со стажем, которые были в отрасли задолго до появления турбо-паскалей, дельфей и прочих рюшечек.
    Современные молодые программисты видят мир через призму своего единственного и любимого языка программирования. Времени и желания расширить кругозор за счет знакомства с дургими языками (не похожими языками как delphi, java, сишарп, а принципиаьно разными языками) нет.
    Поэтому зачастую получается разговор слепого с глухим.
    Как говорил Руслан Богатырев, приводя здесь цитату из Жванецкого - обсуждаем вкус лобстеров с теми кто их не ел :))


    № 550   31-07-2006 16:29 Ответить на это сообщение Ответить на это сообщение с цитированием
    Может быть повторю уже ранее кем-то сказанное, тады сорри. Но всё же...

    Мне кажется, что причины неприятия большинством программистов идей функционального программирования похожи на причины противостояния между программерами на Паскале и Си, только ещё более сильные.
    Ведь Паскаль и Си по сути очень похожи, что признавал ещё Ритчи. Однако мелкие различия в синтаксисе (begin/end против {}) и семантике (оператор присваивания ":=" против операции присваивания "=") разбили программистов на два непримиримых лагеря...

    А для программирования на том же Лиспе нужно уже иметь мышление, очень сильно отличающееся от мышления Паскалистов/Сишников... Когда в языке только (утрированно) два типа данных (атомы и списки) и, соответственно, только операции склеивания/разрезания/вычисления списков - естественно, "обычным" программистам трудно представить себе, что это такое и как с этим можно что-то сделать... Стереотипы, как тут уже упоминалось...

    Я сам лично плохо знаю ФП, да и знаком лишь с Лиспом чуток. Поэтому, я возможно и не прав, но...
    _______________________

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

    Допустим, некая функция А получает на входе список, содержащий тело какой-то функции Б. Что может сделать с этим списком функция А?

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

    Функция А может взять и поэлементно выполнить содержимое списка - вот вам простейший интерпретатор.

    А может и выдать в качестве результата какое-то преобразование входного списка - оптимизированный вариант функции Б или просто машинный код. Развёртка циклов и рекурсивных вызовов...

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

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

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

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


    № 549   31-07-2006 16:14 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 126« (Trurl)
    ___________________________

    Ответ на »сообщение 124« (Jack Of Shadows)
    ___________________________
    >>Не только в наше время. Вот занятный примерчик, которому лет 25.


    Уважаемый Trurl, код, приведённый Вами, не соответствует современному стандарту Алгола-68. :-)
    Вот как примерно он должен теперь (после 78 года) выглядеть:


    PROC queens = (INT k, PROC(INT, INT) BOOL safe, PROC VOID print func) VOID:
      IF k = 8 THEN
        print func
      ELSE
        INT p = k+1;
        FOR q TO 8 DO
          IF safe (p,q) THEN
            PROC safe new = (INT x, y) BOOL:
              IF y = q OR x-p = ABS(y-q) THEN FALSE ELSE safe(x, y) FI;
            PROC print new = VOID:
              (print func; print((",", "abcdefgh"[p], "12345678"[q])));
            queens(p, safe new, print new)
          FI
        OD
      FI;

    PROC safe ini = (INT x, y) BOOL: TRUE;
    PROC print ini = VOID: print(new line);

    queens(0, safe ini, print ini)



    По крайней мере, в таком виде он выполняется имеющимся у меня интерпретатором Algol-68Genie, и вот, что он выдаёт (после того, как я его причесал ;-) ):

    ,a1,b5,c8,d6,e3,f7,g2,h4
    ,a1,b6,c8,d3,e7,f4,g2,h5
    ,a1,b7,c4,d6,e8,f2,g5,h3
    ,....

    короче, 92 строки...

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

    Может быть, старичок Алгол-68, незаслуженно вытесненный Паскалем, ещё имеет шансы на возрождение?
    Раз он такой современно-функциональный? :о))

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

    Интересно, а в Аде можно? Там есть локальные блоки...


    № 548   31-07-2006 13:29 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 547« (hugi)
    ___________________________
    Ещё раз повторю вопрос: "Чем отличаются локальный функции и анонимные методы (анонимные классы в Java, так и быть, не рассматриваем) от closures?"

    Способом записи. Функционально однозначны, о том и речь.
    Это как 5 + 4 отличается от Add(5,4) - форма записи разная, однако функционально однозначны.

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

    Вы хотите сказать что не видите разницы в ФОРМЕ ЗАПИСИ непосредственной передачи блока кода и оформления его в виде локальной функции ?

    Если не видите, то наверное надо заканчиввать разговор на этом.
    Если видите, то тогда можно идти дальше и обсуждать почему форма записи имеет значение.

    Кстати если вы не заметили то мы с вами перешли с обсуждения макросов на обсуждение closures.
    Попробуйте поискать на этой ветке. Уже обсуждали и я приводил примеры.


    № 547   31-07-2006 12:28 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 546« (Jack Of Shadows)
    ___________________________
    Можно тоже самое сказать защищая языки без сборщика мусора.
    Вы, наверное, имеете в виду вызов деструктора для удаления объектов? Только я не понимаю, какое это имеет отношение к нашему случаю? Здесь речь идёт как раз о функциональных отличиях (в данном случае среды исполнения), а мы говорим о разных проявлениях одного и того же по сути механизма в разных языках, -- чисто синтаксические различия, семантика однакова. Так что сборщики мусора и передача блоков кода в функции -- проблемы совершенно разного уровня и абсолютно разного происхождения. Не надо сваливать всё в одну кучу.
    Если вы в ответ на приведенную мною запись приводите пример совершенно другого кода, но типа аналогичного по функциональности, то следующий для вас шаг привести этот же код на ассемблере.
    Совершенно другого кода?! Ещё раз прошу Вас привести список отличий моего кода от Вашего.
    Далее, приведу два примера аргументации в споре - ваш (Артем тоже этим все время грешит), и Макса
    Ваш:
    То есть со скобками, префиксной записью и прочими сопутствующими атрибутами? :)
    Макса:
    если в языке есть анонимные функции, то в чем преимущество?
    например вот http://boo.codehaus.org/Closures


    Спешу Вас разочаровать, приведённая Вами цитата из моего сообщения не рассматривалась мной в качестве аргумента. Разве это похоже на аргумент? Вы бы лучше по существу отвечали, чем выдёргивать фразы и выставлять их автора в невыгодном для него свете. Вас тоже есть в чём упрекнуть, поверьте, но, может всё-таки вместо взаимных упрёков будем приводить действительно стоящие аргументы в пользу своей позиции.
    Как видите, Макс не ерничает и не цепляется за скобки, прекрасно понимая, что под идентичной формой записи я имею в виду идею переджачи блока кода, а не конкретное расположение и количество скобок.
    Подождите, а я разве не понял, что Вы имеете в виду передачу блока кода? Тогда как Вы объясните вот это?:
    Точно также в функцию (пожалуй, это единственное отличие: у меня -- функция, у Вас -- макрос) передаётся экземпляр соединения и блок кода, оформленный в виде делегата. Полный доступ к локальным переменным гарантируется.
    Далее.
    Вы ведь тоже понимаете что речь идет о передаче блока кода, а не о том сколько скобок было при этом написано, но вместо ведения продуктивной дискуссии, когда мы все вместе двигаемся вперед, устраиваете бессмысленную склоку о скобках.
    Знаете, раздувать из мухи слона тоже не очень то красиво. Кроме Вас, я думаю, никто не упрекнёт меня в том, что я устраиваю "бессмысленную склоку о скобках" вместо "ведения плодотворной дискуссии". Я удивлён, что моё ироническое замечание привлекло столь незаслуженно привлекло Ваше внимание, в то время, как действительная аргументация осталась в стороне. Кстати, продиктованы мои слова были тем, что я не понял, в чём кардинальное отличие моего кода от Вашего, да и сейчас не понимаю, по правде говоря, а Вы так и не потрудились объяснить. Прискорбно...
    Так вот Макс совершенно прав. Данный конкретный пример идентично описывается closures.
    А теперь объясните мне, в чём кардинальное отличие столь часто упоминаемых Вами closures (пожалуй, русскоязычный термин "замыкание" действительно не очень подходит) от локальных функций в Delphi  и анонимных методов в C#?
    Однако ни в дельфи, ни в сишарп, ни в java - то есть в тройке основных языков, релевантных на этом сайте, closures нет.
    Ещё раз повторю вопрос: "Чем отличаются локальный функции и анонимные методы (анонимные классы в Java, так и быть, не рассматриваем) от closures?"
    Жду ответа.
     hugi


    № 546   30-07-2006 11:50 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 543« (hugi)
    ___________________________
    Скажите, только честно, это проблема? написать локальную функцию вместо куска кода? Вам ведь всего то нужно дописать три "лишних" слова procedure begin end. Всё!

    hugi, этот аргумент прекрасно подходит против любого языка.
    Можно тоже самое сказать защищая си против си++
    Можно тоже самое сказать защищая языки без сборщика мусора.
    "Разве вам так тяжело написать...."
    "Аналогичный по функциональности код..."

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

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

    Далее, приведу два примера аргументации в споре - ваш (Артем тоже этим все время грешит), и Макса
    Ваш:

    То есть со скобками, префиксной записью и прочими сопутствующими атрибутами? :)


    Макса:

    если в языке есть анонимные функции, то в чем преимущество?
    например вот http://boo.codehaus.org/Closures


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

    Так вот Макс совершенно прав. Данный конкретный пример идентично описывается closures.
    То есть макрос для того чтобы реализовать это - не нужен. Можно ТОЧНО ТАКЖЕ написать и при помощи closures.

    Совсем "не так как в лиспе", то есть нет скобок, то есть при записи придется использовать меток класса в качестве принимающей блок кода функции. Но он прав, я согласен. ТОЧНО ТАКЖЕ.
    Где вы видите "упертость на лисп" ?
    Вы тоже за деревьями скобок не видите леса идеи ?

    Что касается полной замены closures макросов, то этот конкретный пример ничего не доказывает конечно.
    Приведенный простейший пример, лишь один из многочиленных классов задач, решаемых макросами.
    И этот класс задач, совершенно аналогично по записи решается и при помощи closures.
    Однако ни в дельфи, ни в сишарп, ни в java - то есть в тройке основных языков, релевантных на этом сайте, closures нет.
    Но они есть во всех ФЯ, а также во многих динамических языках нового поколения (Ruby, Python (в новой версии 2.5), Boo)

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


    № 545   30-07-2006 09:29 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 535« (Jack Of Shadows)
    ___________________________
    >>>Это сколько же вам таких локальных функций надо создать с огромным количеством по возможности говорящих и понятных имен :))

    >>>Да еще все функции где то, вполне может быть даже не рядом с блоком, хотя работа там может быть мелкая.
    >>>Вы это называете "простота понимания" ?

    если в языке есть анонимные функции, то в чем преимущество?
    например вот http://boo.codehaus.org/Closures


    № 544   30-07-2006 05:02 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ужас! Мне эта дискуссия стала напоминать споры паскалистов с сишниками по поводу операторных скобок (сишники: "begin end -- громоздко!", паскалисты: "фигурные скобки нечитабельны!") -- Вы: "C# и Java громоздки!", Ваши противники: "Лисп нечитабелен!".
    Может, пора завязывать с Лиспом?! Тем более, как я уже говорил, прямого отношения к обсуждению ФП макросы не имеют.
     hugi


    № 543   30-07-2006 04:56 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 540« (Jack Of Shadows)
    ___________________________
    Спасибо! :))
    Прекрасный пример невероятной громоздкости сишарпа и java.

    И Вам спасибо! Невероятный пример абсолютной нечитабельности Лиспа.
    Да и вообще, когда Вам приводили примеры рекурсивных алгоритмов и организации рекурсивной обработки списков в ИЯ, Вы говорили то же самое. Может, пора придумать более весомые аргументы, тем более, что я, например, не вижу в только что приведённом мною коде какой либо громоздкости. Точно также в функцию (пожалуй, это единственное отличие: у меня -- функция, у Вас -- макрос) передаётся экземпляр соединения и блок кода, оформленный в виде делегата. Полный доступ к локальным переменным гарантируется. Покажите же мне теперь кардинальное отличие моего кода от Вашего.
    Не аналогичный по функциональности, а аналогичный по записи.
    То есть со скобками, префиксной записью и прочими сопутствующими атрибутами? :)
    Jack, у меня начинает складываться впечатление, что Вам нечего возразить, и что все Ваши аргументы исчерпаны. Остался только последний неопровержимый аргумент "это не как в Лиспе".
    Далее. Вернёмся к Вашему сообщению »сообщение 535«. Вы пишите:
    Ну это неправда. Ваш код в принципе не может быть похож на тот что я привел.
    Вы не можете передавать кусок кода.
    Вам приходится писать его отдельно в виде функции, а потом передавать функцию.
    Это во первых.

    Скажите, только честно, это проблема? написать локальную функцию вместо куска кода? Вам ведь всего то нужно дописать три "лишних" слова procedure begin end. Всё!
    В случае с C# ещё проще, кусок кода оформляется в анонимный метод (у меня в этот метод передаётся экземпляр соединения, но и этого можно не делать, объявив его локальным), т.е. практически никаких отличий! Но Вы настаиваете, что мой код не похож на Ваш! Что ж, жду списка несоответствий.
    Далее Вы пишете:
    Во вторых вы сильно ограничены сигнатурой передаваемой функции. Ваша функция возвращает код завершения.
    А это значит что всю полезную работу надо запихивать в нее.
    А как быть со случаями кодга надо просто вернуть из БД список, скажем для заполнения выпадающего списка ?
    Или не возвращать ничего а записать что то в бд. Причем что что находящееся в локальных переменных или локальных обьектах ? Ведь сигнатура то функции одна. Вы ограничены набором передаваемых параметров и их типами. Или вы все в глобальных держите ? чтобы ничего не передавать ?

    Как видите, эти Ваши слова совершенно безосновательны. Сигнатура функции (делегата в случае C#) не имеет никакого значения! Всё взаимодействие осуществляется через локальные переменные.

    Опять же:
    Это сколько же вам таких локальных функций надо создать с огромным количеством по возможности говорящих и понятных имен :))
    -- совершеннейшая неправда! Создаётся одна локальная функция, содержащая код работы с БД и передаётся в качестве параметра другой функции (не локальной) открывающей соединение, выполняющей код, закрывающей соединение (аналог Вашего макроса). Название локальной функции не имеет никакого значения (см. мой код на C#, там вообще АНОНИМНЫЙ(!) метод).
    Необходимость каждый селкий кусок кода, в котором нужно что то делать с БД, оформлять в виде ОДНОРАЗОВОЙ функции, то есть кодаЮ который вы нигде больше не будете использовать, вы называете "простотой использования" ?
    Локальные функции по своей природе одноразовые. Если функция используется во множестве мест, то её не делают локальной. Так что видите, Вы снова ошиблись.

    Так что, думаю, Сергей Перовский прав:
    Мы тут все очень часто этим грешим: то что я могу эффективнее решать некоторые задачи с помощью инструмента A, чем B зачастую говорит только о моем плохом знании B, а не преимуществах инструмента A.
     hugi


    <<<... | 562—553 | 552—543 | 542—533 | ...>>>
    Всего сообщений в теме: 5502; страниц: 551; текущая страница: 496


    Добавить свое сообщение

    Отслеживать это обсуждение

    Дополнительная навигация:
    Количество сообщений на странице

    Порядок сортировки сообщений
    Новое сообщение вверху списка (сетевая хронология)
    Первое сообщение вверху списка (обычная хронология)

    Перейти на конкретную страницу по номеру
      
    Время на сайте: GMT минус 5 часов

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

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования