Re: hmmm ... a solution but not a high order procedure.
- From: "Mike" <mcu87992@xxxxxxxxxxxxxx>
- Date: Sat, 05 May 2007 14:23:36 GMT
Hi Ross,
Thank you for this ... although I can see where you are
going with it, I'll need to walk through it a bit to bed it
down properly. This looks so elegant - wouldn't have
considered approaching the solution as you did if I had a
car battery connected to my gonads.
If it's ok with you, I'd like to play with it a bit ... and
get back to you on anything that doesn't gel. Your use of
pred adds a substantial increase in flexibility to the code.
Reading / following the code is OK, designing a solution
(like the one you did) is a different thing altogether.
Pascall (a regular contributor here) posted a very helpful
solution ... walking through his thinking in terms of
defining the task towards a broader solution. His
conceptual approach was to ask a question in terms of
collect what (words) from-where (list of anything / mix of
things). While you approach (aside from using a very
interesting way of 'pulling out' what you want) adds the
capacity to alter the pred procedure to suit changing needs.
So sweet.
I saved Pascall's solution to my PC and it is below my reply
if you are interest in seeing it. As an aside, I noticed
you stayed with car cdr and a couple of minor procedures ...
I'm finding myself do thing much more as I go further. It's
not that things like foldl or match or member aren't useful,
it's because I'm using them without knowing what is going on
to get the results they produce. Also, in general terms, I
find the basics to be very powerful.
Have no idea about the merit of staying with these basic
procedures or using the other ones in terms of efficiency /
memory / cpu time but I suspect the low level stuff might be
faster. Do you know if Scheme does threads or something
close to that?
I truly love this language. As my skills increase, it seems
I can write far tighter solutions and multiple solutions.
And then I see the work others do and drool ... I mean, have
a look at the post on the Groebner Basis in Scheme (the
code) which was a recent new thread. The match behind it is
complex enough but to come up with what he did ... damn.
Once again,
Thank you and no doubt I'll get back to you ASAP.
Kindest regards,
Mike
-----------[ from Pacall ].............
For example, you could say that you want to collect the
words of the sentence:
(define sentence "This is a sentence.")
(collect word sentence)
--> ("This" "is" "a" "sentence.")
sentence is defined.
We need to define collect and word. For word we will need
some kind
of representation of what a word is, that will allow us to
find and
extract the words from the sentence. For this, we can use a
procedure. Therefore, collect will be a higher order
procedure.
Let's try and see how we could define the action of
collecting
something from some-where, abstractly:
(define (collect what from-where)
(let ((item (what 'first from-where)))
(if (null? item)
'()
(cons (car item)
(collect what (what 'rest from-where))))))
Sounds good, no?
So now we can try to implement the function word:
(define (word message sentence)
(cond
((eq? message 'first)
;; find the first word and extract it:
(if (string=? "" sentence)
'()
(list (substring sentence 0 (or (position #\space
sentence)
(string-length
sentence))))))
((eq? message 'rest)
;; find the rest of the sentence and extract it:
(let ((next-space (position #\space sentence)))
(if next-space
(substring sentence (+ 1 next-space)
(string-length sentence))
"")))))
(define (position char string)
(let loop ((p 0))
(cond
((<= (string-length string) p) #f)
((char=? char (string-ref string p)) p)
(else (loop (+ 1 p))))))
C/SCHEME[16]> (collect word sentence)
("This" "is" "a" "sentence.")
Yes, you're right, higher order function for higher order
functions
are not necessarily a good thing. Functions can be used to
represent
any kind of data structure. Closures are equivalent to
objects, and
we can build all scheme from only lambda.
But what's interesting in collect is that it can be used to
collect
other kind of things:
(define (odd-numbers message liste)
(cond
((eq? message 'first)
(cond
((null? liste) '())
((and (integer? (car liste))
(odd? (car liste))) (list (car liste)))
(else (odd-numbers
message (cdr liste)))))
((eq? message 'rest)
(cond
((null? liste) '())
((and (integer? (car liste))
(odd? (car liste))) (cdr liste))
(else (odd-numbers
message (cdr liste)))))))
C/SCHEME[29]> (collect odd-numbers '(1 2 3 4 5 "abc" def 7
8))
(1 3 5 7)
--
__Pascal Bourguignon__
http://www.informatimago.com/
"Ross Andrews" <randrews@xxxxxxxxxx> wrote in message
news:463bcf10$0$16710$4c368faf@xxxxxxxxxxxxxxxxx
|I don't know where your other thread is (or if it rolled
off already)
| but I think I have a HOF that would be useful here. It's
one I made for
| something else that you could apply to this easily; it
came in handy in
| many places when I was doing the "99 Lisp Problems"
| (http://tinyurl.com/tt9e7).
|
| What you want to do is to partition the characters of the
string into
| substrings, based on whether they are whitespace or not,
right? So
| suppose you have a string "cat dog", that you can split
into a list of
| characters, ("c" "a" "t" " " "d" "o" "g"). Compare each
character to
| the next one, and if one is whitespace and one isn't, then
they go in
| different partitions, so that list would become (("c" "a"
"t") (" ")
| ("d" "o" "g")). You can then join those sublists and
remove the ones
| that are all spaces (every 2nd one, actually) to get
("cat" "dog").
|
| I'm probably explaining this badly. Here's the function,
instead; it
| takes a list and a procedure of two arguments.
|
| (define (partition pred lst)
| (if (null? lst)
| lst
| (let loop ((lst (cdr lst)) ; elements unseen
| (curr (list (car lst))) ; the current
group
| (left (car lst)) ; Left side for the
predicate
| (parts '())) ; partitions made so far
| (if (null? lst) ; out of elements
| (append parts (list curr))
| (let ((right (car lst)))
| (cond
| [(pred left right) ; fits in the curr
partition
| (loop (cdr lst)
| (append curr `(,right)) ; tack it on
to the curr
| right
| parts)] ; don't modify parts
| [#t ; need a new partition
| (loop (cdr lst)
| `(,right) ; new part consisting of
the rhs
| right
| (append parts (list curr)))]
| ))))))
|
|
| So given a list (1 1 1 2 2 3) and a predicate =, it will
return ((1 1
| 1) (2 2) (3)).
|
| On 2007-04-28 20:12:30 -0500, "Mike"
<mcu87992@xxxxxxxxxxxxxx> said:
|
| > Hi all,
| >
| > Before I look at any replies I thought I might give it
another go.
| >
| > The original objective was to create a higher order
procedure using a
| > procedure as a param to construct a list of words
contained in a string.
| >
| > While I have a solution, it is not a higher order
procedure of the type I
| > was hoping for. It seemed to me that the task didn't
lend itself to this
| > approach - your comments may prove me completely wrong
(most likely).
| >
| > I see no value of making a fake higher order procedure
by placing
| > definitions inside the master procedure simply to show
it can be done. I
| > see more value having the contributing procedures kept
outside the main one
| > because if necessary, these can be modified to get
different results. Be
| > interested in alternate thoughts about this.
| >
| > I'm certain there are many ways to solve the problem -
but I wanted to avoid
| > using more than the basic Scheme procedures.
| >
| > I'd be interested in feedback on style / problem solving
approach. I have
| > yet to optimise the code but I wanted to make certain
that what was
| > happening was easy to read (and worked!).
| >
| > Minor adjustments can result in spaces being included
either as individual
| > string elements containing one space or n spaces.
| >
| > Now to see what others wrote.
| >
| > Mike
| > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
| > ; Problem: convert a string (sentence)
| > ; into a list of strings (word and
punctuation)
| > ; excluding space characters.
| > ;
| > ; Expected Result: ("This" "is" "a" "sentence" ".")
| > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
| > ; CONSTANTS
| > ;
| > (define a-list (string->list "This is a sentence
.."))
| > ;;;;;;;;;;;;;;;;;;;;;;;;
| > (define [space? x]
| > (eq? x #\space))
| > (define [make-word a-list] ; returns a list of chars
(word)
| > (cond
| > [(empty? a-list) empty]
| > [(space? (car a-list)) empty]
| > [else
| > (cons (car a-list) (make-word (cdr a-list)))]))
| > (define [strip-word a-list]
| > (cond
| > [(empty? a-list) empty]
| > [(space? (car a-list)) (cdr a-list)]
| > [else
| > (strip-word (cdr a-list))]))
| > (define [make-string a-list]
| > (list->string a-list))
| > (define [make-sentence a-list]
| >
| > (cond
| > [(empty? a-list) empty] ; Nothing left. Stop.
| > [(space? (car a-list)) (make-sentence (cdr a-list))]
| > ; ; list isn't empty.
| > ; ; strip spaces
| > [else
| > (cons (make-string (make-word a-list))
| > (make-sentence (strip-word a-list)))]))
| > ; TEST
| > (make-sentence a-list)
| > ; returns
| > ;==> ("This" "is" "a" "sentence" ".")
|
|
.
- Follow-Ups:
- Re: hmmm ... a solution but not a high order procedure.
- From: Pascal Bourguignon
- Re: hmmm ... a solution but not a high order procedure.
- From: Ross Andrews
- Re: hmmm ... a solution but not a high order procedure.
- References:
- Re: hmmm ... a solution but not a high order procedure.
- From: Ross Andrews
- Re: hmmm ... a solution but not a high order procedure.
- Prev by Date: 8 kweenz
- Next by Date: Re: hmmm ... a solution but not a high order procedure.
- Previous by thread: Re: hmmm ... a solution but not a high order procedure.
- Next by thread: Re: hmmm ... a solution but not a high order procedure.
- Index(es):
Relevant Pages
|
Loading