Можете ли вы реализовать какую-либо функцию чистого LISP, используя десять примитивов? (т.е. без предикатов типа) - PullRequest
9 голосов
/ 12 августа 2010

Этот сайт заявляет следующее: http://hyperpolyglot.wikidot.com/lisp#ten-primitives

McCarthy introduced the ten primitives of lisp in 1960. All other pure lisp 
functions (i.e. all functions which don't do I/O or interact with the environment) 
can be implemented with these primitives. Thus, when implementing or porting lisp, 
these are the only functions which need to be implemented in a lower language. The 
way the non-primitives of lisp can be constructed from primitives is analogous to 
the way theorems can be proven from axioms in mathematics.

The primitives are: atom, quote, eq, car, cdr, cons, cond, lambda, label, apply.

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

1 Ответ

14 голосов
/ 12 августа 2010

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

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

Ноль будет пустым списком или ().Один из них будет синглтон-против, или (() . ()).Два будет один плюс один или преемник единицы, где мы определяем преемника x как (cons () x), что, конечно, (() . (() . ())).Если вы принимаете Аксиому Бесконечности (и еще несколько, но в основном Аксиому Бесконечности для наших целей) и игнорируете ограничения памяти реальных компьютеров, это может точно представлять все натуральные числа.

Достаточно легко расширить это, чтобы представить все целые числа, а затем рациональные числа [1], но представить действительные числа в этой записи было бы (я думаю) невозможно.К счастью, это не умаляет нашего удовольствия, так как мы все равно не можем представить все реальное на наших компьютерах;мы обходимся поплавками и двойниками.Таким образом, наше представление столь же мощно.

В некотором смысле, 1 является просто синтаксическим сахаром для (() . ()).

Ура теории множеств!Ура для Lisp!

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

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

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

Итак, здесь, в Clojure (но использование только тех вещей, к которым у нас есть доступ в основном в нашем простом Лиспе, равно numberp. (Надеюсь,; не стесняйтесь поправлять меня, я неуклюжий как ад и т. д. оправдания и т. д.)

(defn numberp 
    [x]
      (cond 
        (nil? x) true
        (and (coll? x) (nil? (first x))) (numberp (second x))
        :else false))

[1] Для целых чисел, представьте их как минусы натуральных клеток. Пусть первый элемент в минусыячейка будет "отрицательной" частью целого числа, а второй элемент будет "положительной" частью целого числа. Таким образом, -2 может быть представлен как (2, 0) или (4, 2) или (5,3) и т. Д.Если говорить рационально, пусть они представляются в виде целых ячеек целых чисел: например, (-2, 3) и т. д. Это дает нам возможность иметь одну и ту же структуру данных, представляющую одно и то же число: однако это можно исправить, написав функцииэтот тест проверяет два числа, чтобы определить, эквивалентны ли они: мы определяем эти функции в терминах уже существующих теорий множеств отношений эквивалентности, предлагаемых нам.Прикольные вещи:)

...