Reputation: 624
I'm looking to implement some proof-of-concept demo for a short presentation in which the running code is aware of a hashed 'value' of the currently executing block of code. For example:
function BBB(a) {
a = 2 * a;
print me.hash; --> "xxxxxxx" (value of BBB-syntax represenation)
return a;
}
function AAA(a, b, c) {
d = BBB(a);
print me.hash; --> "yyyyyyy" (value of AAA-Syntax representation, possibly dependant on value of BBB, but not necessary)
return d;
}
I instinctively turned to LISPish languages, but had no success with Scheme yet. And I've not been in touch with Common LISP for a long time, which I suspect might be able to do it (hints appreciated). It doesn't have to be fast, or a popular platform, can be the most academic and weird platform available. It's just a demo.
Does anybody know a language/platform that can do this pretty much out of the box or with relatively little tinkering? I'd prefer some kind of parsed/treeish thing to work with, not actual source code.
Upvotes: 3
Views: 220
Reputation: 2671
You guessed it. Common Lisp can do it pretty easily:
(defmacro reflective-defun (name args &body body)
(let ((source-form `(reflective-defun ,name ,args ,@body)))
`(let ((me ',source-form))
(defun ,@(cdr source-form)))))
(reflective-defun bbb (a)
(setf a (* 2 a))
(print me)
a)
(reflective-defun aaa (a b c)
(let ((d (bbb a)))
(print me)
d))
(aaa 12 :x :y)
Output:
(REFLECTIVE-DEFUN BBB
(A)
(SETF A (* 2 A))
(PRINT ME)
A)
(REFLECTIVE-DEFUN AAA
(A B C)
(LET ((D (BBB A)))
(PRINT ME)
D))
24
Here's how you can write a self-redefining function:
(defun recursive-replace (tree what with)
"Walks down the TREE and replaces anything that is EQUALP to WHAT with WITH."
(cond ((equalp tree what)
with)
((listp tree)
(loop for item in tree
collect (recursive-replace item what with)))
(t tree)))
(reflective-defun ccc (a b c)
(let ((d (bbb a)))
(print me)
(if (eql b :use-me-from-now-on)
(eval (recursive-replace me '(bbb a) '(bbb b))))
d))
Incidentally, Scheme (and any language where the macros are hygienic) will fight you tooth and nail to prevent you from creating an identifier called me
that can be referenced by source code passed to a macro.
Upvotes: 7
Reputation: 17041
Not a hash, but for a unique ID, you could use Python object identities. Put each function in its own class and then use id()
. An example, in Python 3:
class cBBB(object):
def do(a):
a=2*a
print(self.id()) # self.id() is the "hash"-like unique value
return a;
BBB = cBBB() # now you can call BBB.do(a)
class cAAA(object):
def do(a,b,c):
d = BBB.do(a)
print(self.id()) # self.id() is the "hash"-like unique value
return d;
AAA = cAAA() # now you can call AAA.do(a,b,c)
This can be done more cleanly using __call__
. See, e.g., this question for more on __call__
.
Upvotes: 0