3

New to scheme here and I'm having some trouble learning do loops. I am attempting to make a function that will take in an object and a vector, and then iterate through the vector until it find that object. When the object is found, it would then return a list containing all of the items in the vector before the object. My code is below. All it will return is how many iterations the do loop went through, instead of the list I want it to. If anyone could help me with the syntax, I would greatly appreciate it. Thanks! ( ideally this would return (1 2))

    (define(vector-test-iterative X Vector)    
      (do ((i 0 (+ i 1))) (< i (vector-length Vector))
          (if (eqv? X (vector-ref Vector i))
              (= i (vector-length Vector))
              (cons (vector-ref Vector i) (ls '())))
          ls))


(vector-test-iterative '4 #(1 2 4 3 5))
1
  • In Scheme, parens don't go on their own line. The indentation should be enough to set apart code blocks. Commented Nov 12, 2010 at 0:20

2 Answers 2

4

If you're using Racket, then there's no need to use do, which was never popular among schemers anyway. There's a whole range of iterators -- look for for in the docs, and things that start with for. For example, your code boils down to

#lang racket
(define (values-before x vector)
  (for/list ([y (stop-before (in-vector vector)
                             (lambda (y) (eqv? x y)))])
    y))

(If you really want to use do, then you're missing a pair of parens around the test, and you should add a binding for the accumulator.)

Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the answer. what I want to do is store in a list all of the values that appear in the vector before some other value does. So if my vector is 1 2 3 4 and I pass in 4, I want the function to return 1 2 3. I tried running your code and received an error that "for/list" was a reference to an undefined identifier by the way. but I will definitely look into for loops.
So my initial guess about what you're trying to do was wrong -- I revised it to match what you want now. As for the error, you should be using the "determine language from source" language, and make sure that you have the "#lang racket" at the top. (And hopefully you're using a recent version.)
1

A solution that uses a named loop. Cleaner (in my opinion!) than the do version and should work on any R5RS Scheme:

;; Extracts the sublist of `lst` up to `val`. 
;; If `val` is not found, evaluates to an empty list.
(define (upto val lst)
  (let loop ((res null) (lst lst))
    (cond ((null? lst) null)
          ((eq? val (car lst)) (reverse res))
          (else (loop (cons (car lst) res) (cdr lst))))))

;; Adapts the above procedure to work with vectors.
(define (vector-upto val vec)
  (list->vector (upto val (vector->list vec))))

;; test
(vector-upto 6 #(1 2 3 4 5))
=> #0()
(vector-upto 5 #(1 2 3 4 5))
=> #4(1 2 3 4)
(vector-upto 3 #(1 2 3 4 5))
=> #2(1 2)
(vector-upto 1 #(1 2 3 4 5))
=> #0()

1 Comment

I am not sure that this solution (using alternative let syntax) is clearer than a do, if there is a side effect before each call of the body. But I think this is a matter of personal preference. However +1 for your suggestion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.