quick question.
I'm trying to add something to my function where it prints back whatever args I give it as part of a string to the console.
(defun test (testvar)
(format Your number is *testvar*))
After looking around i think that I am supposed to use format but that's as far as I found.
You can interact in Common Lisp through a console within a REPL loop (READ-EVAL-PRINT Loop). So every expression is read, evaluated, and the result of the evaluation is printed;
CL-USER> (defun test (testvar)
(format nil "Your input is ~A" testvar))
TEST
CL-USER> (test 3)
"Your input is 3"
CL-USER> (test 'symbol)
"Your input is SYMBOL"
CL-USER> (test "string")
"Your input is string"
CL-USER>
The format function (reference) when its second argument is nil, returns as string the result of substituting in its second argument (a format string), special marks, like “~a” “~s”, etc., with the remaining parameters.
If the second parameter of format is instead t or a stream, then the formatted string is output to the stream specified (or, in case of t, to the special *standard-output* stream, that initially is the same as the console), and the result of format is returned (and then printed by the REPL). For instance:
CL-USER> (defun test (testvar)
(format t "Your input is ~A" testvar))
TEST
CL-USER> (test 3)
Your input is 3
NIL
CL-USER>
In this case NIL is the result of the format function. Note also that, differently from the first case, in which Your input is 3 is printed surrounded by double quote (since the result of (format nil ...) is a string, and is printed by the REPL as such), the output is left intact from the printing operation.
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).
How do you convert a list into a string? I am trying to use parse-int to take a list of numbers and convert them to decimal, but i end up getting an error saying "The control-string must be a string, not (contents)".
I'm using format, but I'm not sure if I'm using it incorrectly.
Here's my code:
(princ "Enter a or list of hexadecimal numbers: ")
(setq numList (read-from-string (concatenate 'string "(" (read-line) ")")))
(defun hextodec(nums)
(setq numString (format "%s" nums))
(setq newNum (parse-integer numString :radix 16))
(write nums)
(princ " = ")
(write newNum)
) ;This will format the number that the user enters
(hextodec numList)
Since you're using read-from-string anyway, you can just tell Lisp's reader to read base 16 integers:
;; CLISP session
[1]> (let ((*read-base* 16)) (read-from-string "(9 A B C F 10)"))
(9 10 11 12 15 16) ;
14
read-from-string is a potential security hole if the contents of the string are untrusted input, because of the hash-dot evaluation notation.
When using the Lisp reader on untrusted data, be sure bind *read-eval* to nil.
[2]> (read-from-string "(#.(+ 2 2))")
(4) ;
11
Note how the #. notation causes the + function specified in the string data to be executed. That could be any function, such as something that whacks files in your filesystem, or sends sensitive data to a remote server.
Format's first argument is the stream to print to. You seem to intend to return the string instead of printing, so you should put nil there: (format nil "~s" nums)
The format control string "%s" does not contain any format directives. The entire format form does not make much sense here, as you seem to intend to loop over the given nums instead. You should employ some looping construct for that, e. g. loop, do, map, mapcar ….
In Common Lisp, the special operator quote makes whatever followed by un-evaluated, like
(quote a) -> a
(quote {}) -> {}
But why the form (quote ()) gives me nil? I'm using SBCL 1.2.6 and this is what I got in REPL:
CL-USER> (quote ())
NIL
More about this problem: This is some code from PCL Chapter 24
(defun as-keyword (sym)
(intern (string sym) :keyword))
(defun slot->defclass-slot (spec)
(let ((name (first spec)))
`(,name :initarg ,(as-keyword name) :accessor ,name)))
(defmacro define-binary-class (name slots)
`(defclass ,name ()
,(mapcar #'slot->defclass-slot slots)))
When the macro expand for the following code:
(define-binary-class id3-tag
((major-version)))
is
(DEFCLASS ID3-TAG NIL
((MAJOR-VERSION :INITARG :MAJOR-VERSION :ACCESSOR MAJOR-VERSION)))
which is NIL rather than () after the class name ID3-TAG.
nil and () are two ways to express the same concept (the empty list).
Traditionally, nil is used to emphasize the boolean value "false" rather than the empty list, and () is used the other way around.
The Common LISP HyperSpec says:
() ['nil], n. an alternative notation for writing the symbol nil, used
to emphasize the use of nil as an empty list.
Your observation is due to an object to having more than one representation. In Common Lisp the reader (that reads code and reads expressions) parses text to structure and data. When it's data the writer can print it out again but it won't know exactly how the data was represented when it was initially read in. The writer will print one object exactly one way, following defaults and settings, even though there are several representations for that object.
As you noticed nil, NIL, nIL, NiL, ... ,'nil, 'NIL, (), and '() are all read as the very same object. I'm not sure the standard dictates exactly how it's default representation out should be so I guess some implementations choose one of NIL, nil or maybe even ().
With cons the representation is dependent on the cdr being a cons/nil or not:
'(a . nil) ; ==> (a)
'(a . (b . c)) ; ==> (a b . c)
'(a . (b . nil)) ; ==> (a b)
With numbers the reader can get hints about which base you are using. If no base is used in the text it will use whatever *read-base* is:
(let ((*read-base* 2)) ; read numbers as boolean
(read-from-string "(10 #x10)")) ; ==> (2 16)
#x tells the reader to interpret the rest as a hexadecimal value. Now if your print-base would have been 4 the answer to the above would have been visualized as (2 100).
To sum it up.. A single value in Common Lisp may have several good representations and all of them would yield the very same value. How the value is printed will follow both implementation, settings and even arguments to the functions that produce them. Neither what it accepts as values in or the different ways it can visualize the value tells nothing about how the value actually gets stored internally.
I want to run a function but not have it output the result in the terminal. For example, (set 'A 'B) normally returns B in the console like the following:
>>> (set 'A 'B)
B
>>> A
B
I don't want it to return anything; I still want the function to do what it's supposed to, just silently:
>>> (set 'A 'B)
>>> A
B
It's not perfect, but you can use (values) at the end of your expression to suppress output. You get a blank line instead.
Common Lisp:
(progn (set 'A 'B) (values))
I'm not sure of the equivalent in Scheme.
A lisp REPL always prints some return value. If you really didn't want output, you could run your code as a script in the terminal.
Example:
#!/path/to/interpreter
(set 'A 'B)
[rest of program]
Since the value printed is actually a return value of your function, and the return value of a function is the value of last expression evaluated, you can simply add an "empty" (returning e.g. "") instruction at the end of/after your call.
I came to the same solution as user1613254, however I made a macro for this (have it in my .sbclrc):
(defmacro m-ignore (fun &body body)
"ignores the return value of a function"
`(progn (,fun ,#body)
(values)))
You use it like this:
(m-ignore format t "text")
The output would be:
text
instead of:
text
NIL
which would be printed when using
(format t "text")