HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Determine indentation of a line of code

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
codelinedetermineindentation

Problem

The following function determines the amount of indentation of a string. It returns two values. The first is an effective indentation where tabs are expanded such that their end aligns with 4 spaces steps. The second is just the amount of spaces and tabs before the first non-tab/space character.

roundup is a method that rounds the first argument to next higher multiple of the second argument. The rest is standard CL.

(defun indentation (line)
  (let ((spaces 0))
    (dotimes (index (length line) (values spaces index))
      (case (aref line index)
        (#\Space (incf spaces))
        (#\Tab (setf spaces (roundup (1+ spaces) 4)))
        (otherwise (return (values spaces index)))))))


I don't like having to state the return value twice.

Solution

I guess roundup is something like
(defun roundup (x y) (* (ceiling x y) y))?

For the reason you stated I'd probably go with loop (or alternatives,
iterate comes to mind) instead of the do... family of macros, e.g.:

(defun indentation (line)
  (loop
    with spaces = 0
    for index below (length line)
    do (case (char line index)
         (#\Space (incf spaces))
         (#\Tab (setf spaces (roundup (1+ spaces) 4)))
         (T (loop-finish)))
    finally (return (values spaces index))))


  • Depending on the choice of input you might want to use char for


strings instead of aref.

  • otherwise is pretty long, but of course it's somewhat of a personal


choice - t is a bit shorter.

Code Snippets

(defun indentation (line)
  (loop
    with spaces = 0
    for index below (length line)
    do (case (char line index)
         (#\Space (incf spaces))
         (#\Tab (setf spaces (roundup (1+ spaces) 4)))
         (T (loop-finish)))
    finally (return (values spaces index))))

Context

StackExchange Code Review Q#156891, answer score: 2

Revisions (0)

No revisions yet.