Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Hey that's me!

I had a frustrating moment the other day where a colleague said that

  float(5)
was more explicit and personally preferred in Python than a literal

  5.0
I realised I was being pedantic but I genuinely believed in "good craftsmanship" when I really pushed him to change it.

I need to get better at this because the social friction I caused may cost more than the poor craftsmanship. But the other part of me is thinking, "c'mon man... Seriously?"



I have found that it's best to leave coding discussions like that to tools - we use Rubocop and Overcommit and it's a huge PITA every time it points out a minor quibble (we stop commits locally on our machines if new code doesn't pass both) BUT it saves us from having those conversations during code reviews. My general rule of thumb is that if there is a question of style that isn't caught by Rubocop, then it's very likely not worth having.

The other upside is that code reviews are higher quality and design focused.


By the way, float(5) is slower, because it creates two objects instead of one.


I pointed that out but also immediately conceded they it doesn't matter since it was instantiated once at runtime.

Which is why I call it craftsmanship. It works the same for all intents and purposes, but c'mon. :)


One of my pet peeves in C++ is seeing: std::string s = "";

It causes calls to strlen and potentially memory allocations. Just use the default constructor!


It used to, but it doesn't anymore, presuming you use a reasonably recent compiler. If you enable optimizations the assembly for that snippet and the default constructor are identical, I last checked on some GCC 5 flavor, but I think it was like this all the way back in GCC 3 something.

Compilers can do some pretty fancy things with literals because they know they optimize constants known at compile time.


I just started using GCC 5.4 - I'll have to check again. Last I checked was around 4.8, and it was still generating sub optimal code with the empty literal.


Enabling the optimizations is important too. If you leave it on the defaults it does a very direct translation to machine code.

GCC 7 is available for use now.


Absolutely agreed that the default constructor is better style, but won't it be optimized down to the same code anyways?


This one's tricky, because you're absolutely right, and telling them that won't help them improve. Try asking them, "hey I must have not read that PEP, can you link me to where that's recommended so I can get in sync?", or "hey I read this guide recently and it recommends doing X because <actual legitimate reasons>", or (best), "I don't understand why this is recommended, where can I learn more" (which hopefully doesn't end up on a holistic learn-the-world journey that ends with a 1-to-1 with your boss where you share your concerns about this developer's performance).

"Good craftsmanship" is both subjective AND hard to relate to an increase business value. Better to stick with third-party recommendations, like textbooks or linters.


Why appeal to authority here? Experienced, well-intentioned developers should able to have a discussion of the merits of a particular construct without having to turn the discussion into a citation count contest.

FWIW, I'm firmly on the 5.0 side.


Ohhh boy. The problem is when the guy on the float(5) side genuinely believes that this is better code style. At the end of the day you do have to appeal to some system, whether it be to the PEP, or to SOLID design principles, or even to "someone else thinks this is a good idea on stack overflow".

Personally I like to go with "is accepted by the community" as opposed to "is accepted by most people in this room" or "Greg thinks it's beautiful".


It's not appeal to authority, it's consider the point of view of a disinterested third-party that they may not be aware of and thus can gracefully accept your feedback without losing face.


We all have that part. The trick is not to let it make you an asshole. There might be times when that's the right thing to be - satisfying a pedantic quibble over a style preference, to the detriment of morale and team cohesion, is never, ever one of them.


Your colleague is clearly wrong. Seriously, 'coërce the integer five to floating point' vice 'the floating point number 5.0'?

Does he also prefer to right integers as 'int(float(5))'? The mind boggles, it really does.


I've found the first few chapters of _Crucial Conversations_ extremely useful.

Manager-Tools.com speaks very well to relationships being very valuable, worth more than float(5) vs 5.0... though... I really do agree. Float(5)? Really? And 5 should be replaced with IntNoReallyItJustAnInt(5)?? ;)


You don't use Boolean.ToString(b).Equals("true") ?


It wouldn't even enter my mind to argue about something so trivial.

Then again, I'm not a software developer (even though I did write some Python scripts for my workflow in the past).


I'll be honest, it's pretty hard to see how it matters much either way.


Unless you can prove that one method is significantly faster or the other structurally dangerous, it is just a matter of coding style and opinion. Agree to disagree, or let the lint tool be the referee.


$ python -m timeit 'float(5)' 10000000 loops, best of 3: 0.0776 usec per loop

$ python -m timeit '5.0' 100000000 loops, best of 3: 0.00719 usec per loop


Did you have a typo? Or did you mean to only loop ten million times in the first case and 100 million in the second?


I did the lazy approach and let timeit pick the count. Specifying the number of loops doesn't change the result:

$ python -m timeit -n 10000000 'float(5)' 10000000 loops, best of 3: 0.0771 usec per loop

$ python -m timeit -n 10000000 '5.0' 10000000 loops, best of 3: 0.00717 usec per loop

[timeit] provides a simple way to time small bits of Python code. It has both a Command-Line Interface as well as a callable one. It avoids a number of common traps for measuring execution times. See also Tim Peters’ introduction to the “Algorithms” chapter in the Python Cookbook, published by O’Reilly.

Ref: https://docs.python.org/2/library/timeit.html


Am I reading that right: on average it's 10x faster to use a float literal?


Yes. The difference is the Python compiler is not optimizing out the float() conversion, so every time it creates the value 5.0 it is calling the float() conversion on the literal "5".

Different machine, so the timings are different from above, but here are some permutations:

Float literal:

$ python -m timeit '5.0' 100000000 loops, best of 3: 0.0152 usec per loop

Integer literal coerced to a float:

$ python -m timeit 'float(5)' 10000000 loops, best of 3: 0.146 usec per loop

Float literal coerced to a float:

$ python -m timeit 'float(5.0)' 10000000 loops, best of 3: 0.143 usec per loop

Integer literal:

$ python -m timeit '5' 100000000 loops, best of 3: 0.0152 usec per loop

Float literal coerced to an integer:

$ python -m timeit 'int(5.0)' 10000000 loops, best of 3: 0.155 usec per loop

Integer literal coerced to an integer:

$ python -m timeit 'int(5)' 10000000 loops, best of 3: 0.14 usec per loop


Very cool thanks. So something like PyPy would probably very quickly optimize it, since it has a deterministic result. I think I'm going to experiment with that one.


They're still both magic numbers.


Isnt this a very python thing. Arent all the "brillant jerks" python and ruby programmers. Java and C/C++ guys are the actually smart dudes that know what they are doing and PHP guys just want to get it working and dont give a fuck.


I can't imagine any smart developers using Ruby anyone, I know because I unfortunately work with Rails and anyone with a brain cell has already left. To me deciding to use Rails isn't a very smart decision


What would you use? Serious question, I'm trying to figure this out.


Yeah, idiot GitHub programmers.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

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

Search: