Re[4]: Решение проблемы двух ботинок
От: Mamut Швеция http://dmitriid.com
Дата: 26.12.11 11:14
Оценка:
М>>Здравствуйте, D. Mon, Вы писали:

DM>>>Да чего тут спорить. Си — молодой и динамично развивающийся язык, он появился намного позже лиспа и учел опыт предшественников, исправил их ошибки. Исчезли эти тормозные и жрущие память списки и сборка мусора. Благодаря новым достижениям компиляторостроения появился синтаксис, статическая типизация. Это большие шаги вперед!


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


A>статическая типизация нужна для верификации кода на стадии компиляции.



Для верификации очень маленького подмножества того, что код делает.


dmitriid.comGitHubLinkedIn
Re[2]: Почти оффтоп
От: HrorH  
Дата: 26.12.11 11:35
Оценка: +1
Здравствуйте, Mamut, Вы писали:


T>>Совершенно гениальная фраза из введения:


T>>"Proposals to use other languages sometimes have more obvious flaws in their arguments. An analysis of why Lisp should be used [398] is based on how that language overcomes some of the C-inherent problems, while overlooking its own more substantial weaknesses (rather like proposing that people hop on one leg as a solution to wearing out two shoes by walking on two)"


T>>Близкий к тексту перевод (в квадратных скобках -- мои комментарии):


T>>"Предложения использовать иные [кроме C] языки часто имеет существенные изъяны в своей аргументации. Как пример -- анализ преимуществ языка Lisp приведённый в [ссылка на статью какого-то лисповеда из Беркли] основан на том как средcтва этого языка позволяют преодолевать проблемы, присущие C, но при этом опускаются его [языка Lisp] гораздо более существенные недостатки (примерно как если бы кто-то предлагал людям прыгать на одной ноге как средство избежать необходимости носить два ботинка, когда ходишь на двух)"


M>Странно, что абсолюно верная фраза вызвала столько холивара


Холивар с самого начала был зря, каюсь.
Но меня удивляет другое. Почему никто не видит, что фраза эта с сюрпризом.
На первый взгляд кажется, что здесь говорится о том, что лисповед не упомянул в статье недостатки языка Лисп, и это было замечено автором книги. Все совершенно логично.
Но реально здесь сказано следующее: язык Lisp имеет более существенные недостатки, чем недостатки языка C, указанные в статье лисповеда.
Но сказано это неявно, это подрузамевается в самой констукции фразы. Это так называемая пресуппозиция.
Вообще фраза о том, что где-то чего-то нет, часто подрузамевает то, что это нечто там должно быть.
Я придрался именно к тому, что это неявное утверждение не доказывается, и даже не говорится, о каких недостатках идет речь.
Но у меня (уже позже) сложилось впечатление, что метафора так понравилась топикстартеру, что он сам не заметил тот неявный наезд, который позволил себе автор книги.
Re[3]: Почти оффтоп
От: Mamut Швеция http://dmitriid.com
Дата: 26.12.11 11:42
Оценка:
T>>>Совершенно гениальная фраза из введения:

T>>>"Proposals to use other languages sometimes have more obvious flaws in their arguments. An analysis of why Lisp should be used [398] is based on how that language overcomes some of the C-inherent problems, while overlooking its own more substantial weaknesses (rather like proposing that people hop on one leg as a solution to wearing out two shoes by walking on two)"


T>>>Близкий к тексту перевод (в квадратных скобках -- мои комментарии):


T>>>"Предложения использовать иные [кроме C] языки часто имеет существенные изъяны в своей аргументации. Как пример -- анализ преимуществ языка Lisp приведённый в [ссылка на статью какого-то лисповеда из Беркли] основан на том как средcтва этого языка позволяют преодолевать проблемы, присущие C, но при этом опускаются его [языка Lisp] гораздо более существенные недостатки (примерно как если бы кто-то предлагал людям прыгать на одной ноге как средство избежать необходимости носить два ботинка, когда ходишь на двух)"


M>>Странно, что абсолюно верная фраза вызвала столько холивара


HH>Холивар с самого начала был зря, каюсь.

HH>Но меня удивляет другое. Почему никто не видит, что фраза эта с сюрпризом.
HH>На первый взгляд кажется, что здесь говорится о том, что лисповед не упомянул в статье недостатки языка Лисп, и это было замечено автором книги. Все совершенно логично.
HH>Но реально здесь сказано следующее: язык Lisp имеет более существенные недостатки, чем недостатки языка C, указанные в статье лисповеда.
HH>Но сказано это неявно, это подрузамевается в самой констукции фразы. Это так называемая пресуппозиция.

По-моему, это из разряда школьных «Пушкин использовал в третьей строке пятой строфы шестой главы слово X потому что он считал, что...»

HH>Вообще фраза о том, что где-то чего-то нет, часто подрузамевает то, что это нечто там должно быть.

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

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


dmitriid.comGitHubLinkedIn
Re[4]: Почти оффтоп
От: HrorH  
Дата: 26.12.11 11:50
Оценка:
Здравствуйте, Mamut, Вы писали:

HH>>Но реально здесь сказано следующее: язык Lisp имеет более существенные недостатки, чем недостатки языка C, указанные в статье лисповеда.

HH>>Но сказано это неявно, это подрузамевается в самой констукции фразы. Это так называемая пресуппозиция.

M>По-моему, это из разряда школьных «Пушкин использовал в третьей строке пятой строфы шестой главы слово X потому что он считал, что...»


Совершенно верно. Это не из техники, а из гуманитарных наук. Я встретил это в НЛП, т.е. психологии.
Дело в том, что когда речь идет об умении думать, то необходимо заметить, что думает именно человек, а науки, которые занимаются человеком называются гуманитарными.
Кстати языки высокого уровня тем и интересны, что более подходят для развития человеческого мышления.
Re[5]: Почти оффтоп
От: Mamut Швеция http://dmitriid.com
Дата: 26.12.11 15:48
Оценка:
HH>>>Но реально здесь сказано следующее: язык Lisp имеет более существенные недостатки, чем недостатки языка C, указанные в статье лисповеда.
HH>>>Но сказано это неявно, это подрузамевается в самой констукции фразы. Это так называемая пресуппозиция.

M>>По-моему, это из разряда школьных «Пушкин использовал в третьей строке пятой строфы шестой главы слово X потому что он считал, что...»


HH>Совершенно верно. Это не из техники, а из гуманитарных наук. Я встретил это в НЛП, т.е. психологии.

HH>Дело в том, что когда речь идет об умении думать, то необходимо заметить, что думает именно человек, а науки, которые занимаются человеком называются гуманитарными.

Что думает именно человек, неизвестно никому, потому что чужая душа потемки


dmitriid.comGitHubLinkedIn
Re[7]: Решение проблемы двух ботинок
От: A13x США  
Дата: 26.12.11 19:33
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, __lambda__, Вы писали:


___>>Кстати, справедливости ради, компиляторы Common Lisp'а генерят очень эффективный нативный код.


VD>Скажем так. Иногда генерируют код сравнимый с эффективным. И почему речь о SBCL идет во множественном числе?


Вообще-то есть еще lispworks и allegro common lisp.
Re[5]: Решение проблемы двух ботинок
От: A13x США  
Дата: 26.12.11 19:40
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>...

М>2) почему компиляторы си и документация по языку разрослить до ужасно нескромных размеров?

Тут уже приводили как пример — tcc, не оптимизирующий компилятор с сумасшедшей скоростью компиляции — порядка 40 Мб кода в секунду.
Re[4]: Решение проблемы двух ботинок
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 27.12.11 06:18
Оценка:
Здравствуйте, Tilir, Вы писали:

T>

T>...
T> В языке "C" отсутствуют операции, имеющие дело непосредственно с составными объектами, такими как строки символов, множества, списки или с массивами, рассматриваемыми как целое. Здесь, например, нет никакого аналога операциям PL/1, оперирующим с целыми массивами и строками. Язык не предоставляет никаких других возможностей распределения памяти, кроме статического определения и механизма стеков, обеспечиваемого локальными переменных функций; здесь нет ни "куч"(HEAP), ни "сборки мусора", как это предусматривается в АЛГОЛЕ-68. Наконец, сам по себе "C" не обеспечивает никаких возможностей ввода-вывода: здесь нет операторов READ или WRITE и никаких встроенных методов доступа к файлам. Все эти механизмы высокого уровня должны обеспечиваться явно вызываемыми функциями.
T> Аналогично, язык "C" предлагает только простые, последовательные конструкции потоков управления: проверки, циклы, группирование и подпрограммы, но не мультипрограммирование, параллельные операции, синхронизацию или сопрограммы.
T> Хотя отсутствие некоторых из этих средств может выглядеть как удручающая неполноценность ("выходит, что я должен обращаться к функции, чтобы сравнить две строки символов ?!"), но удержание языка в скромных размерах дает реальные преимущества. Так как "C" относительно мал, он не требует много места для своего описания и может быть быстро выучен. Компилятор с "C" может быть простым и компактным
T>...


Так ведь говорится в контексте 70-х, когда каждая новая возможность вводилась с помощью нового языкового средства. K&R всего лишь указали, что возможности можно вводить с помощью библиотек, а язык прорабатывать в сторону увеличения мощности для написания этих библиотек. Сйчас это ясно кому угодно. Никто не пытается противопоставлять C некий язык блаб, потому что в блабе строки, списки и комплексные числа поддерживаются нативно. Вместо этого к C есть другие претензии. Ну как минимум — некто пишет фреймворк, где в числе прочего поддерживаются строки, списки и комплексные числа. Так почему функции для сравнения этих сущностей должны называться compare_strings, compare_lists, compare_complex_numbers, вместо того, чтобы всем дружно называться — compare?
Re[5]: Решение проблемы двух ботинок
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 27.12.11 06:30
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Для верификации очень маленького подмножества того, что код делает.


Зато это очень маленькое подмножество является очень благодатной почвой для ошибок.
Re[6]: Решение проблемы двух ботинок
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 27.12.11 06:50
Оценка:
Здравствуйте, konsoletyper, Вы писали:

K>Здравствуйте, Mamut, Вы писали:


M>>Для верификации очень маленького подмножества того, что код делает.


K>Зато это очень маленькое подмножество является очень благодатной почвой для ошибок.


Из чего это следует?
The God is real, unless declared integer.
Re[12]: Решение проблемы двух ботинок
От: batu Украина  
Дата: 27.12.11 09:44
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>зачем нам атомы, когда у нас есть пиксели? допустим, три пикселя каждая сторона и три пикселя диагональ. и чему будет равен угол? что-то мне подсказывает, что 90 градусов у нас никак не получается.


М>ничего мистического в диагоналях нет. допустим, квадрат 1 x 1. диагональ 2^1/2. если диагональ принять за единичный отрезок, то иррациональными становятся стороны.

Я хотел сказать о философской проблеме рациональных чисел и ее связи с возможностью измерять. Идея заключается в возможности разделить нечто на целое количество равных (не важно сколь угодно малых) частей. Если это возможно, то возможно и измерить. Так вот появление иррациональных чисел и доказывает что не все можно измерять. В частности диагональ квадрата. Это странно. Хотя и не к такому привыкали
Re[7]: Решение проблемы двух ботинок
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 27.12.11 11:01
Оценка:
Здравствуйте, netch80, Вы писали:

M>>>Для верификации очень маленького подмножества того, что код делает.


K>>Зато это очень маленькое подмножество является очень благодатной почвой для ошибок.


N>Из чего это следует?


Из опыта. Кстати, по поводу ошибок. Тут уместно говорить не столько об автоматическом отлове ошибок, сколько о том, как снизить вероятность их возникновения и приблизить время их обнаружения к месту, где они реально возникли. И тут уже вопрос не только о системе типов языка. Например, в том же C# есть нехорошая в этом смысле конструкция as, которую стараются избегать. Готов обсудить конкретные особенности конкретных языков, которые помогают или мешают легче обнаруживать ошибки.

Вот вам пожалуйста динамически типизированный язык javascript. В нём, если неправильно набрать имя переменной, получим значение undefined. Этот undefined может очень долго путешествовать по графу объектов, пока, например, кто-нибудь не попытается вызвать у него метод. В Ruby есть похожая штука, хорошо хоть в случае с локальными переменными это побороли.
Re[6]: Решение проблемы двух ботинок
От: Mamut Швеция http://dmitriid.com
Дата: 27.12.11 18:44
Оценка: :)
M>>Для верификации очень маленького подмножества того, что код делает.

K>Зато это очень маленькое подмножество является очень благодатной почвой для ошибок.


Безусловно. Что интересно, правильно составленные тесты позволяют выловить не только этот, но и более широкий класс ошибок, одним махом.

Сразу говорю, что тесты не панацея, а то тут начнут мне пенять, чем ни попадя.

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

Пока что единственное но — нет автоматического перехода от упавшего теста к нашалившей строчке в IDE/Emacs'е и нет автоматического запуска тестов по мере написания кода. Но, думаю, это еще впереди


dmitriid.comGitHubLinkedIn
Re[2]: Почти оффтоп
От: Klapaucius  
Дата: 10.01.12 09:08
Оценка: 18 (1) +1
Здравствуйте, Mamut, Вы писали:

