In elisp How do I extract value from a variable - elisp

I'm on the first exercise section (Emacs Lisp Intro) and I'm not getting it; 3.12 exercises:
Write a function that tests whether the current value of
`fill-column' is greater than the argument passed to the function, and if so, prints an appropriate message.
I have:
(defun is-fill-equal (number)
"Is fill-column greater than the argument passed to the function."
(interactive "p")
(if (= fill-column number)
(message "They are equal.")
(message "They are not equal."))
No matter what I try I get this error:
Debugger entered--Lisp error: (void-variable number)

You are missing one parenthesis at the end. Try:
(defun is-fill-equal (number)
"Is fill-column greater than the argument passed to the function."
(interactive "p")
(if (= fill-column number)
(message "They are equal.")
(message "They are not equal.")))
The reason for the error message is that you probably C-x e at the end of the function definition. As you are missing one parenthesis Emacs thinks that the expression you want to evaluate is (if (= fill-column number) ...) and number is unbound in that context.

Related

How to advice-add a function with no arguments to a function that takes arguments?

Say I have a functions as follows:
(defun my/test-a (n)
(interactive)
(message n))
(defun my/test-b ()
(interactive)
(sleep-for .5)
(message "Message - B.")
(sleep-for .5))
I then advice my/test-a with mytest-b like so: (advice-add 'my/test-a :after #'my/test-b).
However when I call (my/test-a "Message - A.") I get a "Wrong number of arguments" error. My understanding is that add-advice is feeding the argument into my/test-b, which is not expecting any arguments.
How to advice-add a function with no arguments to a function that takes arguments?
I could change my/test-b so it takes an argument and doesn't use it, but that feels very messy.
Related followup - how could I advise find-file with a function with no arguments (like my/test-b)? I understand find-file is an unusual case, because it doesn't need an argument if called interactively. But if I run (advice-add 'find-file :after #'my/test-b) and then (call-interactively 'find-file) I get a "Wrong Number Of Arguments" error again.
TIA.
You can't do that.
Your advice function has to accept the arguments for the original function.
C-hig (elisp)Advice Combinators says:
:after
Call FUNCTION after the old function. Both functions receive the
same arguments, and the return value of the composition is the
return value of the old function. More specifically, the
composition of the two functions behaves like:
(lambda (&rest r) (prog1 (apply OLDFUN r) (apply FUNCTION r)))
A way to take arbitrary arguments and ignore them is:
(defun foo (&rest _args) ...)
The underscore tells the byte-compiler that the arguments are unused in the function body on purpose.

Filtering an expression output with regexp

The bad code of main is (string-match "module" (help uri-path)) that returns an error
scheme#(guile-user) [5]> (string-match "module" (help uri-path))
`uri-path' is an object in the (web uri) module.
- Special Form: uri-path
While compiling expression:
Syntax error:
unknown file:9:23: sequence of zero expressions in form (begin)
scheme#(guile-user) [5]>
What I am trying to reach, is displaying only one line of help function output. How to fix it?
Use procedure-documentation to get the documentation of a procedure as a string.
scheme#(guile-user)> (help cons)
`cons' is a procedure in the (ice-9 safe-r5rs) module.
- Scheme Procedure: cons x y
Return a newly allocated pair whose car is X and whose cdr is Y.
The pair is guaranteed to be different (in the sense of `eq?') from
every previously existing object.
scheme#(guile-user)> (procedure-documentation cons)
$6 = "- Scheme Procedure: cons x y\n Return a newly allocated pair whose car is X and whose cdr is Y.\n The pair is guaranteed to be different (in the sense of `eq?') from\n every previously existing object."

SICP exercise 4.5

