Hacker News new | past | comments | ask | show | jobs | submit | more norrius's comments login

> So it broke the experience for all first time users.

To be fair, Python 3 provides a very clear error message if you try to use print as a statement, although I don't know when exactly that was added:

    $ echo 'print "Hello World"' > test.py && python3 test.py
      File "test.py", line 1
        print "Hello World"
                          ^
    SyntaxError: Missing parentheses in call to 'print'. Did you mean print("Hello World")?


That's a terrible message for people trying to run other people's code, unfortunately. It wouod be more useful to say "Are you trying to run Python 2 code in Python 3?", If Python detects enough "2isms" in the file.


Except that is imprecise and can be misleading. It is certain you called print incorrectly. It is not known if you just made a mistake or are trying to execute python 2 code.


This was a while back. In version 3.5 (5 versions after the change was made!) the message was just:

SyntaxError: Missing parentheses in call to 'print'.

This doesn't give the "did you mean" hint, and while it's perfectly understandable for someone who's gotten as far as learning exceptions in Python, that usually comes a few chapters after "hello world". It's definitely enough to throw a newbie off. And even if they're a veteran of other languages, they might have been exposed to a wide variety of error messages like this that commonly indicate a problem elsewhere, and having never yet successfully run a python script at this point, the prior for an error in configuration is much higher than for the tutorial being wrong.


Since Python 3 can detect this case and accurately determine the user intent, it could have just executed the statement as if it were written with parentheses. Had they done that alone, they would have significantly decreased the number of short Python scripts that broke during the transition. Or they could have made a --permissive flag that would do this.


