Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
This code works fine:
(let* ((str (read-line)))
(write (char str 1)))
But if I add some, it breaks:
(let* ((str (read-line))
(str-len (length str))))
(write (char str 1)))
*** - EVAL: variable STR has no value
Why?
let and let* introduce bindings in a set of forms with the following syntax:
(let bindings
declarations
forms)
So the bindings have the value specified only inside the forms.
You have written:
(let* ((str (read-line))
(str-len (length str))))
(write (char str 1)))
If we align it to make it more understandable, it is simply:
(let* ((str (read-line))
(str-len (length str))))
(write (char str 1)))
^
| invalid parenthesis
So, you can discover that you have the forms part of the let* empty, which is legal in Common Lisp, and its value is nil.
You can also discover that the write form is outside the let*, and for this reason, the variables str and str-len are unknown, since they are outside of the global let form.
As specified in a comment, if you use an editor which knows the syntax of Common Lisp (there are several available), you can find this kind of errors as soon as you type your code. For instance, in this case you would have noticed immediately the extra parenthesis, which is highlighted clearly by such an editor. Moreover, the editor would have aligned correctly the forms, with write aligned under let*.
Related
This question already has an answer here:
I want to make circular list with common lisp [duplicate]
(1 answer)
Closed 4 years ago.
I am trying to understand why this produces what seems to be circular list.
* (progn
(setf (car *x*) (append '(3) *x*))
2)
2 ;; No "apparent issue setting the value. Hence it is related to printing `*x*`
*x* ;; infinite loop, perhaps due to the structure of *x*??
Why is it a circular list? I would expect that it should not be a circular list
What is different between this question and the "duplicate" question:
In this question, I believe *x* should not be a circular list. In the duplicate answer chain, it is shown how to create a circular list, and neither of the example uses the result of append in the setf.
Alright, I found the answer:
My confusion arises from misunderstanding the spec where they say that append returns a new list.
Evidently a new list does not mean that each and every member of it is new (does not mean a copy is returned). The last argument of append is actually shared...
It's not the reader, but the printer that is in an infinite loop.
Most implementations have a variable to limit the top level printer,
see *PRINT-LEVEL*, *PRINT-LENGTH*
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Common Lisp provides many flexible coding options for achieving a given result. However, it is sometimes difficult to choose the best approach. For example, the following vector expressions all produce the same result in different ways.
(defparameter objects (list 1 2 3))
(apply #'vector objects)
(coerce objects 'vector)
(make-array (length objects) :initial-contents objects)
(read-from-string (format nil "#~S" objects))
Of course, some expressions are more flexible than others, depending on the required output; but for a given output as above, what criteria are useful for deciding which to use?
(apply #'vector objects) is subject to the usual limitations of APPLY, which is that objects shouldn't hold more than CALL-ARGUMENTS-LIMIT elements. This is bad style even when you have only a few arguments.
COERCE is great: not only it performs the job, it also conveys the intent very well. However, you won't be able to give additional parameters for the resulting vector (e.g. fill-pointer, etc.); you cannot convert nested lists into matrices.
MAKE-ARRAY gives you full control over the resulting array: adjustability, fill-pointer, dimensions, element-type, displacement.
READ-FROM-STRING is a big no for data conversion, in general. In terms of useless computations, this approach is the Rube Goldberg's version of coerce. It also comes with a lot of security concerns, unless you are 100% sure about what the string contains. Here, you create the string yourself, but if your data contains any value for which another part of the code redefined PRINT-OBJECT, the code might break.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I've been reading sicp trying to understand scheme, specially macros. I noticed that sicp doesnt talk about macros at all. I read on Paul Graham's site that:
The source code of the Viaweb editor was probably about 20-25% macros. Macros are harder to write than ordinary Lisp functions, and it's considered to be bad style to use them when they're not necessary. So every macro in that code is there because it has to be.
So I desperately wanted to know how to write macros and what to use them for, so I read this site about macros: http://www.willdonnelly.net/blog/scheme-syntax-rules/
But that site just explains how to write a "for" macro. I think Paul Graham talks about CL and the other blog talks about scheme, but they are partly the same. So, wat can be an example of something that cannot be done with ordinary procedures and thus must be done with macros?
EDIT: I have already seen a similar question, but wanted to ask if there was some sort of crazy algorithm that you could do with macros that couldn't possible be done with procedures(other than syntactic sugar as described in that question's answer).
Macros are a tricky subject that I've personally reversed my own opinions on no less than a dozen times, so take everything with a grain of salt.
If you are just getting acquainted with macros, you'll find the most helpful to be those macros that clarify or expedite existing expressions.
One such macro that you may have been exposed to is the anaphoric macro, which remains as popular today as the day Paul Graham coined the term:
(define-syntax (aif x)
(syntax-case x ()
[(src-aif test then else)
(syntax-case (datum->syntax-object (syntax src-aif) '_) ()
[_ (syntax (let ([_ test]) (if (and _ (not (null? _))) then else)))])]))
These macros introduce "anaphora" variables, namely it that you can use in the consequent and alternative clauses of an if statement, e.g:
(aif (+ 2 7)
(format nil "~A does not equal NIL." it)
(format nil "~A does equal NIL." it))
This saves you the hassle of typing a let statement -- which can add up in large projects.
More broadly, transformations that change the structure of a program, dynamically generate "templated" code or otherwise "break" rules (that you hopefully know well enough to break!) are the traditional domain of the macro. I could write on and on about how I've simplified countless projects and assignments with macros -- but I think you'll get the idea.
Learning Scheme-style macros is a little daunting, but I assure you that there are excellent guides to syntax-rules-style macros for the merely eccentric, and as you gain more and more experience with macros, you'll probably come to the conclusion that they are a beautiful idea, worthy of the name "Scheme".
If you happen to use Racket (previously known as PLT Scheme) -- It has excellent documentation on macros, even providing a few neat tricks along the way (I'd also guess most of what is written there can be readily written in another Scheme dialect without issue)
Here is one standard answer (part of which is also covered in SICP - see Exercise 1.6 for example; also search for the keyword "special form" in the text): in a call-by-value language like Scheme, an ordinary procedure (function) must evaluate its argument(s) before the body. Thus, special forms such as if, and, or, for, while, etc. cannot be implemented by ordinary procedures (at least without using thunks like (lambda () body), which are introduced for delaying the evaluation of the body and may incur performance overheads); on the other hand, many of them can be implemented with macros as indeed done in RnRS (see, for instance, the definition of and by define-syntax on page 69).
The simple answer is that you can make new syntax where delaying evaluation is essential for the functionality. Imagine you want a new if that works the same way as if-elseif. In Lisp it would be something that is like cond, but without explicit begin. Example usage is:
(if* (<= 0 x 9) (list x)
(< x 100) (list (quotient x 10) (remainder x 10))
(error "Needs to be below 100"))
It's impossible to implement this as a procedure. We can implement something that works the same by demanding the user to give us thunks and thus the parts will become procedures that can be run instead:
(pif* (lambda () (<= 0 x 9)) (lambda () (list x))
(lambda () (< x 100)) (lambda () (list (quotient x 10) (remainder x 10)))
(lambda () (error "Needs to be below 100")))
Now it's easy implementation:
(define (pif* p c a . rest)
(if (p)
(c)
(if (null? rest)
(a)
(apply pif* a rest))))
This is how JavaScript and almost every other language that doesn't support macros do it. Now if you want to give the user the power of making the first instead of the second you need macros. Your macro can write the first to the second so that your implementation can be a function or you can just change the code to a nested if:
(define-macro if*
(syntax-rules ()
((_ x) (error "wrong use of if*"))
((_ p c a) (if p c a))
((_ p c next ...) (if p c (if* next ...)))))
Or if you want to use the procedure it's even simpler to just wrap each argument in a lambda:
(define-syntax if*
(syntax-rules ()
((_ arg ...) (pif* (lambda () arg) ...)))
The need of macros is to reduce boilerplate and simplify syntax. When you see the same structure you should try to abstract it into a procedure. If that is impossible since the arguments are used in special forms you do it with a macro.
Babel, a ES6 to ES5 transpiler converts JavaSript ES6 syntax to ES5 code. If ES5 had macros it would have been as easy as making compability macros to support ES6. In fact most features of newer versions of the language would have been unnecessary since programmers don't have to wait for a new version of a language to give it new fancy features. Almost nothing of new language features in Algol languages (PHP, Java, JavaScript, Python) would have been necessary if the language had hygenic macro support.
My understanding is that tail recursion is recursion where a return value is not necessary to finish the operation; that is, the recursion is the last step in the function, and the rest of the function is done once it makes the recursive call.
To that, I ask if this example (from Mr. Norvig) is tail recursion:
(defparameter *titles*
'(Mr Mrs Miss Ms Sir Madam Dr Admiral Major General)
"A list of titles that can appear at the start of a name.")
(defun first-name (name)
"Select the first name from a name represented as a list."
(if (member (first name) *titles*)
(first-name (rest name))
(first name)))
Once the final first-name is called as a branch of the if statement, there is nothing else that function does; therefore, it is tail recursion?
Yup, that is an example.
Tail recursion optimization is available in many implementations of Common Lisp but it is not required by the spec.
This means you can have a Common Lisp without tail recursion optimization.
You may also find that the version you are using needs to be poked a bit to perform this optimization.
So in some implementation you may need to use 'declare' to inform your compiler that you want to optimize for speed.
(defun first-name (name)
"Select the first name from a name represented as a list."
(declare (optimize (speed 3) (compilation-speed 0) (debug 0) (safety 1)))
(if (member (first name) *titles*)
(first-name (rest name))
(first name)))
Edit:
This site is a few years old now but may provide some info.
Also be sure to read the comments as Joshua and Rainer massively improve the detail here.
Yes and no. Usually yes. It will also be optimized if the compiler supports TCO and the right optimization settings are active. But sometimes the compiler will not be able to optimize it.
If name would have been declared special, then possibly not.
If there would be something like
(defvar name '(susanne mustermann))
then the parameter name of the function would be declared special (it would use dynamic binding). Then a compiler might not use tail call optimization in the first-name function.
This means that you also need to know whether variable symbols are declared special or not.
That's one of the reasons, global special variables should be written like *name* to prevent special declaration of those local variables which should be lexical variables. In this case a special declaration would also prevent TCO.
We better write:
(defvar *name* '(susanne mustermann))
I've been learning scheme, and I just realized that I don't really know how to properly comment my functional scheme code. I know how to add a comment of course - you add a ; and put your comment after it. My question is what should I put in my comments, and where should I comment for maximum readability and comprehensability for other programmers reading my code?
Here's a code snippet I wrote. It's a function called display-n. It can be called with any number of arguments and outputs each argument to the screen in the order that they are provided.
(define display-n
(lambda nums
(letrec ((display-n-inner
(lambda (nums)
(display (car nums))
(if (not (equal? (cdr nums) (quote ()))
(display-n-inner (cdr nums))))))
(display-n-inner nums))))
Edit: Improved tabbing and replaced '() with (quote ()) to avoid SO messing up the formatting.
I'm just not sure how/where to add comments to make it more understandable. Some scheme code I've seen just has comments at the top, which is great if you want to use the code, but not helpful if you want to understand/modify it.
Also - how should I comment macros?
The common style for Lisp comments is
Four semicolons for commentary on a whole subsection of a file.
Three semicolons for introducing a single procedure.
Two semicolons for a description of the expression/procedure definition on the following line.
One semicolon for an endline comment.
Procedure overview comments should probably follow the style of RnRS documens, so to just add comments to your procedure as-is, would look something like
;;; Procedure: display-n NUM ...
;; Output each argument to the screen in the order they are provided.
(define
display-n (lambda nums
(letrec ((display-n-inner (lambda (nums)
(display (car nums))
(if (not (equal? (cdr nums) '()))
(display-n-inner (cdr nums))))))
(display-n-inner nums))))
N.B. I don't use three semicolons for the whole procedure description, since it screws up fill-paragraph in Emacs.
Now about the code, I would ditch the whole define-variable-as-a-lambda thing. Yes, I get that this is the "purest" way to define a function, and it makes for a nice consistency with defining procedures are the results of LETs and other procedures, but there's a reason for syntactic sugar, and it's to make things more readable. Same for the LETREC—just use an internal DEFINE, which is the same thing but more readable.
It's not a huge deal that DISPLAY-N-INNER's parameter is called NUMS, since the procedure's so short and DISPLAY-N just hands its NUMS straight to it anyways. "DISPLAY-N-INNER" is sort of a lame name, though. You would give it something with more semantic meaning, or give it a simple name like "ITER" or "LOOP".
Now about the logic of the procedure. First, (equal? (cdr nums) '()) is silly, and is better as (null? (cdr nums)). Actually, when you are operating over an entire list, it's best to make the base case a test of whether the list itself, and not its CDR, is empty. This way the procedure won't error if you pass it no arguments (unless you want it to do that, but I think it makes more sense for DISPLAY-N to do nothing if it gets nothing). Furthermore, you should test whether to stop the procedure, not whether to continue:
(define (display-n . nums)
(define (iter nums)
(if (null? nums)
#t ; It doesn't matter what it returns.
(begin (display (car nums))
(iter (cdr nums)))))
(iter nums))
But for all that, I would say the the procedure itself is not the best way to accomplish the task it does, since it is too concerned with the details of traversing a list. Instead you would use the more abstract FOR-EACH method to do the work.
(define (display-n . nums)
(for-each display nums))
This way, instead of a reader of the procedure getting mired in the details of CARs and CDRs, he can just understand that FOR-EACH will DISPLAY each element of NUMS.
Some random notes:
Traditionally, Scheme and Lisp code has used ;;; for toplevel comments, ;; for comments in the code, and ; for comments on the same line as the code they're commenting on. Emacs has support for this, treating each of these a little differently. But especially on the Scheme side this is no longer as popular as it was, but the difference between ;; and ; is still common.
Most modern Schemes have adopted new kinds of comments: theres:
#|...|# for a block comment -- useful for long pieces of text that comment on the whole file.
#;<expr> is a comment that makes the implementation ignore the expression, which is useful for debugging.
As for the actual content of what to write, that's not different than any other language, except that with a more functional approach you usually have more choices on how to lay out your code. It also makes it more convenient to write smaller functions that are combined into larger pieces of functionality -- and this changes the documentation style too, since many such small functions will be "self documenting" (in that they're easy to read and very obvious in how they're working).
I hate to sound like a broken record, but I still think that you should spend some time with HtDP. One thing that it encourages in its design recipe is to write examples first, then the documentation, and then expand that to actual code. Furthermore, this recipe leaves you with code that has a very standard set of comments: the input/output types, a purpose statement, some documentation about how the function is implemented when necessary, and the examples can be considered as another kind of documentation (which would turn to commented code in "real" code). (There are other books that take a similar position wrt documentation.)
Finally, documenting macros is not different than documenting any other code. The only thing that can be very different i what's written in the comments: instead of describing what some function is doing, you tend to describe what code it expands too, so the comments are also more on the meta level. A common approach to macros is to to minimal work inside the macro -- just what's needed at that level (eg, wrap expressions in (lambda () ...)), and leave the actual implementation to a function. This helps in documenting too, since the two related pieces will have comments on how the macro expands and how it runs, independently.
I follow an approach similar to what's posted here:
http://www.cc.gatech.edu/computing/classes/cs2360/ghall/style/commenting.html
Note: this is for Common Lisp.
Specifically:
" Four Semicolons(;;;;)
...denote a sub heading in the file...
Three Semicolons(;;;)
...denote a description of the succeeding function, macro, or
variable definition...
[I usually just most of the description into the "docstring"
of the function or variable.]
Two Semicolons(;;)
...denote a description of the succeeding expression...
One Semicolon(;)
...denotes an in-line comment that explains a particular element
of the expression on that line... Brevity is important for
inline comments"
I think a great place to start would be to put your one-sentence description of what the function does
It can be called with any number of arguments and outputs each argument to the screen in the order that they are provided.
as a comment at the beginning.
I'm not particularly conversant in scheme, so I can't comment (:-) on whether additional line-by-line comments explaining the mechanics of how the function achieves that result would be expected according to normal scheme style (but I suspect not).