-1

I would like to write the Racket function find-subsets. The function produces the list of subsets of a list of numbers w/o helper functions and that only uses lambda, cond, cons, rest, first, and other primitive functions.

For instance, the following check-expects should be satisfied:

(check-expect (find-subsets '(2 2 3 3)) '(() (2) (3) (2 2) (2 3) (3 3) (2 2 3) (2 3 3)
    (2 2 3 3)))
(check-expect (find-subsets '(1 2 3)) '(() (1) (2) (3) (1 2) (1 3) (2 3) (1 2 3)))

Basically, this function produces the power set of a set of numbers, but I'm not sure how it can produce all of the elements, without recursion.

  • I don't like this given certain restrictions quesion. It's just waste of time. It's just like you can't use multiplication division. Please calculus (1-10*5)/(3*(2+1)/7) – tjorchrt Nov 19 '19 at 07:34
  • @tjorchrt I know you don't like it, but without the restrictions, the problem would be significantly easier. –  Nov 19 '19 at 16:23

1 Answers1

0
#lang racket

(define-syntax-rule (my-let ([var val]) body)
  ((λ (var) body) val))

(define-syntax-rule (Y e)
  ((λ (f) ((λ (x) (f (λ (y) ((x x) y))))
           (λ (x) (f (λ (y) ((x x) y))))))
   e))

(define-syntax-rule (define/rec f e)
  (define f (Y (λ (f) e))))

(define/rec my-append
  (λ (l1)
    (λ (l2)
      (cond [(empty? l1) l2]
            [else (cons (first l1) ((my-append (rest l1)) l2))]))))

(define/rec my-map
  (λ (f)
    (λ (l)
      (cond [(empty? l) empty]
            [else (cons (f (first l)) ((my-map f) (rest l)))]))))


(define/rec my-power-set
  (λ (set)
    (cond [(empty? set) (cons empty empty)]
          [else (my-let ([rst (my-power-set (rest set))])
                        ((my-append ((my-map (λ (x) (cons (first set) x))) rst))
                         rst))])))

Summary: I took the standard definition of powerset from here and curried it. Then I replaced let, append, and map with my-let, my-append, and my-map. I defined the Y combinator as the Y macro and a helper define/rec that makes a function recursive. Then I defined my-append and my-map using the define/rec macro (note that they're curried too). We can substitute everything to get the desired code.

Community
  • 1
  • 1
Atharva Shukla
  • 2,098
  • 8
  • 21
  • Yes, the second code snippet does not use any helper, and it only uses cons, first, empty, empty?, lambda and cond! The first code snippet is to illustrate how I reached the final version (they're macros). Moreover, it seems to be working correctly for me, please specify the error you're getting. – Atharva Shukla Nov 19 '19 at 07:59
  • `my-append`, `my-map`, etc. are parameter names, not functions (in the second code snippet). – Atharva Shukla Nov 19 '19 at 21:04
  • 1
    you're right! Sorry I misunderstood you. +1. Thank you so much! –  Nov 19 '19 at 22:19
  • 1
    why is (lambda (my-power-set) ... (my-power-set (rest set)) ...) not a recursive application? Does it have to do w/ how lambda is defined? –  Nov 19 '19 at 22:46
  • No, that is not a recursive application. There you're just taking in an input `my-power-set` and just passing `(rest set)` to it. You can only recur on things that have already been `define`d. So the question is: can we define recursive functions without using the magical `define`? The answer is the famous "Y combinator". You can read more about it in “The Why of Y”, by Richard Gabriel and also in an explanation in “The Little Schemer” called “(Y Y) Works!” by Dan Friedman and Matthias Felleisen. In essence we're "implementing" recursion everytime we wish to recur as laid out in define/rec, Y. – Atharva Shukla Nov 20 '19 at 05:15
  • I deleted the code because it wasn't necessary. It was enough to explain how each function could be defined in terms of lambda, cons, etc. –  Nov 27 '19 at 21:21