1

I tried making a mutable function with intersect, but I think I'm severely messing it up with how I implemented intersect into the function and I'm not sure about the best way to fix the function.

(define (intersect-mutable)
  (let ((lst '()))
    (let ((lst2 '()))
      (define (insert x)
      (set! lst (cons x lst)))
      (define (intersect)
        (define (helper lst lst2)
          (define contains member)
          (cond ((null? set) '())
                ((contains (car lst) lst2)
                 (cons (car lst) (intersect (cdr lst) lst)))
                (else
                 (intersect (cdr lst) lst2))))
        (helper lst lst2))
      (lambda (function)
        (cond ((eq? function 'intersect) intersect)
              ((eq? function 'insert) insert)
              (else
               'undefined))))))

A test case for the recursive function would be:

>(intersection '(2 4 7 10) '(2 9 0 10))
(2 10)
>(intersection '(1 4 10) '(83 1 48 2 4))
(1 4)

Test cases for insert:

(define mut (intersect-mutable))
((mut 'insert) 'intersect)
((mut 'insert) 'mutable)

To clarify, I'm trying to intersect two separate lists into one list. I added an insert function.

Vicky
  • 19
  • 4
  • 2
    Please provide some example inputs and outputs. Also, it is unclear what 'mutable function' means. – ben rudgers Nov 27 '16 at 02:14
  • Mutable data structures are also known as destructive functions. The functions changes a variable to the current state. So, if v is initially 0 and then I add 3, the value of v is now 3. And then I add 3 to v, the value of v is 6. Basically, the new value of v is stored into memory so it can be later accessed by the user. Hopefully this makes sense. I have a hard time explaining concepts. – Vicky Nov 27 '16 at 02:27
  • So data structures are functions? – Scott Hunter Nov 27 '16 at 02:29
  • Yes. Here's an example of a mutable object. [link](http://stackoverflow.com/questions/40749948/scheme-mutable-functions) – Vicky Nov 27 '16 at 02:32
  • This is the third time you post this question, please don't do that, post a single question and wait until it gets some answers, deleting it and asking it again won't do any good. – Óscar López Nov 27 '16 at 02:35
  • Thats horribble identation. Perhaps you should try with CTRL+i in DrRacket? Where is the variable `method` set? I imagine the muatation is needed to add elements to the two lists that `intersect` uses and thus `intersect` itself doesn't really mutate anything? – Sylwester Nov 27 '16 at 02:43
  • @ÓscarLópez The other times I posted were because I needed someone to help me start my function mutable function. This time, I actually tried to make my function and want help editing it this function after I tried making it myself. The question now and previously are similar, but not the same. I only deleted the previous questions because I didn't require help starting the function, not because nobody answered. And I took into note not to post the exact same questions, so I deleted the second post. – Vicky Nov 27 '16 at 03:03
  • @Sylwester Fixed the issues. I'm having trouble doing a mutation on two lists. I've done it on one list before, but not two. Any tips on how to go about this? – Vicky Nov 27 '16 at 03:08
  • If a procedure takes two lists, do both get mutated to the intersection, or one of them but not the other? Or is a new list returned but constructed via mutation? – ben rudgers Nov 27 '16 at 03:34
  • @benrudgers The new list is returned but constructed via mutation – Vicky Nov 27 '16 at 03:45

2 Answers2

0

Use list->mlist in order to convert a list of immutable cons cells into a list of mutable cons (mcons cells).

See more here: docs

soegaard
  • 30,661
  • 4
  • 57
  • 106
0

If the mutation is only to housekeep the two lists:

(define (intersect-mutable (lst1 '()) (lst2 '()))
  (define (method-insert lst1? value)
    (if lst1?
        (set! lst1 (cons value lst1))
        (set! lst2 (cons value lst2)))
    message-handler)

  (define (method-intersect)
    ;; intersect is a working intersect without mutation
    (intersect lst1 lst2)) 

  (define (message-handler msg)
    (case msg
      ((insert) method-insert)
      ((insert1) (lambda (v) (method-insert #t v)))
      ((insert2) (lambda (v) (method-insert #f v)))
      ((lst1) lst1)
      ((lst2) lst2)
      ((intersect) method-intersect)
      (else (error "No such method" msg))))

  message-handler)

(define obj (intersect-mutable '(10) '(30)))
((obj 'insert) #t 5)
((obj 'insert2) 10)
(obj 'lst1) ; ==> (5 10)
(obj 'lst2) ; ==> (10 30)
((obj 'intersect)) ; ==> (10)

However notice that intersect doesn't really mutate anything. I think perhaps the whole point with this is OO so I imagine we can make operate on one list like this:

(define (list-object (lst '()))
  (define (method-insert . values)
    (set! lst (foldl cons lst values))
    message-handler)

  (define (method-intersect lst2)
    ;; intersect is a working intersect without mutation
    (set! lst (intersect lst lst2))
    message-handler)

  (define (method-member? value)
    (member value lst))

  (define (message-handler msg)
    (case msg
      ((insert) method-insert)
      ((intersect) method-intersect)
      ((member?) method-member?)
      ((lst) lst)             
      (else (error "No such method" msg))))

  message-handler)

(define obj (((list-object '(5)) 'insert) 10 20 30))
(obj 'lst) ; ==> (30 20 10 5)
((obj 'intersect) '(10 30 60))
(obj 'lst) ; ==> (20 30)

Imagine you make many objects like this, then you can make (tiny)CLOS type generic methods:

;; generic. Works on any object that has
;; member? method and lists
(define (member? value  obj)
  (if (procedure? obj)
      ((obj 'member?) value)
      (member value obj)))


;; Another object type that has member?
;; only that it means the values binary bits
;; are set on the object
(define (number-object value)
  (define (method-member? value2)
    (= value2 (bitwise-and value value2)))

  (define (message-handler msg)
    (case msg
      ((member?) method-member?)))

  message-handler)

;; test objects
(define num1 (number-object 24))
(define lst1 (list-object '(1 8)))

;; some test
(member? 2 num1); ==> #f
(member? 8 num1); ==> #t
(member? 8 lst1); ==> (8) (true)
(member? 9 lst1); ==> #f
(member? 9 '(1 3 5 9 10)) ; ==> (9 10)

;; map is the ultimate test
(map (lambda (o) (member? 8 o)) (list num1 lst1))
; ==> (#t (8))
Sylwester
  • 47,942
  • 4
  • 47
  • 79