3

i am new to racket. i am trying create a list from the input of the user and when the value 0 is entred the first three elements are printed.

here is the code:

#lang racket
(define lst '())
(define (add)
   (define n(read))
   (if (= n 0)
      ;then
      (
        list (car lst) (cadr lst) (caddr lst) 
       )
      ;else
      (
        (set! lst (append lst (list n)))
        (add)
       )
     )
 )
(add)

i tested the program with the values 1 2 3 4 5 0

but i keep getting this error:

application: not a procedure;
 expected a procedure that can be applied to arguments
  given: #<void>
  arguments...:
   '(1 2 3)

can anyone help me figure out what's wrong.

Tarounen
  • 1,119
  • 3
  • 14
  • 25
  • 1
    This is a duplicate. While it's hard to search for on Stack Overflow (because of quoting issues in the search), searching for "application: not a procedure" turns up [lots of results](https://www.google.com/search?q=%22application%3A+not+a+procedure%22+tag%3Aracket+site%3Astackoverflow.com&oq=%22application%3A+not+a+procedure%22+tag%3Aracket+site%3Astackoverflow.com&aqs=chrome..69i57.9768j0j1&sourceid=chrome&es_sm=106&ie=UTF-8). – Joshua Taylor Apr 28 '14 at 14:43
  • possible duplicate of ["application: not a procedure" in binary arithmetic procedures](http://stackoverflow.com/questions/19022704/application-not-a-procedure-in-binary-arithmetic-procedures) – Joshua Taylor Apr 28 '14 at 14:46
  • In this case `((set! lst (append lst (list n))) (add))` evaluates `(set! lst (append lst (list n)))` which returns `#`, and then evaluates `(add)` which returns `(1 2 3)`, and then tries to call `#` as a function with the argument `(1 2 3)`. This needs to be `(begin (set! …) (add))`. – Joshua Taylor Apr 28 '14 at 14:48

3 Answers3

5

If you have more than one expression in the "then" or "else" parts, you must enclose them inside a begin, because a pair of () in Scheme are used for function application - that explains the error you're getting. Try this:

(define (add)
   (define n (read))
   (if (= n 0)
      ; then
      (list (car lst) (cadr lst) (caddr lst))
      ; else
      (begin
        (set! lst (append lst (list n)))
        (add))))
Óscar López
  • 232,561
  • 37
  • 312
  • 386
1

I had a similar problem, in a function i called a parameter with the same name of a structure, so, trying to create an instance of that structure i got the same error.

example:

> (struct example (param1 param2) #:transparent)
> (define e (example 1 2))
> e
(example 1 2)
> (define (fn e)
    (example (example-param1 e) 0))
> (fn e)
(example 1 0)
> (define (fn example)
    (example (example-param1 example) 0))
> (fn e)
application: not a procedure;
 expected a procedure that can be applied to arguments
  given: (example 1 2)
  arguments...: 

I hope this helps

Castix
  • 11
  • 3
0

Your code have a few problems, for example it will fail if you enter less than 3 elements. Also, it is not considered good style to define variables at the module level.

I'd suggest the following:

(define (add)
  (define (sub cnt lst)
    (define n (read))
    (if (= n 0)
        (reverse lst)
        (if (< cnt 3)
            (sub (add1 cnt) (cons n lst))
            (sub cnt lst))))
  (sub 0 '()))
uselpa
  • 18,732
  • 2
  • 34
  • 52