What does backtick mean in LISP? - lisp

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.

Related

What is the use of `,` and `,#` in Racket?

I'm new to Racket and I was hoping to get more insights in the these two operators: , & ,#.
There's very little documentation of these new operators, however, to my understanding the former (,) unquotes everything if its is followed by a list. And the latter (,#) splices the values.
For example if the following is typed in the Dr. Racket interpreter:
(define scores '(1 3 2))
(define pets '(dog cat))
and then the following query is made:
`(,scores ,#pets)
this would yield : '((1 3 2) dog cat)
It would be appreciated if I could get more details, definitions and more examples about these operators.
Thanks in advance.
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
Now let's say x is the list (a b).
> `(1 ,x "foo")
(1 (a b) "foo") ; if the value of x is (a b)
This looks as expected. But what if I wanted (1 a b "foo")
as the result? We need a way so show "insert the elements of a list".
That's where ,# comes into the picture.
> `(1 ,#x "foo")
(1 a b "foo") ; if the value of x is (a b)
They are "reader abbreviations" or "reader macros". They are introduced in the section of the Racket guide on quasiquotation. To summarize:
`e reads as (quasiquote e)
,e reads as (unquote e)
,#e reads as (unquote-splicing e)
Because Racket's printer uses the same abbreviations by default, it can be confusing to test this yourself. Here are a few examples that should help:
> (equal? (list 'unquote 'abc) (read (open-input-string ",abc")))
#t
> (writeln (read (open-input-string ",abc")))
(unquote abc)
A more exhaustive description of the Racket reader is in the section on The Reader in the Racket Reference. A list of reader abbreviations is in the Reading Quotes subsection.

Print the sum of entered numbers

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.

String addition assignment in lisp

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).

Lisp - Make a list with variable value

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")

Why no error about undefined variable is raised in LISP while setq()?

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).