[plt-scheme] Re: Permutation correct way to do it ?
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)))) ]))
>