How can I extend Racket's reader for better path handling? -


i've been working on converting static site generator wrote in python racket. learning exercise know racket better. i've got racket version working, there 1 thing better python version: pathlib.path object. generator has lot of path handling, looks in python code:

render_template(root / "templates" / "index.jinja") 

whereas racket code looks more this:

(render-template (build-path (root) "templates" "index.jinja")) 

i find ability read paths cleaner in python code, i'd modify racket reader able support following:

(render-template (root) / "templates" / "index.jinja") 

playing around readers, figured out how make kind of expression work:

(render-template  / foo / templates / index.jinja /) 

i'd ok syntax, can't figure out how evaluate path elements racket expressions , not strings. if did figure out, still have issue naive string handling cause problems like:

(render-template / (root) / (string-join                               (list "templates" "subdir") "/")                   / "index.jinja" /) 

so, advice/input on can here? :)

if understand correctly, had this:

(define (root)   "/")  (define (render-template path)   (displayln path))  (render-template (build-path (root) "templates" "index.jinja")) ;; => /templates/index.jinja 

what suggest changing render-template may called multiple path "parts" -- , handles calling build-path you:

(define (render-template . path-parts)   (define path (apply build-path path-parts))   (displayln path)) 

now can call this:

(render-template (root) "templates" "index.jinja") ;; => /templates/index.jinja 

incidentally, calling original way still works, because build-path act identity in case:

(render-template (build-path (root) "templates" "index.jinja")) ;; => /templates/index.jinja 

i think "rackety" way. 1 nice thing s-expressions don't have type "separators" , or /. spaces suffice. , think more read , write racket code, more you'll feel way.

granted, perhaps rackety thing of ability make own little (or big) languages. if wanted "dsl" write files consisting of paths, might 1 thing. in case i'm not sure see big win.


if anything, maybe want macro makes / act whitespace in context. i.e. make / mean "nothing" needs be, in expanded code.

for example:

#lang racket/base  (require (for-syntax racket/base syntax/parse))  (define-syntax (render-template stx)   (define-splicing-syntax-class pp     (pattern (~seq part (~optional (~literal /)))))   (syntax-parse stx     [(_ p:pp ...) #'(do-render-template p.part ...)]))  (define (do-render-template . path-parts)   (define path (apply build-path path-parts))   (displayln path))  (render-template (root) / "templates" / "index.jinja") ;; => /templates/index.jinja (render-template (root) "templates" "index.jinja") ;; => /templates/index.jinja 

note / optional here. treated whitespace.

also note real work done in function, renamed do-render-template. macro wrapper. it's best macros little work necessary, , things can functions functions.

but again, wouldn't bother macro, i'd go approach suggested above.


update: p.s., if understand correctly, python's pathlib.path defining / operator? well, racket doesn't have "operators". has functions. , math functions / accept number of arguments. instead of 10 / 5 / 2 write (/ 10 5 2). which, really, brings full-circle build-path: function takes number of path parts.

i suppose rename build-path /:

(require (rename-in (except-in racket /)                     [build-path /])) (/ (root) "templates" "index.jinja") 

but isn't operator overloading, because these plain functions not methods. and... wouldn't it. :)


Comments

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

jsf - How to ajax update an item in the footer of a PrimeFaces dataTable? -

django - CSRF verification failed. Request aborted. CSRF cookie not set -