hylang / hy

A dialect of Lisp that's embedded in Python
http://hylang.org
Other
4.85k stars 368 forks source link

Remove true/false in favor of True/False (or the reverse?) #908

Closed gilch closed 7 years ago

gilch commented 9 years ago

ref #240, where the discussion has become too unfocused to make much progress. Let's pick apart the remaining subissues one-by-one.

I'll admit to using the easier-to-type aliases true/false almost exclusively in my own code, and they're used a lot in Hy proper. But I still think this is extra complexity for marginal benefit.

Python keywords are reserved in Hy (they don't have to be, see discussion in #899), because Hy compiles to Python and can be imported from Python. They don't have to mean the same thing in Hy as in Python, though this can get confusing. def (for example) has a pretty different meaning, but there's no other good meaning for True and False that we could use instead. True/False/None are reserved in Python3. They cannot be assigned to in Python. It may be problematic (though possible) to allow this in Hy, and besides We're Still Python(TM). Thus, if we have to choose, the clear choice is the Python words.

I am unconvinced by the argument that true and false are easier to type. True and False literals are actually not used as much as you might expect. Sure, Booleans are used all the time, but usually you type in an expression that evaluates to a Boolean rather than forcing one or the other yourself.

The case where Boolean literals get used the most is in testing. If you're testing at the REPL and just need a generic truthy or falsey value, then, admit it, you're going to use 1 and 0 over even true and false, because it just does not get any easier to type than that.

Unit tests, on the other hand, also serve as a kind of documentation. It's worth making them readable. Now if we decide that it's idiomatic in Hy to use 1/0 for unit tests, then people will be used to it and it will not be considered hard to read. (Many of Hy's unit tests already do this by the way.) On the other hand, True and False are no less readable, and they even stand out more.

I am also unconvinced by the argument that true and false are used all the time. It's a simple one-line fix:

true, false = True, False

The other keywords we've removed breaks stuff a lot harder than this. Yes, the Grand Language Cleanup will break stuff. Best get it over with now. If removing true/false turns out to be a mistake, it will be an easily correctable mistake. If NOT removing true/false turns out to be a mistake, it will only get harder to fix.

gilch commented 9 years ago

Alternate Proposal: Remove True/False in favor of true/false

Obviously incompatible with the above, but I do think we should pick one or the other. I like the status quo least of all.

As pointed out in the discussion of #899, Python keywords don't have to be reserved in Hy. Hy can be set up to treat True/False the same as any other symbol. While potentially problematic for Python interop, there are workarounds.

This has the advantage of keeping what appears to be the more popular alias.

refi64 commented 9 years ago

I like the alternative better. :) I was never much of a fan of Python's uppercase True and False.

gilch commented 7 years ago

A third option from #1119:

Remove both pairs and use T/F instead.

There's plenty of precedent for T meaning "true" in other lisps. (Common Lisp uses T/nil, Scheme uses #t/#f.) The main argument for keeping Clojure's true/false over Python's True/False is that it's easier to type. Well, T/F is even easier than that. It would pretty much remove the temptation to use 1/0, (which works the same in almost all cases).

@hylang/core, what say you?

Kodiologist commented 7 years ago

For what it's worth, I think True and False are better than true or false, merely because that's what Python does. But T and F are even better. I am perfectly okay with keeping the original True and False despite the redundancy, because sometimes it's nice to be able to be more explicit, but I wouldn't mourn them much if they were removed, either.

algernon commented 7 years ago

My preference would be T/F > true/false > True/False.

arrdem commented 7 years ago

IMO T/F is pretty awful and common/traditional lispy. Beyond that legacy, I see no attraction in in using it since the modern algol derivative ecosystems all use true and false variously capitalized.

Personally, I'm missing true and false from Clojure a lot as I'm writing bare python at work these days. But Hy is supposed to first and foremost fit in with python, and it doesn't really make sense to keep true and false around when True and False have to be reserved words so on that basis I'd argue that True and False are the best choice here. Users can always create aliases to lower-case true and false.

Kodiologist commented 7 years ago

So it looks like folks' preferences are:

I think T and F are the closest we have to consensus, unless anybody else wants to pitch in.

olasd commented 7 years ago

I for one think that single-letter uppercase symbols are really ugly, and i've never seen those used anywhere else. I think that removing the True and False variant provides exactly zero gain, and that true and false are okay.

Basically I think this issue should be closed doing nothing.

refi64 commented 7 years ago

I'm on the same side as @olasd.

rcarmo commented 7 years ago

Same here. T/F are ugly and make no sense.

gilch commented 7 years ago

Wow, T/F seems pretty unpopular huh? I thought it was perfectly readable, but I also thought Scheme's #t/#f was perfectly readable, if hard to type. It's not like we're asking the user to memorize dozens of obscure one- or two-character names like in Ruby and especially Perl. It's two values, with very obvious mnemonics.

The conciseness is also nice. I do think that things that get used a lot should have concise representations. With a short representation like T/F you can write lists of Booleans just as easily as lists of 0/1, like [T F T T] etc. I feel that kind of thing is much less readable with the current true/false when it gets even a little long. That's when I expect to use Boolean literals the most: in lists of them.

For most other uses of Booleans, I'd expect to see computed values more often, like (< x 10) etc., instead of the literal true and false.

I doubt this will change anyone's mind (but if it does, speak up!), so I'm going to consider the T/F option dead unless the vote changes dramatically. I'll just have to def some aliases when I make my long lists.

But all that said, I think it's more important that there be one-- and preferably only one --obvious way to do it. This is a good principle for many reasons, including ensuring that Hy users speak a mutually intelligible dialect.

If we had started with only Python's style True/False/None, would anybody have complained? I doubt it. I think we should pretend that happened if we can't reach a consensus for something else. The priorities for Hy have been Python>Clojure>Common Lisp.

If we had started with only Clojure's style true/false/nil, would anybody have complained? I still kind of doubt it, since that's what everyone seems to be using, but there's a stronger case against it, because Python's reserved words should probably still be reserved in Hy. Even so, languages can (and do) have reserved words that they don't use. goto and const in Java, for example. Hy already does this. You can't assign to elif. We could disallow True/False/None, just like elif, and Hy users would use a more consistent language.

The Clojure option seems to be the de facto status quo. Does anyone seriously dispute that even if Hy allowed both Clojure and Python style, then future Hy style guides would eventually settle on one or the other? Then why not just enforce it at the compiler level?

gilch commented 7 years ago

Vote for the de facto Clojure-style true/false/nil.

gilch commented 7 years ago

Vote for the default Python-style True/False/None.

gilch commented 7 years ago

@hylang/core The above is more of an opinion poll than any kind of binding decision process, by the way. We can still discuss the details of how to implement whatever we decide on.

Kodiologist commented 7 years ago

If we're not doing T and F, True and False seem better to me than true and false. All other things being equal, it's better to imitate Python than Clojure.

It's not like we're asking the user to memorize dozens of obscure one- or two-character names like in Ruby and especially Perl.

I don't know about Ruby, but the only two-character names a Perl programmer needs to know are $_ and @_, and the only one of those you really need to know is @_. (I don't think there are any built-in one-character names, unless you count operators, like * and x.)

