0

I'm new to functional programming and I have no idea how to code this in Lisp. For example, for a given power set such as (1 2 3), how do I code it in a way to make it: (WITHOUT using Lambda functions) ( () (1) (2) (3) (1 2 3) )

So far, I have:

(define  (powerSet lis)
  (if (null? lis) '(()))
 )

(define (APPENDS lis1 lis2)
   (cond
   ((null? lis1) lis2)
        (else (cons (car lis1)
            (APPENDS (cdr lis1) lis2)))
  )
)

Which just returns the empty set, or nothing.

EDIT:

Thank you so much Chris! That made so much sense. The second variation (without the append-map function) works well. However, if you input (powerset'(1 2 3 4)), it gives you:

(() (1) (2) (1 2) (3) (1 3) (2 3) (1 2 3) (4) (1 4) (2 4) (1 2 4) (3 4) (1 3 4) (2 3 4) (1 2 3 4))

Is there anyway for me to make it look like:

(() (1) (2) (3) (4) (1 2) (1 3) (1 4) (2 3) (2 4) (3 4) (1 2 3) (1 2 4) (1 3 4) (2 3 4) (1 2 3 4))

Thanks so much!

user3171597
  • 417
  • 1
  • 6
  • 16

1 Answers1

2

All user-defined functions are lambda (or case-lambda) expressions, including the powerset function you're defining. There is no way to avoid it. However, you can hide the lambda identifier by using internal definitions (it's still a lambda behind the scenes!).

With this in mind, here's an implementation (requires Racket or SRFI 1):

(define (powerset lst)
  (define (make-pair x)
    (list x (cons (car lst) x)))
  (if (null? lst)
      '(())
      (append-map make-pair (powerset (cdr lst)))))

If you're trying to avoid append-map or higher-order functions in general, you could jump through a few hoops to do the same thing:

(define (powerset lst)
  (define (inner next)
    (if (null? next)
        '()
        (cons (car next)
              (cons (cons (car lst) (car next))
                    (inner (cdr next))))))
  (if (null? lst)
      '(())
      (inner (powerset (cdr lst)))))

An expression like

(define (foo bar)
  baz)

is actually expanded into the following equivalent expression:

(define foo
  (lambda (bar)
    baz))
Chris Jester-Young
  • 206,112
  • 44
  • 370
  • 418
  • Thanks Chris! The second function works great. I just have a question that I posted as an edit in my original post, if you don't mind taking a look at it. – user3171597 Nov 22 '15 at 03:59
  • @user3171597 Not easily. You can sort the result afterwards (by length then lexicographically), but trying to build that order into the function itself would make it much more complicated than it should be. – Chris Jester-Young Nov 22 '15 at 04:08
  • Wow, I just realised I had already written an identical implementation (including the same ordering) two years ago: http://stackoverflow.com/a/20623486/13 – Chris Jester-Young Nov 22 '15 at 04:09
  • Hmm I see your answer, but is there anyway to make it sort correctly without using lambda? Thanks :) – user3171597 Nov 22 '15 at 04:26
  • That order that you want is really really hard to do in recursive way, and I think trying to do a non-recursive solution is blasphemous (Scheme is generally about doing stuff recursively). – Chris Jester-Young Nov 22 '15 at 04:27