2012-07-25 1 views
4

set-car!set-cdr!이식 가능하게 매크로를 Scheme에서 set!을 사용하여 매크로로 구현할 수 있습니까? 또는 기본 스토리지 시스템에 특별한 액세스가 필요합니까?자동차 세트 가능! 그리고 set-cdr! 매크로로 구현 되나요?

나는 내 자신의 Scheme 인터프리터를 구현하고 있기 때문에 묻고 있는데, 나는 가능한 한 많은 코드를 갖고 싶다. set-cdr!

내 첫 번째 시도했다 :

(define-syntax set-cdr! 
    (syntax-rules() 
    ((set-cdr! location value) 
    (set! location (cons (car location) value))))) 

대부분 작품,하지만 원형 목록에 대한 : 하나 나에게 도움이되지 않았다 let에서 매크로 몸을 포장

#; mickey> (define x (list 1 2)) 
#; mickey> x 
(1 2) 
#; mickey> (set-cdr! x x) 
#; mickey> x 
(1 1 2) 

때문에 (set! (cons (car location) value) 일 때 value은 이미 '(1 2)으로 평가되었습니다.

(set! location (cons (car location) value)) 

(cons (car location) value)에서

+1

왜 박사 라켓에 mpair 라이브러리를 사용하지? 당신은 (scheme/mpair가 필요함) (list mlist를 정의하십시오) ... (cons mcons를 정의하십시오) ... (set-car! set-mcar!) .. 등등을 사용할 수 있습니다. 그러나 여러분의 모든리스트는 기본적으로 변경할 수 있습니다. –

+0

@Rajesh : C++에서 처음부터 거의 완성 된 Scheme을 작성했기 때문에 :-) 나는 C++로 구현 된 많은 함수 대신에 스키마 파일로 라이브러리에있는 많은 함수를 사용할 수 있습니다. 그러나 제안에 감사드립니다! – csl

+0

수술 기능은 기본 요소 여야합니다. 그게 다야. 치킨 계획에 –

답변

4

새로운 쌍을 할당한다.

set-cdr!의 목적은 기존 쌍을 변경하는 것입니다.

따라서 set-cdr!을 구현하려면 기본 저장소에 "특별한"액세스가 필요합니다.

+0

그러나 스키마는 전형적으로/cond, lambda, quote, set을 포함하는 매우 엄격한 코어만을 필요로한다고 생각했습니다! 및 기타 기본 요소 (기본 데이터 형식 및 상수)가 포함됩니다. 나는'단점 '이 문제인지 확실하지 않습니다. 오히려 값의 주소를 얻을 수 없다는 것입니다 (평가 됨). – csl

+1

글쎄, 만약 당신이 * 정말로 * 당신이 클로저를 사용하여 쌍을 시뮬레이션 할 수는 있지만, * 매우 * 비효율적이다. 아래 답변을 참조하십시오. – soegaard

+0

물론,하지만 그건 내가 원하는 것이 아닙니다. :) 나는'set! '을 가지고 있고'set-car!'와'set-cdr! '를 원한다. 어쨌든 다른 것들과 관련하여'set! '을 구현하는 것은 물론 작동합니다. – csl

2

다음은 Cons, Car, Cdr, Set-car!를 구현 한 예입니다. 및 Set-cdr! 클로저 사용.

1

기본적으로 설정! 세트없이!,하지만 나는 당신이 set-car를 구현할 수 있다고 생각하지 않는다!/set-cdr! 쌍을 변경하거나 쌍을 시뮬레이트하지 않고 (예 : soegaard의 예)

Scheme에서 Scheme 구현을하고있는 것처럼 보였으므로 set-car!/set-cdr을 사용했을 것입니다! 통역사에서 구현하거나 전혀 구현하지 않았습니다. 나는 처음부터 기본 최소 구현을 가지고 추가로 향상시키기 위해 정의, if, quote, pair?, eq ?, cons, car 및 cdr (The roots of LISP과 비슷하지만 더 많은 설계)과 함께 시작했을 것입니다. 어쨌든

.. 귀하의 구현, 당신이이 일을 할 수 있어야 구현하는 경우 :

(define odds (list 1 3 5 7 9 11)) 
(set-car! (cddr odds) #f) 
odds 
===> (1 3 #f 7 9 11) 
+0

C++로 구현하고 있습니다. 세트, 세트 - 카를 구현하는 것은 매우 쉽습니다! 그리고 set-cdr! C++에서, 내가 사용하고있는 포인터에 접근 할 수 있기 때문에, 잘 작동한다. 그러나 세트 만하는 것이 더 낫습니다! 그리고 set-car를 구현하십시오! Scheme 소스 코드 라이브러리에서. 아아 ... – csl

+1

세트 차 동안! 그리고 set-cdr! 실제로 데이터 포인터를 변경합니다! 실제로는 매우 다릅니다. 세트! 매개 변수와 전역 변수 모두에 사용할 수 있으며 프로 시저 내에서 변경중인 프로 시저의 환경입니다. 통역사를 구현하는 경우 프레임을 구현해야합니다. 컴파일러를 구현하는 경우 집합을 제거 할 수 있습니다! 다른 람다에 클로저를 래핑함으로써 박스 변수를 변형 할 수 있습니다. 생성자는 다음과 같이 변환 할 수있다. (lambda (x) (let ((x (cons x)) (λ (n))))))))) – Sylwester