100개 언어 Speedrun: 에피소드 71: 팩터

7614 단어 factorforth
죽었고 그 아이디어는 주류 언어로 많이 채택되지 않았지만 Forth 스타일 언어는 큰 주목을 받지 못한 채 가끔씩 나타납니다.

그러한 언어 중 하나는 Factor 입니다. Forth에서 어떻게 개선되는지 봅시다.

안녕하세요, 월드입니다!


brew install factor 할 수 있지만 경로에 있지 않고 이상한 장소에 설치됩니다.

숫자를 인수분해하는 Linux 시스템에는 관련되지 않은factor도 있습니다.

$ factor 420
420: 2 2 3 5 7


어쨌든, 팩터. 첫 번째 성가신 문제는 새로운 Factor 프로그램에 어떤 종류의 라이브러리도 제공되지 않는다는 것입니다. 아니요print, 아니요+, 말 그대로 아무것도 아닙니다.

우리가 이것을 시도한다면:

#!/Applications/factor/factor

"Hello, World!" print


다음 오류가 발생합니다.

$ ./hello.factor
./hello.factor

3: "Hello, World!" print
                        ^
No word named “print” found in current vocabulary search path
(U) Quotation: [ c-to-factor => ]
    Word: c-to-factor
(U) Quotation: [ [ (get-catchstack) push ] dip call => (get-catchstack) pop* ]
(O) Word: command-line-startup
(O) Word: run-script
(O) Word: run-file
(O) Word: parse-file
(O) Word: parse-stream
(O) Word: parse-fresh
(O) Word: (parse-lines)
(O) Word: (parse-until)
(O) Word: parse-until-step
(O) Word: no-word
(O) Word: throw-restarts
(O) Method: M\ object throw
(U) Quotation: [
        OBJ-CURRENT-THREAD special-object error-thread set-global
        current-continuation => error-continuation set-global
        [ original-error set-global ] [ rethrow ] bi
    ]


그래서 진지하게 언어를 싫어하기 시작하는 데 약 1 분이 걸렸습니다. 합리적인 오류 메시지는 다음과 같습니다.

No word named “print” found in current vocabulary search path. It is defined in the following namespaces: io.


그러나 아니요, Factor는 가장 간단한 스크립트에 대한 절대 최악의 오류 메시지를 제공하여 상을 받고 있습니다. 그리고 기억해야 할 몇 개의 라이브러리가 아닙니다. 아니요, Factor split core functions between hundreds of micro-libraries , 그래서 당신이 그것을 코딩하려고 한다면 당신의 고통을 즐기십시오.

Factor VSCode 플러그인도 여기서 도움이 되지 않습니다. Factor는 도움말 시스템이 있는 대화형 앱과 함께 제공되며 이를 검색하는 데 사용할 수 있지만 인터넷 검색에 비해 크게 개선되지는 않습니다. 일반적인 수입품을 모두 외울 때까지는 큰 골칫거리입니다.

안녕하세요, 월드입니다! 다시


printio 에 있다는 것을 알게 되면 다음과 같이 할 수 있습니다.

#!/Applications/factor/factor

USING: io ;

"Hello, World!" print


수학



자, 숫자를 추가해 보겠습니다. 이를 위해서는 3가지 다른 수입품이 필요합니다!

#!/Applications/factor/factor

USING: io math math.parser ;

400 20 + number>string print
60 9 + number>string print



$ ./math.factor
420
69


고리



다음은 1에서 10까지의 숫자를 인쇄하는 간단한 루프입니다. 물론 다른 가져오기가 필요합니다.

#!/Applications/factor/factor

USING: io math math.parser kernel ;

1
[                ! 1
  dup            ! 1 1
  number>string  ! 1 "1"
  print          ! 1
  1              ! 1 1
  +              ! 2
  dup            ! 2 2
  10             ! 2 2 10
  <=             ! 2 t
]
loop
drop



$ ./loop.factor
1
2
3
4
5
6
7
8
9
10


Factor가 완료되면 스택에 무언가가 있는 것처럼 마지막에 drop 해야 합니다.
!는 주석 문자입니다. 각 명령 후에 스택 상태가 될 몇 가지 예를 추가했습니다. 실제 코드에서는 이러한 모든 주석이 없는 훨씬 더 간결한 코드를 사용하고 한 줄에 하나씩 관련 명령을 함께 사용하지 않습니다.

함수 정의



함수를 정의하려면 네임스페이스를 선택하고 스택 상단이 전후에 보이는 것과 함께 함수를 선언하는 두 가지 작업을 수행해야 합니다. 스택 상태에도 많은 주석이 달려 있습니다.

#!/Applications/factor/factor

USING: io math math.parser kernel ;
IN: double

: double-number ( n -- m ) 2 * ;

200
[                ! 200
  dup            ! 200 200
  double-number  ! 200 400
  number>string  ! 200 "400"
  print          ! 200
  1              ! 200 1
  +              ! 201
  dup            ! 201 201
  210            ! 201 201 210
  <=             ! 201 t
]
loop
drop



$ ./double.factor
400
402
404
406
408
410
412
414
416
418
420


피보나치




#!/Applications/factor/factor

USING: io math math.parser kernel ;
IN: fib

: fib ( n -- m )
  dup          ! N N
  2 <=         ! N t/f
  ! called if <= 2
  [             ! N
    drop        ! empty
    1           ! 1
  ]
  ! called if > 2
  [             ! N
    dup         ! N N
    1 -         ! N N-1
    fib         ! N fib(N-1)
    swap        ! fib(N-1) N
    2 -         ! fib(N-1) N-2
    fib         ! fib(N-1) fib(N-2)
    +           ! fib(N-1) + fib(N-2)
  ]
  if
;

! does not remove top of the stack
: print-fib ( n -- n )
  "fib(" write
  dup number>string write
  ") = " write
  dup fib number>string write
  "\n" write
;

1
[
  print-fib
  1 +
  dup 20 <=
]
loop
drop



$ ./fib.factor
fib(1) = 1
fib(2) = 1
fib(3) = 2
fib(4) = 3
fib(5) = 5
fib(6) = 8
fib(7) = 13
fib(8) = 21
fib(9) = 34
fib(10) = 55
fib(11) = 89
fib(12) = 144
fib(13) = 233
fib(14) = 377
fib(15) = 610
fib(16) = 987
fib(17) = 1597
fib(18) = 2584
fib(19) = 4181
fib(20) = 6765


스택 기반 언어에서 기대할 수 있는 것과 거의 비슷합니다. write는 개행을 추가하지 않는다는 점을 제외하고는 print와 같습니다. io 라이브러리에도 있습니다. 흥미로운 기능을 위해 스택 상태에 주석을 달았습니다.

피즈버즈



다음은 주석이 달린 FizzBuzz입니다.

#!/Applications/factor/factor

USING: io math math.parser kernel ;
IN: fizzbuzz

: is-fizz ( n -- t/f )
  3       ! N 3
  mod     ! N%3
  0       ! N%3 0
  =       ! t/f
;
: is-buzz ( n -- t/f )
  5       ! N 5
  mod     ! N%5
  0       ! N%5 0
  =       ! t/f
;

: fizzbuzz ( n -- str )
  dup                 ! N N
  is-fizz             ! N isFizz
  [                   ! N
    is-buzz           ! isBuzz
    [ "FizzBuzz" ]    ! "FizzBuzz"
    [ "Fizz" ]        ! "Fizz"
    if
  ]
  [
    dup               ! N N
    is-buzz           ! N isBuzz
    [ drop "Buzz" ]   ! "Buzz"
    [ number>string ] ! "N"
    if
  ]
  if
;

! does not remove top of the stack
: print-fizzbuzz ( n -- n )
  dup fizzbuzz print
;

1
[
  print-fizzbuzz
  1 +
  dup 100 <=
]
loop
drop


팩터를 사용해야 합니까?



아니.

가져오기 시스템은 터무니없이 나쁘고 그냥 아무렇지 않게 언어를 가지고 놀고 싶다면 언어의 좋은 점을 압도합니다.

당신이 정말로 진지하고 모든 수입품을 암기할 의향이 있다면, 그것은 효과가 있을 수 있지만, 결국에는 그렇게 많은 보상이 없습니다. 특별한 것도 없고 명확한 사용 사례도 없는 또 다른 스택 기반 언어입니다.

플레이할 스택 기반 언어를 선택하려는 사람들에게는 재미를 최대화하고 싶은 난해한 언어 중 하나를 추천합니다. 그들 중 어느 것도 진지하게 사용하기에 좋지 않습니다.

스택을 올바르게 얻을 수 있다고 신뢰하는 대부분의 다른 스택 기반 언어와 달리 Factor는 스택 효과 주석이 필요하며 일종의 "유형 시스템"에서 잘못 이해하면 컴파일되지 않습니다. 이것은 틀림없이 도움이 될 것이지만, 당신이 받는 오류 메시지는 정말 끔찍합니다. 이것은 또한 대부분의 유형 시스템에서 일반적입니다.

암호



All code examples for the series will be in this repository .

Code for the Factor episode is available here .

좋은 웹페이지 즐겨찾기