(defun mirror (tree)
(when tree
(tree
(tree-data tree)
(mirror (tree-right tree))
(mirror (tree-left tree)))))
For completness, here are the definitions: (defpackage :trees (:use :cl)
(:shadow #:copy-tree))
(in-package :trees)
(defstruct (tree (:constructor tree (data &optional left right))
(:type list))
data left right)
As well as a test case: (mirror (tree 4
(tree 2
(tree 1)
(tree 3))
(tree 7
(tree 6)
(tree 9))))
=> (4 (7 (9 NIL NIL) (6 NIL NIL)) (2 (3 NIL NIL) (1 NIL NIL))) (document
#1=(author (id "Bob") ... )
#2=(author (id "Alice") ... )
(span (author #1#) "written by Bob")
(span (author #2#) "written by Alice")
(span (author #1#) "written by Bob"))
I do not claim that this is the most appropriate solution in all cases, just that we are not forced to introduce indirection levels when unnecessary. Now, if I am using Lisp and I want to introduce external references to authors described in other documents, I could introduce a meta-data with an appropriate semantical structure: (external-element (pathname (directory (relative "path" "to"))
(type "lisp")
(name "file"))
(tree-path 2 1 3 2 2 3))
This would be a practical way to encode a precise location in a tree in an external file. And I could use this form everywhere I need to reference an object. Also, the tree-path notation is handy because there is no distinction between an attribute or an element, just which branch to take at each step from the root. <author xref="xref02">
...
<xref id="xref02">
<pathname> ... </pathname>
<tree-path> ... </tree-path>
</xref>
Or, we do as everybody and encode it like for XMI, or ECORE, or any other custom format, with a complex string, hoping that HTML entities are properly escaped. reply?id=9556252&goto=item%3Fid%3D9555880"
href="vote?for=9556252&dir=up&auth=0UU000REDACTED000208d8b9f4a45575b4edea3779&goto=item%3Fid%3D9555880"
Notice how you need to escape HTML entities in inline javascript attributes (onclick) but not on script tags. Why are inline javascript not tags instead? <root>
<document author="id0"
published_in="ACM"
publication_date="2010/03/02"
publication_volume=345
link="doi://1020301.202.301.1023"
reviewers_id="id1;id2;id3;id4">
... content ...
</document>
<peoples>
<people id="id0"><name>John Doe</name>...</people>
<people id="id1">...</people>
<people id="id2">...</people>
<people id="id3">...</people>
<people id="id4">...</people>
</peoples>
<root>
Notice how informations about publication are scattered into different attributes instead of being a single attributes with sub-components? (has the document been published in March or February? In which timezeone?) (link (protocol doi)
(path (digits 1020301 202 301 1023)))
Each time you use a string to encode structured information in an attribute with a custom mini-language, you are asking for trouble.
Imagine how each of those strings now need to have a dedicated parser because you need to take care of escaping "special" characters. (document (author (name "John Doe") (job-title "Professor") (institution "MIT"))
(anchor
(link (protocol doi)
(path (digits 1020301 202 301 1023)))
(target blank-page))
(reviewers (reviewer (name "..."))
(reviewer (name "..."))
...)
(encoding (utf 8))
(sections
...))
Then, you have multiple layers of "meta"-informations, instead of just 2: "data" and "dumb meta-data".
I agree we disagree, but I do not think both approaches are equal.
You talk about tradeoffs, but I really do not see anything useful in having attributes, whereby I can see the inconvenience they bring when trying to structure information in a meaningful way. (ql:quickload :drakma)
(ql:quickload :cl-json)
(ql:quickload :local-time)
(defparameter *data*
(cl-json:decode-json-from-string
(drakma:http-request
"https://gist.githubusercontent.com/jorin-vogel/7f19ce95a9a842956358/raw/e319340c2f6691f9cc8d8cc57ed532b5093e3619/data.json")))
(with-open-file
(stream (make-pathname
:name (local-time:format-timestring
t
(local-time:now)
:format '((:year 4)(:month 2)(:day 2)))
:type "csv")
:direction :output
:if-exists :supersede)
(loop initially (format stream "Name,Credit Card~%")
for slot in *data*
for name = (cdr(assoc :name slot))
for card = (cdr(assoc :creditcard slot))
when (and name card)
do (format stream "~a,~a~%" name card)))
- SmugCeeWeenie: I am so fast, look (oops, core dumped)
- SmugGoWeenie: abstractions are so nasty we should get rid of functions, so that everyhting is laid out clearly. Hopefully, I have copy/paste.
- SmugAdaWeenie: Functions are not procedures and records cannot store objects. Real engineers do not "prototype" code.
- SmugHaskellWeenie: Yeah, it compiles! Job done.
> In the space year 2015 people are still doing this.
About first class functions? citation needed.