Here is the code:
(define path (lambda lst start end)
(let ((nodes (car lst))
(edges (cdr lst)))))
Why is this causing an error?
You misused lambda keyword, and function body isn't complete.
(define path (lambda (lst start end)
(let ((nodes (car lst))
(edges (cdr lst)))
; here should be expression, i think with lst, nodes and edges
)))
Note: when you say "Can anyone help me with this error", please include what error message you're seeing. Your whole program can't be an error in itself. But it can contain errors, and when you try running it, it can produce error messages.
I'm assuming you saw error messages. Include those too, next time. Also tell us what you expected to see. Did you expect to get the error you're seeing?
The reason why you should include the actual error message is because the problem you're seeing may not even have anything to do with what you think the problem is. In that case, the error message allows us to make sure we're on the right track in solving your problem.
Looking at your program, I think it's syntactically incomplete. A let needs to have at least a body, or else it's ungrammatical according to the language's rules. There's no body present in:
(let ((nodes (car lst))
(edges (cdr lst)))
)
(An analogous error message in a language like C would occur if you try to use the if statement but not include a test.)
At the very least, you can include some kind of placeholder until you figure out what you really need to put in there. For example:
(let ((nodes (car lst))
(edges (cdr lst)))
"fixme")
should at least make the program a syntactically acceptable one. Though it won't do anything too useful yet.
Related
I am looking to write a Scheme function numofatoms that determines the number of elements in a list.
For example, (numOfSymbols '((1 3) 7 (4 (5 2) ) ) should return 6.
What I have so far:
;(1 3) 7 (4(5 2)) the list
(define (numofatoms lst) ;defining a numofatoms function
(define (flatten x) ;defining a flatten function
(cond ((null? x) '())
((pair? x) (append (flatten (car x)) (flatten (cdr x))))
(else (list x))))
(length (flatten lst)))
(numofatoms '((1 3) 7 (4(5 2)))); calling the function
After defining numofatoms and flatten I don't see any errors but the program is not working. It doesn't produce any outputs.
The posted code works fine if you load it and call numofatoms from the REPL. I presume that OP is either calling load from the REPL or running the code as a script from the command-line, and when either of these is done OP sees no output. The REPL evaluates and prints results (hence the P), but when you load code that isn't necessarily what happens.
When an expression is evaluated in the REPL, the value to which the expression evaluates is printed. There may be an expectation that the value of the final expression in a file will be printed when the file is loaded into the REPL, but that expectation will not be rewarded.
The load procedure is not standardized for R6RS; here it is implementation-specific, and the particulars depend upon the implementation. For Chez Scheme, load returns an unspecified value, so there should be no expectation of seeing anything useful when a file is successfully loaded.
Both R5RS and R7RS have load procedures described in the standards, but both leave it unspecified whether the results of evaluating the expressions in a file are printed.
The details of any script mechanism for Scheme programs is entirely dependent upon the implementation. But, when you run a script from the command-line your are not in a REPL, so again there should be no expectation that the results of evaluating various forms in the file will be printed to the terminal window.
If you want a Scheme file or script to print something, you have to make it do that. If the final line of the posted file is changed to (display (numofatoms '((1 3) 7 (4(5 2))))) (newline), the program will display the result of calling numofatoms whenever it is run.
I'm triying to use when in Scheme but i dont know why at the last element of my list appears .#void>.
Here is my code
(define (genlist x y)
(when
(< x y)
(cons x (genlist (+ x 1) y))))
And this is my output =>
(2 3 4 5 6 7 8 9 . #void>)
We use when when we need to write an if without an else part, and/or when we need to write more than one expression inside the if. Only the last expression's value gets returned, hence we use it mostly for the side effects. To understand it better, in Racket this:
(when <condition>
<exp1>
<exp2>
<exp3>)
Is equivalent to this:
(if <condition>
(begin
<exp1>
<exp2>
<exp3>)
(void)) ; implementation-dependent
The same considerations apply to unless, except that the condition is surrounded with a (not ...).
The source of your problems (and the reason why it's a code smell to have an if without an else) is that your code is not handling the case when (>= x y). Ask yourself, what should you do in that case? Simple, return an empty list! that's the base case of the recursion that's missing from your code.
You would need to use (if (< x y) (cons ...) '()) to produce a proper list.
when (and it's counterpart unless) is mostly for doing side effects (like printing something out) in a context where the result is not used.
e.g. (when debug-mode? (print "got here"))
when is an one armed ifs with implicit begin. The following examples are the same:
(if (any odd? lst)
(begin
(set! some-binding #t)
(display "Found an odd element")))
(when (any odd? lst)
(set! some-binding #t)
(display "Found an odd element"))
And you can use unless instead of using not in the predicate:
(if (not (any odd? lst))
(set! some-binding #f))
(unless (any odd? lst)
(set! some-binding #f))
Peter Norvig made a nice book about Lisp style and in it he addresses this:
Be as specific as your data abstractions warrant, but no more.
if for two-branch expression
when, unless for one-branch statement
and, or for boolean value only
cond for multi-branch statement or expression
So while you can write all your logic using if it will not be the easiest code to read. Other might use the term principle of least surprise. Even though the book is for Common Lisp much of it can be used in Scheme as well. It's a good read if you want to program any lisp dialect professionaly.
For when and unless this is applies much better to Scheme as you have no idea what an implementation might return in the event the predicate evaluates to #f while in CL you could abuse when since it's destined to return nil in such cases.
In you code you are trying to return something and letting the implementation choose what should happen when the predicate failes is what causes the #<void>. When the return matter you should always use two armed if:
(if test-expression
then-expression
else-expression)
Note there is no else keyword.
I am trying pass in a list input to conversation and have the function check to see if the first element in another list (keyword) matches to the first element of the list that user passed in. If the two match then output a zero otherwise pass the tail of the inputted list recursively back to itself.
(define keyword '(am I))
(define (conversation input)
(cond
((equal? (car keyword) (car input)) 0)
(else (conversation (cdr input)))))
The error I get is:
car: contract violation
expected: pair?
given: '()
I understand that equal? compares two elements, a pair, but what I do not understand is why it would create an error when the car of both lists are both exactly an element. Any help would be much appreciated, I'm assuming the solution is rather simple but I can't seem to see it.
My goal is create several functions that pattern match and output appropriate dialog but without the use of regular expressions or other libraries. There is no mandate not to use the two mentioned above but I would like to do it without them to get a better understanding of the logic and the code. Thanks for the help!
The first thing to consider is that you have no condition of failure. You assume there's either a match now with the car, or there will be a match later with the cdr. But there may be no match at all, and you will cdr down your list until your list is '(). As there is no such thing as the car of '() you are getting an error when you try to extract it. Therefore the first thing to do is make sure you've handled this case. I don't know what you intend to do in this case, so I have made the procedure return #f.
Next you consider what to do if the symbols do match. In your case you are choosing to return 0. This part seems to have no problems.
Finally, we consider what to do if the cars do not match. In this case we continue searching the input. This part seems to have no problems.
(define (conversation input)
(cond ((null? input) #f)
((eq? (car input) (car keyword))
0)
(else
(conversation (cdr input)))))
I'm wondering the difference between the two following code:
(define cont2 #f)
(call/cc (lambda (k) (set! cont2 k)))
(display "*")
(cont2 #f)
and
(let [(cont #f)]
(call/cc (lambda (k) (set! cont k)))
(display "*")
(cont #f))
In my opinion, the correct behavior of these two programs should be printing '*' infinitely.
However, the first one only prints one '*' and exits,
while the second one gives the correct behavior.
So I'm confused. Is there something special done with define
or the continuation is not what I thought - all the following programs until the end of the program, it seems to have a boundary or something.
Another guess is that the top-level of environment is special treated, like this:
(define (test)
(define cont2 #f)
(call/cc (lambda (k) (set! cont2 k)))
(display "*")
(cont2 #f))
(test)
This works, but why?
Thank you for your help!
In Racket, each top-level expression is wrapped with a prompt.
Since call/cc only "captures the current continuation up to the nearest prompt", in your first example, none of the other top-level expressions are captured, so applying cont2 to #f results in just #f.
Also, wrapping the first example in begin won't change things since a top-level begin implicitly splices its contents as if they were top-level expressions.
When you are at the top-level, the continuation of (notice the prompt character '>'):
> (call/cc (lambda (k) (set! cont2 k)))
is the top-level read-eval-print-loop. That is, in your first code snippet you enter the expressions one-by-one, going back to the top-level after each. If instead you did:
(begin
(define cont3 #f)
...
(cont3 #f))
you'd get infinite '*'s (because you got back to top-level only at the completion of the begin). Your third code snippet is an instance of this; you get infinite '*'s because the continuation isn't the top-level loop.
It's not only in your opinion. If your doing this in an R5RS or R6RS both not behaving the same is a violation of the report. In racket (the r5rs implementation) it probably is violating since I did test their plt-r5rs and it clearly doesn't loop forever.
#lang racket (the default language of the implementation racket) doesn't conform to any standard so, like perl5, how it behaves is the specification. Their documentation writes a lot about prompt tags which reduces the scope of a continuation.
There are arguments against call/cc that comes to mind when reading this question. I think the interesting part is:
It is telling that call/cc as implemented in real Scheme systems never
captures the whole continuation anyway: Many Scheme systems put
implicit control delimiter around REPL or threads. These implicit
delimiters are easily noticeable: for example, in Petite Chez or
Scheme48, the code
(let ((k0 #f))
(call/cc (lambda (k) (set! k0 k)))
(display 0)
(k0 #f))
prints the unending stream of zeros. If we put each operation on its
own line (evaluated by its own REPL):
(define k0 #f)
(call/cc (lambda (k) (set! k0 k)))
(display 0)
(k0 #f)
the output is mere 0 #f.
I'm not sure if I'm against call/cc as a primitive (I believe your tools should give you the possibility to shoot yourself in the foot). I feel I might change my mind after writing a Scheme compiler though so I'll come back to this when I have.
This also works, don't ask me why. (Call/cc just blows my mind)
(define cont2 #f)
((lambda ()
(call/cc (lambda (k) (set! cont2 k)))
(display "*")
(cont2 #f)))
In your test define the three lines are within an implicit begin struction that you call together that is invoked at the top level. In my version I've just made an anonymous thunk to which invokes itself. In your first define of cont2, your define is just creating a placeholder for the value, and your function calls after aren't linked together within and environment,
I'm evaluating/testing a browser based application presumably written in common lisp. Apart from the browser based interface, the software provides a 'Listener' window with a 'CL-User >' REPL prompt.
I wish to examine the list of functions, symbols, and packages from the REPL prompt. So that I could co-relate the frontend functionality with what is exposed via the REPL.
Google search is futile for me as it leads to tutorials and resources that teaches lisp step-by-step.
Any hints, pointers on examining the state via REPL will be much appreciated.
If you don't know what symbols you're looking for, but do know what packages you want to search, you can drastically reduce the amount of searching you have to do by only listing the symbols from those specific packages:
(defun get-all-symbols (&optional package)
(let ((lst ())
(package (find-package package)))
(do-all-symbols (s lst)
(when (fboundp s)
(if package
(when (eql (symbol-package s) package)
(push s lst))
(push s lst))))
lst))
(get-all-symbols 'sb-thread) ; returns all the symbols in the SB-THREAD package
The line (get-all-symbols 'sb-thread) does just that.
If you have an idea about what type of symbols you're looking for, and want to take a guess at their names, you can do this
(apropos-list "mapc-") ; returns (SB-KERNEL:MAPC-MEMBER-TYPE-MEMBERS SB-PROFILE::MAPC-ON-NAMED-FUNS)
(apropos-list "map" 'cl) ; returns (MAP MAP-INTO MAPC MAPCAN MAPCAR MAPCON MAPHASH MAPL MAPLIST)
(apropos-list) returns all symbols whose name contains the string you pass in, and takes an optional package to search.
As far as figuring out what all those symbols do, well, try this: http://www.psg.com/~dlamkins/sl/chapter10.html
To list everything:
(apropos "")
To list everything from a specific package add 'project-name:
(apropos "" 'quickproject)
To list all the packages (duh):
(list-all-packages)
To find functions exported from a particular package:
(loop for x being the external-symbol of "CL" when (fboundp x) collect x)
(let ((lst ()))
(do-all-symbols (s lst)
(when (fboundp s) (push s lst)))
lst)
Pretty much taken as-is from here.
Maybe something like this:
(defun get-symbols-in-package (&optional (package *package*))
(let ((lst ()))
(do-symbols (s package)
(push s lst))
lst))
Use as (get-symbols-in-package) or (get-symbols-in-package 'foo) ...