Created
January 12, 2025 13:19
-
-
Save msp729/0ae3c8f46f01969c01ea929f455a0071 to your computer and use it in GitHub Desktop.
Python list comprehensions in lisp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (defun flatmap (fn lst) | |
| "as seen in haskell's (>>=) :: [a] -> (a -> [b]) -> [b], or rust's flat_map" | |
| (apply #'append (mapcar fn lst))) | |
| (defun get-fors (lst) | |
| "extract the for clauses, as (variable list list-of-conditions)" | |
| (unless lst (return-from get-fors nil)) | |
| (let ((v (get-for lst))) | |
| `((,(car v) ,(cadr v) ,(caddr v)) . ,(get-fors (cdddr v))) | |
| )) | |
| (defun get-for (lst) | |
| "get a for clause" | |
| (unless lst (return-from get-for nil)) | |
| (cond | |
| ((equal 'for (car lst)) (cons (cadr lst) (get-in (cddr lst)))) | |
| (t (get-for (cdr lst))))) | |
| (defun get-in (lst) | |
| "get the list a variable is from" | |
| (unless lst (return-from get-in nil)) | |
| (cond | |
| ((equal 'in (car lst)) (cons (cadr lst) (get-ifs (cddr lst)))) | |
| (t (get-in (cdr lst))) | |
| )) | |
| (defun get-ifs (lst) | |
| "conditions to be met" | |
| (unless lst (return-from get-ifs nil)) | |
| (cond | |
| ((equal 'if (car lst)) (let ((v (get-ifs (cddr lst)))) | |
| `((,(cadr lst) . ,(car v)) . ,(cdr v)))) | |
| ((equal 'for (car lst)) (cons nil lst)) | |
| ((null lst) '(() . ())) | |
| (t (get-ifs (cdr lst))))) | |
| (defun flat-mapper (clause expr) | |
| "given a clause and the interior expression, returns the function to flatmap" | |
| `(lambda (,(car clause)) | |
| (if | |
| (and ,@(caddr clause)) | |
| ,expr | |
| nil | |
| ))) | |
| (defun gencode (expr clauses) | |
| "generate code for macro" | |
| (if (null clauses) expr | |
| `(flatmap ,(flat-mapper (car clauses) (gencode expr (cdr clauses))) ,(cadar clauses)) | |
| )) | |
| (defmacro pylc (expr &rest clauses) | |
| "pythonic list comprehensions" | |
| (gencode `(list ,expr) (get-fors clauses)) | |
| ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment