Clojure

for macro does not allow :let clause in first position

Details

  • Type: Enhancement Enhancement
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Declined
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Patch:
    Code and Test

Description

I like to try and keep my level of nesting under control, and this
often involves hiding or re-structuring the let macro. The for macro
can implicitly assemble a let macro for you, but with a limitation
that the :let clause can't be first:

1:5 user=> (for [:let [z [:foo :bar]] x z] (name x))
java.lang.IllegalStateException: Can't pop empty vector (repl-1:5)
1:6 user=> (for [x [:foo :bar] :let [z (name x)]] z)
("foo" "bar")
1:7 user=>

Is this limitation intentional? Could the error message be improved?

Here's what I wanted to write:

(defn add-script-links-for-imported-javascript-libraries
       [env dom-nodes]
       (extend-dom dom-nodes [:html :head] :top
               (template-for [:let [aggregation (-> env :cascade :resource-aggregation)
                                         libraries (@aggregation :libraries)]
                                   asset-map libraries
                                   :let [path (to-asset-path env asset-map)]]
                       :script { :type "text/javascript" :src path } [ linebreak ])))

(the formatting is probably scrambled)

But I had to juggle it to this:

(defn add-script-links-for-imported-javascript-libraries
       [env dom-nodes]
       (let [aggregation (-> env :cascade :resource-aggregation)
              libraries (@aggregation :libraries)]
               (extend-dom dom-nodes [:html :head] :top
                       (template-for [asset-map libraries
                                           :let [path (to-asset-path env asset-map)]]
                               :script { :type "text/javascript" :src path } [ linebreak ]))))

Of course there are any number of ways to write this, but I prefer the
first option, as it does less of a job of obscuring what the main
point of the function is: a call to extend-dom.

Activity

Tassilo Horn made changes -
Field Original Value New Value
Attachment 0001-Implement-CLJ-207-let-as-first-for-binding-form.patch [ 11001 ]
Tassilo Horn made changes -
Description I like to try and keep my level of nesting under control, and this
often involves hiding or re-structuring the let macro. The for macro
can implicitly assemble a let macro for you, but with a limitation
that the :let clause can't be first:

1:5 user=> (for [:let [z [:foo :bar]] x z] (name x))
java.lang.IllegalStateException: Can't pop empty vector (repl-1:5)
1:6 user=> (for [x [:foo :bar] :let [z (name x)]] z)
("foo" "bar")
1:7 user=>

Is this limitation intentional? Could the error message be improved?

Here's what I wanted to write:

(defn add-script-links-for-imported-javascript-libraries
       [env dom-nodes]
       (extend-dom dom-nodes [:html :head] :top
               (template-for [:let [aggregation (-> env :cascade :resource-aggregation)
                                         libraries (@aggregation :libraries)]
                                   asset-map libraries
                                   :let [path (to-asset-path env asset-map)]]
                       :script { :type "text/javascript" :src path } [ linebreak ])))


(the formatting is probably scrambled)

But I had to juggle it to this:

(defn add-script-links-for-imported-javascript-libraries
       [env dom-nodes]
       (let [aggregation (-> env :cascade :resource-aggregation)
              libraries (@aggregation :libraries)]
               (extend-dom dom-nodes [:html :head] :top
                       (template-for [asset-map libraries
                                           :let [path (to-asset-path env asset-map)]]
                               :script { :type "text/javascript" :src path } [ linebreak ]))))


Of course there are any number of ways to write this, but I prefer the
first option, as it does less of a job of obscuring what the main
point of the function is: a call to extend-dom.
I like to try and keep my level of nesting under control, and this
often involves hiding or re-structuring the let macro. The for macro
can implicitly assemble a let macro for you, but with a limitation
that the :let clause can't be first:

{noformat}
1:5 user=> (for [:let [z [:foo :bar]] x z] (name x))
java.lang.IllegalStateException: Can't pop empty vector (repl-1:5)
1:6 user=> (for [x [:foo :bar] :let [z (name x)]] z)
("foo" "bar")
1:7 user=>
{noformat}

Is this limitation intentional? Could the error message be improved?

Here's what I wanted to write:

{noformat}
(defn add-script-links-for-imported-javascript-libraries
       [env dom-nodes]
       (extend-dom dom-nodes [:html :head] :top
               (template-for [:let [aggregation (-> env :cascade :resource-aggregation)
                                         libraries (@aggregation :libraries)]
                                   asset-map libraries
                                   :let [path (to-asset-path env asset-map)]]
                       :script { :type "text/javascript" :src path } [ linebreak ])))
{noformat}

(the formatting is probably scrambled)

But I had to juggle it to this:

{noformat}
(defn add-script-links-for-imported-javascript-libraries
       [env dom-nodes]
       (let [aggregation (-> env :cascade :resource-aggregation)
              libraries (@aggregation :libraries)]
               (extend-dom dom-nodes [:html :head] :top
                       (template-for [asset-map libraries
                                           :let [path (to-asset-path env asset-map)]]
                               :script { :type "text/javascript" :src path } [ linebreak ]))))
{noformat}

Of course there are any number of ways to write this, but I prefer the
first option, as it does less of a job of obscuring what the main
point of the function is: a call to extend-dom.
Priority Blocker [ 1 ]
Tassilo Horn made changes -
Priority Blocker [ 1 ] Minor [ 4 ]
Tassilo Horn made changes -
Patch Code and Test [ 10002 ]
Rich Hickey made changes -
Resolution Declined [ 2 ]
Fix Version/s Backlog [ 10035 ]
Status Open [ 1 ] Closed [ 6 ]

People

  • Assignee:
    Unassigned
    Reporter:
    Anonymous
Vote (1)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: