I was attempting to port Clojure time macro to Phel but encountered issues with it's macro facilities https://github.com/phel-lang/phel-lang/issues/784. It would be great if some Lisp guru could take a look at it. There is a little bit of a backlog of items to polish out, including in REPL usability and such, where any extra help would be useful.
EDIT: fixed in 0.18.0 (2025/06)
Just adding note that this was fixed among bunch of other stuff recently https://github.com/phel-lang/phel-lang/issues/784
Hard to say exactly, that is definitely broken behavior
The suggestion to wrap it in a call to eval is crazy
Looking at the code a little bit (I wrote a lisp to PHP compiler maybe around 2008-9 which was maybe the last project I used PHP for) it looks like maybe macro expansion isn't happening recursively, but I am not sure
I think https://github.com/phel-lang/phel-lang/blob/main/src/php/Compiler/Domain/Analyzer/TypeAnalyzer/AnalyzePersistentList.php#L67 should be checking if the symbol refers to a macro and expanding it and then recursively analyzing the result
Maybe it is looping here https://github.com/phel-lang/phel-lang/blob/main/src/php/Compiler/Domain/Analyzer/TypeAnalyzer/SpecialForm/InvokeSymbol.php#L28
I would try the require test again from the issue (require my-ns\utils :refer [time])
But also in the utils file include a new function f that uses the time macro, and call f to see what the result it is
Thank's for input @hiredman. May I copy that notion to the issue, referring to your nick, as it might give hints to others looking at the problem?
I dunno, I am not very sure about it now, which is why I suggested the require test again, it might instead being losing the fact that time is a macro some how, if that is the case that I would expect the time macro call to work correctly in the function defined in utils, even if it fails when you try to call it from utils in the repl
Seeing if I got the suggestion correct:
(ns my-ns\utils)
(defmacro time
"Evaluates expr and prints the time it took. Returns the value of expr."
[expr]
(let [start (gensym)
ret (gensym)]
`(let [,start (php/microtime true)
,ret ,expr]
(println "Elapsed time:" (* 1000 (- (php/microtime true) ,start)) "msecs")
,ret)))
(defn call-time [expr]
(time expr))
Does not seem to change behavior:
phel:2> (require my-ns\utils :refer [call-time])
# -> my-ns\utils
phel:3> (call-time (* 5 5 5))
# -> (let [__phel_816 (microtime true) __phel_817 125] (println Elapsed time: (* 1000 (- (microtime true) __phel_816)) msecs) __phel_817)huh
Broken still but submitted that macro to phel-lang core where it works.