These are all about passive experiences (which are great don't get me wrong!), but I think you can do better. It's the same phenomenon DHH talked about in the Rails doctrine when he said to "Optimize for programmer happiness".
The python excerpt is my favorite example:
```
$ irb
irb(main):001:0> exit
$ irb
irb(main):001:0> quit
$ python
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
```
<quote>
Ruby accepts both exit and quit to accommodate the programmer’s obvious desire to quit its interactive console. Python, on the other hand, pedantically instructs the programmer how to properly do what’s requested, even though it obviously knows what is meant (since it’s displaying the error message). That’s a pretty clear-cut, albeit small, example of [Principle of Least Surprise].
</quote>
On the one hand, being generous in your inputs is always appreciated. On the other hand, the fact that both exit and quit will terminate ruby means the answer to "how do I quit ruby" now has two answers (technically 4 because `quit()` and `exit()` also work, and if we're talking about "least surprise" if you accept "exit" and "quit", why not also "bye" or "leave" or "close" or "end" or "terminate".
Python might be surprising, but in this example, it's only surprising once, and helpful when it surprises you. Now you know quitting requires calling a function and that function is named exit() (although amusingly python3 anyway also accepts quit()). And being fully pedantic it doesn't know what you mean, it is assuming what you mean and making a suggestion, but that's not the same as knowing.
From here on I'm not arguing the point anymore, just recording some of the interesting things I discovered exploring this in response to your comment:
You can do this in python (which IMO is surprising, but in a different way):
```
>>> quit
Use quit() or Ctrl-D (i.e. EOF) to exit
>>> quit=True
>>> quit
True
>>> quit()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'bool' object is not callable
>>> exit()
```
But this also gives some sense to python's behavior. `quit` and `exit` are symbol names, and they have default assignments, but they're re-assignable like any other symbol in python. So the behavior it exhibits makes sense if we assume that they're not special objects beyond just being built int.
`exit` is a class isntance according to type. So we should be able to create something similar, and indeed we can:
```
>>> class Bar:
... def __repr__(self):
... return "Type bar() to quit!"
... def __call__(self):
... print("I quit!")
...
>>> bar = Bar()
>>> bar
Type bar() to quit!
>>> bar()
I quit!
>>>
```
Interestingly this suggests we should be able to replace exit with our own implementation that does what ruby does if we really wanted too:
```
>>> class SuperExit:
... def __init__(self, real):
... self.real_exit=real
... def __repr__(self):
... print("Exiting via repr")
... self.real_exit()
... def __call__(self):
... print("Exiting via call")
... self.real_exit()
...
>>> exit = SuperExit(exit)
>>> exit
Exiting via repr
```
> why not also "bye" or "leave" or "close" or "end" or "terminate".
We can include these as well, but each keyword that you include brings diminishing returns at the cost of clutter and inconsistence in the API. Python problematically decides that returns diminish after the first --- “first” according to developers, that is --- possibility in all cases. Ruby anticipates that everyone's first choice will be different and practically maximizes comfort of users.
>Python problematically decides that returns diminish after the first --- “first” according to developers, that is --- possibility in all cases
Eh, that feels pretty arbitrary to me. `quit()` and `exit()` both work, and looking at other languages, `exit()` should almost certainly be your first choice
Having `exit` or `quit` without the parens work might accommodate some people whose first choice isn't to call a function (I guess because they're thinking of the REPL as a shell?), but surely if you're going that far `bye` is a reasonable and practical choice. ftp/sftp use it to this day. At some point you make a cutoff, and where you do is pretty arbitrary. You can like that ruby is twice as lenient as python, but I think it's a stretch to say that python using the single most common function call and a very common alias is "problematic" or even surprising. IMO, python's behavior is less surprising because I don't expect `exit` to be a special command that executes inside the REPL. I expect `exit()` because that's what other programing languages do. And python famously ditched the inconsistent `print "Foo"` syntax in favor of `print("Foo")` in python3 exactly because inconsistency in what was and wasn't a function call was surprising.
> Having `exit` or `quit` without the parens work might accommodate some people whose first choice isn't to call a function (I guess because they're thinking of the REPL as a shell?),
In ruby, parentheses are optional for function calls. `exit` is a regular call, not some REPL peculiarity.
EDIT: Nevermind. Just found that despite the `exit` method being already defined, both irb and pry overshadow that with a repl command that does the same thing. Maybe it's so that it can't be redefined.
this actually completely turned me off from python when I first encountered it. I was like... "the program KNEW WHAT I WAS TRYING TO DO, and instead of just DOING that it ADMONISHED me, fuck Python" LOL
The proliferation of Python has only made my feelings worse. Try running a 6 month old Python project that you haven't touched and see if it still runs. /eyeroll
>Try running a 6 month old Python project that you haven't touched and see if it still runs.
My experience has been 6 month of python works fine. In fact, python is my go to these days for anything longer than a 5 line shell script (mostly because argparse is builtin now). On the other hand, running a newly written python script with a 6 month old version of python, that's likely to get you into trouble.
argparse, because argparse is built in. I'm usually writing shell scripts to automate some process for myself and my co-workers. The last thing I want is for them to have to be fiddling with installing external requirements if I can avoid it.
The python excerpt is my favorite example:
```
$ irb
irb(main):001:0> exit
$ irb
irb(main):001:0> quit
$ python
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
```
<quote> Ruby accepts both exit and quit to accommodate the programmer’s obvious desire to quit its interactive console. Python, on the other hand, pedantically instructs the programmer how to properly do what’s requested, even though it obviously knows what is meant (since it’s displaying the error message). That’s a pretty clear-cut, albeit small, example of [Principle of Least Surprise]. </quote>