4 ms·
Ok this is cool and all but where do I put my breakpoints now when something unexpected happens and I need to debug production code?
by noname120 2y ago
Ok this is cool and all but where do I put my breakpoints now when something unexpected happens and I need to debug production code?
- epolanski 2y agoYou do it the same way you do it in any JS application.
- noname120 2y agoWell you can't because now you declaratively represent the execution flow, and the actual execution is implicit. If you put any breakpoint in there it will break during the declaration of the execution flow rather than when the corresponding logic actually gets executed: Http.request.get(`/todos/${id}`).pipe( Http.client.fetchOk, Http.response.json, )
- epolanski 2y agoYou put the breakpoint where you run it with Effect.runX then.
- noname120 2y agoYeah, and then it won't step you through your code but through unintelligible abstractions and Effect internals. Good luck debugging.
- epolanski 2y agoThat's a typical issue when debugging the JS ecosystem, it's not really an effect problem per se, albeit since Effect comes with a runtime there's way more noise as you noticed. It doesn't help your example has only library code to test.
- johnfn 2y agoIt is actually Effect-specific, because Effect modifies control flow in JS. For instance, if you pipe 3 functions in Effect, you'll have to step through the pipe function to get from the execution of the first to the execution of the next. Working around this adds overhead every time you debug your application. In vanilla JS, `a = foo(); b = bar(a); c = baz(b)` might not be as pretty, but it is trivial to step through.
- galaxyLogic 2y agoPlus if you are able to debug it somehow, and discover the bug in your code, can you fix it right there in your debugger? Or do you need to figure out what is the place in your original unprocessed source-code that corresponds to the code you see in the debugger, and then switch from the debugger to edit the original file and then rebuild and rerun everything and see if that fixes the problem? I wonder if that is a solved problem in plain TypeScript either?
- wetpaws 2y ago[dead]
- ivanjermakov 2y agoThis is why it was hard for me to work on complex functional programming projects: execution flow is not obvious and you can't just debug/print in the middle of the function. Repl is often sufficient, but not in cases where you need to pass some convoluted data as input.
- zarathustreal 2y agoYou’re making two invalid assumptions that break down when dealing with a functional paradigm. 1. You don’t have breakpoints, your code doesn’t run. Your code is the thing that configures the code that runs. Your code is descriptive. 2. Nothing unexpected can happen. That’s the point of pure functions and a strong type system. You don’t need to know the exact values that flow through at runtime to know that your code functions as written. Granted, if you write code that doesn’t make sense then it will produce* results that don’t make sense. If you don’t fully understand the problem you’re trying to solve no programming paradigm can save you from creating bugs.
- noname120 2y agoWell that's the theory. Then the code becomes so complex that the type checker is not able to explore all the ramifications anymore. Or if it does then it takes an exponential amount of time, which is the worst ever. After all I guess you're right that the code won't run, but not for a good reason. Have you ever waited forever for Typescript to finish its typechecking and it eventually just gave up and timed out because it was too complex? Now imagine that the typechecker is the only thing that stands between you and insanity. If there is a bug in the framework (here Effect) then you're in trouble because these layers of abstraction make it an absolute nightmare to figure out that it's not your code but the framework that has a bug — you can't step through your code, and there is only so much that you can encode in types.