tran li <litra...@hotmail.com> writes:

> My current code is as follows:
>
> ```ly
>
> #(define* ((_hash-table-deep-ref getter) h keys #:optional (fallback #f))
>   (let* ((target h))
>     (for-each
>       (lambda (key)
>         (set! target (getter target key)))
>       keys)
>     target))
>
> #(define hash-deep-ref (_hash-table-deep-ref hash-ref))
> #(define hashq-deep-ref (_hash-table-deep-ref hashq-ref))
> #(define hashv-deep-ref (_hash-table-deep-ref hashv-ref))
>
> ```
>
> The code works fine only if all the sub-tables are present for the
> given keys. If any of the sub-table is not present for one key in the
> middle of the key list, this function would fail. My ideal case is
> that when such a case happens, the fallback value should be
> returned. Also I want to create a version of the function getting the
> hash entry handle from a multi-layer hash table.

A Scheme-ish way would be

#(define* ((_hash_table-deep-ref getter) h keys #:optional fallback)
   (let loop ((target h) (restkeys keys))
     (cond ((null? restkeys) target)
           ((hashtable? target)
            (loop (getter target (car restkeys)) (cdr restkeys)))
           (else fallback))))

The labeled let defines a function taking two arguments (and in this
case with the name "loop") and runs it with the initial arguments taken
from the let statement.

-- 
David Kastrup

Reply via email to