▲ | j1elo 4 days ago | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
> People expect a map/filter method Do they? After too many functional battles I started practicing what I'm jokingly calling "Debugging-Driven Development" and just like TDD keeps the design decisions in mind to allow for testability from the get-go, this makes me write code that will be trivially easy to debug (specially printf-guided debugging and step-by-step execution debugging) Like, adding a printf in the middle of a for loop, without even needing to understand the logic of the loop. Just make a new line and write a printf. I grew tired of all those tight chains of code that iterate beautifully but later when in a hurry at 3am on a Sunday are hell to decompose and debug. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | kace91 4 days ago | parent | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
I'm not a hard defender of functional programming in general, mind you. It's just that a ridiculous amount of steps in real world problems can be summarised as 'reshape this data', 'give me a subset of this set', or 'aggregate this data by this field'. Loops are, IMO, very bad at expressing those common concepts briefly and clearly. They take a lot of screen space, usually accesory variables, and it isn't immediately clear from just seing a for block what you're about to do - "I'm about to iterate" isn't useful information to me as a reader, are you transforming data, selecting it, aggregating it?. The consequence is that you usually end up with tons of lines like userIds = getIdsfromUsers(users); where the function is just burying a loop. Compare to: userIds = users.pluck('id') and you save the buried utility function somewhere else. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | tuetuopay 4 days ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
Rust has `.inspect()` for iterators, which achieves your printf debugging needs. Granted, it's a bit harder for an actual debugger, but support's quite good for now. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | williamdclt 4 days ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
I'll agree that explicit loops are easier to debug, but that comes at the cost of being harder to write _and_ read (need to keep state in my head) _and_ being more bug-prone (because mutability). I think it's a bad trade-off, most languages out there are moving away from it | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | lenkite 4 days ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
This depends on the language and IDE. Intellij Java debugger is excellent at stream debugging. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | const_cast 4 days ago | parent | prev [-] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
Just use a real debugger. You can step into closures and stuff. I assume, anyway. Maybe the Go debugger is kind of shitty, I don't know. But in PHP with xdebug you just use all the fancy array_* methods and then step through your closures or callables with the debugger. |