6 ms·
Copying vs. sharing in functional languages
- RobertRoberts 9y agoThis article brings up an interesting question. Since much of programming is based on simply making something easier for humans to read, create and design with, is there a trade off with functional programming in regards to debugging? I really appreciate some aspects of both styles, but I am not a die hard either way, my limited experience with functional programming has never lead me into the depths of debugging like discussed in the article. So the article actually makes me wary of going further. I would liken this effect to a form of technical debt similar to a framework. Upfront development is faster, but when there's a problem, it's much harder to fix or work around, and problems can be more obscure. Is this concern valid?
- ShaneWilton 9y agoI've found that it really varies based on the language and the tooling it offers. I code Erlang and Elixir on a daily basis, and I've never used such a full-featured debugging environment before. I can trace messages across a distributed system, connect to production nodes to set breakpoints or tracepoints, and I can render a live visualization of all the supervision trees in my application and watch as processes spawn and are killed. And of all that is just scratching the surface of what you can do. I also remember Racket having pretty powerful debugging capabilities, including the ability to step through programs and see how each expression is evaluated. Some languages have worse tooling than others, but I don't think it's a problem endemic to functional programming.
- tathougies 9y agoThere are perfectly good debuggers for functional languages, but honestly, it's not as useful as it is for imperative languages in my experience. More useful is profiling information -- both execution and heap.
- willtim 9y agoFunctional programming actually opens up more opportunities for debugging, as we are better able to both reason about and transform programs. The caveat is that often we need to build domain-specific debuggers, to effectively debug our high-level domain-specific code. Even in imperative languages like C++ and Java, the standard word-at-a-time debugger gets increasingly less useful as abstractions are piled up. Multiple threads really throw a spanner in the works. Here's an example functional debugger that can step forwards and backwards in time, as well as modify code at any time: http://debug.elm-lang.org http://debug.elm-lang.org
- seanmcdirmid 9y agoBackward step debuggers aren’t limited to just functional languages, they’ve been available for imperative languages as well (e.g. via gdb).
- willtim 9y agoThat's quite a bold promise, when in theory any statement could "launch the missiles". Just like software transactional memory, this idea, AFAICT, really needs pure functional programming to work well.
- seanmcdirmid 9y agoNo way, I’ve implemented a few of them myself (my research area is in love programming), and none of the languages I’ve done were functional. All you need to do is checkpoint, which is true for non trivial FP programs as well.
- naasking 9y agoCheckpointing is more fine-grained and yet, essentially free in pure functional languages though. The tooling has got to be simpler for that reason alone.
- deleted 9y ago
- rdtsc 9y ago> is there a trade off with functional programming in regards to debugging? I have looked and large and hairy C++/Java/C#/Erlang/Python programs. I think overall Erlang are the easiest to debug. Two reasons are: state is most likely to be passed in explicitly, and data is immutable. Compare to, say, looking at a class instance in an OO language, which inherited from a bunch of other classes, and then had some methods called on it, modifying its internal state, and now you're and asking yourself "hmm, this seems broken, but how did we even get to this point?". vs looking at function like "update_state(State, NewData, ...) -> ... NewState.". In the second case it is clear what is happening, what the old state was, what the new is. If the bug happens on a live system, it is easy to attach a trace that would trigger only when NewData matches something or old state matches, or both match.
- ktpsns 9y agoMy observation is that functional languages which are REPL-focused (such as Haskell and Mathematica) generally empower the author to well understand/test/"debug" smaller pieces of her code. In contrast, in traditional non-REPL languages such as Java and C(++), this requires writing special testing code within the actual code. Similarly, at least in imperative languages, I made the experience that people who develop with a debugger write less testable code then people who do the debugging in their code, for instance with assertions or test frameworks. Sometimes I feel these two groups are disjoint.
- seanmcdirmid 9y agoIt’s weird because these are totally different concepts, and catch different things: the debugger is about inspecting how your code executes, assertions allow you to detect when invariants are broken (and provide points that need inspection in the debugger), tests ensure that your code doesn’t break by accident, etc...good developers should be, no, they probably are using all three tools. That functional languages sometimes lack decent debuggers says more about community investment choices than need (e.g. Lisp machines actually had the best debuggers ever). Repls can only give you feedback one code line at a time (and if you type a procedure/function into a REPL, you get no feedback at all until it’s called in the main loop), it’s ironic they are found more commonly in in expression-based rather than statement-based language.
- taeric 9y agoTo be fair, repls can do much more than one line at a time. You just need a more capable editor than a line oriented prompt. This is not to detract from your point. I have gone further and lamented the death of debuggers. Primarily because I have seen them used so rarely in the wild. That combined with the somewhat ironic rise of functional idioms in java that are actually difficult to debug. (My understanding from last time I asserted this, is just that I don't see them used much.)
- seanmcdirmid 9y agoMy experience is that when the debuggers are bad, they aren't used much, and when they are good, they are used all the time. The web browsers offer poor debugging experiences ATM, so for Javascript they aren't as useful as say debugging C# in Visual Studio or even Java in Eclipse. I agree that functional programming idioms in practice makes debugging harder, but only because debuggers lack the right UI to deal with the buried control flow of things like functional orgami. I've heard F# with its Visual Studio plugin is doing better in this regard.
- catnaroek 9y agoI fail to see the point of this work. When I program, what I want to see is how each statement relates a precondition to a postcondition. From this point of view, the selling point of value-oriented programming is that conditions are partially reified in the program as abstract types, rather than merely existing in the programmer's head or a separate piece of paper. Note that this does not require the complete absence of mutability: an abstract value may contain the identities of mutable objects, but the role of abstraction is to constrain the ways in which these objects can in fact mutate. Laziness is a prime example of this.
- danghica 9y agoHello all, I am the author of the blog post. Now the tool is available online: https://fyp.jackhughesweb.com/tasks/ https://fyp.jackhughesweb.com/tasks/ Please fill out the feedback form if you have time, so we can improve the project.