Re: hmmm ... a solution but not a high order procedure.



I mainly stayed with basic procedures because the other ones are all in SRFIs, so I'd have to hunt them down and then include them. Most of the most useful ones (like foldl/foldr) can be done in a very small amount of code anyway.

Scheme does do threads: (thread (lambda () ...)) runs the "..." part in a different thread. It's very simple, and there are other functions for semaphores to synchronize them.

I originally "discovered" (I'm sure it's actually a well-known thing, I am just not sure what real people call it) this function when I was trying to organize a bunch of files. Suppose you have a list of files you downloaded from various places, some of which form sets from the same place (like if you made a habit of going around and downloading every image from every page you visit).

You might want to separate them into archives with all the ones from the same page, but you really don't want to manually go around and say "okay, these have filenames that all look the same, they're the same set". Since ones that go together are likely to be adjacent in a sorted list, if you compare each pair of adjacent filenames with some sort of string difference function, and limit it to some magic number for "these two things are really different", then you can use my partition function to sort them for you. In practice it seemed to work better to take all the differences and then partition /them/, looking for jumps that were well above the average, so if the list of string differences is like (1 1 2 1 1 47 1 3 1) then that 47 is way out of bounds and obviously represents a partition boundary.

From your other posts I see you are learning Scheme. I really can't
recommend the 99 Lisp Problems thing enough. Just doing the first third or so, all the ones on list processing, taught me a lot about the Lispy way of attacking a problem.

--Ross

On 2007-05-05 09:23:36 -0500, "Mike" <mcu87992@xxxxxxxxxxxxxx> said:

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)


.



Relevant Pages


Loading