Discussion:
String processing
Add Reply
B. Pym
2024-09-18 23:13:11 UTC
Reply
Permalink
We've had this discussion before. Perl was designed to make file scanning
and pattern matching easy. The programs we've been designing in this
thread are precisely the kind of application that Perl is intended for.
while (<>) { # Loop over input lines
counter++ if /^\s*\(/; # if first non-white character is open-paren, count i
t
}
would be much more verbose without being significantly more expressive.
-------------
If it weren't for the regexp, which needs a comment of 10 words to
explain what it does, and which is easy to get wrong (either comment,
or regexp that is), I could believe that statement, but so I have to
humbly disagree ;)
(loop for line = (read-line *standard-input* nil nil)
while line
count (starts-with (left-trim-whitespace line) "("))
This uses two trivial string functions which are probably part of
every working CL user[1]. With an extensible LOOP facility, this could
even be clarified further...
....
(defun starts-with (string substring)
"Detect whether the `string' starts with `substring'."
(eql 0 (search substring string)))
(defun left-trim-whitespace (string &optional (ws-bag '(#\Space #\Tab)))
"Trims any whitespace characters (i.e. characters in `ws-bag') from
the left side of `string'."
(string-left-trim ws-bag string))
Gauche Scheme

(use gauche.generator)

Using a regular expression:

(generator-count #/^\s*[(]/ read-line)

Without using a regular expression:

(use srfi-13) ;; string-trim string-prefix?

(generator-count (^s (string-prefix? "(" (string-trim s))) read-line)
B. Pym
2024-09-19 06:23:59 UTC
Reply
Permalink
Post by B. Pym
We've had this discussion before. Perl was designed to make file scanning
and pattern matching easy. The programs we've been designing in this
thread are precisely the kind of application that Perl is intended for.
while (<>) { # Loop over input lines
counter++ if /^\s*\(/; # if first non-white character is open-paren, count i
t
}
would be much more verbose without being significantly more expressive.
-------------
If it weren't for the regexp, which needs a comment of 10 words to
explain what it does, and which is easy to get wrong (either comment,
or regexp that is), I could believe that statement, but so I have to
humbly disagree ;)
(loop for line = (read-line *standard-input* nil nil)
while line
count (starts-with (left-trim-whitespace line) "("))
This uses two trivial string functions which are probably part of
every working CL user[1]. With an extensible LOOP facility, this could
even be clarified further...
....
(defun starts-with (string substring)
"Detect whether the `string' starts with `substring'."
(eql 0 (search substring string)))
(defun left-trim-whitespace (string &optional (ws-bag '(#\Space #\Tab)))
"Trims any whitespace characters (i.e. characters in `ws-bag') from
the left side of `string'."
(string-left-trim ws-bag string))
Gauche Scheme
(use gauche.generator)
(generator-count #/^\s*[(]/ read-line)
(use srfi-13) ;; string-trim string-prefix?
(generator-count (^s (string-prefix? "(" (string-trim s))) read-line)
Another way.

(generator-count (=>> string-trim (string-prefix? "(")) read-line)

Given:

(define-syntax ->>
(syntax-rules ()
[(_ x) x]
[(_ x (y ...) z ...)
(->> (y ... x) z ...)]
[(_ x y z ...)
(->> (y x) z ...)]))

;; currying
(define-syntax =>>
(syntax-rules ()
[(_ func ...)
(lambda (x) (->> x func ...))]))

Loading...