user2761942
user2761942

Reputation: 11

if: Bad syntax error (Scheme programming)

(define generalized-triangular
  (lambda (input n)
    (if (= n 1)
        1
        (+ (input n) (generalized-triangular (- n 1))))))

This program is designed to take a number and a function as inputs and do the following..

f(1) + f(2) + f(3)+ … + f(N).

An example input would be:

(generalized-triangular square 3)

The Error message:

if: bad syntax;
has 4 parts after keyword in: (if (= n 1) 1 (+ (input n) (generalized-triangular (- n 1))) input)

Upvotes: 1

Views: 9722

Answers (4)

Rörd
Rörd

Reputation: 6681

Since you're using the racket tag, I assume the implementation of generalized-triangular is not required to use only standard Scheme. In that case, a very concise and efficient version (that doesn't use if at all) can be written with the racket language:

(define (generalized-triangular f n)
  (for/sum ([i n]) (f (+ i 1))))

There are two things necessary to understand beyond standard Scheme to understand this definition that you can easily look up in the Racket Reference: how for/sum works and how a non-negative integer behaves when used as a sequence.

Upvotes: 0

WorBlux
WorBlux

Reputation: 1413

here's the tail-recursive

(define (generalized-triangular f n-max)
  (let loop ((n 1) (sum 0))
    (if (> n n-max)
        0
        (loop (+ n 1) (+ sum (f n))))))

Upvotes: 0

Óscar López
Óscar López

Reputation: 235984

The error is quite explicit - an if form can only have two parts after the condition - the consequent (if the condition is true) and the alternative (if the condition is false). Perhaps you meant this?

(if (= n 1)
    1
    (+ (input n) (generalized-triangular input (- n 1))))

I moved the input from the original code, it was in the wrong place, as the call to generalized-triangular expects two arguments, in the right order.

For the record: if you need to execute more than one expression in either the consequent or the alternative (which is not the case for your question, but it's useful to know about it), then you must pack them in a begin, for example:

(if <condition> ; condition
    (begin      ; consequent
      <expression1>
      <expression2>)
    (begin      ; alternative
      <expression3>
      <expression4>))

Alternatively, you could use a cond, which has an implicit begin:

(cond (<condition>   ; condition
       <expression1> ; consequent
       <expression2>)
      (else          ; alternative
       <expression3>
       <expression4>))

Upvotes: 5

Greg Hendershott
Greg Hendershott

Reputation: 16250

Literal answer

The code you posted in your question is fine:

(define generalized-triangular
  (lambda (input n)
    (if (= n 1)
        1
        (+ (input n) (generalized-triangular (- n 1))))))

The error message in your question would be for something like this code:

(define generalized-triangular
  (lambda (input n)
    (if (= n 1)
        1
        (+ (input n) (generalized-triangular (- n 1)))
        input)))

The problem is input. if is of the form (if <cond> <then> <else>). Not counting if itself, it has 3 parts. The code above supplies 4.

Real answer

Two tips:

  1. Use DrRacket to write your code, and let it help you with the indenting. I couldn't make any sense of your original code. (Even after someone edited it for you, the indentation was a bit wonky making it still difficult to parse mentally.)

  2. I don't know about your class, but for "real" Racket code I'd recommend using cond instead of if. Racket has an informal style guide that recommends this, too.

Upvotes: 3

Related Questions