summaryrefslogtreecommitdiff
path: root/artima
diff options
context:
space:
mode:
authormichele.simionato <devnull@localhost>2009-06-29 15:29:18 +0000
committermichele.simionato <devnull@localhost>2009-06-29 15:29:18 +0000
commit9a2b047ebd4ff546ce0acaa462bcbf17123587c7 (patch)
tree60661c4ab3fe98260c785d7dbf47e037d2f4e1fc /artima
parentd8e3dcdb814db0c6c11e85cf6961a6691c3d8d00 (diff)
downloadmicheles-9a2b047ebd4ff546ce0acaa462bcbf17123587c7.tar.gz
Added two pictures and minor changes
Diffstat (limited to 'artima')
-rw-r--r--artima/scheme/Love_equality.pngbin0 -> 24830 bytes
-rw-r--r--artima/scheme/scarti.txt113
-rw-r--r--artima/scheme/scheme28.ss8
-rw-r--r--artima/scheme/you-are-here.pngbin0 -> 101834 bytes
4 files changed, 115 insertions, 6 deletions
diff --git a/artima/scheme/Love_equality.png b/artima/scheme/Love_equality.png
new file mode 100644
index 0000000..980bc8d
--- /dev/null
+++ b/artima/scheme/Love_equality.png
Binary files differ
diff --git a/artima/scheme/scarti.txt b/artima/scheme/scarti.txt
index e946906..f46187b 100644
--- a/artima/scheme/scarti.txt
+++ b/artima/scheme/scarti.txt
@@ -1009,3 +1009,116 @@ professional languages which are too tricky to use
for the casual programmer. We have also examples of languages which
are both weak in power *and* difficult to use (insert your chosen
language here).
+
+;Writing your own language
+;------------------------------------
+
+(import (except (rnrs) let) (rename (rnrs) (let let-orig)) (sweet-macros))
+
+(def-syntax let
+ (syntax-match ()
+ (sub (let () lst e e* ...)
+ #'(if (null? lst) (begin e e* ...)
+ (apply error 'let "Too many elements" lst)))
+ (sub (let (arg1 arg2 ... . rest) lst e e* ...)
+ #'(let-orig ((ls lst))
+ (if (null? ls)
+ (apply error 'let "Missing arguments" '(arg1 arg2 ...))
+ (let arg1 (car ls)
+ (let (arg2 ... . rest) (cdr ls) e e* ...)))))
+ (sub (let name value e e* ...)
+ #'(let-orig ((name value)) e e* ...)
+ (identifier? #'name)
+ (syntax-violation 'let "Argument is not an identifier" #'name))
+ ))
+
+(def-syntax (named-let name n v b b* ...)
+ #'(letrec ((name (lambda (lst) (let n lst b b* ...))))
+ (name v))
+ (identifier? #'name))
+
+
+;(write (let (x) (list 1) x))
+;(write (let (x y) (list 1 2) (+ x y)))
+(write (let (x y x) (list 1 2 3) (+ x y)))
+
+
+.. http://community.schemewiki.org/?syntactic-closures
+.. http://community.schemewiki.org/?hygiene-versus-gensym
+
+extra-long thread "What's up with Scheme macros?" Feb 12 2008
+.. http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/75c5f5e550b905d3/9bb9ea36925d4040?#9bb9ea36925d4040
+
+my own thread about phase separation
+.. http://groups.google.com/group/ikarus-users/browse_frm/thread/ec579ad3b619f2d5/7e10a07a8f6789b4?hl=ene10a07a8f6789b4
+
+
+Take for instance this piece of code:
+
+.. code-block:: scheme
+
+ (let ((a 1))
+ (let ((a 2))
+ ...))
+
+Is the first ``a`` equal to the second ``a``? They are bound to
+different values.
+Moreover, consider the following:
+
+.. code-block:: scheme
+
+ (let ((a 1))
+ (let ((b a))
+ ...))
+
+Here ``a`` and ``b`` are different names for the same value, but they
+have different lexical context . Should they
+be considered equal?
+
+Notice that two aliases (same name, same binding) are *not*
+considered ``free-identifier=?``:
+
+.. code-block:: scheme
+
+ > (define a 1)
+ > (define b a) ;; alias for a
+ > (free-identifier=? #'a #'b)
+ #f
+
+
+You can leverage on ``free-identifier=?`` to define a function which is able
+to determine if an identifier is bound or unbound. The trick is to
+take the identifier and to strip its lexical context form it;
+if the identifier was unbound, stripping the lexical context
+does not change much, and the original identifier is
+``free-identifier=?`` to its stripped version. On th other hand,
+if the original identifier was bound in its lexical context,
+it will not be ``free-identifier=?`` to its stripped version.
+
+The R6RS standard does not specify a way to create a truly minimal
+context (i.e. one where no names are bound) however in all R6RS
+implementations (except Ypsilon) ``generate-temporaries``
+returns identifiers with an empty context, so that the
+following trick does the job:
+
+$$lang:UNBOUND?
+
+
+
+What happens if I pass to the macro an identifier ``id`` named ``forbidden``?
+Should it be considered equal to the literal identifier ``#'forbidden``?
+What if ``id`` is bound and what what if ``id`` is unbound? Moreover,
+how do we compare identifiers in systems with full phase separation,
+since an identifier can be bound in a phase and unbound in another
+phase? Finally, what if ``check-id`` is used inside as follows:
+
+.. code-block:: scheme
+
+ (def-syntax (check forbidden)
+ (check-id #'forbidden))
+
+Should ``forbidden`` in this context be traited as a dummy name
+or should it raise a ``syntax-violation``?
+
+This episode will be spent discussing the subtilities of identifier
+equality.
diff --git a/artima/scheme/scheme28.ss b/artima/scheme/scheme28.ss
index af25a29..5ae4b42 100644
--- a/artima/scheme/scheme28.ss
+++ b/artima/scheme/scheme28.ss
@@ -134,6 +134,7 @@ of ``define-macro`` in many references; I learned it from
.. _On Lisp: http://www.paulgraham.com/onlisp.html
.. _hygiene in R6RS: http://docs.plt-scheme.org/r6rs-lib-std/r6rs-lib-Z-H-13.html#node_sec_12.1
.. _post by Alex Shinn: http://lists.gnu.org/archive/html/chicken-users/2008-04/msg00013.html
+.. _chapter about syntax-case: http://www.cs.indiana.edu/~dyb/pubs/bc-syntax-case.pdf
The hygiene problem
---------------------------------------------------------------------
@@ -154,7 +155,7 @@ You can find good discussions of the hygiene problem in Common Lisp in
many places; I am familiar with Paul Graham's book `On Lisp`_ which I
definitively recommend: chapter 9 on variable capture
has influenced this section. Another good
-reference is the chapter about ``syntax-case`` - by Kent Dybvig - in
+reference is the `chapter about syntax-case`_ - by Kent Dybvig - in
the book `Beautiful Code`_. Here I will give just a short example
exhibiting the problem, for the sake of the readers unfamiliar with
it.
@@ -305,8 +306,3 @@ hygiene on purpose, don't miss it!
(unless (>= i stop) body1 body2 ... (loop (+ 1 i))))))
;END
-;DEFINE-A
-(define-macro (define-a x)
- `(define a ,x))
-;END
-
diff --git a/artima/scheme/you-are-here.png b/artima/scheme/you-are-here.png
new file mode 100644
index 0000000..ac8adc5
--- /dev/null
+++ b/artima/scheme/you-are-here.png
Binary files differ