Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I found--when working in Clojure for a while back in 2012--that what I really wanted was just a way to collapse deeply-nested parenthetical definitions, and ended up with a simple reader macro that reads one form and then pushes the rest of the current form down into the end of that one (and I added a special case for a let).

    (use 'reader-macros.core)
    
    (defn macro-read-one [reader]
        (clojure.lang.LispReader/read reader true nil true))
    
    (defn macro-read-rest [stop reader]                                                                      
        (if (skip-whitespace reader)                                                                         
            (let [data (.read reader)]                                                                       
                (.unread reader data)                                                                        
                (condp = (char data)                                                                         
                    \; (do                                                                                   
                        (macro-read-comment reader (.read reader))                                           
                        (macro-read-rest stop reader))                                                       
                    stop ()                                                                                  
                (cons                                                                                        
                    (macro-read-one reader)                                                                  
                    (macro-read-rest stop reader))))))      
    
    (set-dispatch-macro-character \> (fn [reader quote]
        (let [data (.read reader)]
            (.unread reader data)
            (if (= \( (char data))
                (concat (macro-read-one reader) (macro-read-rest \) reader))
                `(let [ 
                    ~(macro-read-one reader) 
                    ~(macro-read-one reader) 
                ] ~@(macro-read-rest \) reader))))))
I just find that the GC (and being hosted in Java, in particular) causes you to have to have a very large number of (with-open)s around in just about everything you do to deal with the lack of deterministic finalization, and, when combined with the number of recursive let bindings I was accumulating, I felt like I was going insane.

    (defn handle [manager socket] 
        #>(with-open [socket socket])
        #>(with-open [input (new java.io.BufferedInputStream (.getInputStream socket))])
        #>(with-open [output (.getOutputStream socket)])
    
        #>input (atom input)
        #>output (atom output) 
    
        #>(let [sendln (fn [& data]
            #>(let [data (apply str data)]) 
            (println "< " data)
            #>(let [data (.getBytes data "ISO-8859-1")])
            (.write @output data)
            (.write @output crlf)
        )])
    
        ...etc etc...
    )
I am now looking back at some of this code--after not seeing it in a decade--and honestly I'm still very happy with this design choice and still feel like this drastically helps my ability to understand what is going on in some of the more complicated functions, as my level of indentation/nesting is so much lower.

So like, if you are going to create a new syntax for Clojure--especially one that is going to force indentation for nesting that could have previously been elided by stylistic choices--my maybe-I'm-unique suggestion would be to add a similar feature that let's you have a version of ":" that just dominates until the end of scope and let's you reduce one level of indent.

(Which, I guess, put like that, is a feature I could see also adding to Python. The existence of mutable data--and how the most popular implementation has deterministic finalization via reference counting--means I don't feel quite as visceral of a need for this, but it would still be pleasant at times.)

(Ugh... reading that macro reminds me just how angry I found myself getting every day I used that language how ',' was bound to something entirely useless and so they had to break the beautiful symmetry of ',' with '`' in macro definitions. It is something so small, and yet, and I appreciate this is nigh unto ridiculous for someone who clearly didn't exactly like Lisp either enough to not implement this insane reader macro ;P, kept making me sad about Clojure any time I had to touch a macro, and macros were the only reason I was using it in the first place.)



Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: