Strings as argument to function Scheme Racket

1.5k views Asked by At

I want to get two strings as arguments, and check if the first string is the beginning of the second string. I cannot get that since I don't know how to get strings as arguments to my function.

(define starts-with( lambda (prefix str)
                  (define str2 (string->list (str)))
                  (define prefix2 (string->list (prefix)))
( cond ( (= (string-length(prefix2) 0) display "#t")
      ( (= car(prefix2) car(str2)) (starts-with (cdr(prefix2)cdr(str2) ) ) )
      ( display "#f")))))

Error:  application: not a procedure; expected a procedure that can be
 applied to arguments

given: "ab" arguments...: [none]

Can anyone explain me what is my mistake, and in general how scheme works with lists or strings.. ? I want to have:

 (starts-with "baz" "bazinga!") ;; "#t"
1

There are 1 answers

2
Óscar López On BEST ANSWER

The problem is not how to pass strings as arguments, the problem is... that you have to understand how Scheme works in the first place. The parentheses are in all the wrong places, some are missing, some are unnecessary, and the way you're invoking procedures is incorrect. There are so many mistakes in your code that a complete rewrite is needed:

(define (starts-with prefix str)
  (let loop ((prefix2 (string->list prefix)) ; convert strings to char lists 
             (str2 (string->list str)))      ; but do it only once at start
    (cond ((null? prefix2) #t) ; if the prefix is empty, we're done
          ((null? str2) #f)    ; if the string is empty, then it's #f
          ((equal? (car prefix2) (car str2)) ; if the chars are equal
           (loop (cdr prefix2) (cdr str2)))  ; then keep iterating
          (else #f))))                       ; otherwise it's #f

Be aware of the following errors in your original implementation:

  • You have to convert the strings into lists of chars, but only once before starting with the recursion.
  • Because we're going to need a helper procedure, it's a good idea to use a named let for it - it's just syntactic sugar for a recursive procedure, not really a loop
  • You were missing the case when the string is shorter than the prefix
  • You should not display the values you intend to return, just return them
  • We must not use = for comparing chars, the correct way is to use char=? or equal?, which is more general
  • The last condition of a cond should be an else
  • And last but not least, bear in mind that in Scheme a function is called like this: (f x) and not like this: f(x). Also, you can't put () around something unless you intend to call it as a function, that's why this: (str) was producing the error application: not a procedure; expected a procedure that can be applied to arguments