stringtranslate.com

Неявное программирование

Неявное программирование , также называемое стилем без точек , представляет собой парадигму программирования , в которой определения функций не идентифицируют аргументы (или «точки»), на которых они работают. Вместо этого определения просто составляют другие функции, среди которых есть комбинаторы , которые манипулируют аргументами. Неявное программирование представляет теоретический интерес, поскольку строгое использование композиции приводит к программам, которые хорошо адаптированы для эквациональных рассуждений. [1] Это также естественный стиль некоторых языков программирования , включая APL и его производные, [2] и конкатенативные языки, такие как Forth . Отсутствие именования аргументов дает стилю без точек репутацию излишне непонятного, отсюда и эпитет «стиль без точек». [1]

Скрипты Unix используют парадигму с каналами .

Примеры

Питон

Неявное программирование можно проиллюстрировать следующим кодом Python . Последовательность операций, например, следующая:

 пример определения ( x ):  return  baz ( bar ( foo ( x )))

... может быть записано в бесточечном стиле как композиция последовательности функций без параметров: [3]

из  functools  import  partial ,  reduce def  compose ( * fns ):  return  partial ( reduce ,  lambda  v ,  fn :  fn ( v ),  fns )пример  =  составить ( foo ,  bar ,  baz )

Для более сложного примера код Haskell p = ((.) f) . gможно перевести как:

p  =  частичный ( составить ,  частичный ( составить ,  f ),  g )

Функциональное программирование

Простой пример (на Haskell ) — это программа, которая вычисляет сумму списка чисел. Мы можем определить функцию суммы рекурсивно, используя указанный стиль (ср. программирование на уровне значений ) как:

сумма ( x : xs ) = x + сумма xs сумма [] = 0         

Однако, используя складку, мы можем заменить это на:

сумма xs = фолдr ( + ) 0 xs      

И тогда аргумент не нужен, так что это упрощается до

сумма = фолд ( + ) 0    

который является бесточечным.

В другом примере используется композиция функций :

п х у z = ф ( г х у ) z         

Следующий псевдокод в стиле Haskell демонстрирует, как свести определение функции к ее эквиваленту без точек:

p = \ x -> \ y -> \ z -> f ( g x y ) z = \ x -> \ y -> f ( g x y ) = \ x -> \ y -> ( f . ( g x )) y = \ x -> f . ( g x ) ( * Здесь инфиксный оператор компоновки "." используется как каррированная функция . * ) = \ x -> (( . ) f ) ( g x ) = \ x - > ( ( ( . ) f ) . g ) x                                                                   р = (( . ) ф ) . г     

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

список операторов критериев mf = критерии фильтра ( список операторов карты )         

Это можно выразить без точек [4] как

mf = ( . map ) . ( . ) . filter       

Обратите внимание, что, как уже было сказано ранее, точки в «точечно-бесточечном» относятся к аргументам, а не к использованию точек; это распространенное заблуждение. [5]

Было написано несколько программ для автоматического преобразования выражения Haskell в бесточечную форму.

Семейство АПЛ

В J такой же тип бесточечного кода встречается в функции, созданной для вычисления среднего значения списка (массива) чисел:

средн. =: +/ % #   

+/суммирует элементы массива путем сопоставления ( /) суммирования ( +) с массивом. %делит сумму на количество элементов ( #) в массиве.

Формула Эйлера, выраженная молчаливо:

соз =: 2 о . ] грех =: 1 о . ] Эйлер =: ^@ j . = потому что j . грех              

( j.— примитивная функция, монадическое определение которой — 0j1умножить на x, а диадическое определение — x+0j1×y.) Те же самые неявные вычисления, выраженные в Dyalog APL :

средн. + ÷     cos 2 sin 1 EulerCalc cos + 0j1 × sin ⍝ 0j1 обычно записывается как i EulerDirect * 0J1 ×⊢ ⍝ То же, что и ¯12○⊢ ⍝ Дают ли эти 2 метода одинаковый результат? 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 функции — это компьютерные программы, которые получают данные из стандартного ввода и отправляют результаты в стандартный вывод . Например,

сортировка | uniq -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 | pow(.; .)

оценивается как 4, поскольку pow(x;y) — это x в степени y.

Последовательность Фибоначчи

Программа молчаливого jq для генерации последовательности Фибоначчи будет выглядеть так:

 [0,1] | рекурсия( [последний, добавить] ) | первый

Здесь [0,1] — начальная пара, которая будет взята в качестве первых двух элементов в последовательности Фибоначчи. (Пара [1,1] также может быть использована для определения варианта.)

Буквенные токены являются встроенными фильтрами: `first` и `last` выдают первый и последний элементы своих входных массивов соответственно; а `recurse(f)` рекурсивно применяет фильтр f к своим входным данным.

jq также позволяет определять новые фильтры в неявном виде, например:

 def fib: [0,1] | recurse( [last, add] ) | first;
Композиция унарных функций

В разделе, посвященном Python в этой статье, рассматривается следующее определение Python:

 пример определения ( x ):  return  baz ( bar ( foo ( x )))

В бесточечном стиле это можно записать на Python так:

пример  =  составить ( foo ,  bar ,  baz )

В jq эквивалентное определение без точек будет иметь вид:

 пример определения: foo | bar | baz;

Смотрите также

Ссылки

  1. ^ ab Мануэль Алсино Перейра да Кунья (2005) Расчет программы без баллов
  2. ^ W. Neville Holmes, ред. (2006) Компьютеры и люди
  3. ^ "Имя кода, а не значения". Concatenative.org . Получено 13 сентября 2013 г. .
  4. ^ pipermail
  5. ^ "Pointfree - HaskellWiki". wiki.haskell.org . Получено 2016-06-05 .

Внешние ссылки