[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Writing a procedure in different style

From: Zelphir Kaltstahl
Subject: Writing a procedure in different style
Date: Sat, 12 Dec 2020 13:22:20 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Icedove/68.10.0

Hello Guile Users!

I've been using PEG parsing lately a few times, for advent of code and
needed to write a procedure, which would give me a subtree of the
peg-tree, searching by any criteria. So what I did is writing a
procedure, which takes a predicate and if that predicate is #t then I
would collect the subtree for which it is true into a list.

Problem was, that those subtrees could be on different depths of the
tree, depending on the grammar I defined. So my initial version would
give me back all occurrences of any predicate fulfilling subtree, but in
a list, which was not flat. So I thought for a few hours on and off, how
I could solve it and tried various incantations of (list ...) (cons ...)
and (append ...), for the recursive calls of the procedure, but none
would get the resulting list in ways I wanted. Then I had an idea: I
could use a continuation! I would "flatten" the structure, by giving the
continuation of "where else to look for more subtrees" as an argument
and could later on put it all on the same level. Perhaps this is
difficult to describe and here is my code:

(define find-in-tree*
  (λ (peg-tree filter-proc)

    (define traverse
      (λ (subtree cont)
        (simple-format (current-output-port)
                       "working with subtree ~a\n"
         [(null? subtree) (cont)]
         [(pair? (first subtree))
          (traverse (first subtree)
                    (λ () (traverse (cdr subtree) cont)))]
         [(filter-proc (first subtree))
          (cons subtree (cont))]
          (traverse (cdr subtree) cont)])))

    (traverse peg-tree (λ () '()))))

(I know, I could probably use a named let here, but somehow I like the
current form of it with the inner define, SICP style.)

(I've only tested this for the parsing here:
in puzzle 1. I should probably write some tests for it, for more wildly
nested trees. The procedure is in peg-tree-utils.scm. The program can be
called with `guile -L . puzzle-01.scm input`.)

I am wondering however, whether there is a way to write the procedure
without resorting to mutation (so no hash table or vector) and
continuations. I could not find the correct version without using
continuations. Not that using continuations is inherently bad, I simply
think perhaps there is an alternative version, which is simple, but
which I could not find.

Best wishes,


reply via email to

[Prev in Thread] Current Thread [Next in Thread]