Forums
New posts
Search forums
Members
Current visitors
Log in
Register
What's new
Search
Search
Search titles only
By:
New posts
Search forums
Menu
Log in
Register
Install the app
Install
Forums
Archive
Archive
Java
Re: Seeking computer-programming job (Sunnyvale, CA)
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Reply to thread
Message
[QUOTE="Pascal J. Bourguignon, post: 3861899"] Dogs are dogs are dogs. How loud does your hot-dog bark? Lisp macros are functions, not symbols. Symbols are only used to name lisp macros. You may want to write a macro such as: (print-and-return (incf x)) that should print the value returned, without evaluating the expression twice. (An artificial example, since the function PRINT already does that). Then you'd write it: (defmacro print-and-return (expression) (let ((value-name (gensym))) `(let ((,value-name ,expression)) ; evaluates expression once (print ,value-name) ; prints its value ,value-name))) ; and returns it. On the other hand, you may want to write a macro such as: (repeat-thrice (incf x)) that should evaluate the expression three times. Then you'd write: (defmacro repeat-thrice (expression) `(progn ,expression ,expression ,expression)) so expression will be evaluted three times. If you want to do something, then do it. If you don't want it, then just don't do it. That's what we call not being dumb. If you want to capture a variable, then you can. If you want to capture a variable specified as parameter, then you can. If you want to define variables that are not accessible to the subexpressions, then you can. If you want to define variables that are accessible to the subexpressions, then you can. If you want to define variables specified as parameter that are accessible to the subexpressions, then you can. If you want to define variables specified as parameter that are accessible to the subexpressions but protected from any interference, then you can. If you want to avoid capturing any variable (see print-and-return above), then you can. If you want to have side effects, then you can. If you want to be side-effect free, then you can. Why would you do something that you wouldn't want? Are you dumb? Capture a variable: (defmacro capturing-x (y) `(- (* 157 x x) ,y)) (let ((x 42)) (capturing-x 239)) --> 276709 Capture a variable specified as parameter: (defmacro capture (var y) `(- (* 157 ,var ,var) ,y)) (let ((x 42) (y 1)) (list (capture x 239) (capture y 42))) --> (276709 115) Define variables that are not accessible to the subexpressions: (defmacro repeat-using-inaccessible-variable (n expression) (let ((inaccessible-variable (gensym))) `(dotimes (,inaccessible-variable ,n) ,expression))) (repeat-using-inaccessible-variable 3 (print "whatever you do here you can't get access to the counter")) prints: "whatever you do here you can't get access to the counter" "whatever you do here you can't get access to the counter" "whatever you do here you can't get access to the counter" Define variables that are accessible to the subexpressions: (defmacro repeat-using-accessible-variable-named-counter (n expression) `(dotimes (counter ,n) ,expression)) (repeat-using-accessible-variable-named-counter 4 (format t "The value of COUNTER in the ~A~:*~[th~;st~;nd~;rd~;th~] iteration is ~A~%" (1+ counter) counter)) prints: The value of COUNTER in the 1st iteration is 0 The value of COUNTER in the 2nd iteration is 1 The value of COUNTER in the 3rd iteration is 2 The value of COUNTER in the 4th iteration is 3 Define variables specified as parameter that are accessible to the subexpressions: (defmacro repeat-with-counter ((counter n) expression) `(dotimes (,counter ,n) ,expression)) (repeat-with-counter (my-counter 4) (format t "The value of ~A in the ~A~:*~[th~;st~;nd~;rd~;th~] iteration is ~A~%" 'my-counter (1+ my-counter) my-counter)) prints: The value of MY-COUNTER in the 1st iteration is 0 The value of MY-COUNTER in the 2nd iteration is 1 The value of MY-COUNTER in the 3rd iteration is 2 The value of MY-COUNTER in the 4th iteration is 3 Define variables specified as parameter that are accessible to the subexpressions but protected from any interference: (defmacro repeat-with-protected-counter ((counter n) expression) `(dotimes (,counter ,n) (let ((,counter ,counter)) ,expression))) (repeat-with-protected-counter (my-counter 4) (progn (format t "The value of ~A in the ~A~:*~[th~;st~;nd~;rd~;th~] iteration is ~A~%" 'my-counter (1+ my-counter) my-counter) (setf my-counter 0))) prints: The value of MY-COUNTER in the 1st iteration is 0 The value of MY-COUNTER in the 2nd iteration is 1 The value of MY-COUNTER in the 3rd iteration is 2 The value of MY-COUNTER in the 4th iteration is 3 Avoid capturing any variable: (defmacro print-and-return (expression) (let ((value-name (gensym))) `(let ((,value-name ,expression)) ; evaluates expression once (print ,value-name) ; prints its value ,value-name))) ; and returns it. (let ((x 0) (value-name 'toto)) (print-and-return (incf x)) (print value-name)) prints: 1 TOTO Have side effects: (defmacro define-typed-function (name arguments &body body) `(defun ,name ,(mapcar (function first) arguments) (declare ,@(mapcar (lambda (var-type) (destructuring-bind (var type) var-type `(type ,type ,var))) arguments)) ,@body)) (define-typed-function fact ((n integer)) (if (<= n 0) 1 (* n (fact (1- n))))) --> FACT (macroexpand-1 '(define-typed-function fact ((n integer)) (if (<= n 0) 1 (* n (fact (1- n)))))) --> (DEFUN FACT (N) (DECLARE (TYPE INTEGER N)) (IF (<= N 0) 1 (* N (FACT (1- N))))) ; T (fact 20) --> 2432902008176640000 Not have side effects: (defmacro print-and-return (expression) (let ((value-name (gensym))) `(let ((,value-name ,expression)) ; evaluates expression once (print ,value-name) ; prints its value ,value-name))) ; and returns it. (let ((x 0) (value-name 'toto)) (print-and-return (incf x)) (print value-name)) prints: 1 TOTO Yes. So why would you do that if that's not what you want to do? Oh! How dumb! We were discussing Lisp macros... Dog, Hot-Dog? Ok. Assembler macros where invented in the 1950's. Lisp macros were invented in the early 1960's. C macros where invented in the 1970's. All the above can be done as well in good macro assemblers, this has already been mentionned in this thread. We have priority on the terminology here. [/QUOTE]
Verification
Post reply
Forums
Archive
Archive
Java
Re: Seeking computer-programming job (Sunnyvale, CA)
Top