5 Replies - 2308 Views - Last Post: 22 January 2013 - 03:11 PM

trouble sorting numbers

Posted 17 January 2013 - 07:44 PM

Im basically doing two calculations (quadratic formula) and I want to sort them. I am very very new to lisp and so much of the documentation just goes way beyond what I understand at this point, regardless, I still have an assignment to do and I pretty much have it done, I just need some help sorting the results.

You have two problems there: First, as the error message is telling you, you're calling sort with too few arguments. Namely you're passing it a single list, while it expects a list and a function. Now you say "Stop talking nonsense, fool! I did pass it a function - are you blind?", but if you look closely at where the parentheses open and close in your code, you've put the function inside the list to be sorted, not as a second argument to sort.

The second problem is that your list doesn't contain what you think it does. Try this in the REPL: '( (/ 4 2) (* 2 3) ). You probably expect it to return a list containing the number 2 and 6, but it doesn't. It returns a list containing two sublists: one that contains the symbol / and the number 4 and 2, and one that contains the symbol * and the numbers 2 and 3. This is because ' is not a shortcut for defining lists, it's a shortcut for quoting a value. When applied to a symbol it returns that symbol as a value rather than evaluating it to the value of the variable with that name and when applied to a list, it quotes the entire contents of that list. To create an unquoted list, use the list function.

Here's some documentation on let: HyperSpec. There are two important things to note here:

The first is that the first part of a let is a list of variable bindings where each binding is itself a list containing two elements (the variable name and the value). So it should be (let ((x value-of-x)) ... ), not (let x value-of-x). This also means that you don't need a second let for y, you can just put it as a second binding in the list:

The other important thing is that lets have body and the variables bound by that let, are only bound within that body. So you don't do (let ((x 41))) (+ x 1), you do (let ((x 42)) (+ x 1)). So for your code that would be:

Except there's still problems with that. First the syntax of an if is (if condition then-part else-part) where the else-part is optional. In your case cons is the then-part and (x y) (which is a function call that calls the non-existent function x with the argument y) is the else-part. You probably meant (cons x y) to be the then-part and the else-part to be empty. Note that this creates a cons-cell where both elements are numbers - that's not a list. If you wanted to create a list containing x and y, you should use (list x y).

Another problem I see is that you don't handle the case where x and y are equal. But the most important problem is that you now have two ifs next to each other that both don't have an else-part. If an if doesn't have an else-part and the condition is false, the if will evaluate to nil. So since the result of a function is the result of the last expression in its body, that means that if your last condition is false, the value of your function will be nil. The result of the first if will not affect the value of your function at all. The rule of thumb is, if the then-part of your if does not have any side-effects, your if should also have an else-part. So I'd do it like this: