-
Notifications
You must be signed in to change notification settings - Fork 371
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
def vs setv #911
Comments
Alternative proposal 1: And replace with Why Python fixed this by not counting Edit: We should probably rename Hy's |
Alternative proposal 2: Like I said before, filling keyword quotas is poor language design. But there have been proposals to kind of enforce the existing convention for The best I've come up with is to make Many languages distinguish between delcaring a variable and assigning to it, and also variables vs constants--both points Python kind of glosses over. You could use the new asserting We could have our linter (hydiomatic) emit a warning whenever an earmuffed symbol was We could also have a convention that variables are declared with One question I still have is (def foo "foo!")
(defn foonorf []
(def foo "footwo!")) Should the above case trigger the assertion or not? You're not overwriting the global, so I'm inclined to answer "not". But this assertion would be a bit more difficult to implement in the |
The assertion in proposal 2 should be a runtime assertion, IMO. It could be compiled to: try:
foo
except NameError:
foo = 'footwo!'
else:
# error Also, what about the proposal for |
I suppose runtime could work. We could even have a I didn't understand how this works in nested scopes at first, but it does seem to work. I was expecting
I'm including that in the "But there have been proposals to kind of enforce the existing convention for def...", from the OP. The reason I'm not considering this as an alternative is that I don't approve. Global variables are considered harmful. It scatters state dependency throughout the program. This is a problem OO encapsulation was made to address, though (in practice) mutable fields can be almost as bad if you aren't careful. We really don't want to encourage this in Hy by giving it dedicated syntax. We already have Global constants, on the other hand, are not so bad. Every top level class, function, and macro name is effectvely used as a global constant anyway. We can manage these pretty well with namespaces. We don't need |
A variation on alternative 2:
(setv a 1 b 2)
;; expands to
(do
(nonlocal a b)
(def a 1 b 2)) nonlocal a, b
a = 1
b = 2 I don't think multiple And, of course, |
So what's the status here? Why can't we bring back |
I had proposed that already, but it broke in the case of closures, e.g.: (defn f []
(let [x 1]
(fn [] x)))
((f)) ; ERROR: x was deleted when f ended |
You mean @gilch's proposal 2? Nobody's been working on it that I know of, but not for any special reason. I like it, for what that's worth. Or at least, I'd appreciate an optional feature that requires you to declare variables before you use them and checks this at compile-time, like Perl's |
I usually use def for constants and setv for variables. Could we change def to prevent further assignments? Absolutely breaking change but we're still pretty early. |
I believe that that's the proposal 2 I was just talking about. |
UpdateAfter my original proposals, Python has added a new option to declare a variable before assignment. See PEP 526 -- Syntax for Variable Annotations These do have runtime effects, so Hy will need to support them anyway for compatibility. I think it's likely that Python's new optional static type checker, mypy, will be able to declare constants python/mypy#1214. This would have no runtime effect, but the static type checker could catch a violation in most cases. Once we've added variable and function annotation syntax to Hy I'd like to see if mypy is compatible. I think it can check the AST in Python 3 instead of the text, so it should work. These annotations can also be used by metaclasses and decorators, and are already being used in the standard library--see the workaround for NamedTuple I had to use to answer this StackOverflow question. So Hy needs a syntax for this to fully support the standard library, not just for the linter. So rather than expand to some awkward runtime assertion for constants, let's just do it Python's way when it's available. Then how should an advance type declaration look in Hy? From the PEP, we can see that it can be done either in an assignment statement, or in advance of it. So it might make sense to put it in the But mypy uses both variable and function annotations. They should have a consistent syntax. We should seriously consider adopting Clojure's We're only using |
@kirbyfan64 do you know what happened after python/mypy#590? Could mypy be made to work on Hy on Python 3.6+ if we put the type annotations in the AST? Would stub files work now? |
@hylang/core @vodik I'm uncomfortable dictating new syntax without feedback. Variable annotations could be coming in #1475. The current proposal.
That means Option A(current proposal--multiple
Option B(Clojure-like--use
B may be more consistent with function annotation proposals. #656, which follow Clojure syntax for this kind of thing (like we're already doing for most of Hy). It would be nice if these were consistent. But Option A gives us an excuse to keep both
|
Wait, |
I guess I like Option A the best. Using sigils in Lisp is always a bit weird. |
I guess another option could be to use a keyword like how import uses (def foo 42 :as int) I also played around taking a symbol as an annotation: I do kinda like how racket does it with That said, something worth noting is how painful type annotations are possible going to be as they've been implemented in the typing library. For example, consider the following Python stub: def get_users(id: int) -> Generator[User, None, None]: ... That But this problem makes me wonder if Option B is best, and instead provided a mechanism for defining new type aliases and types as a practical solution - and one admittedly probably too tied to the current Python implementation of types. I do like how Clojure offers Another option is to only support string annotations, in which case the annotation would litterally be |
Like the
Does
I thought Python could already do type aliases via the
It seems a little weird to me to write annotations in Python when we're writing everything else in Hy. We want our code to be made of data structures so we can manipulate it with macros. If we have to manipulate strings to do our metaprogramming, we might as well just use Python. |
It does actually. Didn't know that.
My concern was that
So I'm completely happy with that. No need for anything special then. Should have tried that first.
Just musing out loud. I was worried about potential complication of PEP 563, but I somehow missed this line my first few glances through it:
Which means its really a non-problem as well and this is a lot more straightforward than I was worried it be. |
|
A subissue from #240.
These do exactly the same thing as far as I can tell. We don't need both.
def
is a Python keyword, so it gets priority in my mind. However, it's currently defined to do something very different than the Pythondef
, so I'm less certain.As pointed out in the discussion for #899, we don't actually have to reserve Python keywords in Hy. It might be problematic for Hy/Python interop not to, but there are workarounds. So the opposite is also possible. We can just keep
setv
and treatdef
like any other symbol.I've heard arguments that we should keep both, the gist being because
def
feels more like a global constant definition, andsetv
feels more like a variable change. I don't exactly buy this because,defn
,defclass
, anddefmacro
--meaning the def- prefix does not really mean global nor constant elsewhere in Hy;But if this feeling is still that important, there are some alternative ways to deal with it.
The text was updated successfully, but these errors were encountered: