게시판 인덱스

 
 FAQFAQ   검색검색   멤버리스트멤버리스트   사용자 그룹사용자 그룹   사용자 등록하기사용자 등록하기 
 개인 정보개인 정보   비공개 메시지를 확인하려면 로그인하십시오비공개 메시지를 확인하려면 로그인하십시오   로그인로그인 

알쏭달쏭한 문제

 
이 게시판은 잠겼으므로 글을 올리거나, 답변을 하거나 수정을 할 수 없습니다   이 주제는 잠겼으므로 답변을 하거나 수정을 할 수 없습니다     게시판 인덱스 -> 4190.210 Principles of Programming (Fall 2008)
이전 주제 보기 :: 다음 주제 보기  
글쓴이 메시지
이충민



가입: 2008년 9월 20일
올린 글: 76

올리기올려짐: 2008년9월26일 22:00    주제: 알쏭달쏭한 문제 인용과 함께 답변

코드:
(define (foo)
  (define (cap x) (lambda () x))
  (define (bar)
    (define a (cons 0 (cap b)))
    (define b (cons 1 a))
    b)
  (bar))

(foo)
((cddr (foo)))

를 실행하면 결과는
코드:
(1 0 . #<procedure>)
(1 0 . #<procedure>)

입니다.

그런데
코드:
(define (cap x) (lambda () x))

(define (foo)
  (define (bar)
    (define a (cons 0 (cap b)))
    (define b (cons 1 a))
    b)
  (bar))

(foo)
((cddr (foo)))

를 실행하면 결과는
코드:
(1 0 . #<procedure>)
#<undefined>

가 됩니다. 왜 그럴까요?
위로
사용자 정보 보기 비밀 메시지 보내기
최원태



가입: 2006년 9월 16일
올린 글: 369

올리기올려짐: 2008년9월27일 21:47    주제: 인용과 함께 답변

1.
우리가 수업시간에 배운 Evaluation 방식들 따른다면
위의 두 코드는 모두 실행중에 에러가 나야합니다.

코드:
(define a (cons 0 (cap b)))
(define b (cons 1 a))


이 부분에서 a라는 이름에 넣을 값을 만들 때 b를 모르기 때문에 그렇습니다.

2.
생각할 수 있는 경우의 수가 세가지 있습니다.

1)현재의 Scheme은 R5RS를 따르고 있으므로, 교과서에서 정의한 방식에서 달라졌을 수 도 있습니다.

2) PLT자체에서 다른 실행규칙을 쓸 수 도 있습니다.
같은 R5RS를 구현한 MIT에서는 제가 말한 에러가 납니다

3) 코드를 최적화실행하는 과정에서 의미가 변할 수 있습니다.
Scheme 실행기는 대체로 코드를 Scheme VM 코드로 컴파일하여 실행합니다.
Scheme 코드를 컴파일할때 사용하는 아주 쉬운 최적화가
"함수콜이 뻔한 경우 inline하기" 입니다. (cap b)가 여기 해당되요.
그런데 이 최적화가 항상 가능하지는 않습니다.
불행하게 Scheme 코드 최적화 컴파일은 70년대에 논문으로 나오다가
구현이 본격화되면서는 더 이상 논문으로는 나오지 않습니다.
소스코드를 뜯어봐야 답이 나오겠지요.

찾아보고, 자세한 답변을 드릴께요.
하지만 정확한 답을 하기 위해 봐야할 자료들이 많아서
금방 답하기는 힘들겠어요.
위로
사용자 정보 보기 비밀 메시지 보내기 이메일 보내기 글 올린이의 웹사이트 방문
이충민



가입: 2008년 9월 20일
올린 글: 76

올리기올려짐: 2008년9월28일 0:14    주제: 인용과 함께 답변

(lambda () c)라고 그냥 써도 되는 걸 어찌된 일인지 저렇게 해도 R5RS, Pretty Big 모두 되길래 했는데 MIT에서는 에러가 나는군요 ㅜㅜ
위로
사용자 정보 보기 비밀 메시지 보내기
이충민



가입: 2008년 9월 20일
올린 글: 76

올리기올려짐: 2008년9월28일 1:46    주제: 인용과 함께 답변

코드:
(define (foo)
  (define (bar)
    (define a (cons 0 (lambda () b)))
    (define b (cons 1 a))
    b)
  (bar))

(foo)
((cddr (foo)))

는 MIT Scheme에서도 error가 나지 않고 자기 자신을 품을 수 있네요. lambda 식 안은 언제 계산되나요? lambda는 b가 (bar) 안에 정의된 b인지 어떻게 알죠?
위로
사용자 정보 보기 비밀 메시지 보내기
최원태



가입: 2006년 9월 16일
올린 글: 369

올리기올려짐: 2008년9월28일 3:41    주제: 인용과 함께 답변

lambda의 body가 볼 수 있는 scope는 약간 특이합니다.
이 녀석은 자신의 부모scope 전체를 볼 수 있습니다.

코드:
(define a (cons 1 b))
(define b 1)

이 코드는 에러이지만

코드:
(define a (lambda () b))
(define b 1)


이 코드는 제대로 작동합니다.
mutual recursive function를 지원하려고
만들다보니 이렇게 된 듯 하군요.
위로
사용자 정보 보기 비밀 메시지 보내기 이메일 보내기 글 올린이의 웹사이트 방문
정영범



가입: 2005년 9월 5일
올린 글: 167

올리기올려짐: 2008년9월29일 11:43    주제: 인용과 함께 답변

1. lambda식 안의 계산은 그 함수가 적용(application) 되었을 때 일어납니다.

코드:

(define out 1)

(define f1
  (let ((out 2))
    (lambda x
      ((lambda ()  out)))
    ))

(define out 3)

(define f2
  (lambda x
    (let ((out 4))
      (f1 x))))

(f2 10)


2. 위의 코드를 실행해보면 값이 2가 나옵니다. static scoping입니다.
근데 재밌는 것은 let (out 2) 부분을 지우고 실행을 시키면 3이 나온다는 사실입니다.
함수가 정의될때의 environment를 가지고 변수들의 값을 결정하는 방식이 static scoping인 것을 생각하면 결과로 1이 나올 것 같은데 말이죠. global scope의 environment는 항상 가장 마지막의 정의가 이전의 정의를 덮어쓰도록 구현이 되어 있나 봅니다.
위로
사용자 정보 보기 비밀 메시지 보내기 이메일 보내기 글 올린이의 웹사이트 방문
이전 글 표시:   
이 게시판은 잠겼으므로 글을 올리거나, 답변을 하거나 수정을 할 수 없습니다   이 주제는 잠겼으므로 답변을 하거나 수정을 할 수 없습니다     게시판 인덱스 -> 4190.210 Principles of Programming (Fall 2008) 시간대: GMT + 9 시간(한국)
페이지 11

 
건너뛰기:  
새로운 주제를 올릴 수 없습니다
답글을 올릴 수 없습니다
주제를 수정할 수 없습니다
올린 글을 삭제할 수 없습니다
투표를 할 수 없습니다


Powered by phpBB 2.0.21-7 (Debian) © 2001, 2005 phpBB Group
Translated by kss & drssay