I'm learning SICP and do the programming exercises. I have a question about exercise 4.5. The exercise 4.5 is:
Scheme allows an additional syntax for cond clauses, (<test> => <recipient>). If <test> evaluates to a true value, then <recipient> is evaluated. Its value must be a procedure of one argument; this procedure is then invoked on the value of the <test>, and the result is returned as the value of the cond expression. For example:
(cond
((assoc 'b '((a 1) (b 2))) => cadr)
(else false))
As shown above,if <test> is true,the value of the cond clause should be (<recipient> <test>) (i.e.
then <recipient> is evaluated. Its value must be a procedure of one argument; this procedure is then invoked on the value of the <test>, and the result is returned...
But when I search the solution on the Internet, almost all I found are (list (extended-cond-recipient first) (extended-cond-test first)). It's a list consist of <recipient> and <test> , not a function call.
What should I do? It has troubled me a long time...
In The Core of the Evaluator, under “Special Forms”, is written:
• A case analysis (cond) is transformed into a nest of if expressions and then evaluated.
That is, first a transformation at the program level is done, and only after this transformation the resulting expression is evaluated. The transformation is done by the function cond->if, which does not evaluate the cond expression, only transform it in a nested list containing multiple if. This can be seen in the definition of the eval function, where there is the case:
((cond? exp) (eval (cond->if exp) env))
In the solutions that you have seen, the cond->if function is modified so that it transforms the => syntax in a list (as you have correctly observed), a list that contains the function as first element, and its argument as second element, and that list will be evaluated correctly in the subsequent steps of the interpreter.

re-internilizing a symbol from namespace-mapped-symbols

I'm not sure if the question title is appropriate but here is what I wonder:
From the repl, I wanted to get the list of bindings defined in the current module. After some searching this seemed like a good solution:
(define (racket-symbols-set)
(list->set (namespace-mapped-symbols (module->namespace 'racket))))
(define (namespace-symbols-set)
(list->set (namespace-mapped-symbols)))
(define (module-bindings)
(set->list (set-subtract
(namespace-symbols-set)
(racket-symbols-set))))
so, calling (module-bindings) returns a list of symbols. But if I try to call a symbol from that result, such as doing ((first (module-bindings))), I get a "application: not a procedure" error although the first symbol is a procedure.
How do I call the corresponding procedure of that symbol?
You can look up the value of a namespace variable using namespace-variable-value. And since your namespace-symbols-set just uses the current namespace, which is also the default namespace for namespace-variable-value, using it is very simple.
For example, to invoke the procedure associated with the first item in the list returned by your module-bindings procedure:
((namespace-variable-value (car (module-bindings))))
Alternatively, specify your preferred namespace as the fourth argument of the namespace-variable-value call.
You need to evaluate that symbol in order for it to return the corresponding procedure.
> (define (foo) 'bar)
> (eval 'foo)
#<procedure:foo>
> ((eval 'foo))
'bar
Hence in your case
((eval (car (module-bindings))))
will call the first procedure of the list returned by module-bindings.

How to create interactive elisp function with optional arguments

How do you write an elisp function, that should be bound to a key-press, that works without prompting by default, but when preceeded by Ctrl-u prompts the user for an argument. Something similar to (which is wrong syntax, but I hope you get the idea)?
(defun my-message (&optional (print-message "foo"))
(interactive "P")
(message print-message))
(global-set-key "\C-c\C-m" 'my-message)
The following use a feature of interactive that allows you to use code instead of a string. This code will only be executed when the function is called interactively (which makes this a different answer compared to the earlier answer). The code should evaluate to a list where the elements are mapped to the parameters.
(defun my-test (&optional arg)
(interactive (list (if current-prefix-arg
(read-from-minibuffer "MyPrompt: ")
nil)))
(if arg
(message arg)
(message "NO ARG")))
By using this method, this function can be called from code like (my-test) or (my-test "X") without it prompting the user for input. For most situations, you would like to design functions so that they only prompt for input when called interactively.
Following the same kind of implementation as your example, you could do something like this:
(defun my-message (&optional arg)
(interactive "P")
(let ((msg "foo"))
(when arg
(setq msg (read-from-minibuffer "Message: ")))
(message msg)))
If you just want to use the function as an interactive one, this code is all you need:
(defun my-message (&optional ask)
(interactive "P")
(message (if ask
(read-from-minibuffer "Message: ")
"foo")))

Resources