#lang racket ; Common Racket Bugs: ; "procedure-name": contract violation ; expected: ... ; given: ... ; tl;dr: you are calling a built-in Racket procedure with the wrong type of argument, ; there is probably some underlying flaw in your logic and you may need to add ; additional base cases ; ------------------------------------------------------------------------------------------- ; CORE PROBLEM: ; ------------------------------------------------------------------------------------------- ; This is one of the more common bugs that novices to Racket will run into. ; So what does it mean? ; Well the short answer is that you called a built-in Racket procedure with the wrong ; argument types. Let's look at the example below: (define (own-length lst) (+ 1 (own-length (rest lst)))) (own-length '()) ; Trying running this code! ; Contract violations can be a bit trickier to fix compared to the other common errors. ; Let's take a look at the error message: ; rest: contract violation ; expected: (and/c list? (not/c empty?)) ; given: '() ; Next, let's break this down line by line. ; The first line, "rest: contract violation", tells you what procedure is giving the error, ; so in this case we know that there is something wrong with our call to (rest). ; The second line, "expected: (and/c list? (not/c empty?))", tell us what kind of argument ; (rest) wants as input. The "and/c" part means that there are multiple requirements that must be ; satisfied. Next, "list?" means that the input should be a list, and "(not/c empty?)" means that ; the input should not be a empty list. So altogether, "expected: (and/c list? (not/c empty?))" ; is telling us that (rest) expects a list that is not empty. ; The third line, "given: '()", tells us what (rest) actually got as an argument. As you can see, ; we gave (rest) an empty list '(). No wonder there's an error! We just talked about above how ; (rest) explicity wants to be given a non-empty list as an input. ; So now is the tough part, fixing your code. A contract violation almost always points to an ; underlying flaw in your logic. Often, it means that you did not account for enough cases ; when you were writing your code. For example, in the code above, something should have been ; done to prevent (rest) having being called on an empty list. In this particular example, it ; makes sense to check that the list is empty, before calling rest. Thus, this code is missing ; a base case, and it probably needs an (if) or (cond) statement. ; See if you can fix the code above! ; ------------------------------------------------------------------------------------------- ; MORE COMPLICATED EXAMPLE: ; ------------------------------------------------------------------------------------------- ; (sum-list lst) should add up all the numbers in a list, any non-numbers in the list are ignored (define (sum-list lst) (cond [(empty? lst) 0] [else (+ (first lst) (sum-list (rest lst)))])) (sum-list '(1 2 3)) (sum-list '(1 a 2 3)) ; Trying running this code! ; You should see an error similar to the one you saw above. Here, the error message is telling you ; that the (+) command expected to get a number, but it got 'a instead. ; How would you fix this code? ; You should be able to fix it by adding another base case, in case the first thing in the list ; is not a number. ; ------------------------------------------------------------------------------------------- ; Feedback: ; ------------------------------------------------------------------------------------------- ; Did this help you fix your bug? If not, feel free to shoot us an e-mail or come to ; office hours. You can also send feedback about this help file to: nathan.lin@yale.edu ; Thanks!