LISP dynamically define functions - function

I want to define a function with a parameter that defines another function with that parameter as the name.
example that dont work:
(DEFUN custom (name op const var)
(DEFUN name (var) (op const var)))
The problem is that name isnt evaluated and so the function that is defined is always called name.
I know that FUNCALL and APPLY can evaluate parameter dynamically, but i don't know how to call FUNCALL DEFUN... correctly.

I don't think you can use nested defuns.
You can either use a defun to return a lambda:
(defun custom (op const)
(lambda (arg) (funcall op const arg)))
and then use fdefinition:
(setf (fdefinition '+42) (custom '+ '42))
or use defmacro:
(defmacro custom (name op const)
(let ((arg (gensym)))
`(defun ,name (,arg)
(,op ,const ,arg))))
(custom +42 + 42)
PS. I think you need to explain why you are trying to do this, then we will be able to explain your options better.

It seems to me you might want to curry a function. Imagine you did this:
(defun curry (op arg1)
(lambda (&rest args) (apply op (cons arg1 args))))
(funcall (curry #'+ 10) 20) ; ==> 30
(mapcar (curry #'+ 10) '(1 2 3 4)) ; ==> (11 12 13 14)
Now defun makes a function in the global namespace always. It's not like in Scheme where it creates a closure. To do the same as defun we use symbol-function and setf:
(defun create-curried (name op arg1)
(setf (symbol-function name)
(lambda (&rest args) (apply op (cons arg1 args)))))
(create-curried '+x #'+ 10) ; ==> function
(+x 20) ; ==> 30
;; since it's a function, it even works with higher order functions
(mapcar create-curried '(+x -x /x *x) (list #'+ #'- #'/ #'*) '(10 10 10 10))
(/x 2) ; ==> 5
Last. With macros you can prettify it.
(defmacro defun-curried (newname oldname arg)
(if (and (symbolp newname) (symbolp oldname))
`(create-curried ',newname (function ,oldname) ,arg)
(error "Newname and Oldname need to be symbols")))
(defun-curried +xx + 20)
(+xx 10) ; ==> 30
oldname is taken from the lexical scope so you may use flet or labels with this but it ends up being global, just like with defun.

The main problem is that DEFUN isn't a function, it's a macro that treats its arguments specially (specifically, it doesn't evaluate "the function name", "the argument list", not "the function body").
You could probably make something work by careful use of (setf (symbol-function ...) ...), something like:
(defun define-custom-function (name op const)
(setf (symbol-function name) (lambda (var) (funcall op const var))))
This binds the function definition of the symbol to an anonymous function that calls your "operator" on your fed-in constant.
* (defun define-custom-function (name op const)
(setf (symbol-function name) (lambda (var) (funcall op const var))))
DEFINE-CUSTOM-FUNCTION
* (define-custom-function 'add3 #'+ 3)
#<CLOSURE (LAMBDA (VAR) :IN DEFINE-CUSTOM-FUNCTION) {1002A4760B}>
* (add3 5)
8
However, unless you absolutely need to define (or re-define) these custom functions dynamically, you are probably better off defining a custom DEFUN-like macro.

Related

Invoking Common Lisp macros systematically with varying expressions

I am learning Common Lisp (SBCL).
I want to create a facility to invoke two (or more) macros with several similar expressions that differ only in some parameters.
I would like to define the base of the expression, then modify it with the parameters I supply. For this a lambda function definition came to mind.
As far as I know, there is no analogue to funcall for macros, so I've also wrapped the macros in lambdas.
I feel like I'm overcomplicating with with all these lambda-s and funcall-s. Is there a more elegant way?
The macros are from an external lib, so I'd prefer not to modify them. (Specifically, the fiveam testing library's finishes and signals.)
Here is a sample code:
(defmacro macro1 (body) ())
(defmacro macro2 (body) ())
(defun check-expr-with-args (do-m func args)
(dolist (arg args)
(format t "~a " arg)
(funcall do-m (lambda () (funcall func arg)))))
(let ((test-expr
#'(lambda (val) (format t "~a" val)))
(cases (list
(list #'(lambda (func) ( macro1 (funcall func)))
(list 1 2 3 4 5))
(list #'(lambda (func) ( macro2 (funcall func)))
(list -4 -5 -6 -7 -8 -9)))))
(dolist (c cases)
(check-expr-with-args (first c) test-expr (second c))))
Originally I've tried to pass the macro names to my check-expr-with-args function, and the expressions in quoted form, relying on lexical scoping for the parameter insertion. That didn't work out.
I think you can write a wrapper macro that produces code that invokes macro1 (and macro2). For example here I'm defining m1 that takes (i) a test expression and (ii) an expression that is expected to evaluates at runtime to a list of values.
(defmacro m1 (test-expr input-expr)
(let ((arg (gensym)))
`(dolist (,arg ,input-expr)
(macro1 ,test-expr ,arg))))
Both test-expr and input-expr are injected in a dolist expression, which binds a variable named arg. Here arg is a fresh symbol introduced with gensym, to avoid accidentally shadowing a variable or symbol-macro possibly used in test-expr.
For example:
(m1 (some-test-p) (list 1 2 3 4))
The above expands as:
(DOLIST (#:G1909 (LIST 1 2 3 4))
(MACRO1 (SOME-TEST-P) #:G1909))
The resulting expression contains MACRO1, which will also be expanded. But it is now wrapped in an expression that iterates over some list computed at runtime. Here, it is a constant but you could replace it with any other expression.
In conclusion, it is often best to combine macros at the macro level, by expanding your own macros into other ones.
I want to create a facility to invoke two (or more) macros
(defmacro invoke-macros (macro-forms)
`(progn ,#macro-forms))
with several similar expressions that differ only in some parameters.
(defmacro invoke-macros (macro-names &rest macro-arguments)
`(progn ,#(loop for m in macro-names
appending (loop for a in macro-arguments
collecting `(,m ,#a)))))
Check:
[1]> (macroexpand '(invoke-macros (m1 m2) (a b c) (d e f)))
(PROGN (M1 A B C) (M1 D E F) (M2 A B C) (M2 D E F)) ;
T
Of course, this works with any operators, including functions, not only macros; we should call this invoke-operators. Or some better name reflecting that we are creating a cartesian product from operators and argument syntax.
If we need the returned values, we can change progn to list. Or possibly values if the number of combinations isn't expected to be large.
If this had to be a function:
(defun invoke-ops (op-names &rest op-arguments)
(loop for o in op-names
appending (loop for a in op-arguments
collecting (eval `(,o ,#a)))))
Check:
[1]> (invoke-ops '(list +) '(1 2) '(10 20))
((1 2) (10 20) 3 30)
Since invoke-ops is now a function, we have to quote the arguments.
There is no funcall for macros. If you gain access to the expander function of a macro, then there is a funcall, but all it does is perform the code transformation; it won't invoke the macro.
The only ways to invoke the code generated by a macro are: you can eval the code, or you can compile the code and funcall it. The latter approach requires a function, so you place the code into a lambda expression first:
(funcall (compile nil `(lambda () ,code-output-by-macro)))
The nil argument of compile is the function name; we are telling compile that we are not dealing with a named function definition. We supply the code in the second argument. In some Common Lisp implementations, there is no evaluator; the eval function does something similar to:
(defun eval (code)
(funcall (compile nil `(lambda () ,code))))

Is there a way to obtain the function name of current function?

(defun foo ()
(send-to-debug-log "Error. Function terminated." (get-current-function-name)))
I currently do this:
(defun foo ()
(send-to-debug-log "Error. Function terminated." 'foo)))
Hard coding the function name seems not to be a good practice.
Any suggestion to implement the get-current-function-name or get-function-name-that-call-me.
(defun foo ()
(send-to-debug-log "Error. Function terminated." (nth 1 (backtrace-frame 2))))
You could try something like:
(defconst my-defun-macros '(defun cl-defun defmacro cl-defmacro))
(defun my-add-defun-name (orig-fun name &rest args)
(let* ((my-current-defun-name (if (consp name) (cadr name) name))
(macroexpand-all-environment
(cons (cons 'my-get-current-function-name
(lambda () my-current-defun-name))
macroexpand-all-environment))
(code (apply orig-fun name args)))
(macroexpand-all code macroexpand-all-environment)))
(defmacro my-get-current-function-name ()
"Return current defun's name.
Only works within the advised macros in `my-defun-macros'."
(error "my-get-current-function-name used outside of a defun"))
(dolist (m my-defun-macros)
(advice-add m :around #'my-add-defun-name))
Here's something that seems to work pretty well:
(defun calling-function ()
(let ((n 6) ;; nestings in this function + 1 to get out of it
func
bt)
(while (and (setq bt (backtrace-frame n))
(not func))
(setq n (1+ n)
func (and bt
(nth 0 bt)
(nth 1 bt))))
func))
If you call it in a lambda, you get the whole lambda. It works with apply, funcall, and eval.
I think the most simple, robust way is to just explicitly write the function name, as you're doing now.
With the package which-function-mode (in melpa), you can programmatically call the function
(Which-function)
more info:
https://www.masteringemacs.org/article/which-function-mode
http://emacsredux.com/blog/2014/04/05/which-function-mode/

recursive definition of map in common lisp [duplicate]

This question already has answers here:
Why do we need funcall in Lisp?
(3 answers)
Closed 8 years ago.
I was expecting the Scheme approach:
(defun mmap (f xs)
(if (equal xs NIL)
'()
(cons (f (car xs)) (mmap f (cdr xs)))))
but i get a compiler warning
;Compiler warnings for ".../test.lisp" :
; In MMAP: Undefined function F
I can see that I need to make the compiler aware that f is a function. Does this have anything to do with #'?
Common Lisp is a LISP2. It means variables that are in the first element of the form is evaluated in a function namespace while everything else is evaluated from a variable namespace. Basically it means you can use the same name as a function in your arguments:
(defun test (list)
(list list list))
Here the first list is looked up in the function namespace and the other two arguments are looked up in the variable namespace. First and the rest become two different values because they are fetched from different places. If you'd do the same in Scheme which is a LISP1:
(define (test list)
(list list list))
And pass a value that is not a procedure that takes two arguments, then you'll get an error saying list is not a procedure.
A function with name x in the function namespace can be fetched from other locations by using a special form (function x). Like quote function has syntax sugar equivalent so you can write #'x. You can store functions in the variable namespace (setq fun #'+) and you can pass it to higher order functions like mapcar (CL version of Scheme map). Since first element in a form is special there is a primitive function funcall that you can use when the function is bound in the variable namespace: (funcall fun 2 3) ; ==> 5
(defun my-mapcar (function list)
(if list
(cons (funcall function (car list))
(my-mapcar function (cdr list)))
nil))
(my-mapcar #'list '(1 2 3 4)) ; ==> ((1) (2) (3) (4))
A version using loop which is the only way to be sure not to blow the stack in CL:
(defun my-mapcar (function list)
(loop :for x :in list
:collect (funcall function x)))
(my-mapcar #'list '(1 2 3 4)) ; ==> ((1) (2) (3) (4))
Of course, mapcar can take multiple list arguments and the function map is like mapcar but it works with all sequences (lists, arrays, strings)
;; zip
(mapcar #'list '(1 2 3 4) '(a b c d)) ; ==> ((1 a) (2 b) (3 c) (4 d))
;; slow way to uppercase a string
(map 'string #'char-upcase "banana") ; ==> "BANANA"
functions in CL that accepts functions as arguments also accept symbols. Eg. #'+ is a function while '+ is a symbol. What happens is that it retrieves #'+ by fetching the function represented by + in the global namespace. Thus:
(flet ((- (x) (* x x)))
(list (- 5) (funcall #'- 5) (funcall '- 5))) ; ==> (25 25 -5)
Trivia: I think the number in LISP1 and LISP2 refer to the number of namespaces rather than versions. The very first LISP interpereter had only one namespace, but dual namespace was a feature of LISP 1.5. It was he last LISP version before commercial versions took over. A LISP2 was planned but was never finished. Scheme was originally written as a interpreter in MacLisp (Which is based on LISP 1.5 and is a LISP2). Kent Pittman compared the two approaches in 1988.

How to pass elisp function or command into function parameters? [duplicate]

I'm trying to pass one method to another in elisp, and then
have that method execute it. Here is an example:
(defun t1 ()
"t1")
(defun t2 ()
"t1")
(defun call-t (t)
; how do I execute "t"?
(t))
; How do I pass in method reference?
(call-t 't1)
First, I'm not sure that naming your function t is helping as 't' is used as the truth value in lisp.
That said, the following code works for me:
(defun test-func-1 () "test-func-1"
(interactive "*")
(insert-string "testing callers"))
(defun func-caller (callee)
"Execute callee"
(funcall callee))
(func-caller 'test-func-1)
Please note the use of 'funcall', which triggers the actual function call.
The note towards the end of "ยง13.7 Anonymous Functions" in the Emacs Lisp manual says that you can quote functions with #' instead of ' to signal to the byte compiler that the symbol always names a function.
Above answers are okey, but you can do something more interesting with defmacro, wich evaluates functions later for some reason:
(defun n1 ()
"n1")
(defmacro call-n (n)
(apply n))
(call-n (n1))
A practical example with a for loop that takes any amount of functions and their arguments:
(defmacro for (i &optional i++ &rest body)
"c-like for-loop"
(unless (numberp i++) (push i++ body) (setq i++ 1))
(while (/= i 0)
(let ((args 0))
(while (nth args body)
(apply (car (nth args body))
(cdr (nth args body)))
(setq args (1+ args))))
(setq i (- i i++))
)
)

Common Lisp - Using a function as input to another function

Say I have a function that takes a list and does something:
(defun foo(aList)
(loop for element in aList ...))
But if the list is nested I want to flatten it first before the loop does stuff, so I want to use another function (defun flatten(aList)) that flattens any list:
(defun foo(flatten(aList))
(loop for element in aList ...))
Lisp doesn't like this. Is there another direct way around this?
Here's one way:
(defun foo (alist)
(loop for element in (flatten alist) ...)
You can pass the function as an &optional argument.
(defun foo (alist &optional fn)
(if (not (null fn))
(setf alist (funcall fn alist)))
(dostuff alist))
A sample run where dostuff just print its argument:
(foo '(1 2 (3)))
=> (1 2 (3))
(foo '(1 2 (3)) #'flatten)
=> (1 2 3)
This approach is more flexible as you are not tied to just one 'pre-processor' function.