Having print as a statement was a mistake with a lot of downsides (see https://www.python.org/dev/peps/pep-3105/ for the rationale).

It would take quite a lot of effort to offer the new print function and the old print statement at the same time, and it would require either a lot of special cases or renaming the new print function.

And there's really no upside. If the only legacy thing in your script is the use of print statements, that's trivial to fix by hand or with one of the automatic converters.


> And there's really no upside.

Yes there is, the print function is the biggest syntactic incompatibility. Besides the (optional) u marker for unicode strings that they reintroduced later. Most of the other difference (like changed packages) are semantic.

You would have been able to import and run Python 2 in Python 3, maybe with a couple of "if"s or some magic in the module loader. Breaking compatibility like this felt petty and deliberate and made it really hard to have one codebase target both python 2 and 3 (temporarily).


But as the GP mentioned, it can be fixed automatically.

In this specific case I think it's a non-issue. If python3 was limited (or limited except in very niche cases) to changes that could be made programmatically, we wouldn't be in this situation. Everyone would just run 2to3.py and never look back.


It's also extremely easy to fix.


Python is a teaching language. One of its strengths is that it can be your first language and still be one you use professionally a decade later.

A "trivial" obstacle to a seasoned programmer can be an insurmountable obstacle to a beginner.


The problem here is that print "statement" can't be upgraded to a log "function" easily as the programmer grows in experience.

A print "function" conversely is quite easy to upgrade to a log "function".

In addition, "print" is almost always a code smell in professional code. The moment you need to localize, change destination, etc., "print" goes right out the window.

I have lots of beefs with Python 3. Changing print to a function is NOT one of them.


Or people can just read the error and fix their code.


That removes the nudge. People should update their materials.


If you think that, do you think Word should start refusing to open .doc documents at some point?

Code is sometimes alive and changing, and sometimes an artifact. Requiring that code become alive after being an artifact carries significant risks. One might say "code should never be unmaintained" but I think that ignores the reality of limited resources that all of us deal with.


Well, we can either have continuous innovation and improvement with proper security, or we can have long-term support for code that is unmaintained, but it currently seems impossible to have both. I don’t think anyone would consider the .doc format a paragon of design elegance or security.


I'm willing to bet latest Word will have issues opening earliest Word documents ?



>To be fair, Python 3 provides a very clear error message

To be fair, nobody reads error or warning messages.


This is largely due to conditioning of over 30+ years of bad error messages.

  The program exited with error code -2
  Error MS1337 occurred
  Something went wrong. Contact your Administrator
Ideally; error codes should provide information about how to fix the problem (which python in this case does). That falls on the developer side of things (and may not be possible in many cases).

Learning that error messages are useful and can solve your problem, and de-training the reflexive "This message won't help me", lies on the end user side of things (assuming the devs did their part).


Python itself has a habit of contributing to this long history of extremely hostile messages.

If run in interactive mode, the Python interpreter takes its cues from vi and deliberately frustrates the obvious methods to quit. Ctrl-C results in Python whining KeyboardInterrupt but doing nothing helpful. Typing 'exit' or 'quit' both result in messages that make it clear that the interpreter knows what you want to do but won't comply out of spite.

More fun can be had with certain versions of Python 3 when running on Windows, where the Python print function would throw an exception if told to print Unicode characters. This made printing to the console non-portable because Unicode characters had to be stripped if running under Windows. This seems to have been fixed, however.

Still existing are the misleading warnings that Python produces if you forget to include the self parameter on a class method. Python emits an error that blames code that calls the method for passing one too many parameters instead of identifying the underlying problem. Python also gets similarly unhappy, and points fingers at the wrong code, if the brackets are omitted when instantiating a class.

Since Python is dynamically typed, these errors can't be identified until execution. Requiring all-paths testing to catch syntax errors is a special kind of user hostility in and of itself.

Python is an utterly horrible language and it's deeply unfortunate that it has become so popular when so many less error-prone, less obnoxious, alternatives exist.


> Typing 'exit' or 'quit' both result in messages that make it clear that the interpreter knows what you want to do but won't comply out of spite.

The interpreter knows no such thing. Both quit and exit are regular python objects that implement a __repr__ method, both of which return a string that inform the user how to exit. The __repr__ method could have implemented exit, but that would have been poor form (and create issues with tooling), set bad precedent, and go against python coding guidelines.

Ctrl-C giving a keyboard exception rather than exiting is a good thing, as it is far more likely that you are trying to terminate a long running statement, or exit out of sub code block, than trying to kill the interpreter process. This is also the standard behavior of almost any interpreter you care to name (irb, node, clisp, shell). This is because the interpreters try to mimic unix shell semantics (CTRL-D also kills your shell), since they are, after all, shells.


> Ideally; error codes should provide information about how to fix the problem (which python in this case does). That falls on the developer side of things (and may not be possible in many cases).

Rust generally tries to do that, although the fixes it proposes tend to lack context, and can thus lead you into the wrong direction entirely (e.g. once upon a time it would tell you to go and implement a trait on your type when the issue was that you'd forgotten a trait bound on a generic type, it still kinda says that but now there's a snippet which adds the trait bound so it's less error-inducing).


then those people are helpless? you can lead a horse to water.


I agree with the parent actually. My first python program was a json read and print something. 4 lines, maybe 5. I had a need to parse json and print something specific and I suspected I would be able to do it in python. After 4 hours, I was able to and I felt happy. This is not to complain about that 4 hours.

But when I think back at that 4 hours and how much time will it take to do it today, it reminds me of all the learnings. Is it load or loads? Which one is from file? What is a json object? Do I need to quote? If so how? Why does it work with the small block but not the big block? Is it the nesting? Am I doing something wrong?

I think the same is true of hello world. Hello world is a newbie presumably who has not written a single line of code. Well you copy and paste and it does not run. Yes the error is there but hey I copied working code : did I install something wrong? Should I check some website? It says it is python but is it? You can't imagine the questions that will come to a newbie. We need to be mindful of this rather than have a stack overflow mindset.


I think the choice of an object in this comparison is interesting, altough it doesn't affect the result that much, of course. The 5-franc coin is ridiculously big: measuring 31.45 mm (1.24 inch) in diameter and weighing 13.2 g, it's one of the largest circulating coins in the world.


That reminds me of a story where a student couldn't figure out the properties of some physical system, so he ran a massive simulation of a universe with laws of physics similar to his own (but, of course, cutting corners whenever possible). This universe eventually produced a life form intelligent enough to figure out the necessary equations, at which point he happily copied them to his homework and forgot about the simulation.

...only to find it days later (= billions of years of simulated time), by which point the simulated life had figured out that their universe was written hastily and its laws were full of subtle bugs, like floating-point rounding errors showing up in physical measurements. Their technological advance let them move stars around, which they grumpily arranged in a message saying "your code sucks".

Can't find it at the moment, does anyone recognise the reference? It could be in one of these books, I suppose, but I don't have them.


Relatedly, I’ve always found quantum mechanics to be reasonable “proof” that we’re living in a simulation.

Take wave-partical duality: how is that not an artifact of the implementors wanting to reuse some core routines from an legacy particle-based universe while building our next-gen wave based one? The particle-based simulation wouldn’t work at the scales needed, so they moved to waves (much easier to simulate), and rigged up some adaptors to switch to particle mode in a JIT manner as needed.

The folks trying to unify quantum and classical mechanics are essentially reverse-engineering that JIT (and others like it).


A short story along similar lines, though less of a joke and more of an Aesop's Fable: That Alien Message by Eliezer Yudkowsky.

https://www.lesswrong.com/posts/5wMcKNAwB6X4mp9og/that-alien....


Could that be Dibb's Dilemma?


If you do something really simple like a Gaussian blur (which is a type of convolution), it might be possible to find the inverse convolution (de-convolution) and restore the original image with some accuracy.

One method is the Lucy-Richardson deconvolution [1], which is an iterative algorithm, and here [2] is the best practical example I could find right away. Unfortunately the text is not in English, but the illustrations and formulae might be enough to give some intuition of the process.

[1] https://en.wikipedia.org/wiki/Richardson%E2%80%93Lucy_deconv...

[2] https://habr.com/en/post/136853/



Yes, that's it, thank you! And here's the English version of the article I linked above: https://yuzhikov.com/articles/BlurredImagesRestoration1.htm


Yes this is possible before JPEG compression, because convolution removes fairly little information but once you compress using JPEG you remove the frequency components that make it reversible.


I recall being taught a (fairly rudimentary?) explanation of the memory model that the available space is used from one side as the stack, and from the other side as the heap. Reading the article, I realised that memory management in a concurrent context is way more complex than that, but you don't go into a lot of details here (fair enough, that's not the main focus).

So each task gets 16k of stack space, but what if it runs out of it? These are allocated from the "main" heap, so they won't exactly run into each other, but might trigger UB or crash the program. This is something that a real scheduler (like the one in the OS's kernel) would have to deal with anyway, so how does, say, Linux, solve this? Giving a lot of stack space to each running thread would lead to fragmented and underused memory, or is it not a concern at the stack spaces you'd normally deal with?


