-
Notifications
You must be signed in to change notification settings - Fork 11
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
time-it macro #39
Comments
For maximum flexibility, a macro has to be able to interpret a keyword as as keyword instead of a kwarg pair. This way you can write macros that contain keywords as part of the syntax, even if there are two in a row or one at the end. I think you could simply have the macro call a function that accepts |
Revise, remove excessive (defmacro/g! time-it [expr &optional setup round]
`((fn []
(import [timeit [timeit :as ~g!timeit]])
~(when setup setup)
(defn testee [] ~expr)
(setv kwargs {})
~(when round `(assoc kwargs "number" ~round))
(apply ~g!timeit [testee] kwargs)))) In the beginning, I did not wrap everything inside a function, thus the |
@gilch |
A simple example: => (defmacro foo [x &rest xs] `((fn [s &kwargs kws] (, s kws)) '~x ~@xs))
=> (foo norf :bar 1 :baz 2)
('norf', {'bar': 1, 'baz': 2}) Note that the macro can quote the first symbol and still parse the remaining kwargs. |
Okay, this is what I have so far (defmacro/g! time-it [expr &rest options]
(if
(not (keyword? (first options)))
(setv setup (first options) args (rest options))
(in :setup options)
(do
(setv index (.index options (keyword "setup")))
(when (= index (dec (len options)))
(macro-error None "Keyword argument :setup needs a value."))
(setv skipped (, index (inc index))
setup (get options (inc index))
args (list-comp exp
[(, i exp) (enumerate options)]
(not-in i skipped))))
(setv setup None args options))
`((fn []
(import [timeit [timeit :as ~g!timeit]])
~(when setup setup)
(~g!timeit (fn [] ~expr) "pass" ~@args)))) Test drive: hy 0.11.0+353.gca6fd66 using CPython(default) 3.5.2 on Linux
=> (defmacro/g! time-it [expr &rest options]
... (if
... (not (keyword? (first options)))
... (setv setup (first options) args (rest options))
... (in :setup options)
... (do
... (setv index (.index options (keyword "setup")))
... (when (= index (dec (len options)))
... (macro-error None "Keyword argument :setup needs a value."))
... (setv skipped (, index (inc index))
... setup (get options (inc index))
... args (list-comp exp
... [(, i exp) (enumerate options)]
... (not-in i skipped))))
... (setv setup None args options))
... `((fn []
... (import [timeit [timeit :as ~g!timeit]])
... ~(when setup setup)
... (~g!timeit (fn [] ~expr) "pass" ~@args))))
=> (time-it (inc 1))
0.6054470939998282
=> (time-it (inc answer))
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 1, in _hy_anon_fn_2
File "/usr/lib64/python3.5/timeit.py", line 213, in timeit
return Timer(stmt, setup, timer, globals).timeit(number)
File "/usr/lib64/python3.5/timeit.py", line 178, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 6, in inner
File "<input>", line 1, in _hy_anon_fn_1
NameError: name 'answer' is not defined
=> (time-it (inc answer) (setv answer 42))
0.6117291800001112
=> answer
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'answer' is not defined
=> (time-it (print 'Hit) :number 3)
Hit
Hit
Hit
0.00010172399925068021
=> (time-it (print 'Hit) () :number 3)
Hit
Hit
Hit
9.308399967267178e-05
=> (time-it (print 'Hit) :number 3 :setup (print 'Setup...))
Setup...
Hit
Hit
Hit
7.982400347827934e-05
=> (time-it (print 'Hit) :setup (print 'Setup...) :number 3)
Setup...
Hit
Hit
Hit
8.413199975620955e-05
=> (time-it (inc 1) :setup (print 'Setup...))
Setup...
0.5945940750025329
=> (time-it (inc 1) :setup)
File "<input>", line 1, column 1
(time-it (inc 1) :setup)
^----------------------^
HyMacroExpansionError: b'Keyword argument :setup needs a value.'
=> (time-it (inc 1) :i-dont-know-what-i-am-doing 42)
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 1, in _hy_anon_fn_2
TypeError: timeit() got an unexpected keyword argument 'i_dont_know_what_i_am_doing' |
As inspired by @gilch in discussion here: hylang/hy#1179
The macro:
Another approach is using
read-str
Caveat
I've been fighting the macro system for the last hour, as we cannot use
&kwargs
withdefmacro
, so unless we use&rest
and parse the argument ourselves (I have a kind-of-working prototype, but it is so ugly that I do not dare to share), the form of the macro is a bit rigid, I skipped thetimer
argument for simplicity's sake, and right now, one have to pass in thesetup
code to specify the round of iteration, see above.The text was updated successfully, but these errors were encountered: