[plt-scheme] Re: Permutation correct way to do it ?

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Fri Apr 4 11:53:41 EDT 2008

On Apr 4, 2008, at 5:21 AM, richard gere wrote:
> Thank you for taking a look at my code.
>

Here is a second look. Up to this point you are right on track:

>    [else (append (insert-symbol-in-a-word a-sym (first alow) empty)
>                  (insert-everywhere/in-all-words a-sym (rest  
> alow))) ]))


The use of insert-symbol-in-a-word contradicts the contract/purpose  
statement of the actual function definition:


> ;;here is the final definition
> ;;insert-symbol-in-a-word : a-sym word -> list-of-words
> ;;to create a list of words by inserting a-sym between cl and
> ;; a-word for all letters in a-word
> ;;eg (insert-symbol-in-a-word 'a (cons 'b empty)) give us
> ;;(cons (cons 'a (cons 'b empty)) (cons (cons 'b (cons 'a empty))  
> empty))
> (define (insert-symbol-in-a-word a-sym a-word cl)


As you can see your function consumes THREE arguments in reality, but  
your contract says TWO.

You discovered another design technique (you are using a form of  
accumulator) and are using in an ad-hoc fashion. At the scale at  
which you are programming, this is probably fine. BUT if this were a  
large module and you might have to hand it over to someone else, this  
person would get confused now.

In a typed programming language, say Java, this would be discovered  
by type checks. So this particular mistake may not show up. You could  
still end up using a random ad hoc design, which would still confuse  
other programmers.

You could, for example, claim that this is plain structural recursion  
in a comment and .. it isn't. And there is no tool that really checks  
this aspect of code.

;; ---

A second criticism: I urge you to design tests for individual  
functions as well as the main function. It really helps think through  
designs.

For an exercise, you may wish to actually design the function that  
you advertise:

;; insert-symbol-in-a-word : Symbol Word -> Listof-Word
;; insert let in each position into word (including beginning and end)
;; Example:
;; given 'a and (cons 'b (cons 'c empty)) ---> ???
;; given 'x and (cons 'a (cons 'b (cons 'c empty))) ---> ???
(define (insert-symbol-in-a-word let a-word)
   empty) ;; <---- Note: I recommend a dummy response


(check-expect (insert-symbol-in-a-word 'a (cons 'b (cons 'c empty)))
	      ????)
(check-expect (insert-symbol-in-a-word 'x  (cons 'a (cons 'b (cons 'c  
empty)))
	      ????)

(generate-report)

;; ---

Having said that, I have never seen your solution and will study it  
to see how it can be easily explained as another example of  
accumulator design.

-- Matthias

> ;;here is the final definition
> ;;insert-symbol-in-a-word : a-sym word -> list-of-words
> ;;to create a list of words by inserting a-sym between cl and
> ;; a-word for all letters in a-word
> ;;eg (insert-symbol-in-a-word 'a (cons 'b empty)) give us
> ;;(cons (cons 'a (cons 'b empty)) (cons (cons 'b (cons 'a empty))  
> empty))
> (define (insert-symbol-in-a-word a-sym a-word cl)
>  (cond
>    [(empty? a-word) (cons (append cl (list a-sym ) a-word ) empty)]
>    [else (cons (append cl (cons a-sym empty)  a-word )
>                (insert-symbol-in-a-word a-sym (rest a-word)
>                                         (append cl (cons (first
> a-word) empty)))) ]))
>








Posted on the users mailing list.