Re: Macro noob

Liste des GroupesRevenir à cl lisp 
Sujet : Re: Macro noob
De : 643-408-1753 (at) *nospam* kylheku.com (Kaz Kylheku)
Groupes : comp.lang.lisp
Date : 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/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

Date Sujet#  Auteur
18 Jun 25 * Re: Macro noob3B. Pym
18 Jun 25 `* Re: Macro noob2B. Pym
18 Jun 25  `- Re: Macro noob1Kaz Kylheku

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal