Curious if any of the more advanced folks on this board can show how to properly do the above code (such that I can learn from). Or is the above code not so bad after all? Thanks.
Thus, instead of doing (defop r), it's kind of like we're doing (defop (eval r)). That is, instead of expanding into
(defop r req (rpage 'r))
we're expanding into
(defop 10a req (rpage '10a)) ; when r == '10a
(defop 10b req (rpage '10b)) ; when r == '10b
; etc
We could've done the eval inside the macro, too, but that's often a sign you're doing something wrong --- macros are usually there to not evaluate their arguments. So we should probably use a function.
However, defop itself is a macro, so the first parameter (the op's name) won't be evaluated regardless. We still need eval.
Since this approach seems to require eval regardless, we should just look for a better solution. aw's works nicely.
Some other nitpicks over your rewrite (hey, you asked!):
1) Unless you need strings for some reason, you can probably default to symbols (they're a bit easier to use).
; Instead of
(= routes* '("10a" "10b" "15a" "20a" "20b" "30a" "30b" "30c" "40a" "59u"))
; we could use
(= routes* '(10a 10b 15a 20a 20b 30a 30b 30c 40a 59u))
2) Proper spacing & indentation saves lives. :)
; Instead of
(defop shuttle req
(each r routes* (link r)(nbsp)))
; why not
(defop shuttle req
(each r routes* (link r) (nbsp)))
; or even
(defop shuttle req
(each r routes*
(link r)
(nbsp)))
3) Though using symbols renders this point moot, fromstring is unnecessary to simply (read) from a string, since Arc's definition of read is
(def read ((o x (stdin)) (o eof nil))
(if (isa x 'string) (readstring1 x eof) (sread x eof)))
So, instead of
(fromstring rs (read))
you can use
(read rs)
If your goal is just to turn a string into a symbol, you should use
(sym rs)
This is an important distinction. e.g.,
arc> (sym "abc")
abc
arc> (read "abc")
abc
arc> (sym "(a b c)")
|(a b c)|
arc> (type that)
sym
arc> (read "(a b c)")
(a b c)
arc> (type that)
cons
Very instructive. Thank you for doing such a thorough analysis.
',r from your snippet
(mac rdefop (r)
`(defop ,r req (rpage ',r)))
was a realization for me. Never thought of quoting a comma'd symbol in a backquoted expression before, but I like knowing it's possible. Do you find yourself doing this much, or is there usually something simpler like aw's solution available to make it unnecessary?