3 ms·
FP feels neat, but good luck debugging it.
by whatever1 4y ago
FP feels neat, but good luck debugging it.
- Jtsummers 4y agoWeird. Functional code is usually easier to debug in my experience because it's based more on composition so you can test components much more easily and isolate error causing sections. It's a lot easier than a 1k SLOC C function (or even 100 SLOC one) where you have to use a debugger or introduce logging (printf debugging) to try and isolate the error.
- Eji1700 4y agoYeah this has generally been my experience with f#. On top of all that runtime errors are way less common because the compiler catches so much more
- whatever1 4y agoFP hides the individual elements behind neat functions. If you are investigating to find a single outlier that broke your program, you need to examine the data points one by one.
- Jtsummers 4y ago> you need to examine the data points one by one. What does this phrase mean? And yes, FP promotes "neat functions". Which isolate behavior and consequently means they can be individually evaluated and evaluated in combination with each other to find the error. It's not a hard problem. And much easier than the 1k SLOC (or worse, several 10k SLOC) C functions I've had to debug in my career. I have repeatedly reduced that kind of garbage down to 10-20% of the original code by applying a functional style and decomposing the horrendously complicated logic into something sensible and, wait for it, debuggable. Why was it debuggable? Because unlike the original it was comprehensible.
- whatever1 4y agoFP assumes that every component works correctly for all input data. Even the example given in the OP, it assumes that the "+" operator will work correctly for all of the data entries. What if one of my inputs was an imaginary number? What if I want special treatment for specific entries? Not all problems generalize.
- Jtsummers 4y ago> FP assumes No, fools assume. FP assumes nothing, it's a non-thinking thing and consequently incapable of assuming. People assume, and we all know what assuming does. So don't. Sensible people validate. Be sensible, don't be a fool. > What if I want special treatment for specific entries? Then do it? What's the hold-up?
- Eji1700 4y ago> What if one of my inputs was an imaginary number? Then the code would call that out and not compile and run until you handled that case (at least in F#, i believe ocaml and haskell have strong typing as well for this reason but it's been awhile). One of the huge upsides of most FP is letting the compiler do a ton of the heavy lifting because it can better check the "sanity" of what you've told it to do. If it's possible to pass an imaginary number to that function, it will say "hey, you could pass an imaginary number to this, and you don't handle it, here's some red squiggly underlining until you deal with that". There's lots written about this. Designing to not represent error states and domain driven design being the two main topics i've come across that really hammer home how a strong typing system and a functional mindset can create extremely bullet proof code. It's trivial to debug (mostly because 90% of the time, if it compiles it runs) and it's trivial to adjust (because the compile errors light up everywhere you need to adjust and you just do that).
- Jtsummers 4y agoMy original reply was just before heading to bed, but I have a real question for you: Do you think this is FP specific? > Even the example given in the OP, it assumes that the "+" operator will work correctly for all of the data entries. What if one of my inputs was an imaginary number? What if I want special treatment for specific entries? Do you really think only functional programming encounters the situation where the data may not all be valid? You think that this imperative style JS is going to work any better on heterogenous data: sum = 0 for(const item of data) sum = sum + data That's going to fail in the same way, and it's not functional, just imperative. So what is your argument about FP here?
- pjmlp 4y agoMy debugger works regardless of the paradigm, maybe step up from vim and emacs?
- toast0 4y agoThe cout school of debugging has worked for me anywhere with output (and I don't understand the point of computing with no output?), don't need a fancy environment for that. Stepping through code is nice when it works, but it often falls apart when there's concurrency, since all you get to step through are timeouts.
- pjmlp 4y agoYou need to improve your debugging experience, that is why things like dynamic instrumentation and dynamic breakpoints exist. There is no output in GPGPU for example, unless you consider updating a matrix set as output.
- eyelidlessness 4y agoThanks! It has been excellent luck. I always know what I’m debugging because the input and output are the only factors I have to consider.