0

I have the following code:

(require [hyrule [-> ->>]])

(defn static/freezer [value freezer]
                      (cond [(not value) (setv freezer [])]
                            [(isinstance value list)
                             (do (if (not (isinstance freezer list)) (setv freezer []))
                                 (.extend freezer value)
                                 (setv freezer (->> (lfor i
                                                          (lfor j freezer :if j j)
                                                          (if (isinstance i list) i [i]))
                                                    (list)
                                                    (chain #*))))]
                            [True (raise (TypeError f"Sorry! The 'm/freezer' can only accept lists or non-truthy values!"))])
  (return freezer))

(print (static/freezer [[1 2] [3 4] 5))

... but am getting the following error:

Traceback (most recent call last):
  File "/usr/lib/python3.9/runpy.py", line 267, in run_path
    code, fname = _get_code_from_file(run_name, path_name)
  File "/home/shadowrylander/bakery/test.hy", line 12
    (chain #*))))]
             ^
hy.lex.exceptions.LexException: Ran into a RPAREN where it wasn't expected.

I am assuming the ->> macro isn't taking effect, as every bracket checks out, but neither eval-when-compile nor eval-after-compile helps.

ShadowRylander
  • 361
  • 2
  • 8

1 Answers1

2

As suggested by the error message, (chain #*) is not lexically legal. #*, as well as #**, must be followed by a form. The underlying idea is that #* and #**, like ( and ", are not forms themselves, but characters that can be used along with some other characters to construct forms, namely (unpack-iterable …) and (unpack-mapping …). #1730 discusses some related issues. At any rate, lexing happens before any macros are expanded, so ->> can't get around this.

Kodiologist
  • 2,984
  • 18
  • 33
  • So should I simply use `(chain (unpack-iterable ... ))` in the `->>` macro instead? – ShadowRylander Jan 19 '22 at 03:23
  • @ShadowRylander That's not how `->>` works, unless I'm missing something. The easiest thing to do here is just use ordinary, prefix calls in place of `->>`. – Kodiologist Jan 19 '22 at 14:21
  • Sorry; I meant something like this: `(-> (lfor i (lfor j freezer :if j j) (if (isinstance i list) i [i])) (list) (unpack-iterable) (chain))`, which would create the list, ... make it a list? I have no idea why that is there... , then unpack the list and chain all the elements. – ShadowRylander Jan 19 '22 at 19:03