shibata

部分継続call/pc

call/pcを使えば「2つの数値を入力して和を返す」3ページの遷移を次のように書ける。

(define-entry (sum)
  (main-page
   (h1: "sum is")
   (number->string
    (+ (read-input "first number")
       (read-input "second number")))))

ページ遷移は

first number入力ページ
↓
second number入力ページ
↓
sum is ページ

となる。

ユーザの入力が必要な時に入力ページを表示し、入力結果をそのまま使えて良い感じ。

(define (read-input label)
  (let/pc cont
          (main-page
           (h1: label)
           (form/cont:
            (@@: (cont (entry-lambda (:keyword input)
                                     (cont (string->number input)))))
            (input: (@: (type "text") (name "input")))
            " "
            (input: (@: (type "submit") (value "Submit")))))))

ちょっとしたマクロを組めば、昔話題になったElevenっぽい書き方もできる。

(define-entry (hello)
  (statesafe: (first last)
    (display:
      (print: "Please enter your name")
      (edit: "First name:" first)
      (edit: "Last name:" last))
    (display:
      (print: "Thank you"  first " " last "."))))

ページ遷移は

Please enter your name
First name [    ]
Last name [    ]
↓
Thank you ほげ ほげ

となる。

階乗を計算し続けるアプリケーション(elvenのサンプルそのまんま)

(define-entry (fact)
  (statesafe: (i)
    (display:
      (print: "Welcome to the factorial program (demonstrating recursive functions).")
      (edit: "Input value: " i))
    (let loop ()
      (statesafe: (f)
        (set! f (factrial i))
        (display:
          (print: "The factorial of " i " is " f ".")
          (edit: "Enter another input value: " i))
        (loop)))))

こんなのはどうだろう

(define (read-name)
  (let/pc cont
    (main-page
     (form/pc: cont
       (print: "Please enter your name.")
       (edit: "First name: " first)
       (edit: "Last name: " last)
       (input: (@: (type "submit")
                   (value "OK")))))))

(define-entry (r-hello)
  (let ((request (read-name)))
    (main-page
     (print: "Thank you"
             (ref request "first")
             " "
             (ref request "last")
             "."))))

マクロとかぐちゃぐちゃですがコードです。

Powered by Kahua