예제 코드 here (아래 예제)을 이해하려고합니다. 나는 파라미터 구조를 이해하지 못한다. 문서는 here이지만 도움이되지 않습니다. 그것은 무엇을합니까?DrScheme에서 '매개 변수화'는 무엇입니까?
답변
parameterize
은 "동적으로 범위가 지정된"값을 사용합니다. make-parameter
으로 매개 변수를받습니다. 매개 변수 자체는 함수로 작동합니다. 입력이 없으면이 매개 변수를 호출하고 해당 값을 가져 와서 한 값으로 호출하면 값이 설정됩니다. 예 :
> (define p (make-parameter "blah"))
> (p)
"blah"
> (p "meh")
> (p)
"meh"
많은 기능 (많은 기본 기능 포함)은 동작을 사용자 정의하는 방법으로 매개 변수를 사용합니다. 예를 들어 printf
은 current-output-port
매개 변수의 값인 포트를 사용하여 항목을 인쇄합니다. 이제, 인쇄 몇 가지 기능을 가지고 있다고 무언가 : 당신은 일반적으로이 함수를 호출하고 뭔가 화면에 출력 참조
> (define (foo x) (printf "the value of x is ~s\n"))
-하지만 어떤 경우에는 파일이나 어떤 뭔가를 인쇄하는 데 사용할 . 당신은 이것을 할 수있다 :
(define (bar)
(let ([old-stdout (current-output-port)])
(current-output-port my-own-port)
(foo some-value)
(current-output-port old-stdout)))
이것에 대한 하나의 문제는 지루한 일이다. 그러나 그것은 매크로로 쉽게 해결된다. (사실, PLT에는 여전히 일부 언어에서는 해당 작업을 수행하는 구문이 있습니다. fluid-let
) 그러나 여기에는 더 많은 문제가 있습니다. foo
을 호출하면 런타임 오류가 발생합니까? 이렇게하면 시스템이 모든 상태로 돌아가는 나쁜 상태가 될 수 있습니다. 아무 것도 출력하지 않으므로 문제가 보이지 않습니다. (fluid-let
도 사용하는) 그 해결책은 매개 변수의 저장/복원을 dynamic-wind
으로 보호하는 것입니다. 그러면 오류가있는 경우 (계속해서 계속 알면) 값이 복원됩니다.
그렇다면 전역과 fluid-let
을 사용하는 대신 매개 변수를 사용하는 것이 중요한 이유는 무엇입니까? 단지 전역 변수로는 풀 수없는 두 가지 문제가 더 있습니다. 하나는 여러 개의 스레드가있을 때 일어나는 일입니다.이 경우 일시적으로 값을 설정하면 다른 스레드가 영향을 받아 표준 출력으로 계속 인쇄됩니다. 매개 변수는 스레드마다 특정 값을 가짐으로써이를 해결합니다. 각각의 스레드는 스레드를 생성 한 스레드의 값을 "상속"하며 한 스레드의 변경 사항은 해당 스레드에서만 볼 수 있습니다.
다른 문제는 더 미묘합니다.당신이 숫자 값을 가진 매개 변수가 있음을 말해, 당신은 다음을 수행 할 : 계획에서
(define (foo)
(parameterize ([p ...whatever...])
(foo)))
는 "꼬리 호출"중요하다 - 그들이 루프 등을 만들기위한 기본 도구입니다. parameterize
은 일시적으로 매개 변수 값을 변경하지만 이러한 꼬리 호출을 유지할 수있는 마법을 수행합니다. 예를 들어, 위의 경우에 은이 스택 오버플로 오류가 발생하지 않고 무한 루프가 발생합니다. 이전에 parameterize
이 더 이상 필요하지 않은 경우 이러한 parameterize
표현식을 각각 감지 할 수 있습니다 대청소.
마지막으로 parameterize
은 실제로 PLT의 두 가지 중요한 부분을 사용합니다. 스레드 셀을 사용하여 스레드 당 값을 구현하고 연속 호출을 사용하여 꼬리 호출을 보존 할 수 있습니다. 이러한 각 기능은 그 자체로 유용합니다.
흥미로운 답변 - 감사합니다! – Claudiu
매개 변수화는 람다를 사용하지 않고 기존 함수 내에서 값을 동적으로 다시 바인딩 할 수있는 방법입니다. 실제로 매개 변수를 전달하고 람다를 사용하여 바인드해야하는 대신 함수 내에서 값을 다시 바인드하려면 parameterize를 사용하는 것이 훨씬 쉽습니다.
예를 들어, 사용하는 라이브러리가 HTML을 표준 출력으로 내보내지만 편의상 그 값을 문자열로 캡처하여 추가 작업을 수행한다고 가정하십시오. 라이브러리 설계자는 1) 기능에 대한 인수로 출력 포트를 승인하거나 2) 현재 출력 포트 값을 매개 변수화하는 데 필요한 최소한 두 가지 선택 사항이 있습니다. 1은 추악하고 번거 롭습니다. 2는 stdout으로 인쇄하는 것이 가장 좋기 때문에 더 좋지만, 문자열 포트로 인쇄하고자 할 경우에는 해당 함수에 대한 호출을 매개 변수화 할 수 있습니다.
왜 tinyurl.com을 사용하십니까? 전체 URL을 사용하는 데 상당한 공간 제약이 없으며, 짧은 URL로 인해 링크의 의심이 더 커집니다. –
링크에는 꼬리표가 붙어있어 마크 업과 함께 작동하지 않는 꼬리표가 있습니다. 즉, – Claudiu
지미니 크리스마스 (Zimmermy Christmas)를 사용하면 해당 링크는 인용순 하단 인용 스타일로 작동하지 않습니다. – Chuck