> Giving a lot of stack space to each running thread would lead to fragmented and underused memory, or is it not a concern at the stack spaces you'd normally deal with?

That's exactly what happens, and it's not a problem in practice -- each thread gets 8 megabytes of memory allocated. (Note, due to demand paging, physical usage grows in 4kb increments.)


I am disappointed that the references at the end are made up and are not the prior art in the obviously important field of non-textual languages. I'd really love to learn about that "system for aromatic computation and its applications in cheese production [7]"!


These are bast shoes [0], known in Russian as lápti, which were the typical footwear in villages until the 20th century. They are strapped to the leg so that they don't fall off.

[0]: https://en.wikipedia.org/wiki/Bast_shoe


Given what appears to be exponential growth, the calculation seems to ignore potential future deaths in the currently known cases. Pardon the morbidity and cynicism, but maybe some of these 14628 people haven't had the time to die yet?

Wouldn't it be more appropriate to compare deaths (305) to the number of people successfully recovered (348 as per the same page)? This gives the survivability rate of 53%, which does sound scary (and I'd love to be proven wrong here).


I'm pretty sure you die faster than you can recover from this thing. So we should see a better deaths / recoveries ratio in the coming weeks.


You are assuming that the data quality here isn't complete garbage.


In addition to recovery taking much longer, there are likely far more than 15k people who have been infected but haven't been to the hospital since the majority of cases aren't serious.


Given the next sentence (...if it isn't true, it seems like a polynomial algorithm would be unwieldy indeed), I think the GP actually meant P!=NP to be true.


I wonder if the French parts of the book were altered in the translation or kept as is. Or do you get excerpts of untranslated Russian instead, huh?


No excerpts of untranslated Russian. What about the English version?

But I read that Tolstoy participated in the french translation, since he spoke french fluently.


Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: