LINUX.ORG.RU
ФорумTalks

Про сложность языков программирования

 , , ,


1

1

Невеяло видео:
Что бесит программиста | Анастасия Лукьяненко
Ravens - Intelligent Rascals of the Skies | Free Documentary Nature
Если ворон сумел освоить тачскрин, то скоро его наймут писать софт для андроида. Ну или хотя бы веб-приложухи на JS.

Если серьезно, то мне не дает покоя недавнее обсуждение сложности отдельных конструкций в ЯП:

programming languages performance benchmarks (комментарий)

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

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

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

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

  • если программа успешно отработала на одном наборе входных данных, то нет никакой гарантии, что она успешно отработает на другом наборе входных данных;
  • для достаточно сложной программы нет способа узнать, где произошла ошибка на прошлых циклах вычисления, если у нас есть только состояние текущего цикла вычисления;
  • машина Тьюринга — кусок дерьма с плохо предсказуемыми свойствами.

Есть ли выход из Тьюринг-западни? То есть, существуют ли/можно ли создать инструменты, на которых сможет достаточно эффективно писать даже умственно осталая мартышка? Очевидно, есть Тьюринг-неполные языки, которые просты и достаточно мощны для некоего узкого набора задач. Регулярные выражения, SQL, в конце-концов подмножества обычных ЯП, или какая-нибудь Clojure, построенная на персистентных структурах данных с очень хорошей предсказуемостью поведения и ограничением применения макросов. Даже Rust в каком-то смысле тоже попытался пойти именно по этому направлению, то есть, через ограничение применения изменяемого состояния, характерного для Тьюринг-машины.

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

Или когда пользователь хочет отсортировать некий массив или даже банально посчитать сумму, ему совсем не обязательно писать цикл, ему не нужно проходить по массиву последовательно от первого элемента до последнего — исходный порядок здесь не имеет значения. Но Тьюринг-машины научили нас, что действия должны выполняться строго последовательно, и нынче никто уже никто не ставит под сомнение такой подход. Функциональные языки, даже весьма «чистые», имеют функции reduce, но я не видел еще ни одного языка, который имел бы реализацию reduce, безразличную к порядку прохода по элементам, вроде иерархического агрегирования аки агрегатные функции в SQL.

Одна из относительной свежих попыток решить эту проблему для разработки фронтэнда — React.js. Не Angular, который значительно сложнее и мартышку за него не посадишь, а именно React, который если и тьюринг-полон, то эту тьюринг полноту непросто достичь. С позиции программиста-пользователя React, имеет тупейше прямолинейное преобразование данных в отображение, и такую же простую функциональность для измения состояния по событиям пользователського ввода, причем, механизм «ввод->изменение модели» развязан с механизмом «модель->данные», и оба они развязаны между отдельными компонентами, потому косяки реализации мартыхой одного компонента не рушат другой.

Продолжайте список, какие инструменты/приемы вы знаете или о каких вы думали/мечтали.

PS: давно хочу вкатиться в ограниченное подмножество C++ без наследования, без зубодробильных шаблонов, с минимумом исключений. Потому что на Си неудобно писать без обобщений и замыканий. Буду благодарен за литературу и/или готовые опенсорсные проекты, реализованные в подобном стиле. Знаю, что Unity сделан в этом духе, но беда в том, что Unity проприетарен.

★★★★
Ответ на: комментарий от snake266

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

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

Ушли с ЛОРа. Не кастовать.

Вы уж определитесь, ушельцы вы или нет. Или только некоторые?

Хотя мы-то ведь знаем, что с лора не уходят.

Nervous ★★★★★
()

По сабжу

Сложность не в языках, а в задачах. Если для задач не хватает языков с ограниченной Тьюринг-полнотой — значит:

1​) языки с Тьюринг-полнотой всё равно нужны;

2​) макаки такие задачи всё равно не осилят;

3​) для узких задач, где без Тьюринг-полноты можно обойтись, уже и так успешно создаются специализированные языки.

Итого: программисты не опасносте, а вот макаки-вайтишники да.

mertvoprog
()
Последнее исправление: mertvoprog (всего исправлений: 1)
Ответ на: комментарий от Nervous

с лора не уходят

Ну почему, Нас отсюда таки ушли.

А потом отсюда ушли @Dimez — и всё вернулось восвояси.

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

А никто не спорит, что какой-нибудь клей для тьюринг-неполных конструкций нужно писать на чем-то тьюринг-полном. Но для большей части кода тьюринг-неполных конструкций более чем достаточно, а они могут быть намного, намного проще.

В поисках серебряной пули, путь запретов и упрощений. Серия 100500-я. Ничему люди не учатся.

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

В поисках серебряной пули, путь запретов и упрощений. Серия 100500-я. Ничему люди не учатся

Напомнишь мне, какие там были предыдущие серии?

byko3y ★★★★
() автор топика

Хочется опровергнуть собственный аргумент про «я не знаю про безразличные к порядку элементов функции агрегирования» — я хаскеле эта штука пишется довольно несложно:

foldt            :: (a -> a -> a) -> a -> [a] -> a
foldt f z []     = z
foldt f z [x]    = x
foldt f z xs     = foldt f z (pairs f xs)
 
pairs            :: (a -> a -> a) -> [a] -> [a]
pairs f (x:y:t)  = f x y : pairs f t
pairs f t        = t

Вот и всё, можно считать сумму/среднее/минимум/максимум «ёлочкой».

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

Не понимаю смысла в этом. Всё равно ведь проход по списку не параллелизуется.

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