funcool / cuerdas

String manipulation library for Clojure(Script)
https://cljdoc.org/d/funcool/cuerdas/2020.03.26-3/
BSD 2-Clause "Simplified" License
304 stars 30 forks source link

String interpolation doesn't work with anonymous function literal % arguments #57

Closed emlyn closed 6 years ago

emlyn commented 7 years ago

E.g.:

(require '[cuerdas.core :refer [istr]])

;; This works fine:
(let [f (fn [n] (istr "n=~{n}"))]
  (f 1))
;; => "n=1"

;; This should be equivalent, but doesn't work:
(let [f #(istr "n=~{%}")]
  (f 1))
;; => clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to resolve symbol: % in this context

This seems to be because the #() form is expanded before istr, so it doesn't see the % inside the string and therefore doesn't convert it to the mangled form. Unfortunately I'm not sure there's much that can be done to fix this.

niwinz commented 7 years ago

That is expected, istr is a macro and it evaluates the string interpolation on the compilation time.

emlyn commented 7 years ago

Yeah, it's a shame though, it would be handy if it worked.

niwinz commented 6 years ago

Seems like this is not a cuerdas problem, because is the clojure parser that does not detects the % inside string. Let see some code:

user=> (macroexpand '#(istr "n=~{%}"))
(fn* [] (istr "n=~{%}"))
user=> (macroexpand '#(istr "n=~{%}" %))
(fn* [p1__1418#] (istr "n=~{%}" p1__1418#))

You can see that if you use the % only inside the string, the expanded reader macro is results in a function with no argument.