Loop over variables in Lisp - lisp

I wrote the function
(defun test ()
(let ((str1 "foo") (str2 "bar"))
(loop for s in '(str1 str2) do (message s))))
but it does not work. The Elisp Backtrace message is:
Debugger entered--Lisp error: (wrong-type-argument stringp str1)
How can I make it work?
P.S.: the following modified version works perfectly, but I need the original version
(defun test1 ()
(loop for s in '("asdf" "fdsa") do (message s)))

The quote operator (for which the apostrophe is syntactic sugar) means that its arguments are not evaluated, i.e. (quote (str1 str2)) returns a list of two symbols. Use list instead: (list str1 str2).

Build a list of the values:
(defun test ()
(let ((str1 "foo") (str2 "bar"))
(loop for s in (list str1 str2) do (message s))))

try:
`(,str1 ,str2)

Related

How to evaluate the code passed to the `parenscript:ps` macro?

How can I evaluate the code passed to the ps macro in Parenscript?
(let ((x 1))
(format nil "~a" (parenscript:ps x)))
;; => "x;" but I would like "1;"
I know that ps is a macro and is the reason to not evaluate, but how to can I evaluate the code to passing to ps macro?
Your example using ps:lisp:
(let ((x 1))
(format nil "~a" (ps:ps (ps:lisp x))))
"1;"
It is introduced in the first section of the documentation: https://common-lisp.net/project/parenscript/reference.html#section-ps-compiler
I got it:
(defmacro lisp-to-js (lisp)
(eval ``(parenscript:ps ,,lisp)))
(let ((x 1))
(format nil "~a" (lisp-to-js x)))
;; => "1;"

For-each loop over pairs in Racket

I'm trying to print a list of pairs of values (representing key/value pairs) in Racket.
Here's the code I have right now:
#lang racket
(define (write-json keyvalues)
(displayln "{")
(for-each
(lambda (kv) (
(displayln (format "~a: ~a," (car kv) (cdr kv)))))
keyvalues)
(displayln "}"))
(write-json (list (cons "a" 1) (cons "b" 2)))
When I run the example, it prints:
{
a: 1,
Then, it crashes with this error message:
application: not a procedure;
expected a procedure that can be applied to arguments
given: #<void>
arguments...: [none]
context...:
/.../racket/collects/racket/private/map.rkt:58:19: loop
"test.rkt": [running body]
for-loop
run-module-instance!125
perform-require!78
Any idea what's going on?
Thanks!
This is a paren issue. You have an extra set of parentheses around your lambda's body, ie:
( (displayln (format "~a: ~a;" (car kv) (cdr kv))) )
Since displayln is used for side effect, its output is void, hence why your error message states that you're trying to run (#<void>).
In general, whenever you get an error stating "expected a procedure that can be applied to arguments", see if you have parentheses issues in your code block. Editors like Dr. Racket would highlight that region for you.

Why doesn't this quoted form evaluate as expected

I have a simple function that works:
(defun ifelse (the-test)
(cond (the-test (format t "passed test, true!"))
(t (format t "failed test, boo hoo"))))
If I do this, I get what you'd expect:
(ifelse (funcall (lambda () nil)))
failed test, boo hoo
NIL
I'm curious why this doesn't also result in a "failure" :
CL-USER> (ifelse '(funcall (lambda () nil)))
passed test, true!
NIL
My thinking is that, rather than evaluating the funcall in place and then passing the return value into ifelse, the entire funcall is being passed unevaluated into the ifelse -- however, how is a quoted form treated within the function? Wouldn't it be essentially copied in-place and then treated as a true Lisp form?
Let's see what you actually get:
(defun return-argument (element) element)
[9]> (defun return-argument (element) element)
RETURN-ARGUMENT
[10]> (return-argument (funcall (lambda () nil)))
NIL
Ok, this is as expected. Now your second function call, which results in a failure.
[11]> (return-argument '(funcall (lambda () nil)))
(FUNCALL (LAMBDA NIL NIL))
Aha, this gives us a clue. We're not evaluating argument, because it's quoted. In fact, we can see we're getting it back as a list:
[19]> (listp (return-argument '(funcall (lambda () nil))))
T
Remember, when you quote something, you prevent it from being evaluated.
Note: return-argument is the same function as the built-in identity. I wrote a new one so you could see what it's doing under the hood.
In the example , you pass a list as argument (because of the quote).
You need to use eval to evaluate the quoted list to have the 'failure'.
like this
(ifelse (eval '(funcall (lambda () nil))))
or remove the quote
(ifelse (funcall (lambda () nil)))

Debugging code with a mix of functions, macros, and bash calls in elisp

I am trying to call a bash program herbstclient from Emacs via process-lines. I created a macro hc-call which actually calls herbstclient that is invoked by the function hc which is supposed to convert its numeric arguments into strings via stringify-numbers.
Needless to say it's not working. Calling hc with "keybind" "Mod4-Shift-r" "reload" gives the error:
*** Eval error *** Wrong type argument: listp, stringified-args
I tried using edebug on hc and the output suggested stringify-numbers was working properly. The function errored immediately on the hc-call. Yet, when I run:
(hc-call ("keybind" "Mod4-Shift-r" "reload"))
it works as expected. I then tried:
(setq sargs (list "keybind" "Mod4-Shift-r" "reload"))
(hc-call sargs)
and I got the same error. I don't know how to approach debugging this further. Below is all the code:
(defmacro hc-call (args)
"Call herbstclient to with the given arguments."
`(process-lines "herbstclient" ,#args))
(defun stringify-numbers (args)
"Take a list of random arguments with a mix of numbers and
strings and convert just the numbers to strings."
(let (stringified-args)
(dolist (arg args)
(if (numberp arg)
(setq stringified-args (cons (number-to-string arg) stringified-args))
(setq stringified-args (cons arg stringified-args))))
(nreverse stringified-args)))
(defun hc (&rest args)
"Pass arguments to herbstclient in a bash process."
(let ((stringified-args (stringify-numbers args)))
(hc-call stringified-args)))
Why would it complain stringified-args isn't a list?
Your hc-call should be a function, along the lines of
(defun hc-call (args)
"Call herbstclient to with the given arguments."
(apply #'process-lines "herbstclient" args))
BTW, while I'm here:
(if (numberp arg)
(setq stringified-args (cons (number-to-string arg) stringified-args))
(setq stringified-args (cons arg stringified-args))))
is better written
(setq stringified-args (cons (if (numberp arg) (number-to-string arg) arg) stringified-args))))
or
(push (if (numberp arg) (number-to-string arg) arg) stringified-args)))
Unlike most expressions, macro arguments are passed unevaluated.
This is why (hc-call ("keybind" "Mod4-Shift-r" "reload")) does not result in an error!
It therefore follows that (hc-call sargs) is passing the symbol sargs to the macro, rather than the list to which it would otherwise evaluate.
If you wish your macro to process a variable in this way, you could change ,#args to ,#(eval args), or else conditionally process args either way, depending on what it turns out to actually be.

Emacs lisp - can a defun reference itself somehow? [duplicate]

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