wisp
 
(Arne Babenhauserheide)
2016-06-07: merge with

merge with

diff --git a/examples/d6.w b/examples/with.w
copy from examples/d6.w
copy to examples/with.w
--- a/examples/d6.w
+++ b/examples/with.w
@@ -1,42 +1,39 @@
 #!/usr/bin/env sh
 # -*- wisp -*-
-exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples d6) main)' -s "$0" "$@"
+exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples with) main)' -s "$0" "$@"
 ; !#
 
-define-module : examples d6
-   . #:export : roll check
+;; A cleaner way to implement this might be using dynamic-wind.
 
-use-modules : srfi srfi-1
+;; FIXME: This might not be continuation-safe and might break if the
+;; code in the with block uses dynamic-wind. Check whether it’s safe
+;; and fix it if not.
 
-; basic d6 rules, implemented in guile
+define-module : examples with
 
-define : roll
-    . "Roll one ± d6"
-    let* 
-        : eyes '(-5 -3 -1 2 4 6)
-          d6 : lambda () : list-ref eyes : random 6 : random-state-from-platform
-        let rolling : : rolled : cons (d6) '()
-            cond
-              : = 1 (length rolled)
-                if : not : member (first rolled) '(-5, 6)
-                     first rolled
-                     rolling : cons (d6) rolled
-              : not : equal? (first rolled) (second rolled)
-                apply + : cdr rolled
-              else
-                rolling : cons (d6) rolled
-                
-                
-          
-define : check skill target effect-threshold
-    . "Check whether a given skill-roll succeeds and provide a margin of success."
-    let : : result : + skill : roll
-        if : > result target
-            floor/ {result - target} effect-threshold
-            . #f
+import : oop goops
+
+define : enter thing
+       . thing
+define-generic enter
+
+define : exit thing
+       . thing
+define-generic exit
+
+define-syntax with
+    syntax-rules : as
+      : _ thing as name thunk ...
+        let*
+           : name : enter thing
+             res : begin thunk ...
+           exit thing
+           . res
+
+define-method : exit (thing <port>)
+              . "Ensure that a port is always closed at the end of the with-block."
+                close-port thing
 
 define : main args
-         display : check 12 9 3
-         newline
-         newline
-         display : roll
+         with (open-file "with.w" "r") as port
+              format #t "~a\n" : read port