Skip to main content
Typo
Source Link
(defun trace (symbol) (setf (get symbol 'old-def) (fdefinition symbol) (fdefinition symbol) (lambda (&rest args) (print (cons symbol args)) (apply (get symbol 'old-def) args)))) (defun untrace (symbol) (setf (fdefinition symbol) (get symbol 'old-def)) (remprop symbol 'odd'old-def)) 
(defun trace (symbol) (setf (get symbol 'old-def) (fdefinition symbol) (fdefinition symbol) (lambda (&rest args) (print (cons symbol args)) (apply (get symbol 'old-def) args)))) (defun untrace (symbol) (setf (fdefinition symbol) (get symbol 'old-def)) (remprop symbol 'odd-def)) 
(defun trace (symbol) (setf (get symbol 'old-def) (fdefinition symbol) (fdefinition symbol) (lambda (&rest args) (print (cons symbol args)) (apply (get symbol 'old-def) args)))) (defun untrace (symbol) (setf (fdefinition symbol) (get symbol 'old-def)) (remprop symbol 'old-def)) 
add trace/untrace
Source Link
sds
  • 60.5k
  • 31
  • 178
  • 303

First of all, one should never underestimate the importance of style. We write code not just for computers to run, but, much more importantly, for people to read. Making code readable and understandable for people is a very important aspect of software development.

The "small" differences are that defun can also set the doc string of the function name (actually, depending on how your imeplementation works, it might do that with lambda also), and creates a named block (seen in the macroexpansions below) which you would otherwise have to create yourself if you want to.

This does not mean that setf fdefinition has no place in a modern lisp codebase. You can use it, e.g., to implement a "poor man's trace" (UNTESTED):

(defun trace (symbol) (setf (get symbol 'old-def) (fdefinition symbol) (fdefinition symbol) (lambda (&rest args) (print (cons symbol args)) (apply (get symbol 'old-def) args)))) (defun untrace (symbol) (setf (fdefinition symbol) (get symbol 'old-def)) (remprop symbol 'odd-def)) 

First of all, one should never underestimate the importance of style. We write code not just for computers to run, but, much more importantly for people to read. Making code readable and understandable for people is a very important aspect of software development.

The "small" differences are that defun can also set the doc string of the function name (actually, depending on how your imeplementation works, it might do that with lambda also), and creates a named block which you would otherwise have to create yourself if you want to.

First of all, one should never underestimate the importance of style. We write code not just for computers to run, but, much more importantly, for people to read. Making code readable and understandable for people is a very important aspect of software development.

The "small" differences are that defun can also set the doc string of the function name (actually, depending on how your imeplementation works, it might do that with lambda also), and creates a named block (seen in the macroexpansions below) which you would otherwise have to create yourself if you want to.

This does not mean that setf fdefinition has no place in a modern lisp codebase. You can use it, e.g., to implement a "poor man's trace" (UNTESTED):

(defun trace (symbol) (setf (get symbol 'old-def) (fdefinition symbol) (fdefinition symbol) (lambda (&rest args) (print (cons symbol args)) (apply (get symbol 'old-def) args)))) (defun untrace (symbol) (setf (fdefinition symbol) (get symbol 'old-def)) (remprop symbol 'odd-def)) 
mention `block`
Source Link
sds
  • 60.5k
  • 31
  • 178
  • 303

The "small" difference isdifferences are that defun can also set the doc string of the function name (actually, depending on how your imeplementation works, it might do that with lambda also), and creates a named block which you would otherwise have to create yourself if you want to.

thanthen the compiler will probably warn you that you call foo in bar with the wrong number of arguments:

CLISP expands it to

(LET NIL (SYSTEM::REMOVE-OLD-DEFINITIONS 'FOO) (SYSTEM::EVAL-WHEN-COMPILE (SYSTEM::C-DEFUN 'FOO (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '(X)))) (SYSTEM::%PUTD 'FOO (FUNCTION FOO (LAMBDA (X) "doc" (DECLARE (SYSTEM::IN-DEFUN FOO)) (BLOCK FOO (PRINT X))))) (EVAL-WHEN (EVAL) (SYSTEM::%PUT 'FOO 'SYSTEM::DEFINITION (CONS '(DEFUN FOO (X) "doc" (PRINT X)) (THE-ENVIRONMENT)))) 'FOO) 

SBCL does:

(PROGN (EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-C:%COMPILER-DEFUN 'FOO NIL T)) (SB-IMPL::%DEFUN 'FOO (SB-INT:NAMED-LAMBDA FOO (X) "doc" (BLOCK FOO (PRINT X))) (SB-C:SOURCE-LOCATION))) 

The point here is that defun has a lot "under the hood", and for a reason. setf fdefinition is, on the other hand, more of "what you see is what you get", i.e., no magic involved.

The "small" difference is that defun can also set the doc string of the function name.

than the compiler will probably warn you that you call foo in bar with the wrong number of arguments:

The "small" differences are that defun can also set the doc string of the function name (actually, depending on how your imeplementation works, it might do that with lambda also), and creates a named block which you would otherwise have to create yourself if you want to.

then the compiler will probably warn you that you call foo in bar with the wrong number of arguments:

CLISP expands it to

(LET NIL (SYSTEM::REMOVE-OLD-DEFINITIONS 'FOO) (SYSTEM::EVAL-WHEN-COMPILE (SYSTEM::C-DEFUN 'FOO (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '(X)))) (SYSTEM::%PUTD 'FOO (FUNCTION FOO (LAMBDA (X) "doc" (DECLARE (SYSTEM::IN-DEFUN FOO)) (BLOCK FOO (PRINT X))))) (EVAL-WHEN (EVAL) (SYSTEM::%PUT 'FOO 'SYSTEM::DEFINITION (CONS '(DEFUN FOO (X) "doc" (PRINT X)) (THE-ENVIRONMENT)))) 'FOO) 

SBCL does:

(PROGN (EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-C:%COMPILER-DEFUN 'FOO NIL T)) (SB-IMPL::%DEFUN 'FOO (SB-INT:NAMED-LAMBDA FOO (X) "doc" (BLOCK FOO (PRINT X))) (SB-C:SOURCE-LOCATION))) 

The point here is that defun has a lot "under the hood", and for a reason. setf fdefinition is, on the other hand, more of "what you see is what you get", i.e., no magic involved.

Source Link
sds
  • 60.5k
  • 31
  • 178
  • 303
Loading