#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 NOT 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!