'factor-language'에 해당되는 글 5건

  1. 2009.04.11 팩터 OOP: 프로토콜, 믹스인
  2. 2009.03.30 팩터 OOP: 메서드와 제네릭 (2)
  3. 2009.03.30 팩터/OOP: 클래스? 튜플? (1.5)
  4. 2009.02.17 io.encodings.korean 커밋 (2)
  5. 2009.01.31 FactorLanguage을 위한 SLIME? (2)
posted by 아겔-_- 2009.04.11 16:19
이전 '다양한 클래스 선언'에서 믹스인에 대해서 설명했었음.

믹스인은 유니온과 유사하지만, 어떤 범주가 되는 클래스에 계속해서 다른 클래스를 추가해넣을수있음.

팩터는 단일상속이지만, 어떤 객체나 클래스는 다른 클래스에 속하거나 할 수 있는 '관계'를 지정할있으므로 이런것이 가능.

프로토콜 슬롯은 이러한 믹스인을 이용하여 다른 언어에서 프로토콜이나 인터페이스처럼 특정한 '규약'을 클래스가 준수함을 표현.

  1. MIXIN:으로 믹스인 클래스를 선언한다.
  2. SLOT: 선언으로 공유할 슬롯을 선언한다.
  3. 믹스인을 구현할 클래스에서 SLOT: 선언에 해당하는 슬롯들을 구현한다
  4. 믹스인을 구현한 클래스를 INSTANCE:을 이용하여 믹스인에 추가한다.

은근히 이런식으로 구현한 클래스들이 팩터에 많은듯. (시퀀스 프로토콜, growable 프로토콜...)

그리고 믹스인과 슬롯의 구분이 분리된듯한데 이럴때는 사실 PROTOCOL: 선언을 통해서 프로토콜의 이름과 그 프로토콜이 구현하기를 원하는 word들을 나열하고 이를 구현하는것으로 대신할수있다. (자세한것은 delegates을 참고)



신고
posted by 아겔-_- 2009.03.30 23:21
팩터에서 튜플 클래스를 선언하고 속성을 붙이는것까지 설명했다.
이제는 객체에 메서드를 붙여줄 시간이다. (객체지향에서 객체는 속성과 행위로 표현하니까.)

팩터의 타입시스템 자체는 하스켈이나 OCaml의 그것들과 유사한데, 메서드나 슬롯에 대한 부분은 커먼리습의 CLOS와 유사하다.

무슨말인가하면, 어떤 객체에 대해서 메서드를 붙이는것과는 조금 다르다는말이다.
예를 들어서 우리는 메서드의 polymorphism에 대해서 다음에 익숙해있다.

someCircle.area();
someRectangle.area();
단순히 이름이 같다는것정도.

팩터는 그 언어의 특색(nature)에 따라 객체의 메서드도 사실은 그냥 일반적인 워드와 같다.
리습에서 객체의 메서드는 그냥 일반적인 함수호출과 같고, 하스켈에서 어떤 타입에 대한 함수는 일반적인 함수와 같다.
단지 그 인자중 하나가 그 클래스/타입에 속할때 원하는 메서드의 코드를 선택하는것이 다르다.

팩터에는 별도로 연산자가 없다. 모두 워드다. 마찬가지로 메서드를 만드는것만으로 기존의 연산자를 재정의하는것이 가능하다.

팩터나 CLOS에서 이런 "메서드의 이름"을 규정하는것을 제네릭(generic)이라고한다. 그리고 다음처럼 선언한다.

( scratchpad ) GENERIC: area
( scratchpad ) GENERIC: perimeter ( obj -- perimeter )
단순히 제네릭의 이름을 주거나, 제네릭의 stack effect declaration을 적어줘도 좋다.

이렇게하면, 객체별로 이 제네릭에 대한 메서드를 붙일 준비가 끝났다.

일단 넓이를 구하는 메서드들은 다음처럼 붙여봤다.

( scratchpad ) USE: math.constants
( scratchpad ) pi .
3.141592653589793
( scratchpad ) pi sq .
9.869604401089358
( scratchpad ) M: circle area r>> sq pi * ;
( scratchpad ) 9 <circle> area .
254.4690049407732
( scratchpad ) M: rectangle area [ w>> ] [ h>> ] bi * ;
( scratchpad ) 3 4 <rectangle> area .
12

"M: 클래스 제네릭 ..." 이렇게 시작해서 일반적인 워드와 같이 그 구현을 하는것을 알 수 있다.

다수개의 인자에 대해서도 제네릭을 다르게 만들어놓고서 하면 되는데, 이때 주의점은 GENERIC: 선언은 반드시 스택의 맨 위가 해당 클래스의 인스턴스여야 한다는것이다. 특정 클래스를 다른 위치에 두고자 한다면 "GENERIC#" 선언을 이용한다.

또한, HOOK:을 통해서 multiple dispatch에서처럼 다수의 인자의 타입에 따른 메서드 dispatch을 구현이 가능하다.
(그 이외에도 MATH:등을 통해서 수학연산자에서처럼 양변의 타입에 따른 dispatch도 가능하다)

또한 상속 받은 클래스의 메서드에서 상위 메서드를 호출하려면 super등을 통하지 않고 단순히 "call-next-method"을 호출한다.
(circle의 area에서 shape의 area을 호출하고자 한다던지...)

마지막으로 메서드의 인자가 많거나 할때도, locals의 M::을 이용하여 "::"와 같이 인자들에 이름을 붙이거나 할수있다.

( scratchpad ) M: circle perimeter r>> pi * 2 * ;
( scratchpad ) 9 <circle> perimeter .
56.54866776461628
( scratchpad ) M: rectangle perimeter [ w>> 2 * ] [ h>> 2 * ] bi + ;
( scratchpad ) 3 4 <rectangle> perimeter .
14








신고
posted by 아겔-_- 2009.03.30 00:18
팩터에서 모든 값은 어떤 클래스의 인스턴스.
( scratchpad ) 1 class .
fixnum
( scratchpad ) 1 class class? .
t
( scratchpad ) 1 fixnum instance? .
t
( scratchpad ) 1 number instance? .
t
( scratchpad ) 1 string instance? .
f
"class" 워드를 통해서 어떤 값의 클래스를 보거나, 어떤 객체가 어떤 클래스의 인스턴스인지를 실행시간에 확인이 가능함을 보임.

팩터에서 클래스는 크게 다음과 같이 나뉜다.

  • 내장 클래스 : builtin class, 프리미티브로 vm자체에서 구현하는 값에 대한 클래스.
  • union, intersection class : 기존의 클래스들의 합집합, 혹은 클래스 워드의 교집합이 일치하는 클래스들을 묶는 클래스
  • predicate class : 어떤 객체가 'predicate'을 충족하는지에 따라 동적으로 수용여부가 결정되는 '값에 의한' 클래스
  • singleton class
  • 믹스인 클래스 : mixin class, union class와 유사하게 클래스들을 묶지만, 계속해서 그 집합에 사용자정의 클래스를 더해나갈수있는 클래스
다른 객체지향언어와는 다르고, 차라리 Algebraic Data Type와 유사함을 알수있다. (그리고 더 디테일한 조정이 가능하다)

이들 클래스의 대부분은 이 시리즈에서 다룰것임.

어쨌든 사용자 정의 클래스 '튜플(Tuple)'이라고 부르고 다음처럼 선언한다.

TUPLE: shape ;

TUPLE: rectangle < shape w h ;

TUPLE: circle < shape r ;
단순히 아무런 속성도 없는 "shape" 클래스를 선언하고 이를 상속하는 rectangle, circle 클래스를 선언. 각각의 속성은 w, h, 그리고 r.

이 이름만으로는 기본적으로 인스턴스가 아니다. (인스턴스를 만드는 방법이 별도로 존재한다.)

( scratchpad ) shape shape instance? .
f
( scratchpad ) shape boa shape instance? .
t
"boa"라는 워드를 이용해서 인스턴스를 생성했음. ("by order of arguments") BOA 생성자는 그 슬롯(속성)의 순서대로 스택에서 취하여 인스턴스를 생성.

생성자는 컨벤션에 의해서 <circle>, <rectangle>, <shape>와 같이 표현.

"C:"워드를 통해서 BOA 컨스트럭터를 자동으로 선언할수있다.

( scratchpad ) C: <circle> circle
( scratchpad ) C: <rectangle> rectangle
( scratchpad ) 9 <circle> .
T{ circle { r 9 } }
( scratchpad ) 3 4 <rectangle> .
T{ rectangle { w 3 } { h 4 } }
( scratchpad )
<circle>, <rectangle>을 일반적인 워드와 같이 이용함을 알수있음.

추가적으로 속성, 즉, 슬롯에 타입제한이나 읽기전용슬롯, 초기값을 지정하는것도 가능하다. (이후에 슬롯만을 다룰때 다루겠다.)

기본 생성자를 이렇게 만드는것이고, 추가적인 생성자를 만들려면 단순히 <circle>와 같은 이름의 word을 선언하면 되겠다. (이미 <circle>이 있다면 컨벤션에 의해서 <circle>*와 같은 이름으로도 되겠죠)

인스턴스의 슬롯들은 "slot accessors"을 통해서 접근이 가능.

( scratchpad ) 3 4 <rectangle> 5 >>h .
T{ rectangle { w 3 } { h 5 } }
( scratchpad ) 8 <circle> 9 >>r r>> .
9
이름이 "r"인 슬롯에 대해서 getter가 "r>>", setter가 ">>r"임을 볼수있다. 이들 accessor들은 자동적으로 생성된다.


마지막으로 클래스 선언과 함께 predicators도 함께 선언을 해주는데, 어떤 객체가 해당 클래스에 속하는지를 판별하는데 이용한다.

( scratchpad ) 9 <circle> shape? .
t
( scratchpad ) 9 <circle> circle? .
t
( scratchpad ) 9 <circle> rectangle? .
f


기본적인 클래스의 선언과 인스턴스의 생성, 그리고 속성에 대해서 살펴봤다. 이제 메서드를 붙이고 하는 방법에 대해서 살펴보고, 계속해서 디테일하고 다양한 부분을 살펴보도록 하겠다.



ps. 9서클을... 드디어 내가! 타이번!
신고
posted by 아겔-_- 2009.02.17 22:20
저의 개인 factor clone에 io.encodings.korean을 push했습니다.

사실 지난 주말부터 factor offical git-repository에 올라와있어서 원하는 사람은(특히 개별적으로 팩터를 빌드하시거나 하시는 분들) 얼마든지 한글코드 지원을 맛보실 수 있었습니다.

Daniel Ehrnberg의 큰 갈굼도움으로 좋은일을 할수있었던것 같습니다. (Daniel, thank you!)

도움말 문서도 얼추 작성했고 보람차네요.

현재로서는 cp949(euckr, uhc, 확장완성형)만을 지원하지만 조합형이나, 쌩뚱맞게 euc-jp코드에 대한 작업도 해나갈 생각입니다. (마지막것두 io.encodings.korean에 넣어볼까요?^^;)

나름 별거 아닌 인코딩 지원이지만, 이를 위해서 많은 지원을 해준 Slava Pestov에게도 고맙네요. (알고보니 저보다 두살이나 어리더군요! 아... 참 인생 헛살았다는 느낌;;)


팩터가 io.encodings.korean와 연관하여 개선된 부분과 개선될 부분도 생겨서 기쁩니다.
  • 리소스 pathname에 vocab:을 지정가능하게되었습니다. 예를 들어, resource:work/io/encodings/korean/cp949.txt
  • 와 같이 work디렉토리나 basis디렉토리에 참조가 있을수밖에 없었는데, 이를 vocab:io/encodings/korean/cp949.txt와 같이 어떤 위치에 있건 vocab의 위치에 따라가게. (현재 git버젼엔 반영)
  • cp949, shift-jis, euc-jp등 unicode.org에서 제공하는 코드 테이블을 이용하여 매핑하는 방식을 공식적으로 지원하기 위한 파서/코드테이블 vocab (작업중)



마지막으로 스샷 하나 올립니다. 아직 ui-listener에서는 유니코드 한글출력이 구현되지않아 어렵지만, 유니코드를 정상적으로 지원하게 설정한 emacs+fuel에서는 한글을 느끼실수있답니다. ^^
신고

'삽질+돈되는짓 > FactorLanguage' 카테고리의 다른 글

Imperative Factor  (0) 2009.02.21
어째서 함수의 조합은 복잡해야만 할까?  (0) 2009.02.19
io.encodings.korean 커밋  (2) 2009.02.17
Factor에서 개발하기  (0) 2009.02.15
Factor History & Features  (0) 2009.02.14
concatenative language?  (1) 2009.02.14
posted by 아겔-_- 2009.01.31 23:04
저는 FactorLanguage을 좋아합니다. (http://en.wikipedia.org/wiki/Factor_(programming_language))

실용적이고 제가 원하는것을 모두 갖춘것 같은 언어라고 생각해요. 커먼리습은 너무 오래되고 커지기만 한 느낌이고(물론, 언어자체의 설계를 뒤집을 필요가 전혀없으니까 그렇긴해도, 구현이나 개발환경이 그런게 사실 윈도나 런곳에서는 좀 제한적이잖아요?), 스킴은 뭔가 구현마다 너무 큰 갭이 있는것 같고요. (다른분들보다 제가 아둔해서 그렇게 느끼는걸수도 있겠죠. ^^;)

커먼리습 같은 네이티브 컴파일러, 파일/이미지기반의 개발, ffi도 괜찮고, 이미 다른 언어에서 구현하기 힘들정도로 멋진 도구들을 많이 갖추고 있고, 그리고 무엇보다 심플하고 완전한 언어 그자체로부터 나오는 강력한 표현력은 리습의 s-expression에서 느낀것보다 훨씬 신선하게 저에게 충격을 줬었습니다. 제게 있어서 리습은 제 생각하는 방법을 바꿔버린 언어이고, Factor은 생각하는 방법을 다시 바꾼 언어죠.

하여튼 제게 있어서는 다른 리습해커들에게 커먼리습이 갖는것처럼 뭔가 완전하고 아름다운 제 도구인 FactorLanguage에서 좀 싫어하는건 사실 개발환경이었어요.

익숙해지기 힘들고, 거추장스럽고, 마우스에 손이 자주가야하고, 그리고 무엇보다 아직은 한글입력/출력이 안되는! ㅜ.ㅜ




그런데 좋은 소식이 있었더라구요.
언제나 팩터쪽은 그런식(!!!)이듯이 순식간에 엄청난 물건이!

FUEL(Factor's Ultimate Emacs Library)이라는 겸손한 이름(;;;)의 Emacs모드였어요.

원래 팩터를 개발한 슬라바 아저씨(Slava Pestov, http://factor-language.blogspot.com/)가 jEdit을 개발한 사람이어서 그런지 jEdit쪽 바인딩이나 그런건 나름 괜찮았었는데, jEdit자체가 요즘엔 좀 거시기한 에디터가 되고 그랬던 와중에, 기존에 팩터에서 사용가능한 vim, emacs 모드에서 이맥스 모드였던 "factor.el"이 발전하여 SLIME(http://common-lisp.net/project/slime/)처럼 막강한 개발환경이 되었어요!

관련 블로그 포스팅 : http://factor-language.blogspot.com/2009/01/screencast-editing-factor-code-with.html


하악하악... 설정도 그냥 이맥스랑 팩터만 설치하고, 이맥스에서 fu.el을 load-file하면 끝!

;;; ~/.emacs에서...
(load-file "d:/tools/factor/misc/fuel/fu.el")

그리고 "M-x run-factor"하고 잠시 (처음 시작할때는 좀 많이 기둘려야 해용 ㅜ.ㅜ) SLIME-REPL처럼 사랑스러운 scratchpad을 만날수있답니다!

팩터 파일을 편집하고, 바로 REPL측에 컴파일/적재하고, 이를 테스트하고, 작성하면서 관련된 레퍼런스를 즉시 검색하고(팩터은 코드와 함께 문서도 적재되서 언제나 실행시간에 관련 문서를 바로바로 찾아볼수있답니다. ^^), 코드를 "리-팩터링"한다던지 하는 개발환경으로서 SLIME 못지 않은 환경을 간단히 갖출수있었어요.
(심지어 이클립스와 같은 자바IDE에서나 보던 'Organize Imports'와 같은 "fuel-update-usings"같은것까지 있더라구요.)

자세한 /뽀대/는 다음 스크린캐스트 : http://blip.tv/file/1658806


저에게는 FUEL이 참 설레이는 환경이 되었어요. *^^*




ps. 처음 "M-x run-factor"하면 많이 느린데요, 이유는 필요한 vocab(모듈이랑 비슷한 개념이에요)을 vm에 적재하고, 최적화 컴파일러를 거쳐서 컴파일하기 때문인데요, 빠르게 하시려면 한번 그렇게 적재하신 다음에 scratchpad에서 "save"을 쳐서, 이미지를 업데이트 하시면 다음번 "run-factor'부터는 빠르게 올라온답니다. 스몰톡이나 커먼리습처럼 파일기반으로 개발이 가능하면서도, vm의 현재 상태를 이미지로 만들어서 deploy하거나 개발할때 편리하게 이용할수있어요. ^^
신고

'삽질+돈되는짓 > FactorLanguage' 카테고리의 다른 글

팩터는 어떤 언어임까?  (0) 2009.02.13
Why "Factor"?  (0) 2009.02.13
io.encodings.korean을 완성했습니다.  (2) 2009.02.12
factor-kr을 시작했습니다.  (0) 2009.02.08
ProjectEuler 풀면서 한컷!  (0) 2009.02.01
FactorLanguage을 위한 SLIME?  (2) 2009.01.31

티스토리 툴바