How to control decimal point in Common Lisp format? - common-lisp

How to pass a value to a function that control how many number in decimal point to print.
I can do with $ or f, e.g
(format t "~,3f" 3.141592)
(format t "~2$" 3.141592)
But how to do something like this
(defun control-format (x)
(format nil "~,xf" 3.141592))
So we can pass any number as argument to control-format to control how many decimal number we want.
Thanks.

Use v instead of a literal number:
* (dotimes (i 8)
(format t "~,vf~%" i pi))
3.
3.1
3.14
3.142
3.1416
3.14159
3.141593
3.1415927
NIL
*

Related

LISP Recursive Triangle

My recursive call seems to not be working, I am trying to make a triangle given an integer, and with the help of you guys I was finally able to make the string print on the same line, the correct amount of times for 1 line. At the end of printing the line, I have a recursive call that calls on triangle to make another line, one character shorter. This call seems to never be reached for some reason. Please find the code below, thank you all in advance for any and all help, it is all greatly appreciated!
Note: On a side note, is there any way to stop a function in Lisp similar to a return statement? I would like for the recursion to stop at k = 1, and not continue to k = 0.
(defun newTriangle (k)
(cond ((<= k 0) (princ '(Nope)))
((or (= k 1) (= k -1)) (princ 'a))
((> k 0) (make-string k :initial-element #\a))
(newTriangle (- k 1))))
(print (newTriangle 3))
sample output triangle(3)
aaa
aa
a
sample output triangle(-3)
aaa
aa
a
First, you need to decide exactly what it is that newTriangle is doing. The call (print (newTriangle 3)) suggests that newTriangle should return a string, which is then printed by the call to print. But, the OP definition of newTriangle is both printing output, and returning a single line of the triangle as a string.
The recursive call to newTriangle is never reached because all possible cases for the value of k are exhausted before this line is reached. Since k can only be less than zero, equal to zero, or greater than zero, and since all of these cases are tested for before reaching the recursive call, it is never reached. Also note that the OP code has the syntax wrong for the final part of the cond statement. The first expression in a cond branch is a test, and the convention is to use t here for a branch that will always be evaluated if reached. But, this many cases are not needed here.
Assuming the newTriangle function should not return a string, but should print a triangle as a side-effect, what should it do? If the input number is greater than 0, it should print a line with a number of characters equal to the input number and then call itself with the input reduced by one; otherwise it should do nothing:
(defun print-triangle (k)
(when (> k 0)
(princ (make-string k :initial-element #\a))
(terpri)
(print-triangle (- k 1))))
This definition is named print-triangle to emphasize that it prints a triangle as a side-effect, and because kebab-case is idiomatic in Lisps, and camelCase is not. Note that each time that print-triangle is called with input greater than zero, a string of the correct length is printed, and then a newline is printed (with the obscurely-named terpri, which just writes a newline to the current output stream), before calling print-triangle again with k reduced by 1.
Sample REPL interaction:
CL-USER> (print-triangle 3)
aaa
aa
a
NIL
If the goal is instead to return a string, one approach would be to call a helper function that keeps the result in a parameter:
(defun new-triangle (k)
(build-triangle k ""))
(defun build-triangle (k result)
(if (> k 0)
(build-triangle (- k 1)
(concatenate 'string
result
(make-string k :initial-element #\a)
(string #\newline)))
result))
Here, new-triangle takes an integer argument, and calls build-triangle, passing both the integer argument and an empty string in the result position. The build-triangle function operates much the same as print-triangle before, but instead of printing the lines, they are concatenated with result, along with a string containing a newline. When build-triangle is finished, the result string is returned to new-triangle. Note that simply calling new-triangle from the REPL will print the resulting string as data (i.e., with quotation marks); calling print on the result of new-triangle will both print the string as data, and return the string. To see the string printed without quotation marks, format can be used; or you could use princ which will print the string without quotation marks, and return the string itself:
CL-USER> (new-triangle 3)
"aaa
aa
a
"
CL-USER> (print (new-triangle 3))
"aaa
aa
a
"
"aaa
aa
a
"
CL-USER> (format t "~A" (new-triangle 3))
aaa
aa
a
NIL
CL-USER> (princ (new-triangle 3))
aaa
aa
a
"aaa
aa
a
"

Multiple return values of floor in dotimes

The floor Hyperspec article on dotimes has this example:
(defun palindromep (string &optional
(start 0)
(end (length string)))
(dotimes (k (floor (- end start) 2) t)
(unless (char-equal (char string (+ start k))
(char string (- end k 1)))
(return nil))))
If floor returns two values, e.g. (floor 5 2) -> 2 and 1, how does dotimes know to just use the first value and disregard the second for its count-form?
It's a general mechanism and not specific to dotimes.
If one calls a function or sets a variable, then only the first value will be passed:
CL-USER 52 > (defun foo (x) x)
FOO
CL-USER 53 > (foo (floor 5 2))
2
CL-USER 54 > (let ((foo (floor 5 2)))
foo)
2
To do the equivalent (calling functions, binding variables) with multiple values, one needs to use special constructs:
CL-USER 55 > (multiple-value-call #'list
(floor 5 2) (floor 7 3))
(2 1 2 1)
CL-USER 56 > (multiple-value-bind (foo0 foo1)
(floor 5 2)
(list foo0 foo1))
(2 1)
From 7.10.1,
Normally multiple values are not used. Special forms are required both to produce multiple values and to receive them. If the caller of a function does not request multiple values, but the called function produces multiple values, then the first value is given to the caller and all others are discarded; if the called function produces zero values, then the caller gets nil as a value.
Unless you specifically do something to deal with the multiple values (such as by multiple-value-call or one of the various macros equipped to handle them), all except the first value will be ignored.

Computing linear combination of vectors in Common Lisp

I'm working on some numerical computations in Common Lisp and I need to compute a linear combination of several vectors with given numerical coefficients. I'm rewriting a piece of Fortran code, where this can be accomplished by res = a1*vec1 + a2*vec2 + ... + an*vecn. My initial take in CL was to simply write each time something like:
(map 'vector
(lambda (x1 x2 ... xn)
(+ (* x1 a1) (* x2 a2) ... (* xn an)))
vec1 vec2 ... vecn)
But I soon noticed that this pattern would recur over and over again, and so started writing some code to abstract it away. Because the number of vectors and hence the number of lambda's arguments would vary from place to place, I figured a macro would be required. I came up with the following:
(defmacro vec-lin-com (coefficients vectors &key (type 'vector))
(let ((args (loop for v in vectors collect (gensym))))
`(map ',type
(lambda ,args
(+ ,#(mapcar #'(lambda (c a) (list '* c a)) coefficients args)))
,#vectors)))
Macroexpanding the expression:
(vec-lin-com (10 100 1000) (#(1 2 3) #(4 5 6) #(7 8 9)))
yields the seemingly correct expansion:
(MAP 'VECTOR
(LAMBDA (#:G720 #:G721 #:G722)
(+ (* 10 #:G720) (* 100 #:G721) (* 1000 #:G722)))
#(1 2 3) #(4 5 6) #(7 8 9))
So far, so good...
Now, when I try to use it inside a function like this:
(defun vector-linear-combination (coefficients vectors &key (type 'vector))
(vec-lin-com coefficients vectors :type type))
I get a compilation error stating essentially that The value VECTORS is not of type LIST. I'm not sure how to approach this. I feel I'm missing something obvious. Any help will be greatly appreciated.
You've gone into the literal trap. Macros are syntax rewriting so when you pass 3 literal vectors in a syntax list you can iterate on them at compile time, but replacing it with a bindnig to a list is not the same. The macro only gets to see the code and it doesn't know what vectors will eventually be bound to at runtime when it does its thing. You should perhaps make it a function instead:
(defun vec-lin-com (coefficients vectors &key (type 'vector))
(apply #'map
type
(lambda (&rest values)
(loop :for coefficient :in coefficients
:for value :in values
:sum (* coefficient value)))
vectors))
Now you initial test won't work since you passed syntax and not lists. you need to quote literals:
(vec-lin-com '(10 100 1000) '(#(1 2 3) #(4 5 6) #(7 8 9)))
; ==> #(7410 8520 9630)
(defparameter *coefficients* '(10 100 1000))
(defparameter *test* '(#(1 2 3) #(4 5 6) #(7 8 9)))
(vec-lin-com *coefficients* *test*)
; ==> #(7410 8520 9630)
Now you could make this a macro, but most of the job would have been done by the expansion and not the macro so basically you macro would expand to similar code to what my function is doing.
Remember that macros are expanded at compile-time, so the expression ,#(mapcar #'(lambda (c a) (list '* c a)) coefficients args) has to be meaningful at compile-time. In this case, all that mapcar gets for coefficients and args are the symbols coefficients and vectors from the source code.
If you want to be able to call vec-lin-com with an unknown set of arguments (unknown at compile-time, that is), you'll want to define it as a function. It sounds like the main problem you're having is getting the arguments to + correctly ordered. There's a trick using apply and map to transpose a matrix that may help.
(defun vec-lin-com (coefficients vectors)
(labels
((scale-vector (scalar vector)
(map 'vector #'(lambda (elt) (* scalar elt)) vector))
(add-vectors (vectors)
(apply #'map 'vector #'+ vectors)))
(let ((scaled-vectors (mapcar #'scale-vector coefficients vectors)))
(add-vectors scaled-vectors))))
This isn't the most efficient code in the world; it does a lot of unnecessary consing. But it is effective, and if you find this to be a bottleneck you can write more efficient versions, including some that can take advantage of compile-time constants.

Recursive Factorial Function in Common-Lisp

Ok, I'm been learning COMMON LISP programming and I'm working on a very simple program to calculate a factorial of a given integer. Simple, right?
Here's the code so far:
(write-line "Please enter a number...")
(setq x (read))
(defun factorial(n)
(if (= n 1)
(setq a 1)
)
(if (> n 1)
(setq a (* n (factorial (- n 1))))
)
(format t "~D! is ~D" n a)
)
(factorial x)
Problem is, when I run this on either CodeChef or Rexter.com, I get a similar error: "NIL is NOT a number."
I've tried using cond instead of an if to no avail.
As a side note, and most bewildering of all, I've seen a lot of places write the code like this:
(defun fact(n)
(if (= n 1)
1
(* n (fact (- n 1)))))
Which doesn't even make sense to me, what with the 1 just floating out there with no parentheses around it. However, with a little tinkering (writing additional lines outside the function) I can get it to execute (equally bewildering!).
But that's not what I want! I'd like the factorial function to print/return the values without having to execute additional code outside it.
What am I doing wrong?
One actually needs to flush the I/O buffers in portable code with FINISH-OUTPUT - otherwise the Lisp may want to read something and the prompt hasn't yet been printed. You better replace SETQ with LET, as SETQ does not introduce a variable, it just sets it.
(defun factorial (n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
(write-line "Please enter a number...")
(finish-output) ; this makes sure the text is printed now
(let ((x (read)))
(format t "~D! is ~D" x (factorial x)))
Before answering your question, I would like to tell you some basic things about Lisp. (Neat fix to your solution at the end)
In Lisp, the output of every function is the "last line executed in the function". Unless you use some syntax manipulation like "return" or "return-from", which is not the Lisp-way.
The (format t "your string") will always return 'NIL as its output. But before returning the output, this function "prints" the string as well.
But the output of format function is 'NIL.
Now, the issue with your code is the output of your function. Again, the output would be the last line which in your case is:
(format t "~D! is ~D" n a)
This will return 'NIL.
To convince yourself, run the following as per your defined function:
(equal (factorial 1) 'nil)
This returns:
1! is 1
T
So it "prints" your string and then outputs T. Hence the output of your function is indeed 'NIL.
So when you input any number greater than 1, the recursive call runs and reaches the end as input 1 and returns 'NIL.
and then tries to execute this:
(setq a (* n (factorial (- n 1))))
Where the second argument to * is 'NIL and hence the error.
A quick fix to your solution is to add the last line as the output:
(write-line "Please enter a number...")
(setq x (read))
(defun factorial(n)
(if (= n 1)
(setq a 1)
)
(if (> n 1)
(setq a (* n (factorial (- n 1))))
)
(format t "~D! is ~D" n a)
a ;; Now this is the last line, so this will work
)
(factorial x)
Neater code (with Lisp-like indentation)
(defun factorial (n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
(write-line "Please enter a number...")
(setq x (read))
(format t "~D! is ~D" x (factorial x))
Common Lisp is designed to be compiled. Therefore if you want global or local variables you need to define them before you set them.
On line 2 you give x a value but have not declared the existence of a variable by that name. You can do so as (defvar x), although the name x is considered unidiomatic. Many implementations will give a warning and automatically create a global variable when you try to set something which hasn’t been defined.
In your factorial function you try to set a. This is a treated either as an error or a global variable. Note that in your recursive call you are changing the value of a, although this wouldn’t actually have too much of an effect of the rest of your function were right. Your function is also not reentrant and there is no reason for this. You can introduce a local variable using let. Alternatively you could add it to your lambda list as (n &aux a). Secondarily your factorial function does not return a useful value as format does not return a useful value. In Common Lisp in an (implicit) progn, the value of the final expression is returned. You could fix this by adding a in the line below your format.
For tracing execution you could do (trace factorial) to have proper tracing information automatically printed. Then you could get rid of your format statement.
Finally it is worth noting that the whole function is quite unidiomatic. Your syntax is not normal. Common Lisp implementations come with a pretty printer. Emacs does too (bound to M-q). One does not normally do lots of reading and setting of global variables (except occasionally at the repl). Lisp isn’t really used for scripts in this style and has much better mechanisms for controlling scope. Secondarily one wouldn’t normally use so much mutating of state in a function like this. Here is a different way of doing factorial:
(defun factorial (n)
(if (< n 2)
1
(* n (factorial (1- n)))))
And tail recursively:
(defun factorial (n &optional (a 1))
(if (< n 2) a (factorial (1- n) (* a n))))
And iteratively (with printing):
(defun factorial (n)
(loop for i from 1 to n
with a = 1
do (setf a (* a i))
(format t “~a! = ~a~%” i a)
finally (return a)))
You can split it up into parts, something like this:
(defun prompt (prompt-str)
(write-line prompt-str *query-io*)
(finish-output)
(read *query-io*))
(defun factorial (n)
(cond ((= n 1) 1)
(t (* n
(factorial (decf n)))))
(defun factorial-driver ()
(let* ((n (prompt "Enter a number: "))
(result (factorial n)))
(format *query-io* "The factorial of ~A is ~A~%" n result)))
And then run the whole thing as (factorial-driver).
Sample interaction:
CL-USER 54 > (factorial-driver)
Enter a number:
4
The factorial of 4 is 24

Difference between quote, list when used in equal

I need to know what the difference between quote and a list. For example:
cl-prompt> (equal (first (list * 1 2)) *)
T
cl-prompt> (equal (first '(* 1 2)) *)
NIL
I don't get what's the problem.
When used as a variable * refers to the last result printed to the repl.
CL-USER> (+ 4 4)
8
CL-USER> *
8
In the first one, both asterisks are unquoted, so they are treated as variables rather than symbols (their value being whatever you evaluated before that line). They are the same variable, so of course EQUAL.
CL-USER> (list * 1 2)
(8 1 2)
In the second one, the first asterisk is a quoted symbol, while the second is a variable with the value T. The symbol * is not EQUAL to T, so it returns NIL
CL-USER> '(* 1 2)
(* 1 2)

Resources