2

Я ищу для демонстрации демонстрационной концепции для краткой презентации, в которой запущенный код знает хэшированное «значение» исполняемого в настоящее время блока кода , Например:Язык программирования/платформа с доступом во время работы к AST

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; 
} 

Я инстинктивно повернулся к LISPish языков, но не имел успеха с Scheme еще. И я давно не общался с Common LISP, и я подозреваю, что смогу это сделать (подсказки оценены). Он не должен быть быстрым, или популярной платформой, может быть самой доступной академической и странной платформой. Это просто демо.

Кто-нибудь знает язык/платформу, которая может сделать это в значительной степени из коробки или с относительно небольшим мастерингом? Я бы предпочел какую-то разборную/деревенскую работу, а не фактический исходный код.

+0

В обычном общем Lisp работающая функция не знает о себе. В конкретных реализациях должно быть возможно проверить стек. –

ответ

6

Вы догадались. Common Lisp может сделать это довольно легко:

(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) 

Выход:

(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 

Вот как вы можете написать самостоятельно переопределение функции:

(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)) 

Кстати, Scheme (и любой язык, где макросы гигиеничны) будут сражаться с вами зубами и гвоздями, чтобы вы не могли создать идентификатор с именем me, на который можно ссылаться исходным кодом, переданным макросу.

+0

Помимо отсутствия документации, гигиена, кажется, является стеной, с которой я работал против Джулии. Большое спасибо! Это именно то, что мне нужно. – Secoe

0

Не хэш, но для уникального идентификатора вы можете использовать идентификаторы объектов Python. Поместите каждую функцию в свой класс, а затем используйте id(). Пример, в 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) 

Это можно сделать с помощью более аккуратно __call__. См., Например, this question для получения дополнительной информации о __call__.

Смежные вопросы