tags:

views:

111

answers:

3
+5  A: 

You probably want to create a list, like this:

(define (med x y z) (car(cdr(list x y z)))

However, it seems like a waste to bundle up the values into a list just to undo them again. This would have the same effect:

(define (med x y z) y)
Greg Hewgill
A: 

Note that as defined, (med . rest) is equivalent to (cadr rest) (except that med only takes three values). Personally, I would expect a function that's supposed to return the median of values to return, well, the median, regardless of list order. For example, (med 4 2 5) would return 4 and (3 0 9 6 5) would return 5.

As for the syntax error (which doesn't matter so much for writing med, since there is a better way using sort, length and list-ref), you don't have your parentheses in the right spots. Here's another way of writing what you have now, lining up terms with their siblings and to the right of their ancestors:

(if (and (
           (<x y) 
           (<y z) 
           y
           if
           (and (
                  (<y x) 
                  (<x z) 
                  x 
                  z
)   )    ) )    )

The format for if is:

(if test-expr true-expr false-expr)

All of your terms are sub-terms of the conditional, and there's no true-expr or false-expr. You'd want to write your code as:

(if (and ...)
    y
    (if (...) ; we know that (not (and (< x y) (< y z))
        x
        z))

Note that you might be ably to simplfy the later tests, since you know the earlier tests are false.

You could also use a cond, which is clearer than a nested sequence of ifs:

(cond (test result)
      (test result)
      (test result)
      ... )

For your code, it would be:

(cond ((and ...) y)
      ((...) x)
      (else z))

There's nothing too special about else (it's a syntactical construct rather than an expression, not that it matters much). You can use any value that evaluates to true (e.g. #t) instead.

Remember, parentheses surround both the function and arguments in Lisp ((foo 1 2 3), not foo(1, 2 ,3)), unlike mathematical notation where parentheses surround just the arguments.

outis
@ outis yes yes exactly Im doing it this way but Im lost with the IFs and ANDs and ORs ...
kristian Roger
@kristian: try sorting the list first. After that, it's easy.
outis
@ outis I stated what u said and i tried doing it but still having problems
kristian Roger
@kristian: what's the project you're working on? `length` and `list-ref` (http://docs.plt-scheme.org/reference/pairs.html#%28def._%28%28quote._~23~25kernel%29._list-ref%29%29) should also be of use.
outis
to write a function that return the median of 3 values | so later when I write 4example (median 12 17 14) i will get 14 we can use function such as and , or , if
kristian Roger
@that's not the project, that's the immediate task, which you've already stated. Why do you need `med`? Are you writing a statistics package? A game, where only the upper half advances to the next round? Are you studying scheme for a class? For your own benefit?
outis
its for class about (programming priciples) I suppose to know the basic of scheme. the link u posted in ur previous comment is nice I can use the (sort '(x y z) <) to avoid using IFs but then how to get the middle value and how to merge the two functions under the main function median()
kristian Roger
@kristian: examine the various list processing functions (http://docs.plt-scheme.org/reference/pairs.html), especially the two I mentioned previously. Combined with `sort`, you can write `median` in short order. The best abstraction level (http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#%_sec_2.1.2) for this problem is operations on lists rather than elements of the list (the division is very thin, but present).
outis
@kristian: as for merging functions (which doesn't have a clear meaning, so I'm assuming you mean call multiple functions in the body of another function), remember that every expression has a value and can be passed as an argument to another function: `(define (fifth-place . rest) (list-ref (sort rest <) 4))`
outis
A: 

while outis did a pretty good job of explaining the issue, there's one other important bit you need to know

(<x y) 

calls the function named <x with the parameter y. you need to make sure you add a space inbetween the < and the x, like so:

(< x y)
aspo