-
Notifications
You must be signed in to change notification settings - Fork 372
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
Consider adding Common Lisp's Sharpsign-dot (#.) reader macro #919
Comments
Is |
Maybe. It's not documented, so I'm not sure. And many of my use cases would need a shorter alias. |
I was wrong; |
The Emacs docs on
Unlike Hy, in Emacs
But since Hy's version doesn't expand to anything, it can't be used that way. But how can we make a constant appear in the compiled program? As my first attempt demonstrated, only certain data types have a Hy model. To get an arbitrary object into the compiled file, it would have to be serialized somehow. Sounds like a job for As a first attempt, (deftag "." [expr]
(import pickle)
`((. (__import__ "pickle")
loads)
~(pickle.dumps (eval expr)))) This does have some runtime overhead. It's not a big deal at the toplevel, but in a nested loop, that would be pretty bad--and that was a major motivation for doing I think we can overcome this problem with memoization. (import pickle)
;; you can memoize with functools in Python3...
(defn loadstatic [bytestr &optional [_memo {}]]
(try
(get _memo bytestr)
(except [KeyError]
(assoc _memo bytestr (pickle.loads bytestr))
(loadstatic bytestr))))
(deftag "." [expr]
`(loadstatic ~(pickle.dumps (eval expr)))) This way it would only get unpickled once. There's two more problems with this though. First, if you pickle two equal mutable objects, then the memoization will make them point to the same instance. We can avoid this by adding a gensym to the lookup key, e.g. And secondly, |
I think you want |
In the linked pull request, I've opted to add (defreader .
(hy.eval (.parse-one-form &reader) (globals)))
#.`(setv ~(hy.models.Symbol (* "x" 5)) 15)
(print xxxxx) ; => 15 |
Pushing the eval of certain forms back to readtime has various uses. A big one is to swap out code based on various conditions, like the
#if
and related preprocessor directives from C.This would probably fit well with #740.
Another is to substitute for literals that don't have a literal notation. Compare:
Because evaluation happens at read time, it's safe to use in loops and such, without a performance hit for recomputing it every time.
I thought it would be a simple implementation in Hy:
And this does seem to work for the above examples, but I'm running into
HyModel
issues again:=> #.(lambda [] nil)
[long stack trace including
hy.errors.HyCompileError: Internal Compiler Bug \U0001f631\u2937 TypeError: Don't know how to wrap a <class 'function'> object to a HyObject
]But this works fine in Common Lisp:
Is there a simple change in the macro definition that would fix this? Can we perhaps make everything a HyObject by default if it doesn't already have a model?
The text was updated successfully, but these errors were encountered: