![]() |
![]() |
|
home—info—lectures—exams—archive
Talking points:
Java makes using Strings easy: it will automatically call toString in certain contexts1, it will automatically call the constructor when you give a string-literal2, it will automatically call concat method if 3 say +, etc.. Of course, these are nothing fundamental -- just shallow, syntactic niceties.
Scheme doesn't provide syntactic help for strings. However, it does provide shortcuts for lists: we've already seen ' (quote).
'(a b 3 "hi" c) = (list 'a 'b 3 "hi" 'c) '(a b (c d (e ()))) = (list 'a 'b (list 'c 'd (list e empty))) |
`(a b (+ 3 4) ,(+ 3 4)) = (list 'a 'b (list '+ 3 4) 7) `(a b ,(list (+ 3 4) 5)) = (list 'a 'b (list 7 5)) `(a b ,@(list (+ 3 4) 5)) = (list 'a 'b 7 5) |
`(a b ,@(list (+ 3 4) 'w `(x y ,(sqrt 16) z) 5)) = (list 'a 'b 7 '2 (list 'x 'y 4 'z) 5) |
Since lists are convenient to use in Scheme, we're showing how to implement xml not with structs (the arguably proper way), but instead with lists. But, even though we're not using structs, we're still maintaining the data abstraction by providing our own accessors and predicates (and, if we wanted, mutators):
(define xtag-tag first)4 (define xtag-attrs second) (define xtag-contents (compose rest rest))5 |
Btw, what does this show us? That if we had a language which included lists but not define-struct, we wouldn't terribly mind: we could always implement our ersatz structs as lists. In fact, how do you think scheme implements structs internally? Sure, it probably keeps them as lists: (make-foo 7 'hi) is really returning (list 7 'hi).
One glitch with that , though: clearly (make-foo 7 'hi) is different from (make-lala 7 'hi): they're both structs with two fields, but they're different types! Alas, if they both were internally represented as (list 7 'hi), then we lose that distinction. Solution? Yep -- scheme *really* adds a hidden tag to every struct. (And, in fact, to every datum; even ints carry along some extra bits indicating that they're ints.)
Digression on static typing vs. carrying this info. ML's approach (and its strength/weaknesses). The halting problem gets mentioned.
Exercise: let's write handle-em, which: replaces its tag explicitly with an i tag, and puts all of its children in blue font: (Draw parse tree before&after.)
if the current tag is "em", then call handle-em,Rather than hard-code it, we'll be more flexible: we'll create an association-list of processors. xnode2.ss How to the node's process children?
else if it's "html", call handle-html,
else if it's ….
We'll see tomorrow: We can now dymically 'override' processors by cons'ing on new processors when we recur! This is the same flavor as dynamic scoping: an 'em' tag which is inside a 'list' tag might be processed differently than one that isn't!
1 Java also does automatic type-conversion in other instances, too ↩
2 Actually, the compiler checks for multiple uses of the same string-literal, and is free (but not required!) to share memory. This means that the result of if ("hi"=="hi") … is compiler-dependent. ↩
3 This isn't quite precise: the compiler is allowed to pre-compute literal-string concatenations at compile time, but calls to concat must be made at run-time. ↩
4This could be written equivalently as: (define (xtag-tag some-xtag) (first some-xtag)) ↩
5 This could be written equivalently as: (define (xtag-contents some-xtag) (rest (rest some-xtag))) ↩
home—info—lectures—exams—archive
©2008, Ian Barland, Radford University Last modified 2008.Nov.03 (Mon) |
Please mail any suggestions (incl. typos, broken links) to ibarland ![]() |
![]() |