Ввод/вывод на «математических» языках программирования [закрыто]

Я не раз наблюдал это: человек описывает функциональный язык программирования (в отличие от языка программирования, в котором интенсивно используются вкрапленные состояния), этот человек скажет, что он очень математический, поэтому мы должны использовать язык математики; затем, чтобы продемонстрировать, начинается: «Допустим, у нас есть функция f, которая принимает входные данные x и выдает выходные данные y...» или что-то в этом роде.

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

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

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

Однако я думаю, что возможен более фундаментальный конфликт. Как выразился Шопенгауэр в «Четырехкратном корне», существует проблема применения понятия «причинности» в физическом смысле к метафоре логической «причинности».

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

Хотя я вижу абзацы и форматирование (что является хорошим признаком), я не совсем понимаю, где вопрос философии . Хотя я вижу много заявлений о вычислениях. Не могли бы вы как-то выделить вопрос, который вы здесь задаете?
Добро пожаловать в философию! Это больше похоже на ответ, чем на вопрос — есть ли шанс, что вы можете попытаться уточнить, в чем именно заключается проблема, с которой вы столкнулись при изучении философии? Как ответ на этот вопрос выглядит в вашем воображении; что именно вы хотели бы, чтобы кто-то здесь вам объяснил (в нескольких абзацах)?
Привет спасибо! Может быть, мой вопрос был скорее ответом, чем вопросом, и, возможно, немного общим. Я действительно надеялся расширить свои исследования, получив в ответ ссылку по философии или истории. Ответ @CortAmmon был хорошим, но я подумал, что «все возможно», а «метафоры меняются» не совсем в точку, хотя они могли быть расширены. Раздел «Кратко» ответа Килана, хотя и основанный на мнении, был довольно хорошим планом. Ответ quen_tin был указан, но не имел вспомогательной ссылки. У FredBarker была ссылка, но он не совсем разобрался с проблемой.

Ответы (3)

Я не думаю, что мы на самом деле делаем что-то еще, кроме как используем разные слова для одного и того же. Если вы, например, посмотрите на функцию Haskellmod по модулю:

mod :: a -> a -> a

Математически функция по модулю имеет вид   Z × Z → N   (где Z — множество целых чисел; N — множество натуральных чисел, неотрицательных целых чисел).

Вы можете увидеть то же самое в Haskell, за исключением того, что они не различают Z и N, что математически правильно, и что они используют только стрелки вместо × и стрелки.

В математике мы называем левую часть стрелки доменом, а правую — кодовым доменом; в функциональном программировании мы называем левые входы, а правые — выходы.

Использование слов «ввод» и «вывод» в контексте функционального языка программирования ужасно , потому что изменение ввода и вывода и функциональные языки основаны на идее, что вещи не меняются. Когда вы используете фактический ввод и вывод (вещи, которые меняются), вы используете язык таким образом, который больше не является строго функциональным, с использованием монад . Однако, когда кто-то понимает концепцию функционального языка, я не думаю, что использование «ввода» и «вывода» может принести больше вреда, чем вызвать некоторую путаницу.

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

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

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

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

Короче говоря:

  • Я не думаю, что функциональные языки обращаются с функциями иначе, чем с математикой, хотя программисты могут использовать запутанные термины.
  • Разница во времени работы может быть значительно уменьшена за счет отложенного выполнения .
  • Физическая причинность, пытающаяся имитировать логическую причинность, безусловно, может вызвать проблемы, но мы еще не так далеко.
Я не думаю, что квантовые вычисления повернут вспять стрелу времени или что-то в этом роде, но мне интересно, могут ли они изменить понимание времени обработки с обратимыми операциями и тому подобным. С другой стороны, я только недавно начал использовать Clojure для написания веб-скриптов, но как бы отскочил от Haskell. Не могу не задаться вопросом, не пропущу ли я что-то из этого.
@dwn важное отличие состоит в том, что Clojure нечист, «в том смысле, что он не заставляет вашу программу быть ссылочно прозрачной и не стремится к «доказуемым» программам. Философия Clojure заключается в том, что большинство частей большинства программ должны быть функциональными» (из clojure.org/functional_programming ) — когда язык не полностью функционален, могут применяться разные вещи. Насколько я знаю, Haskell наиболее близок к полной функциональности. Однако это также усложняет использование, если вы не делаете что-то чисто математически.
@Keelan - Ну что, Идрис? Кок? Haskell на самом деле не самый функциональный, а просто самый функциональный из языков, которые, возможно, можно использовать в реальном мире (в том смысле, что он имеет библиотеки, может работать с вводом с клавиатуры и т. д.).
Дело не в том, что функциональные языки, даже чистые функциональные языки, обычно ленивы. Haskell в этом необычен. (Он также необычайно заметен среди чистых функциональных языков.)
@RexKerr спасибо, мои знания пока не достигают.
@ChristianConkle тоже спасибо, я этого не знал.

Ленивый ответ: Да, все возможно

Хорошо, теперь более длинный ответ

Я думаю, что разница в формулировках между «вводом/выводом» и «отображением» используется из-за побочных эффектов. Математические отображения не имеют побочных эффектов, это просто отображения. Разница между значением 1 и вычислением сложного уравнения в точке, которая соответствует 1, не имеет значения, если только вы не хотите работать с уравнением явно.

Языки функционального программирования стараются избегать побочных эффектов, чтобы достичь аналогичной математической чистоты. Однако есть побочные эффекты, которых нельзя избежать, например потребление вычислительных ресурсов. Это заставляет людей мыслить менее математическими терминами. Во-первых, в каждом функциональном языке программирования есть по крайней мере одно процедурное понятие «вычислить», которое запускает процесс. Это маленькое ядро ​​заставляет программистов мыслить немного иначе.

У функциональных программистов есть один веский аргумент: если мне нужно вычислить f(1, 2), ответ не изменится, если я вычислю f(1,2) и f(3, 4). Функциональный язык можно рассматривать как одновременное сосуществование всех значений по сравнению с процедурными языками, имеющими побочные эффекты, которые лишают нас возможности выполнять произвольный код.

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

Уже есть отличные примеры мест, где метафоры не работают. Рассмотрим в мире процедурного программирования многопоточность. Долгое время мы могли использовать машину фон Неймана как метафору нашего настоящего компьютера. Однако с современными атомарными операциями мы вынуждены признать наличие кэшей памяти и других вещей, которые не фигурируют в метафоре. C++ только что выпустил новую спецификацию, включающую атомарные операции. 90 % обработки атомных характеристик в спецификации теперь относится к вещам, которые нельзя объяснить с помощью машины фон Неймана. Решение заключалось в том, что C++ изобрел новую метафору: модель памяти C++11, которая приближается к тому, что делает современное оборудование. Когда эта модель не сработает, мы изобретем новую.

В математике часто говорят, что функция принимает входные данные и дает выходные данные. Функция является более ограничительной концепцией, чем общее отношение между двумя доменами: она будет отображать только одно значение в выходном домене на каждое значение входного домена (это отношение «многие к одному»). Это также определенная характеристика функций в функциональном языке программирования. Математическая функция, строго говоря, не является функцией программирования, но, основываясь на этих сходствах, она является полезной абстракцией для обращения к последней (в отличие от императивных языков, где некоторые функции могут возвращать разные значения в разное время, например, когда они используют переменные состояния или внешние входы, такие как часы). В любом случае между математикой и алгоритмикой существует тесная связь. Оба имеют одинаковые логико-математические основы.

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

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

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