Racket Recursive Practices

2 years ago
1 comment

This is actually a lab for my CSCC24 course (Principles of Programming Languages).

Racket is very different from popular programming languages, such as Python, C++.

Its concept is based on something called "functional programming", which I had never touched before.

Honestly, I think Racket is an interesting and elegant language, but it is a little hard to get used to.

This is my solution for the lab. I'm putting it here in case I forget some expressions one day. xD

#lang racket

(require test-engine/racket-tests)
(provide my-length my-reverse is-pal? num-els sum-els repeat-twice my-filter my-map)


;; (my-length xs) -> integer?
;; xs: list?
;; returns the length of xs
(define (my-length xs)
  (if (null? xs) 0 (+ (my-length (rest xs)) 1))
)

;; (my-reverse xs) -> list?
;; xs: list?
;; returns the reverse of xs
(define (my-reverse xs)
  (if (null? xs) '() (append (my-reverse (rest xs)) (list (first xs))))
)

;; (is-pal? xs) -> boolean?
;; xs: list?
;; returns whether xs is a palindrome
(define (is-pal? xs)
  (cond [(<= (length xs) 1) #t]
        [(equal? (take xs 1) (take-right xs 1)) (is-pal? (drop (drop-right xs 1) 1))]
        [else #f]
  )
)

;; (num-els xs) -> integer?
;; xs: list?
;; returns the number of (non-list) elements of xs, on any nesting level
(define (num-els xs)
  (cond [(null? xs) 0]
        [else
          (let ([res (num-els (rest xs))])
            (if (list? (first xs))
                (+ res (num-els (first xs)))
                (+ res 1)
            )
          )
        ]
  )
)

;; (sum-els xs) -> number?
;; xs: list?
;; returns the sum of (non-list) elements of xs, on any nesting level.
;; returns 0 if xs is empty.
(define (sum-els xs)
  (cond [(null? xs) 0]
        [else
          (let ([res (sum-els (rest xs))])
            (if (list? (first xs))
                (+ res (sum-els (first xs)))
                (+ res (first xs))
            )
          )
        ]
  )
)

;; (repeat-twice xs) -> list?
;; xs: list?
;; returns a list which repeats each element of lst twice
(define (repeat-twice xs)
  (if (null? xs)
      '()
      (append (append (list (first xs)) (list (first xs))) (repeat-twice (rest xs)))
  )
)

;; (my-filter f xs) -> list?
;; f: boolean-valued function applicable to every element of xs
;; xs: list?
;; returns a list of those elements from xs that pass the function
;;  f (i.e., f(x) is true for element x in xs), in their original order
(define (my-filter f xs)
  (if (null? xs)
      empty
      (let ([res (my-filter f (rest xs))])
        (if (f (first xs)) (append (list (first xs)) res) res)
      )
  )
)

;; (my-map f xs) -> list?
;; f: function applicable to every element of xs
;; xs: list?
;; return the result of applying f to every element of xs
(define (my-map f xs)
  (if (null? xs)
      empty
      (append (list (f (first xs))) (my-map f (rest xs)))
  )
)

(module+ main

  (check-expect (my-length empty) 0)
  (check-expect (my-length '(1 2 3)) 3)

  (test)
)