Негласное программирование
Неявное программирование , также называемое бесточечным стилем , представляет собой парадигму программирования , в которой определения функций не идентифицируют аргументы (или «точки»), над которыми они работают. Вместо этого определения просто составляют другие функции, среди которых есть комбинаторы , манипулирующие аргументами. Неявное программирование представляет теоретический интерес, поскольку строгое использование композиции приводит к созданию программ, которые хорошо адаптированы для уравнений . [1] Это также естественный стиль некоторых языков программирования , включая APL и его производные. [2] и конкатенативные языки, такие как Форт . Отсутствие именования аргументов дает бесточечному стилю репутацию излишне неясного, отсюда и эпитет «бессмысленный стиль». [1]
Unix Сценарии используют парадигму с каналами .
Примеры [ править ]
Питон [ править ]
Неявное программирование можно проиллюстрировать с помощью следующего кода Python . Последовательность операций, например, следующая:
def пример ( x ):
return baz ( bar ( foo ( x )))
... можно записать в бесточечном стиле как композицию последовательности функций без параметров: [3]
из functools import частичный , уменьшить
def compose ( * fns ):
вернуть частичный ( сокращение , лямбда v , fn : fn ( v ), fns )
пример = составить ( foo , bar , baz )
Более сложный пример: код Haskell. p = ((.) f) . g
можно перевести как:
p = частичный ( сочинять , частичный ( сочинять , ж ), г )
Функциональное программирование [ править ]
Простым примером (на Haskell ) является программа, которая вычисляет сумму списка чисел. Мы можем определить функцию суммы рекурсивно, используя заостренный стиль (см. значений программирование на уровне ) следующим образом:
сумма ( x : xs ) = x + сумма xs
сумма [] = 0
Однако, используя складку , мы можем заменить это на:
сумма xs = foldr ( + ) 0 xs
И тогда аргумент не нужен, так что это упрощает
сумма = Foldr ( + ) 0
который является бесточечным.
В другом примере используется композиция функций :
п Икс y z знак равно ж ( грамм Икс y ) z
Следующий псевдокод в стиле Haskell показывает, как свести определение функции к ее бесточечному эквиваленту:
p = \ x -> \ y -> \ z -> f ( g x y ) z
= \ x -> \ y -> f ( g x y )
= \ x -> \ y -> ( f . ( g Икс )) y
знак равно \ Икс -> ж . ( g x )
( * Здесь инфиксный функция компоновки оператор "." как f каррированная . ) = * ) =
\ x - > (( . ) f ) ( g x \
( x - > (( . ) ) используется . г ) Икс
п знак равно (( . ) ж ) . г
Наконец, чтобы увидеть сложный пример, представьте себе программу фильтра карты, которая берет список, применяет к нему функцию, а затем фильтрует элементы на основе критерия.
mf критериев операторов Список = фильтра критерии ( карты операторов список )
Его можно выразить без точек [4] как
мф = ( . карта ) . ( . ) . фильтр
Обратите внимание, что, как указывалось ранее, точки в слове «без точек» относятся к аргументам, а не к использованию точек; распространенное заблуждение. [5]
Было написано несколько программ для автоматического преобразования выражения Haskell в бесточечную форму.
Семейство APL [ править ]
В J такой же бесточечный код встречается в функции, предназначенной для вычисления среднего значения списка (массива) чисел:
среднее =: +/ % #
+/
суммирует элементы массива путем сопоставления ( /
) суммирование ( +
) в массив. %
делит сумму на количество элементов ( #
) в массиве.
Формула Эйлера выразил молчаливо:
соз =: 2 о . ]
грех =: 1 о . ]
Эйлер =: ^@ j . = потому что j . грех
( j.
— это примитивная функция, монадическое определение которой есть 0j1
раз x и чье двоичное определение x+0j1×y
.) Те же неявные вычисления, выраженные в Dyalog APL :
avg ← + ⌿ ÷ ≢
cos ← 2 ○ ⊢
sin ← 1 ○ ⊢
EulerCalc ← cos + 0j1 × sin ⍝ 0j1 — это то, что обычно записывается как i
EulerDirect ← * 0J1 ×⊢ ⍝ То же, что ¯12○⊢
⍝ Дают ли два метода тот же результат?
EulerCheck ← EulerDirect = EulerCalc
EulerCheck ¯1 1 2 3
1 1 1 1
⍝ Да, пока все хорошо!
На основе стека [ править ]
В языках программирования, ориентированных на стек (и конкатенативных языках , большинство из которых основаны на стеке). [ нужна цитата ] ), обычно используются бесточечные методы. Например, процедура вычисления чисел Фибоначчи может выглядеть следующим образом в PostScript :
/fib
{
dup dup 1 eq exch 0 eq или нет
{
dup 1 sub fib
exch 2 sub fib
add
} if
} def
Трубопроводы [ править ]
Конвейер Unix [ править ]
В сценариях Unix функции представляют собой компьютерные программы, которые получают данные со стандартного ввода и отправляют результаты на стандартный вывод . Например,
сортировать | уникальный -c | сортировка -rn
представляет собой неявную или бесточечную композицию, которая возвращает количество своих аргументов и аргументов в порядке убывания количества. 'sort' и 'uniq' являются функциями, '-c' и '-rn' управляют функциями, но аргументы не упоминаются. Труба '|' является оператором композиции.
Из-за особенностей работы конвейеров обычно можно передавать только один «аргумент» за раз в виде пары стандартных потоков ввода/вывода. Хотя дополнительные дескрипторы файлов могут быть открыты из именованных каналов , это больше не является бесточечным стилем.
jq [ править ]
jq — это язык программирования, ориентированный на JSON, в котором '|' символ используется для соединения фильтров в конвейер знакомым способом. Например:
[1,2] | добавлять
оценивается как 3. (Да, массив JSON — это фильтр jq, который оценивается как массив.)
Хотя конвейеры jq похожи на конвейеры Unix, они позволяют входящие данные должны быть отправлены более чем одному получателю на Правая часть знака '|' как бы параллельно. Например, программа `add/length` вычислит среднее значение чисел в массиве, так что:
[1,2] | добавить/длина
оценивается в 1,5
Сходным образом:
[1,2] | [длина, добавить, добавить/длина]
оценивается как [2,3,1.5]
Точку ('.') можно использовать для определения точки крепления на правой части, например:
1 | [., .]
оценивается как [1,1]
и аналогично:
2 | пау(.; .)
оценивается как 4, поскольку pow(x;y) равен x в степени y.
Последовательность Фибоначчи [ править ]
Негласная программа jq для генерации последовательности Фибоначчи будет такой:
[0,1] | рекурсия([последний, добавить]) | первый
Здесь [0,1] — исходная пара, которую следует принять в качестве первых двух элементов. в последовательности Фибоначчи. (Пара [1,1] также может быть использована для вариант определения.)
Алфавитные токены представляют собой встроенные фильтры: «первый» и «последний». выдать первый и последний элементы своих входных массивов соответственно; и `recurse(f)` рекурсивно применяет фильтр f к своим входным данным.
jq также позволяет определять новые фильтры в неявном стиле, например:
защита фиб: [0,1] | рекурсия([последний, добавить]) | первый;
Композиция унарных функций [ править ]
В разделе Python этой статьи рассматривается следующее определение Python:
def пример ( x ):
return baz ( bar ( foo ( x )))
В бесточечном стиле это можно было бы записать на Python так:
пример = составить ( foo , bar , baz )
В jq эквивалентное бесточечное определение будет таким:
пример определения: foo | бар | баз;
См. также [ править ]
- Комбинаторная логика
- Конкатенативный язык программирования
- Программирование на функциональном уровне
- Joy (язык программирования) , современный высокомолчаливый язык.
Ссылки [ править ]
- ^ Перейти обратно: а б Мануэль Алсино Перейра да Кунья (2005) Расчет программы без очков
- ^ В. Невилл Холмс, изд. (2006) Компьютеры и люди
- ^ «Код имени, а не значения» . Concatenative.org . Проверено 13 сентября 2013 г.
- ^ пипермейл
- ^ «Pointfree — HaskellWiki» . wiki.haskell.org . Проверено 5 июня 2016 г.
Внешние ссылки [ править ]
- От программирования на функциональном уровне к бесточечному стилю
- Чистые функции в APL и J. Как использовать неявное программирование на любом APL-подобном языке.
- Закрытые аппликативные языки 1971–1976 и далее , у Джона В. Бэкуса (Публикации)