[racket] This is too clumsy. Is there a better way?

 From: Stephen Bloch (bloch at adelphi.edu) Date: Fri Jul 13 09:30:28 EDT 2012 Previous message: [racket] This is too clumsy. Is there a better way? Next message: [racket] This is too clumsy. Is there a better way? Messages sorted by: [date] [thread] [subject] [author]

```On Jul 13, 2012, at 9:02 AM, Rouben Rostamian wrote:

> The function `all-lower-case?' defined below takes a string and
> returns #f if the string has at least one uppercase alphabetic
> character, else returns #t.
>

> Examples:
>  (all-lower-case? "asdf12#@") => #t
>  (all-lower-case? "asDf12#@") => #f

Then a better name would be no-upper-case? .  I would expect (all-lower-case? "asdf12#@") to return false.

> Here is how I have written it:
>
> (define (all-lower-case? str)
>  (not (memq #t
>             (map (lambda (i)
>                    (if (and (char-alphabetic? i) (char-upper-case? i))
>                      #t #f))
>                  (string->list str)))))

For starters, I would replace
(if (and (char-alphabetic? i) (char-upper-case? i))
#t #f)
with the logically equivalent
(and (char-alphabetic? i) (char-upper-case? i))
(As a general rule of thumb, Boolean-valued functions are usually shorter and simpler if you write them WITHOUT conditionals.)

Second, since char-upper-case? is a subset of char-alphabetic?, you can simplify this further to
(char-upper-case? i)
which is just a single function, so you can now drop the "lambda" and just say
(map char-upper-case? ...)

You can also replace
(memq #t (map F L))
with
(ormap F L)

So the new definition is
(define (no-upper-case? str)
(not (ormap char-upper-case? (string->list str))))

> This looks rather clumsy to me.  I am converting the string into
> a list of characters, then I check the case of each character
> and issue the requisite verdict.

We're still doing the exact same thing, but in a whole lot less code -- indeed, the code is very nearly a rewording of the purpose statement.  As a bonus, it's also more efficient, since "ormap" does short-circuit evaluation: as soon as it finds an upper-case letter, it stops without looking at the rest of the string.

Another, weirder and less efficient but even shorter, definition is
(define (no-upper-case? str)
(string=? str (string-downcase str)))

Stephen Bloch