I save the variable value (setf num (+ 4 5)) like this and
I save the (setf str '("Hello")).
And then I want make a list like this (setq v '(num str)).
However because of the single quote, it doesn't recognize it as a string and not working as expected.
how can i make a list with variable value?
The special operator quote prevents evaluation of your variables.
You need to call a function (which evaluates its arguments), e.g., list:
(list num str)
==> (9 "Hello")
Related
I'm using command prompt and notepad and I can't print the sum of the entered numbers.
I tried
(format t "Sum ~d ~%" I don't know what should put here)
and I know if I put num then there's no value
here's my code
(princ"Enter how many numbers to read: ")
(defparameter a(read))
(defun num ()
(loop repeat a
sum (progn
(format *query-io* "Enter a number: ")
(finish-output)
(parse-integer (read-line *query-io* )))))
(num)
Thank you
You are almost there. Instead of ... below, format expects a number:
(format t "Sum ~d ~%" ...)
If you put num, this won't work
(format t "Sum ~d ~%" num)
Because num refers to a variable named num, which does not exist in your environment. You defined a function named num. That function computes a value when it is called, so you need to call the function named num.
The way you call a function in Lisp is by writing (num), this is the syntax for calling function num with zero arguments.
Equivalently, you could also call (funcall #'num), which is a bit different: funcall accepts a function object and calls it, and #'num is syntax for accessing the function object bound to the symbol num. In fact #'num is a shorter way of writing (function num), where function is a special operator that knows how to return a callable object given a name.
In your case, you can directly write (num), as follows:
(format t "Sum ~d ~%" (num))
The evaluation of this forms first evaluate all the arguments in order, T, the control string, then (num). While evaluating (num) it will prompt for a numbers. Eventually, it will return the sum thanks to the loop, and the arguments to format will be known. Then format will be executed, will all its parameters bound to the computed values.
I have a loop with a condition, based on which I decide whether I should append something to existing string or not.
In Python, it should look like (this is dummy code, just to show the idea):
result_str = ''
for item in range(5):
if item % 2 == 0:
result_str += str(item)
print(result_str)
Output: 024
So the question is: how can I perform addition assignment on strings (+=) in lisp?
String concatenation relies on the more general CONCATENATE function:
(concatenate 'string "a" "b")
=> "ab"
Since it considered verbose by some, you can find libraries that implement shorter versions:
(ql:quickload :rutils)
(import 'rutils:strcat)
And then:
(strcat "a" "b")
In order to assign and grow a string, you need to use SETF with an existing variable.
(let ((string ""))
(dotimes (i 5)
(when (evenp i)
(setf string (strcat string (princ-to-string i)))))
string)
A more idiomatic way in Lisp is to avoid string concatenation, but print in a stream which writes into a buffer.
(with-output-to-string (stream)
;; now, stream is bound to an output stream
;; that writes into a string. The whole form
;; returns that string.
(loop
for i from 0 below 5 by 2
do (princ i stream)))
=> "024"
Here above, stream is just the symbol used for naming the stream, you could use any other one, including *standard-output*, the special variable that represents current output stream. Doing so would make the enclosed code redirect its standard output to the string stream.
An alternative way to build the intermediate list is the following, where iota is a small utility in the alexandria library:
(delete-if #'oddp (alexandria:iota 5))
=> (0 2 4)
In order to produce a string, you can also use FORMAT, which has a directive that can iterate over lists:
(format nil "~{~a~}" '(0 2 4))
=> "024"
The nil stream destination represents a string destination, meaning (format nil ...) returns a string. Each directive starts with a tilde character (~), ~{ and ~} enclose an iteration directive; inside that block, ~a prints the value "aesthetically" (not readably).
I'm doing a tutorial on emacs lisp, and it's talking about the let function.
;; You can bind a value to a local variable with `let':
(let ((local-name "you"))
(switch-to-buffer-other-window "*test*")
(erase-buffer)
(hello local-name)
(other-window 1))
I don't understand the role of the double parentheses after let in the first line. What are they doing that a single set wouldn't do? Running that section without them, I get an error: Wrong type argument: listp, "you".
You can introduce multiple variables there. The outer parentheses delimit the list of bindings, the inner the individual binding form.
(let ((foo "one")
(bar "two"))
(frobnicate foo bar))
There are not "double parens".
Presumably, you are thinking of (let ((foo...)...)), and you mean the (( that come after let? If so, consider this:
(let (a b c) (setq a 42)...)
IOW, let declares local variables. It may also bind them. In the previous sexp, it declares a, b, and c, but it doesn't bind any of them, leaving it to the let body to give them values.
An example that declares two variables but binds only one of them (a):
(let ((a 42) b) ... (setq b ...) ...)
According to gnu.org, it looks like you can construct and initialize multiple variables with one let statement, so the double parenthesis is there to allow the separation between the variables.
If the varlist is composed of two-element lists, as is often the case, the template for the let expression looks like this:
(let ((variable value)
(variable value)
…)
body…)
The let special form takes a list of bindings: (let (<binding-form> ...) <body>).
The binding form is one of <symbol> (denoting a variable bound to the value nil) or a list (<symbol> <value>) (where value is computed when the let is entered).
The difference between let and let* is how the "value" bits are executed. For plain let, they're executed before any of the values are bound:
(let ((a 17)
(b 42))
(let ((a b) ; Inner LET
(b a))
(list a b)))
Whereas let* executes the binding forms one after another. Both have their places, but you can get by with only using let since (let* (<form1> <form2>...) is equivalent to (let (<form1>) (let (<form2>) ...))
I have this macro, which rewrites define. If I remove the " ` " backtick it won't work. What is the explanation?
(defmacro define ((name &rest r) body)
`(defun ,name ,r ,body))
A single quote followed by the written representation of a value
will produce that value:
Example:
'(1 x "foo")
will produce a value that prints as (1 x "foo").
Suppose now that I don't want a literal symbol x in the list.
I have a variable x in my program, and I want to insert
the value to which x is bound.
To mark that I want the value of x rather than the symbol x,
I insert a comma before x:
'(1 ,x "foo")
It won't work as-is though - I now get a value that has a literal comma as well as a symbol x. The problem is that quote does not know about the comma convention.
Backtick or backquote knows about the comma-convention, so that will give the correct result:
> `(1 ,x "foo")
(1 3 "foo") ; if the value of x is 3
Read more here: http://www.lispworks.com/documentation/HyperSpec/Body/02_df.htm
The backtick/backquote disables evaluation for every subexpression not preceded by a comma for the list that follows the operator.
From the common lisp cookbook, explanation and a few examples.
In my Emacs config I have such a string:
(setq ibuffer-saved-filter-groups
(quote (("default"
("dired"
(mode . dired-mode))
("System"
(or (name . "\*scratch\*")
(name . "\*Messages\*")))
("SVN"
(name . "^\\*vc-.*\\*$"))))))
The variables name and mode are undefined but the code is evaluated correctly. When I try to make a such on my own:
(some-var . "some-value")
I receive an error about the undefined variable some-var.
When a datum is quoted, nothing within is evaluated. For example:
foo
evaluates to the value bound to the identifier foo, whereas
'foo
or
(quote foo)
evaluates to the symbol foo.
Likewise,
(+ 1 2 3)
evaluates to 6, whereas
'(+ 1 2 3)
or
(quote (+ 1 2 3))
evaluate to a list with four elements: the symbol +, and the numbers 1, 2, and 3. In particular, the + is not evaluated.
Similarly, your name and mode, both being within the quoted datum, are not treated as identifiers, but as symbols. They are not evaluated.
Looks to me like it's because name and mode are in (quote )
Look at C-h v ibuffer-saved-filter-groups. It explains about this variables further. It is an alist variable. According to documents, it should look like (("STRING" QUALIFIERS) ("STRING" QUALIFIERS) ...) Now QUALIFIERS is a LIST of the same form as `ibuffer-filtering-qualifiers'. It is a LIST like (SYMBOL . QUALIFIER).