Live data from Hacker News

Comparing Pythagorean triples in C++, D, and Rust

atilanevesoncode.wordpress.com

51–60 of 118 posts

Re: Comparing Pythagorean triples in C++, D, and Rust

#51

Earlier quoted context omitted.

How do you debug logic errors in that case? I imagine that most logic errors can't be caught by the compiler, although I could be wrong.

Most logic errors can definitely be caught by the compiler if you're taking the approach of encoding your logic into your type system. I've done this with real codebases (in Python as well, actually, using Mypy) and it's been very effective.

Can it catch something like accidentally writing "x == y", when you meant to write "x != y"? I feel like this kind of bug can be insidious enough to waste lots of debugging time, yet difficult to catch until you run the code.

Re: Comparing Pythagorean triples in C++, D, and Rust

#52

The C++ version is taking a compile and runtime short cut by using printf instead of iostream. This pull request has timings with this changed: https://github.com/atilaneves/pythagoras/pull/1#issuecomment...

Using the stuff isn’t really idiomatic - on both modern and legacy code bases I’ve used operator<< overloads on custom types, but never called std::cout in a hot loop or used std::endl to do anything but actually flush the stream.

Is std::endl guaranteed to flush the stream? I’d think you’d be better off with std::cout::flush(), std::flush if you prefer manipulators. It would certainly be clearer, assuming it’s not temporary debug code.

Re: Comparing Pythagorean triples in C++, D, and Rust

#53

Earlier quoted context omitted.

Most logic errors can definitely be caught by the compiler if you're taking the approach of encoding your logic into your type system. I've done this with real codebases (in Python as well, actually, using Mypy) and it's been very effective.

Can it catch something like accidentally writing "x == y", when you meant to write "x != y"? I feel like this kind of bug can be insidious enough to waste lots of debugging time, yet difficult to catch until you run the code.

Not easily. Rust's type system has limits, and what you're talking about is something you'd probably want dependent types for.

But it can catch lots of other logic errors.

The approach I have used in both mypy and rust is to encode state transitions into types. It's more elegant in Rust, and safer as well, but even with mypy it means I could be very sure about certain properties of my service (it was a sensitive service and I needed to be reasonably sure it wouldn't end up in an invalid state).

https://insanitybit.github.io/2016/05/30/beyond-memory-safet...

This is an example of the pattern.

When you take a "Type driven" approach to your code - stating your constraints upfront, and encoding them into your types - you can push a lot of the debug cycle to your compiler.

Re: Comparing Pythagorean triples in C++, D, and Rust

#54
post #52

Earlier quoted context omitted.

Using the stuff isn’t really idiomatic - on both modern and legacy code bases I’ve used operator<< overloads on custom types, but never called std::cout in a hot loop or used std::endl to do anything but actually flush the stream.

Is std::endl guaranteed to flush the stream? I’d think you’d be better off with std::cout::flush(), std::flush if you prefer manipulators. It would certainly be clearer, assuming it’s not temporary debug code.

It is guaranteed to flush.

Re: Comparing Pythagorean triples in C++, D, and Rust

#55
post #5

By the way, is it a secret to programmers that Pythagorean triples can be parametrised? I understand that the point of the code is to enumerate them without knowing that they can be parametrised, but the parametrisation in this case is not so scary, so it's a fun bit of trivia for programmers (for mathematicians, it's more fundamental, as the Pythagorean parametrisation is an important prototype for counting rational…

Last time I bothered with calculus was around 1996, so yeah it isn't something that sticks around.

Re: Comparing Pythagorean triples in C++, D, and Rust

#56
post #55
post #5

By the way, is it a secret to programmers that Pythagorean triples can be parametrised? I understand that the point of the code is to enumerate them without knowing that they can be parametrised, but the parametrisation in this case is not so scary, so it's a fun bit of trivia for programmers (for mathematicians, it's more fundamental, as the Pythagorean parametrisation is an important prototype for counting rational…

Last time I bothered with calculus was around 1996, so yeah it isn't something that sticks around.

This doesn't have anything to do with analysis-like techniques, and is closer to combinatorial/number-theoretic stuff that programmers are more likely to be familiar with.

Re: Comparing Pythagorean triples in C++, D, and Rust

#57

Earlier quoted context omitted.

In my work (text search), if I'm debugging, then the vast majority of my time is spent debugging performance problems. In those cases, it only makes sense to debug with all optimizations turned on. If I'm debugging logic problems, which is a bit more rare, then I've found debug builds to be fast enough in most cases. When they aren't, then I turn on release mode. Incremental compilation mostly makes compile times bea…

I mostly use printf. A debugger is only good for telling you where it seg faulted and the stack trace. The reason is because I write a custom printf to print exactly what I need to know. Debuggers just bury you in irrelevant output.

A good debugger is good for quite a bit more than that. Watches, break points, performance/profiling. I actually can't believe you're hating on debuggers.

Re: Comparing Pythagorean triples in C++, D, and Rust

#58

Earlier quoted context omitted.

In my work (text search), if I'm debugging, then the vast majority of my time is spent debugging performance problems. In those cases, it only makes sense to debug with all optimizations turned on. If I'm debugging logic problems, which is a bit more rare, then I've found debug builds to be fast enough in most cases. When they aren't, then I turn on release mode. Incremental compilation mostly makes compile times bea…

I mostly use printf. A debugger is only good for telling you where it seg faulted and the stack trace. The reason is because I write a custom printf to print exactly what I need to know. Debuggers just bury you in irrelevant output.

Debuggers are great interrogating arbitrary program state (it's a printf you don't need to hardcode!) and acting as a REPL for trying out new code.

Re: Comparing Pythagorean triples in C++, D, and Rust

#59

Earlier quoted context omitted.

Using the stuff isn’t really idiomatic - on both modern and legacy code bases I’ve used operator<< overloads on custom types, but never called std::cout in a hot loop or used std::endl to do anything but actually flush the stream.

What would you suggest is C++ recommended way for doing io?

I would use std::cout but output "\n" instead of endl.
Post reply on HN