All streams
Search
Write a publication
Pull to refresh
195
0
Михаил @mikhanoid

ИММ УрО РАН

Send message
Вы не правы, к сожалению. То, что вы описали не сводится к MT. Потому что я вам запросту предоставлю ввод, для которого вы не построите ленту для МТ, однако компьютеры с этим вводом будут работать. Например, пускай на вводе случайная величина. Если вы вы попытаетесь разместить последовательность её значений на ленте, то это (1) результирующая лента не будет случайной величиной и (2) для размещения на ленте потребуется бесконечно много времени.

Компьютер (MT c вводом\выводом) же может с такой последовательностью производить осмысленные операции, например, считать текущее математическое ожидание. А другая машина может этим пользоваться для своей активности, и так далее.

Классическая же МТ даже не сможет начать работать с этим входным потоком, ведь его изначально надо будет разместить на ленте.
Эмс, и какой из этих трёх стеков получается алгоритм, основанный на посылках сообщений друг дружке? И где тот объект, которому надо послать сообщений solve или move, чтобы он выдал объект - решение?
Вы забыли ещё один вопрос задать: как размещаются данные на ленте, которые формируют входящие данные? Математическая модель МТ ТРЕБУЕТ, чтобы ВСЕ данные были размещены ДО начала вычислений. Обычный современный компьютер в этом значительно отличается от классической МТ. Значительно, потому что модели алгоритмов, которые пытаются учесть это свойство, такие как МТ с регистром ввода/вывода, обладают существенно другими математическими свойствами, о которых уже было сказано.
Хм... А какие ещё объекты, например?
Речь о том, что из классических МТ сеть даже нельзя собрать. Из МТ с вводом/выводом - можно, и математические свойства у них совсем другие.
Не сводится. Потому что в процессор способен обрабатывать прерывания, а в память компьютера данные могут записываться устройствами ввода\вывода, во время работы программ. Для МТ это не так.
В формализме МТ нет никакого помещения данных на ленту. Данные выкладываются в начале работы, и впоследствии только машина их может менять. Считываются они по окончании. Во время работы никто не может новые данные классической машине предоставить. В этом суть математической абстракции. Машина со вводом/выводом - это уже совсем другая по своим математическим свойствам конструкция, которая берёт данные из вне во время своей работы.
Лента не служит для обмена данными. Это лишь устройство для хранения промежуточных данных во время работы алгоритма.
А вот и нет. Отсутсвие ввода/вывода - это серьёзная деталь классической МТ. Математическая модель МТ с регистром ввода/вывода - значительно отличается от классики. Например, среди таких машин нет универсальной машины, а сеть из них является гиперкомпьютером, то есть, способна решать алгоритмически неразрешимые на классической МТ задачи.
Можно, но линейный вариант не естественнен для этих подходов. Решения принимаются уводящие программу в другую сторону.
Так какая жизнь, так и пишу ( :

По делу. Рекурсия действительно не обязательна - последний вариант это показывает. Но в ФП и ООП рекурсивное решение кажется более естественным, в этом основная мысль. Потому что эти подходы как раз предполагают не синтез решения, а декомпозицию задачи, при этом сразу же. Я же утверждаю, что объекты при проектировании должны не навязываться сверху при проектировании, а возникать при реализации программы, проект которой заключается в описании необходимых преобразований над некими состояними (не автоматными), если в ходе проектирования и программирования этих преобразований будет видно, что возникают некие структуры из данных и алгоритмов, то это прямое указание на модульную декомпозицию, или на классовую, кому как удобнее. Но это следствие того, как происходят преобразования в программе, а не их причина. Не нужно, по моему глубокому убеждению, начинать проектирование с определения модулей и классов. Сами потом появятся.

Эмс... И про автоматы. Те состояния и их изменения, о которых я говорю, это не автоматные состояния и не автоматные изменения. Автомат - это опять же логическая конструкция с постоянными свойствами, которая должна возникать в процессе решения, а не навязываться сверху путём декомпозиции программы на множество этих самых автоматов. Потому что состояния у процессов могут быть потенциально бесконечными, а конечные автоматы с такими объектами оперировать не в состоянии. Нужны как минимум МП-автоматы, но это не панацея. Панацея - это сдвоенные МП-автоматы, которые тъюринг-полные. Которые, кстати, невозможны в рамках подхода иерархических конечных автоматов, которые предлагают авторы указанного Вами сайта.

Но даже если бы были - это же жутко неудобно. Попробуйте в этих автоматах выразить алгоритм пирамидальной сортировки. Конечно, во многих случаях динамика в программе описывается именно конечными автоматами, они очень полезный инструмент. Но во многих случаях они ничем не могут помочь, в преобразованиях данных возникают совсем иные структуры.
Где именно ересь? В том, что компьютер - больше машины Тьюринга? Так это очевидно: у МТ нет устройства для ввода/вывода, в том числе и для ввода/вывода новых программ, а у компьютера есть.

И на все три пункта. Цель не в том, чтобы сравнить языки по мощности, а в том, чтобы показать, как подходы к проектированию влияют на конечный результат. Там прямо в тексте написано, что линейный вариант с переименованием списков можно реализовать и на Haskell в виде функций над монадами (хоть это и потребует шаманства некоторого), и в виде объектов, но это не первая мысль, которая приходит в голову при построении программ в рамках функциональной и ОО парадигм. Первое, что приходит в голову - это разложение на очевидные объекты, которые мы берём из своего материального или математического представления о программе. Но на деле 'существующим' в процессе вычисления может быть нечто иное.

Без определения N можно просто запустить бесконечный цикл. На каждом шаге, конечно, списки будут конечными, но само вычисление может продолжаться бесконечно долго, конечно, оно будет не менее ресурсоёмким, чем рекурсия - понадобиться постепенное наращивание памяти и так далее. НО хоть какие-то результаты можно будет получать уже во время вычислений, а рекурсия будет просто молча бесконечно долго спускаться к решению.
Не так уж и далеко, если честно. До Inferno была Ada, был Oberon, была Lisp Machine, с точно такими же идеями. Сейчас есть JavaOS и Erlang. Они не новички в этом.

Inferno и Plan9 далеко ушли в другом: в эффективной и в простой для использования распределённости и в очень простом для программиста и пользователя API. Это действительно уникально и даёт много интересных возможностей.

Совсем не важно, на каком языке система написана, важно, что она позволяет делать.
Ну. Согласен с высокой производительностью I/0, она действительно не зависит, обычно, от способа исполнения программы, но иногда данные обсчитывать приходится, и тут уже Perl не поможет, как ни распараллеливай. Потому что, чем больше параллельности, с той целью, чтобы каждый процесс работал с небольшим объёмом работ, тем больше времени будет растрачиваться на обмен данными между узлами, что тоже занимает время. Иногда весьма значительное. Поэтому язык с 'толстыми' указателями и постоянной проверкой доступа к памяти, для таких задачек может и не подойти. А задачки есть такие. У меня по крайней мере, поэтому plan9.
Тык, чтобы коммьюнити была стойкой, она должна быть честной с самой собой. И не говорить, что plan9 - больше теоретическая, а Inferno - больше практическая. Видите, какая у меня, части community, ибо неравнодушен к 9p, реакция. И никакой идеологии в моих словах нет, скорее уж желание восстановить справедливость. Но, признаю свою ошибку, я не корректно выразился. Inferno и Plan9 одинаковые по интерфейсу к функциональности, по философии их использования, но созданы с разными целями. Поэтому говорить, что одно теоретическое, а другое практическое у нас нет оснований, они просто разные.
В Plan9 больше практики. Она эффективнее, и она реально используется. Скорее уж Inferno - это некая теория насчёт того, как можно сделать нечто легковесное, переносимое и надёжное. Но они жертвуют производительностью, значительно. Сервер на Inferno я бы поднимать не стал.
Конкретно в этом аспекте организации вычислений inferno полностью повторяет Plan9, документацию на которую можно раздобыть тут http://plan9.bell-labs.com/ . Можно почитать об идеологии и о том, как всё работает. Это я к тому, что документации мало.
Вам определённо следует учесть, что я прочитал 'Шаблоны' : ) И ничего нового для себя не открыл, всё то же самое, но не феноменологически: в этом случае делаем так, а в этом так, а в третьем задом-наперёд - а на гораздо более строгом и детальном уровне, в реальном коде, а не в стрелочках, описано у Бадда в 'ООП в действии' или у Голуба в 'правилах программирования на C и C++'.
Функциональное программирование больно той же самой болезнью: нужно проектировать задом наперёд. Сначала проектируется общий вид основной функции, а потом всё ниже и ниже проектируются вспомогательные. То же самое в ООП: сначала проектируем интерфейс, а потом пытаемся реализовать. И если интерфейс оказался неподходящим, то переделывать придётся весь код. Если высокоуровневая функция в функциональном подоходе оказалась неподходящей, то переделывать весь код придётся в гораздо большей степени, чем в императивном ООП.

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

C же освобождает от необходимости проектировать строго определённый интерфейс, конечно, от ответа на вопрос: что код должен делать? уйти вряд ли удасться, но ответ этот может быть достаточно нестрогим. Язык ориентирован на работу с данными, а не объектами. Если я совершу ошибку на этапе придумывания интерфейса, то мне никто не мешает напрямую залезть в структуру данных, и написать новый код для работы с ней, в том месте, где он нужен. Да, это грязно, это не математично, это нарушение кучи принципов, об этом не напишешь умную книжку, потому что это глупо, но это работет. И работает не только корректно, но и эффективно. Если подобный код мне нужен будет во многих местах - родилась абстракция - я его вынесу в соответсвующий модуль, и доступ к нему сделаю частью интерфейса.

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

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

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

Да, всё то же самое можно делать и на C++, например. Но тогда надо будет делать все данные и методы изначально открытыми, и возникает вопрос, а зачем тогда этот весь этот лишний классовый синтаксис?

Ещё можно сказать, что в Smalltalk именно так формировались интерфейсы. Они формировались снизу вверх. Они возникали, а не навязывались сверху. Наследования же вообще не было. Все эти, на мой взгляд, сложности, связанные с проектирование сверху вниз, появились в компилируемых языках, в которых для повышения эффективности стали путать типы и объекты.

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

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

Information

Rating
Does not participate
Registered
Activity

Specialization

System Software Engineer, scientific programming
Scheme
C
Assembler
Linux
Maths
Julia
Compilers
Math modeling
Machine learning
Computer Science