M>Ведь если посмотреть почти на все холивары типа X vs. Y, где X и Y — два произвольно взятых языка, то они все моментально скатываются в: X — лучше, потому что в Y фича A сделана плохо, а в X фича А сделана хорошо. При этом таки да, недостатки языка X старательно замалчиваются или считаются несущественными.


А вам не кажется странным, что адвокат концентрируется на защите и совсем не уделяет времени обвинению своего клиента, а прокурор — наоборот — по какой-то причине не желает его защищать?

M>Смешно, что даже автор, который эту фразу нашел, и представил ее к нам сам скатился в точно такой же спор в C vs. Fortran и т.п.


Ну так эта фраза ему понравилась в той форме, что он нашел. И я сомневаюсь, что она понравилась ему, если бы она была такой:

Предложения использовать иные [кроме LISP] языки часто имеет существенные изъяны в своей аргументации. Как пример -- анализ преимуществ языка C приведённый в [ссылка на статью какого-то сиведа из Беркли] основан на том как средcтва этого языка позволяют преодолевать проблемы, присущие LISP, но при этом опускаются его [языка C] гораздо более существенные недостатки (примерно как если бы кто-то предлагал людям прыгать на одной ноге как средство избежать необходимости носить два ботинка, когда ходишь на двух)

В этом проблема такой фразы. Вот кто-то сказал "я прав, а ты ошибаешься" — и ему очень фраза понравилась. И тут ему отвечает кто-то другой: "я прав, а ты ошибаешься" — и та же самая фраза уже не кажется первому такой хорошей.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re: Решение проблемы двух ботинок
От: Klapaucius  
Дата: 10.01.12 09:08
Оценка:
Здравствуйте, Tilir, Вы писали:

T>Относительно каждой строчки стандарта C99 обсуждаются причины почему она должна быть именно такой и не иначе


А причины, почему она должна была быть не такой, а иной обсуждаются?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[3]: Решение проблемы двух ботинок
От: Klapaucius  
Дата: 10.01.12 11:49
Оценка: +1
Здравствуйте, Tilir, Вы писали:

T>Речь идёт о том что программирование это инженерная дисциплина в которой нельзя что-то получить чем-то не заплатив.


Это-то, конечно, верно. Зато вполне можно что-то заплатить и не получить за это ничего, ну или меньше, чем в принципе возможно. И не просто "можно". Из-за ранних этапов развития программирования как инженерной дисциплины такое происходит постоянно.

T>Получаете скорость разработки -- платите объёмом кода, получаете высокоуровневые примтивы -- платите быстродействием и так далее. Без вариантов. Решатель проблемы двух ботинок это человек который предлагает нечто новое и по его мнению лучшее (ага мы теперь не будем вынуждены носить два ботинка -- ну там не заботится о памяти, иметь функции как объекты первого класса, у нас будет паттерн матчинг и т.дю) -- при этом не осознавая настоящей инженерной цены этого решения (мелким шрифтом -- только прыгать придётся на одной ноге, треть времени программы у нас будет орудовать сборщик мусора, а для написания hello world -- вам придётся учить теорию категорий).


Если учесть общие темпы развития и консерватизм отрасли, сложно предположить, что такие персонажи — реальная проблема. Более реальная проблема — это персонажи, отвергающие нечто новое, по их мнению ненужное, при этом не осознавая настоящей инженерной цены этого решения.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[4]: Решение проблемы двух ботинок
От: Undying Россия  
Дата: 12.01.12 05:53
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>как минимум очевидна чуть другая формулировка:

DG>(при прочих равных) лучше тот язык, который позволяет записать решение меньшим кол-вом бит.

Лучше тот язык, который позволяет записать решение меньшим количеством сущностей. Биты здесь вообще не в тему.
Re[8]: Решение проблемы двух ботинок
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.01.12 07:04
Оценка:
Здравствуйте, konsoletyper, Вы писали:

M>>>>Для верификации очень маленького подмножества того, что код делает.

K>>>Зато это очень маленькое подмножество является очень благодатной почвой для ошибок.
N>>Из чего это следует?
K>Из опыта.

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

K> Кстати, по поводу ошибок. Тут уместно говорить не столько об автоматическом отлове ошибок, сколько о том, как снизить вероятность их возникновения и приблизить время их обнаружения к месту, где они реально возникли.


Спасибо, кэп (tm)

K> И тут уже вопрос не только о системе типов языка. Например, в том же C# есть нехорошая в этом смысле конструкция as, которую стараются избегать. Готов обсудить конкретные особенности конкретных языков, которые помогают или мешают легче обнаруживать ошибки.


А что в ней не так?

Я могу рассказать грабли только Python и Erlang. Ну ещё проругаться в общем на Perl. По отношению к остальным я не считаю себя вправе сейчас рассказывать что-то системное.

K>Вот вам пожалуйста динамически типизированный язык javascript. В нём, если неправильно набрать имя переменной, получим значение undefined.


Да, javascript — кошмарный ужас, причём не только из-за таких примеров. Тут в соседней ветке обсуждалось. Когда "5" + 3 == 53, но "5" — 3 == 2, авторов языка следует изгонять на Лабрадор. В нормальном языке неявные конверсии типов, такие, как между строкой и числом, должны быть запрещены.

Но не только с ним тут грабли. Я сейчас перечитываю "Рефакторинг" Фаулера. Там в начале есть пример ошибки в коде на Java, выловленной только тестом, от неявной конверсии double -> int.

K> Этот undefined может очень долго путешествовать по графу объектов, пока, например, кто-нибудь не попытается вызвать у него метод. В Ruby есть похожая штука, хорошо хоть в случае с локальными переменными это побороли.


Жуть.
The God is real, unless declared integer.
Re[5]: Решение проблемы двух ботинок
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 12.01.12 11:18
Оценка: +1
DG>>как минимум очевидна чуть другая формулировка:
DG>>(при прочих равных) лучше тот язык, который позволяет записать решение меньшим кол-вом бит.

U>Лучше тот язык, который позволяет записать решение меньшим количеством сущностей. Биты здесь вообще не в тему.


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

ты сейчас о каком из них?
если минимизировать первое — то лучшим ЯП становится: машина тьюринга, там всего две сущности в алфавите: 0 и 1
если минимизировать второе — то лучшим ЯП становится: ЯП с бесконечным алфавитом, когда все программы записываются одним символом из этого алфавита.

обе крайности плохие: в первом случае, требуется неограниченное время на анализ конкретной программы, во втором случае — требуется неограниченное время на изучение алфавита.
Re[9]: Решение проблемы двух ботинок
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 12.01.12 11:35
Оценка:
Здравствуйте, netch80, Вы писали:

K>> И тут уже вопрос не только о системе типов языка. Например, в том же C# есть нехорошая в этом смысле конструкция as, которую стараются избегать. Готов обсудить конкретные особенности конкретных языков, которые помогают или мешают легче обнаруживать ошибки.


N>А что в ней не так?


В ней — это в конструкции as из C# или в чём-то другом. На всякий случай про C# (хотя это уже везде, где можно, обсуждали). При обычном касте (который синтаксически аналогичен оному из C) CLR кидает исключение, если объект не принадлежит к классу, что понятно описывает ошибку. Если же использовать as, то ошибка произойдёт только при попытке обратиться к null, который получится в результате. Это null может очень долго путешествовать по графу объектов, прежде чем у него решат чего-нибудь вызвать. Оно понятно, что для каждой конструкции есть своё применение, но вот процент случаев, когда благодаря as код становится короче, очень невелик. По крайней мере, он меньше процента вероятности получить ошибку по причине наличия as не по месту, потому я вообще не использую такие конструкции. И заставляю IDE на них громко материться.

K>>Вот вам пожалуйста динамически типизированный язык javascript. В нём, если неправильно набрать имя переменной, получим значение undefined.


N>Да, javascript — кошмарный ужас, причём не только из-за таких примеров. Тут в соседней ветке обсуждалось. Когда "5" + 3 == 53, но "5" — 3 == 2, авторов языка следует изгонять на Лабрадор. В нормальном языке неявные конверсии типов, такие, как между строкой и числом, должны быть запрещены.


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

По поводу конверсии. Конверсии число -> строка вполне допустимы. Ошибки, которые возникают из-за конверсии, вполне отлавливаются системой типов. Ну за исключением случаев, когда результат неявно приводится к вышестоящему типу (java.lang.Object, например). Ну а автоматическая конверсия строк во что угодно — действительно зло.

N>Но не только с ним тут грабли. Я сейчас перечитываю "Рефакторинг" Фаулера. Там в начале есть пример ошибки в коде на Java, выловленной только тестом, от неявной конверсии double -> int.


Наверное, из double в int. А можно пример?

K>> Этот undefined может очень долго путешествовать по графу объектов, пока, например, кто-нибудь не попытается вызвать у него метод. В Ruby есть похожая штука, хорошо хоть в случае с локальными переменными это побороли.


N>Жуть.


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