-
-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
error macroexpanding recur
macro
#856
Comments
Hi @chrisrink10, Do you have any suggestions on how to address this problem? adding @_analyze_form.register(llist.PersistentList)
@_analyze_form.register(ISeq)
@_with_loc
def _list_node(form: ISeq, ctx: AnalyzerContext) -> Node:
if form == llist.PersistentList.empty():
with ctx.quoted():
return _const_node(form, ctx)
if ctx.is_quoted:
return _const_node(form, ctx)
s = form.first
if isinstance(s, sym.Symbol):
handle_special_form = _SPECIAL_FORM_HANDLERS.get(s)
if handle_special_form is not None and not ctx.should_allow_unresolved_symbols:
return handle_special_form(form, ctx)
elif s.name.startswith(".-"):
return _host_prop_ast(form, ctx)
elif s.name.startswith(".") and s.name != _DOUBLE_DOT_MACRO_NAME:
return _host_call_ast(form, ctx)
return _invoke_ast(form, ctx) thanks |
I think I have an idea for a solution, but I'm not really clear on why this is something anyone would do. |
This reproducible test case is an over simplification of an issue I've encountered while porting the (defn- pprint-simple-list [alis]
(pprint-meta alis)
(pprint-logical-block :prefix "(" :suffix ")"
(print-length-loop [alis (seq alis)]
(when alis
(write-out (first alis))
(when (next alis)
(.write ^java.io.Writer *out* " ")
(pprint-newline :linear)
(recur (next alis))))))) The exception on the REPL is basilisp.user=> (require '[basilisp.pprint :as pp])
exception: <class 'basilisp.lang.compiler.exception.CompilerException'> from <class 'basilisp.lang.compiler.exception.CompilerException'>
phase: :macroexpansion
message: error occurred during macroexpansion: no recur point defined for recur
form: (when (next alis) (.write *out* " ") (pprint-newline :linear) (recur (next alis)))
location: <Macroexpand>:83-89 Btw, the new exception format looks fantastic, though for some reason we are missing the source file path in the output making it very difficult to locate the code location where the error is coming from. |
Are you actually using Is your |
There is no macroexpansion used here (as in me not calling The code is not on GH yet, I'll see if I can contrive an example that it fails as such by just trying to load the fn. |
Hi, I found the culprit, it is indeed (defn- pll-mod-body [var-sym body]
(letfn [(inner [form]
(if (seq? form)
(let [form (macroexpand form)]
(condp = (first form)
'loop* form
'recur (concat `(recur (inc ~var-sym)) (rest form))
(walk inner identity form)))
form))]
(walk inner identity body))) and the error can be reproduced as basilisp.user=> (require '[basilisp.walk :refer [walk]])
nil
basilisp.user=> (defn- pll-mod-body [var-sym body]
(letfn [(inner [form]
(if (seq? form)
(let [form (macroexpand form)]
(condp = (first form)
'loop* form
'recur (concat `(recur (inc ~var-sym)) (rest form))
(walk inner identity form)))
form))]
(walk inner identity body)))
#'basilisp.user/pll-mod-body
basilisp.user=> (pll-mod-body nil '(when alis
(write-out (first alis))
(when (next alis)
;; (prlabel --pprint-simple-list (next alis))
(.write ^Writer *out* " ")
;; (prlabel --pprint-simple-list :1)
(pprint-newline :linear)
;; (prlabel --pprint-simple-list :2)
(recur (next alis)))))
exception: <class 'basilisp.lang.compiler.exception.CompilerException'> from <class 'basilisp.lang.compiler.exception.CompilerException'>
phase: :macroexpansion
message: error occurred during macroexpansion: no recur point defined for recur
form: (when (next alis) (.write *out* " ") (pprint-newline :linear) (recur (next alis)))
location: <Macroexpand>:NO_SOURCE_LINE contrast with Clojure which has no such constraint user> (require '[clojure.walk :as walk])
nil
user> (defn- pll-mod-body [var-sym body]
(letfn [(inner [form]
(if (seq? form)
(let [form (macroexpand form)]
(condp = (first form)
'loop* form
'recur (concat `(recur (inc ~var-sym)) (rest form))
(walk inner identity form)))
form))]
(walk inner identity body)))
#'user/pll-mod-body
user> (pll-mod-body nil '(when alis
(write-out (first alis))
(when (next alis)
;; (prlabel --pprint-simple-list (next alis))
(.write ^Writer *out* " ")
;; (prlabel --pprint-simple-list :1)
(pprint-newline :linear)
;; (prlabel --pprint-simple-list :2)
(recur (next alis)))))
(when
alis
(write-out (first alis))
(if
(next alis)
(do
(. *out* write " ")
(pprint-newline :linear)
(recur (clojure.core/inc nil) (next alis))))) My humble opinion is that Basilisp should not be restricting users how to organise their code, this seems like a valid case to me. Thanks |
Fixes #856 Co-authored-by: Christopher Rink <christopher@ChristophersMBP.cjlocal>
Basilisp throws an error when trying to macroexpand a well formulated macro with a
recur
fn:basilisp.lang.compiler.exception.CompilerException: no recur point defined for recur
.To reproduce
loop
/recur
macroCalling the macro works fine otherwise
It also works fine in Clojure
Thanks
The text was updated successfully, but these errors were encountered: