Hi guys,

I am currently learning this language and have 2 simple questions.

1: What is the equivalent of "break" and "continue" statement in Racket?? I can't find it anywhere on the site's documentation nor online on other sites.

2: Is there a way to create new variable using a loop in Racket? In other languages you can do something like:

for (i= 0; i<=10; i++)
{
  newvar[i] = i+1;
}

Where for each iteration of loop, it creates new variables: newvar[0], newvar[1], newvar[2]...ect

Thanks,

Limiter

Recommended Answers

All 6 Replies

Actually, that doesn't create new variables, but simply sets the value of an array member.

The good news is, there is a control structure in Scheme that can be used as either a break or a continue; the bad news is, it is really hairy, and not something you would want to use in most cases. The (call-with-current-continuation) function (abbreviated as (call/cc) in most implementations) is more than just a loop short-circuit; it is a generalized form of goto that allows to to halt a computation, move on to a different one, and then pick up again where you left off. This example (taken from a page of Scheme idioms uses a continuation to break out of a nested loop:

   (define (continued x) 
     (call/cc (lambda (return)
                (let loop ((y 0))
                  (if (eq? x y) (return)
                      (begin 
                        (display y)
                        (newline)
                        (display "next? ")
                        (loop (read))))))))

Fortunately, you rarely need it; in most cases, careful design of the returns from a call can avoid the need to break a loop entirely.

Can you give a more specific case of what you want? Scheme (and Racket) uses recursion for nearly all forms of repetition, including those that would be done by iteration in other languages (what is referred to as a 'recursive iteration' in Scheme parlance). Normally in Scheme, you can escape a simple loop by using multiple returns in a (cond) clause, with the return percolating back up the function-call stack.

As for creating new variables, I'm not sure I follow your question. Are you asking how to generate a list or vector, or how to assign a value to an existing list's elements? The former would usually be done using a list constructor like (cons) or (append), or better still, through a map/filter/reduce higher-order function. To take your previous example, you would use the (range) function, which is in the Racket library, or can be implemented easily enough like so:

(define (range m n)
  (if (>= m n)
      '()
      (append (list m) (range (+ m 1) n))))

(range 1 10)

I assume, however, that you have something a bit bigger in mind.

As for assignment, or mutation, that is usually avoided in Scheme, but it is possible; the basic assignment primitives are (set!), (set-car!), and (set-cdr!). The procedure (set!) changes what a symbol points to, while (set-car!) and (set-cdr!) alter the first and last halves of a pair, respectively.

Thanks for the reply,

For the continue statement, I am looking for something that skips that iteration of the loop: In Python it would be like this definition: "The continue statement is used to tell Python to skip the rest of the statements in the current loop block and to continue to the next iteration of the loop."

For the assigning variable, I want to dynamically create a new variable everytime a loop is executed.

For example:

I would have a variable x

On the first iteration of loop, it creates a new variable called x1
On the second iteration of loop, it creates a new variable called x2

ect... Until whatever terminates the loop.

There isn't any kind of procedure in Scheme to do that, no; how could there be, when you aren't actually looping in the sense of an iterative construct? Instead, what you would do is have a different pathway in your conditional which makes the appropriate call.

For example, let's say that in our example where you were generating a list, and you wanted to have it skip, say, the values for 5 and 11 in a range of 20. You would do this in one of two ways. The way closer to what you are talking about would have a test for those cases, with calls specific to the case at hand:

(define (interrupted-range m n . skips)
  (let range-loop ((count-up m))
    (cond ((>= count-up n) '())
          ((memv count-up skips)
           (append (list (+ 1 count-up)) (range-loop (+ count-up 2))))
          (else (append (list count-up) (range-loop (+ count-up 1)))))))

(interrupted-range 0 20 5 11)

However, no self-respecting Schemer would do that for this particular case. Instead, you would generate the initial list, and then filter the list to remove the unwanted values:

(define (int-range-2 m n . skips)
  (filter (lambda (x)
            (not (memv x skips)))
          (range 0 20)))

The point is, there may not be an exact equivalent to continue or break, but there are alternatives that are just as effective.

As for the case where you are populating a list or array, Rubberman is correct; the values aren't separate values, but part of the array in question, and in a language like (say) JavaScript where there are dynamic arrays, the system is simply setting the size of the array for you, and resizing it when it gets larger than it's initial size. Now, in Python, or Scheme, where you work with lists rather than arrays, you are indeed creating a new object or element, but not a new variable: the variable is still x, even if it has several subscripted values.

To get the members of a list by their absolute subscript, you can use:

(list-ref x 3)

which is the equivalent of

x[3]

in Python. However, again, it is more common to use (car) and (cdr) and their variants, to get the values by their relative positions.

I would suggest that you take a look at SICP and the Abelson-Sussman Lecture series. The videos are dated - it is from 1986 - and deliberately uses a small sub-set of the Scheme language, but its still more or less accurate to the current form of the language. Scheme really does take a different mindset, and these videos are excellent in getting you into the Scheme way of doing things. They go slowly at first, but build to dizzying heights in a remarkably short time.

Thanks, I will try and see what I can do. :)

Limiter, the Racket Guide, section 11.9, 'Breaking an Iteration'.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.