LISP 머신을 구축하려면 얼마나 많은 프리미티브가 필요합니까? 10, 7, 5?


80

이 사이트에는 10 개의 LISP 프리미티브가 있다고합니다. 기본 요소는 다음과 같습니다 atom, quote, eq, car, cdr, cons, cond, lambda, label, apply..

http://hyperpolyglot.wikidot.com/lisp#ten-primitives

Stevey는 7 개 (또는 5 개)가 있다고 생각합니다.

LISP 아이디어의 순수함의 일부입니다. 전체 머신을 구축하려면 7 개 (또는 5 개입니까?) 기본 요소 만 필요합니다. http://steve-yegge.blogspot.com/2006/04/lisp-is-not-acceptable-lisp.html

LISP 머신을 구축하기위한 최소 프리미티브 수는 얼마입니까 (즉, LISP 코드에서 평가 / 값 함수를 실행할 수있는 것)? (그리고 그들은 어떤 것입니까?)

(당신이없이 살 수 있다는 것을 이해할 수 있습니다 atom, label and apply)

답변:


58

기본 술어 / F 함수

McCarthy기본 S- 함수 및 술어 는 다음 같습니다.

  1. atom

    car와 cdr은 목록에 대해서만 정의 되었기 때문에 필요했습니다. 즉 car, 원자 를 주면 무슨 일이 일어 났는지 나타내는 어떤 종류의 대답도 믿을 수 없습니다 .

  2. eq

    원자 간의 평등을 테스트합니다.

  3. car

    단점 셀의 전반부 (주소)를 반환합니다. (주소 레지스터의 내용).

  4. cdr

    단점 셀의 후반 (감소)을 반환합니다. (감소 레지스터의 내용).

  5. cons

    새로운 cons 셀을 만들기 위해 주소 half는 cons에 대한 첫 번째 인수를 포함하고 감소 절반은 두 번째 인수를 포함합니다.

함께 묶기 : S-Functions

그런 다음 기본 표기법을 추가하여 S- 함수라고 부르는 것을 작성할 수있게했습니다.

  1. quote

    평가하지 않고 표현을 표현하는 것.

  2. cond

    이전에 설명한 술어와 함께 사용할 기본 조건입니다.

  3. lambda

    기능을 나타냅니다.

  4. label

    그는 재귀를 위해 이것을 필요로하지 않았지만, Y-Combinator 에 대해 알지 못했을 수도 있습니다 ( 폴 그레이엄에 따르면 ), 그는 편의와 쉬운 재귀를 가능하게하기 위해 이것을 추가했습니다.


그래서 그가 실제로 Lisp 머신에 대해 9 개의 기본 "연산자"를 정의한 것을 볼 수 있습니다. 다른 질문에 대한 이전 답변 에서이 시스템 으로 숫자표현하고 조작 하는 방법을 설명했습니다 .

그러나이 질문에 대한 답은 Lisp 머신에서 원하는 것이 무엇인지에 달려 있습니다. label기능적으로 모든 것을 구성하고 Y-Combinator를 적용하여 재귀를 얻을 수 있으므로 함수 없이 구현할 수 있습니다.

atomcar반환 할 원자에 대한 작업을 정의한 경우 버릴 수 있습니다 NIL.

기본적으로 이러한 9 개의 정의 된 기본 요소 중 7 개가있는 McCarthy의 LISP 시스템을 가질 수 있지만, 자신에게 얼마나 많은 불편을 끼치고 싶은지에 따라 표면적으로 더 간결한 버전을 정의 할 수 있습니다. 나는 그의 기계가 아주 훌륭하거나 Clojure와 같은 새로운 언어의 많은 원시를 좋아합니다.


19
McCarthy가 Y-Combinator에 대해 몰랐다는 제안은 잘못된 것 같습니다. "재귀 함수 ..."의 7 페이지에서 McCarthy는 다음과 같이 씁니다. 변수를 사용하지 않고 함수를 결합하기 위해 결합 자라고하는 연산자를 포함하는 표기법이 있습니다. 불행히도 흥미로운 함수 조합에 대한 조합 식은 길고 읽을 수없는 경향이 있습니다.
luser droog 2011-08-20

1
여기에 뭔가 빠진 것이 있습니다. 그러한 lisp는 두 개의 숫자를 더할 수 없으며 12가 숫자라는 것을 이해할 수도 없습니다.
Albert van der Horst

1
참으로 할 수 있습니다! 나도 블로그 글을 썼다. blog.isaachodes.io/p/set-theory-and-lisp
이삭

1
확실히, 그것은 정수의 전통적인 기계 표현을 사용하지 않을 것이고 결과적으로 오히려 비효율적 일 것입니다.
Isaac

14

이것을 확실히 아는 가장 좋은 방법은 구현하는 것입니다. Brainfuck에서 실행되는 McCarty-ish LISP 인 Zozotez 를 만들기 위해 3 개의 여름을 사용 했습니다 .

나는 내가 필요한 것을 찾으려고 노력했고 포럼에서 당신은 람다 만 필요하다는 스레드를 찾을 것 입니다. 따라서 내가 원하는 람다 미적분으로 전체 LISP를 만들 수 있습니다. 나는 그것이 흥미 롭다는 것을 알았지 만 결국 부작용이 있고 현실 세계에서 작동하는 것을 원한다면 갈 길은 거의 없습니다.

Turing 완전한 LISP를 위해 저는 McCarthy의 논문에 대한 Paul Grahams의 설명을 사용 했으며 실제로 필요한 것은 다음과 같습니다.

  • 기호 평가
  • 특별 양식 견적
  • 특수 형식 if (또는 cond)
  • 특수 형식 람다 (따옴표와 유사)
  • 함수 eq
  • 기능 원자
  • 기능 단점
  • 기능 차
  • 기능 cdr
  • 함수 디스패치 (list-lambda)

10.이 외에도 드로잉 보드뿐만 아니라 테스트 할 수있는 구현을 가지려면 :

  • 기능 읽기
  • 기능 쓰기

Thats 12. 내 Zozotez에서 나는 세트와 flambda (람다와 같은 익명 매크로)도 구현했습니다. 파일 I / O를 제외하고 동적 바인딩 된 lisp (Elisp, picoLisp)를 구현하는 라이브러리를 제공 할 수 있습니다 (기본 BF가 stdin / stdout 이외의 것을 지원하지 않기 때문에).

언어 구현 방법을 완전히 이해하려면 LISP와 (LISP가 아님) 모두에서 LISP1 인터프리터를 구현하는 것이 좋습니다. LISP는 구문이 매우 간단하므로 파서의 좋은 시작점입니다. 저는 현재 다른 타겟 (예 : 스탈린이 타겟 C를위한 것)으로 작성된 스킴 컴파일러를 작업 중입니다. 바라건대 BF가 그 중 하나입니다.


3
람다 만 사용하는 경우에는 "하나의 명령어 세트 컴퓨터", "NAND 논리", "SKI
결합기

2
@ ajm475du 모두 "당신은 람다 만 필요합니다"와 동일합니다. 완전 튜링이지만 I / O 부족으로 사용하기 거의 불가능합니다. BF는 튜링을 완료하는 데 6 개의 지침 만 필요합니다. 나머지는 실용적입니다.
Sylwester 2014 년

1
흠. bf 인터프리터의 stdin / stdout을 file / io 명령을 해석 할 수있는 다른 프로그램에 연결하면 어떻게됩니까? 그런 다음 bf-lisp는 요청을 작성한 다음 요청 된 파일에서 읽을 수 있습니다.
luser droog

2
@luserdroog 당신이 제안하는 것은 시스템 호출을 구현하기 위해 일부 프로그램 / OS에 대한 메시지 버스로 stdin / stdout을 사용하는 것입니다. 실제로 BF로 컴파일되는 컴파일러에 대해 그렇게 할 생각입니다. 예 : 읽기 / 쓰기보다 더 많은 I / O를 사용하는 경우 프로그램은 마법의 요구 사항 문자열을 보내고 API는 90 년대에 DOS에서 Windows 프로그램을 실행할 때 오류가 발생한 것과 거의 동일한 방식으로 핸드 헤이 크를 제공합니다. BF는 여전히 터미널을 제공해야하므로 I / O를 시작해야하므로 추가 확장 일뿐입니다.
Sylwester

10

맥카시는 원래 리스프를 정의하는 일곱 연산자를 사용 : quote, atom, eq, car, cdr, conscond. 이 기사는 그의 발걸음을 되돌아갑니다.


1
그는 실제로 사용할 label필요는 없었지만를 사용 했습니다.
Isaac