I've noticed Python programmers talk about Perl a lot, usually as an example of what not to do, but it seems that most people who complain about Perl don't know it very well in the first place.

gilch commented 7 years ago

I was including operators, actually. Ruby also has some arcane global names. ($! $@ $_ $. $& $~ $n $= $/ $\ $0 $* $$ $?). I have to use Ruby some at work. It seems to be something of a cross between Smalltalk and Perl. So the weird parts of Ruby that I don't recognise from Smalltalk I've been blaming on Perl. But Matz also cites Eiffel and Ada (and Lisp) as influences, so perhaps some of that is undeserved?

It's not like I know Perl well enough to hate it. Learning more Perl is actually on my to-do list. Any recommendations for good textbooks or something? Should I look at Perl 6 first? Or at all? It doesn't seem ready, and hasn't for a very long time.

gilch commented 7 years ago

That poll is actually really close. I thought we might see some kind of consensus, but it looks more like a stalemate.

I feel like we need some kind of decision process to keep progress on Hy from getting stuck like this. Do we just go with @paultag's vote? Does anyone know a system that works really well from your other projects?

paultag commented 7 years ago

If it comes down to a deadlock tie, I'm going to make the following argument:

  1. Hy's failures mostly stem from us trying to cover up the fact it's actually Python
  2. We're about to break large chunks of the language in a few cleanups
  3. If we're going to break anything it should be done in the next release or two

Therefore:

  1. We should remove as much as much aliasing as we can, since it's not actually helping anything, and hiding the truth of the universe.

If folks feel strongly enough that the above isn't going to be enough to gain consensus, we'd be at our first deadlock as a project. Which is both great (yay!) and not great. I don't want to do the BDFL thing if I can avoid it, but I'm happy to.

It's worth stating, if I had to make a call, it would be to gut all aliases of True and False from Hy. I use true, false and nil in my programs, but they cover up the fact it's actually True, False, and None. I mean, None and nill also strike me as semantically different too, but that's another matter maybe :)

Kodiologist commented 7 years ago

@gilch Years ago, I was a Perl 6 developer, but I eventually lost interest when I felt it simply wasn't getting anywhere. The odds were too far against it from the start because of the sheer variety of features that were desired for the core language. It's a victim of the second-system effect (even though Perl was big and ugly (and proud of it!) to begin with).

Perl 5 is still alive and well even though it's much less popular than it was in previous decades, presumably from competition with Python, Ruby, PHP, and even JavaScript now that server-side JS is a thing. The famous camel book, Programming Perl, deserves its good reputation. You might also want to check out Modern Perl. I haven't read it, but I understand that it makes a clear case for how Perl ought to be used in modern times, in contrast to the troublingly common practice of writing Perl in the 2010s as if it were the 1990s (using local where my would do, calling every user-defined subroutine with &, not using strict, not using English, etc.). The Perl team's heroic successes in maintaining backwards compatibility has the side-effect of enabling this kind of thing. Of course, in the Python world, we have a similar problem, of the community kicking and screaming to resist the pretty minor backwards incompatibilities of Python 3.

Back on topic. Ideally all serious Hy users would show up here and we could poll them all, but since that's not happening, I guess we should give Paul the deciding vote. Besides, this is clearly the sort of ugly bikesheddy issue where reaching a decision at all is more important than what choice we make.

gilch commented 7 years ago

@Kodiologist Thanks, I'll look at Modern Perl then. It was actually my best guess about where to start.

@paultag Thanks for that weigh in. I think that argument gives us some good direction for other issues too.

Kodiologist commented 7 years ago

@gilch If you want to review #1156 and approve it, I think we can merge it and then close this issue, unless you want to wait a bit longer to see if anybody else votes, or something.