Hi,
I want to learn a Racket way of writing recursive generators. Speaking of the programming languages in general, it's either yield
or flatMap
approach, depending on the language.
Walking the file tree, MWE, Python:
#!/usr/bin/env python
import os
from pathlib import Path
from typing import Iterator, List, Tuple
SRC_DIRS = (".",)
EXTENSIONS = (".RKT",)
def children(parent: Path) -> Tuple[List[Path], List[Path]]:
lst = os.listdir(parent)
dirs = [Path(x) for x in lst if (parent / x).is_dir()]
files = [Path(x) for x in lst if (parent / x).is_file()]
return dirs, files
def traverse(parent: Path) -> Iterator[Path]:
dirs, files = children(parent)
for directory in dirs:
yield from traverse(parent / directory)
for file in files:
yield parent / file
for dir in SRC_DIRS:
for file in traverse(Path(dir)):
if file.suffix.upper() in EXTENSIONS:
print(f">> {file}")
The online sources say that yield
is known in the Racket context. Unfortunately, it's only bits and pieces, no clean picture. Today one could ask the AI, which I did. The translation looks uncannily clean and plausible:
#!/usr/bin/env racket
#lang racket
(require racket/path)
(define SRC_DIRS '("."))
(define EXTENSIONS '(".RKT"))
(define (children parent)
(define lst (directory-list parent))
(define dirs (filter path-directory? lst))
(define files (filter path-file? lst))
(values dirs files))
(define (traverse parent)
(define-values (dirs files) (children parent))
(for*/flatten ([directory dirs])
(traverse (path->string (build-path parent directory))))
(for ([file files])
(path->string (build-path parent file))))
(for ([dir SRC_DIRS])
(for ([file (traverse (path->string (build-path dir)))])
(when (member (path-extension file) EXTENSIONS)
(displayln (format ">> ~a" file)))))
It won't run, though: the AI invented path-file?
and path-directory?
functions. Which is understandable, because I couldn't find them, or their counterparts, either.
Of course, I already have the key bit of information: flatMap
approach is supported by Racket, see and learn for*/flatten
.
How can I make it work? How can I make it even more beautiful, if possible ?