2
그리고 그는 또한 필요 lambda했습니다.
Isaac

9
나도 처음에는 이것에 대해 혼란 스러웠지만, 그는 실제로 주어진 일곱 가지 기본 요소를 정의 lambda하고 label있습니다. 그는 정의의 구현을 제공하기 전에 말하고자하는 것을 그는 단지 소개 eval섹션 4에 당신의 구현 것을 볼 수 있습니다 eval에 대한 지원 제공 lambda/를 list자체가 하나에 의존하지 않고.
amalloy

8

FAQ는 다음과 같이 설명합니다.

하나의 "최상의"최소 프리미티브 세트는 없습니다. 그것은 모두 구현에 달려 있습니다. 예를 들어, 숫자처럼 기본적인 것조차도 원시적 일 필요는 없으며 목록으로 표현할 수 있습니다. 하나의 가능한 프리미티브 세트에는 S- 표현식 조작을위한 CAR, CDR 및 CONS, S- 표현식의 입력 / 출력을위한 READ 및 PRINT, 인터프리터의 내장을위한 APPLY 및 EVAL이 포함될 수 있습니다. 그러나 함수에는 LAMBDA, 같음에는 EQ, 조건에는 COND, 할당에는 SET, 정의에는 DEFUN을 추가 할 수 있습니다. QUOTE도 유용 할 수 있습니다.

그것은 Carnegie Melon 웹 사이트의 School of Computer Science에서 온 것입니다.


2

Paul Graham은 seven을 사용하여 eval을 구현 합니다.

McCarthy의 LISP 용 Micro Manual에서 그는 ten을 사용하여 eval을 구현 합니다.


2

당신은 단지 86 필요한 MOV지시를 .

"M / o / Vfuscator (짧은 'o',"mobfuscator "처럼 들림)는 프로그램을"mov "명령어와"mov "명령어로만 컴파일합니다. 산술, 비교, 점프, 함수 호출 및 기타 프로그램에 필요한 모든 것은 모두 mov 작업을 통해 수행됩니다. 자체 수정 코드, 전송 트리거 계산 및 다른 형태의 비 움직임 부정 행위가 없습니다. "

진지하게,이 프리미티브는 Lisp Machine을 구현하지 않을 것입니다. 기계에는 I / O 및 가비지 콜렉션과 같은 기능이 필요합니다. 함수 호출 메커니즘은 말할 것도 없습니다! 좋아요, 함수 인 7 개의 기본 요소가 있습니다. 기계는 어떻게 함수를 호출합니까?

이러한 프리미티브가 무엇을 가능하게하는지에 대한 적절한 이해 는 Universal Turing Machine 의 명령어 세트를 노출 한다는 것 입니다. 그 지시는 "Lispy"이기 때문에 (Lisp로 말하는) 혀의 미끄러짐에 의해 우리는 이것을 "Lisp Machine"이라고 부릅니다. "Universal"은 기계를 프로그래밍 할 수 있음을 의미합니다. Universal Turing Machine에 적용되는 일부 조합 명령을 사용하여 모든 Turing Machine을 인스턴스화 할 수 있습니다. 하지만 지금까지이 모든 것은 순전히 수학적 구조입니다.

이 UTM을 실제로 시뮬레이션하려면 컴퓨터에서 탐색하기 위해 물리적으로 실현하려면 7 개의 Lisp 명령어 조합에서 튜링 머신을 생성하는 형식을 실제로 입력 할 수있는 방법을 제공하는 머신이 필요합니다. 그리고 어떤 형태의 출력도 필요합니다. 최소한 "예", "아니오"또는 "잠깐, 아직 실행 중입니다."라고 말할 수있는 기계입니다.

즉, 7 개의 명령어가 실제로 작동 할 수있는 유일한 방법은 환경을 제공하는 더 큰 시스템에서 호스트되는 경우입니다.

또한 Graham의 7 가지 프리미티브는 숫자에 대한 명시적인 지원이 없으므로 함수 ( "교회 숫자"기술)로 구성해야합니다. 어떤 생산 Lisp 구현도 그렇게 미친 짓을하지 않습니다.


1
그것을 사랑하십시오. UTM에 대해 질문하고 싶지만 이미 부 수신 것 같습니다. 나는 홈 브루 8 그러나 컴퓨팅, UTM 및 Lisp와 관련된 질문을 생각하고 있습니다.
hawkeye
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.