make (Factor's quasiquote)

원문: http://useless-factor.blogspot.com/2007/01/factors-make.html


Factor의 또 다른 특이한점은 "make"라는 워드입니다. 이는 literal로 표현할 수 없거나, sequence initializer을 사용하지 못하거나, 또는 기존의 시퀀스에 대해서 시퀀스를 생성하려고 할때에 사용합니다. 이의 가장 간단한 형태는 다음과 같습니다.:


[ 1 , 2 , 3 , ] { } make


이 코드는 "{ 1 2 3 }"와 같습니다. "," 워드는 특정한 배열(내부적으로 "building" 배열에)에 스택 최상의 객체를 이동합니다. 이는 당연히 loop에 대해서도 적용할 수 있는데 다음처럼 이를 이용해 각 요소를 배열에 넣는 것을 볼 수 있습니다.


: add-all ( seq -- ) [ , ] each ;
...
[ 3 add-all 4 add-all ] { } make


결과는 "{ 0 1 2 0 1 2 3 }"입니다. (Note: 이로서 Factor의 흥미로운 점을 발견할 수 있습니다. 숫자를 0..n-1의 범위를 표현하는 시퀀스로서 표현하는 점입니다.) "add-all"은 매우 유용한 것이므로 이미 Factor standard library에 "%"이란 이름으로 구현되어 있습니다. 실제로 위의 코드는 "[ 3 % 4 % ] { } make"와 같습니다. (이 이름들이 처음에는 이상하지만 익숙해질것입니다.)

"make"의 중요한점은 이를 통해서 복잡한 시퀀스를 생성하는 것들을 더 명시적으로 쉽게할 수 있다는 것입니다. 이의 예제로서 "take-until"을 살펴봅시다.


: take-until ( quot -- string )
#! Take the substring of a string starting at spot
#! from code until the quotation given is true and
#! advance spot to after the substring.
[ [
dup slip swap dup [ get-char , ] unless
] skip-until ] "" make nip ;


또 다른 예제를 살펴봅시다. 만일 하나의 숫자를 받아서 "The answer to [n] sqaured is [n * n]."이라는 식으로(n은 입력값)으로 출력되는 문자열을 출력하고 싶을때가 있을것입니다. 다른 언어에서는 string-concat, string-interpolate등을 사용하지만 Factor에서는 그러한 것들이 필요하지 않습니다.


: square-description ( num -- )
[
"The answer to " %
dup #
" squared is " %
sq #
"." %
] "" make ;


이 경우에는 "" make 부분은 마치 C함수 sprintf처럼 문자열을 만드는데 이용할 수 있습니다. 대부분의 경우 "{ } make"은 lisp의 "`"(quasiquote)처럼 작동합니다.

"make"은 그자체가 특별한 내장함수이거나 하지 않습니다. 이도 일반적인 Factor 코드로 구현되어 있습니다. namespaces vocab에 다음처럼 선언되어 있습니다.


: make ( quot exemplar -- seq )
>r [
V{ } clone building set
call
building get
] with-scope
r> like ; inline


이는 새로운 빈 벡터를 만들고, 이를 "building"이라는 변수로 바인드합니다. 그리고 주어진 quotation을 실행하고, 변수값을 다시 가져와 그 형식을 exemplar와 같게 변환합니다. 이는 실행때마다 새로운 scope을 만드므로 그 외부의 "building" 변수는 영향을 주지 않습니다.

명백하게 무언가가 부족합니다. 그러면 어떻게 이 'building'에 새로운 요소들을 추가해줄까요? 그것들을 위해서 ",", "%", "#"등의 워드를 사용합니다.


: , ( elt -- ) building get push ;


by 아겔 | 2007/05/30 19:48 | factor-language | 트랙백

트랙백 주소 : http://ageldama.egloos.com/tb/3197712
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

◀ 이전 페이지          다음 페이지 ▶