Sujet : Re: Macro noob
De : 643-408-1753 (at) *nospam* kylheku.com (Kaz Kylheku)
Groupes : comp.lang.lispDate : 18. Jun 2025, 19:54:30
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <20250618113730.17@kylheku.com>
References : 1 2
User-Agent : slrn/pre1.0.4-9 (Linux)
On 2025-06-18, B. Pym <
Nobody447095@here-nor-there.org> wrote:
B. Pym wrote:
>
Frank Buss wrote:
(defun count-words (string)
"returns the number of words in a string"
(loop for char across string
with count = 0 and in-word = nil
finally (return count)
do (if (alphanumericp char)
(unless in-word
(setf in-word t)
(incf count))
(setf in-word nil))))
Gauche Scheme:
(use srfi-13) ;; string-index string-skip
(use srfi-14) ;; character sets
(define (count-words str)
(define p 0) ;; Position.
(let go ((cnt 0) (inc-a 1) (inc-b 0)
(f0 string-index) (f1 string-skip))
(set! p (f0 str char-set:letter+digit p))
(if p
(go (+ cnt inc-a) inc-b inc-a f1 f0)
cnt)))
gosh> (count-words "hi ?? ho xx23zz")
3
gosh> (count-words " !! ")
0
gosh> (count-words " ")
0
gosh> (count-words " foo---bar ")
2
>
More understanbable.
>
(define (count-words str)
(define p 0) ;; Position.
(let go ((cnt 0)
(inc-a 1) ;; Amount to increment cnt when finding alphanumerics.
(inc-b 0) ;; Amount to increment cnt when skipping alphanumerics.
(func-a string-index) ;; Function to find an alphanumeric.
(func-b string-skip)) ;; Function to skip alphanumerics.
(set! p (func-a str char-set:letter+digit p))
(if p
;; When we recurse, we swap the increments and the
;; functions. So if we were finding alphanumerics,
;; during the next pass we'll be skipping alphanumerics.
(go (+ cnt inc-a) inc-b inc-a func-b func-a)
cnt)))
That's longer than Frank Buss' loop and less understandable.
You've got iteration expressed by tail recursion.
Sine you have only one tail call in one place, you might
as well relocate that to the top and have a do loop:
(do ((cnt 0 (+ cnt inc-a))
(inc-a 1 inc-b)
(func-a string-index func-b)
(func-b string-skip func-a))
...)
You have a loop which swaps two functions on each iteration.
What's next; continuations?
Frank's loop code doesn't do any function indirection.
A programming neophyte can work out what it does.
Now watch:
2> [partition-by chr-isalnum "How, now brow cow!!"]
("How" ", " "now" " " "brow" " " "cow" "!!")
3> (flow "***How now, brown cow?!"
(partition-by chr-isalnum))
("***" "How" " " "now" ", " "brown" " " "cow" "?!")
4> (flow "***How now, brown cow?!"
(partition-by chr-isalnum)
(keep-if [chain 0 chr-isalnum]))
("How" "now" "brown" "cow")
5> (flow "***How now, brown cow?!"
(partition-by chr-isalnum)
(keep-if [chain 0 chr-isalnum])
len)
4
Or, just use regex!
6> (tok #/[\w\d]+/ "***How now, brown cow?!")
("How" "now" "brown" "cow")
7> (len (tok #/[\w\d]+/ "***How now, brown cow?!"))
4
-- TXR Programming Language: http://nongnu.org/txrCygnal: Cygwin Native Application Library: http://kylheku.com/cygnalMastodon: @Kazinator@mstdn.ca