2013-07-02 3 views
8

Let Over Lambda Chapter 3 Section 'Unwanted Capture' sagt:..Was kann schief gehen, wenn ich ein Makro definiere und nur einen seltenen Namen für eine temporäre Variable verwende?

„Sicher können wir selten genug Namen denken, so dass das Problem nie auftaucht Ja, in vielen Fällen, die Pakete und intelligente variable Namensgebung kann das Problem der variablen Erfassung lösen jedoch schwerwiegendsten Variable Capture Fehler im Code nicht direkt von einem Programmierer erstellt wurden, auftreten. Die meisten variable Erfassung Probleme nur Oberfläche wenn andere Makros Makro verwenden (mit Ihrem Makro kombinieren) in einer Weise, Sie erwarten nicht. "

und dann gibt mir kein Beispiel für den kühnen Teil. Was wäre eines dieser Beispiele? Stellen Sie sich eine hypothetische Lisp Dev-Team, wo seine verrückten Chef die Verwendung von gensym verboten oder alles, was zu werfen alphanumerische Würfel uninterned Symbole und die Programmierer einfach greifen schafft, um mit Zufallsvariablen Namen wie temp-27s63f8sk2n oder Summen 3t84hj4df, wann immer sie gensym verpassen. Was wäre ein Beispiel, wo das Team in Schwierigkeiten geraten wird?

davon Speaking, Emacs 24.3.1 definiert DOTIMES und DOLIST ohne uninterned Symbole zu verwenden. Seltsam.

+6

Warum stimmen die Menschen dies zu schließen? Es ist eine echte und komplexe Frage. – d11wtq

Antwort

1

Das Problem entsteht, wenn Sie Ihr eigenes Makro in einem anderen Kontext wiederverwenden und Ihre geschickt Namespace-Variablen sind effektiv dann überflüssig, da sie alle auf dem gleichen Namensraum sind.

kann ich ein Beispiel denke, dass, wenn ein Verschluss verwenden, die eine Variable in einem umschließenden (let) zugreift, sondern auf einen Makro übergeben, die auch eine umschließende (let), die einen „sicheren“ Variable mit einem Namen Zusammenstoß verwendet. Es ist ein künstliches Beispiel, tut mir leid, ich kann mir im Moment keinen realen Fall vorstellen.

(defmacro my/a (x) 
    (let ((my/safe-name x)) 
    `(progn ,(my/b (lambda() my/safe-name)) 
      ,my/safe-name))) 

(defmacro my/b (f) 
    `(let ((my/safe-name 4)) 
    (when (evenp (funcall ,f)) 
     (print "F is even!")))) 

(my/a 3) ; will print "F is even", but it shouldn't 
+0

Ein übliches Entwicklerteam schreibt das mit * zwei * Gensyms oder Calls-Symbols. Das hypothetische Entwicklerteam wird seinen pseudozufälligen alphanumerischen Postfix-Generator * zweimal * ausführen. So wird es sein ((mein/safe-name-6kuyd4kq x)) in meinem/a und ((meinem/safe-name-pqedzkwg 4)) in meinem/b. Damit dieses Team in Schwierigkeiten gerät, würden wir Code benötigen, der so erweitert wird, dass er irgendwie meinen/safe-name-6kuyd4kq aufgreift und es mit sich selbst kollidieren lässt. Ich vermute, dass dies der kühne Teil ist, außer es fehlt ein Beispiel, also kann ich nicht sicher sein. –

+0

Die Verwendung von Gensym ist genau das, was Doug Hoyte als Lösung für unerwünschte Aufnahmen vorschlägt. Sie haben nur Probleme, wenn Sie die Verwendung von Gensymmen vernachlässigen. Das ist es, was Hoyte zu sagen versucht. An dieser Stelle des Buches geht er davon aus, dass Sie noch nichts über Gensymmen wissen, nur handverlesene (aber Namensräume) Variablennamen. – d11wtq

2

OK, dann würde ich vorschlagen, diesen Prozess zu automatisieren, "alphanumerische Würfel zu werfen". Natürlich muss es nicht zufällig sein, Sie könnten einfach einen Zähler verwenden. Außerdem wäre es schön, ein Präfix zum Debuggen angeben zu können. Oh warte, genau das tut gensym.

+0

Gensym gibt Symbole ohne Unterbrechungen zurück. Das hypothetische Team verwendet nur INTERNED-Symbole. Wenn das Team auf 'intern-gensym' stützt, die wie' gensym' ist außer es internierten Symbole gibt, dann werden sie in Schwierigkeiten geraten, weil die Namen G10, G11, G12 .... nicht selten genug sind, und es gibt eine Chance, dass Benutzer von Makros solche Variablennamen verwenden würden, und ein solches Beispiel ist im verknüpften Let Over Lambda-Artikel gegeben. –

+0

Wenn das Team internierte Symbole mit zufälligem Postfix verwendet, können Probleme eines solchen Beispiels vermieden werden. Dann sagt der Artikel, dass es noch einen anderen Weg gibt, Ärger zu bekommen, der kühne Teil im Zitat. Kann der mutige Teil das Team in Schwierigkeiten bringen? –

Verwandte Themen