Pivoted to record and replay. Developers can put assertion + mocking around the replay. We are working on a feature that shows what _value_ each variable contains. Check unlogged.io
Disclaimer : I am the founder
- super intricate algorithms with lots of variables running around
- lots of huge numpy arrays storing the bulk of the data
I find the current debuggers lacking here:
- showing numpy arrays in colours, easily changing color scales, etc. is not easy (you can do your own visualization, but then it's code); explore specific parts of the array in detail; link that to other arrays, etc.
- build watches panels where you can mix analysis and values extracted from code. I can't count the number of time I freeze the execution, export data to R, then do analysis there, then fix the code. It'd be nice to have that integrated in the IDE.
- have watches that record values as execution runs (I guess that's one of the stuff omniscient debugging does)
And while I'm at it:
- why can't I cut paste formulas, pictures, etc. in my code ?? (no Jupyter, you're ok for a nice paper like presentation but not for code with hundreds of thousands of lines)
I'm sure there's a space here where one can provide tools. For example a drop in "record_this(object)" method integrated with the debugger so that I can look at the results, without the need to build a logging structure to do it myself.
Also, I think code should be written so that it can be easily visualized. Nothing else! Code is for humans to read, not machines - that's what compilers are for.
Code instrumentation is usually for code coverage...but for debugging it can be great too.
You can do a very simple form of value tracing with just RR by setting a watchpoint on the memory where the value is stored, and then using the “reverse continue” command to run the program backwards(!). The watchpoint will trigger when the memory changes, when will happen whenever it is “overwritten” by the previous value. This is exactly the point where the value you are tracing was written into memory.
This is not as precise as Pernosco’s value traces, but it is still immensely useful. It makes debugging buffer overruns, use after free, stack or heap corruption, etc, etc extremely easy. Since traditional methods of detecting these types of bugs are a lot more work, you can earn an astounding rate as a contractor fixing people's C++ code using RR or Pernosco.
While I also wish Pernosco were open source, there is at least reason to be glad that it is a managed service rather than something we run on our laptops. I talked to Roc about self–hosting (which is available) once and he mentioned that a trace of an application like Firefox gets turned into a database taking up dozens or hundreds of gigabytes of disk space. The only reason Pernosco can turn them around in just a minute or two is that each trace uploaded is given to it’s own 36–core instance for the conversion. Even if it were open source, we wouldn’t exactly be running it on our laptops at the beach.
My major gripe with jupyter is that it's hard to document classes because a class must be inside one code block and you can't mix in comments block...
(unless I didn't see some obvious thing)
We mortals barely got to see or hear anything about it. I heard one podcast interview of a developer there who said they basically represent the code as an s-expression tree with a bunch of metadata on each node.
I've been researching these kind of things for ages...and this is the first time I find out about this.
Code as a database.
I mean.. the two are tightly related. The type represents the outer bounds of values possible. Types will give you as much utility as you put into them (or as the language allows).
I agree in general, i just think you massively undersell types haha. It's not either or, it's AND. Always AND.
Types also mean that I can describe my program in ways others can understand and trust. I don’t want to pass off potentially broken programs to other people and say don’t worry, the debugging experience is great.
I feel that mathematical types are so far distant from the type system of something like C or C++ that the term foot guns itself somewhat.
I can't take anyone's word anymore that a tool is useless because they don't need it. We as humans need tons of things we pretend that we don't. It's positively pathological.
types describe all possible values. a debugger observes one value.
they're fundamentally different things, and are useful in different ways. sure, sometimes they overlap, but not always.
Great typing, like great documentation or great design, helps with debugging - but that’s not the main goal.
This is only possibly true in the context of languages with poor static typing ecosystems, and even then I don't think I fully agree.
When a type-checker admits a program, it is because it has proved the program to be free from certain classes of errors. The more expressive your type system, the more elaborate and precise your claims about your program's behavior can be. This is fundamentally distinct from providing documentation that tells your users "please don't input values outside this range".
Early type systems (like C's) are woefully incapable of any serious specification. Modern type systems are significantly more expressive, and are therefore significantly more capable than you suggest. Types in the context of these expressive type systems are logical propositions, and the programs we write are their proofs.
Already designed. Called AnimationCPU platform and a new ACPU OS with ACPUL programming language and real-time time travel debugger. But there is not much marketing here, so you can only watch some demos:
[1]https://tomorrowcorporation.com/posts/how-we-make-games-at-t...
I don’t recall the specifics, but I remember someone mentioning it having some impressive debugging capabilities on hn.
- https://news.ycombinator.com/item?id=35100708
- https://news.ycombinator.com/item?id=36905215
- https://news.ycombinator.com/item?id=33725141
For those willing to sift through the comments:
https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
Some of the original Dart designers have developed a new language Toit that is Smalltalk-like: https://toit.io/company/about
Always wondered why we usually stop at adding first-class features at the code. Or go “Oooh” if a language lets you go one step up the chain to eg metaprogramming methods.
The whole chain is where we are working; the whole chain should be the first-class citizen of the language/tool.
Sums it up well!
I thought this too. I'm a huge Ruby fan, and also Clojure and Elixir. In Clojure you have Spec (https://clojure.org/guides/spec) which is pretty powerful if you choose to use it. And in Elixir, you have pattern matching that can take you quite a long distance without need for specifying explicit types. ...
But lately I've been learning Swift, and now I'm in favor of explicit static typing. (You don't have to be explicit always with Swift, but it's not much trouble to be so... and it's necessary sometimes.) And then switching back to Ruby, I find myself wishing for that visible type clarity on function params. Am I dealing with an object and needing to reference properties? Is this a hash and I can access key/value pairs? A developer using some library may have to dig in and read library source to really know what's expected when types are not required or listed in the function signature.
What I would like to see is Elixir style pattern matching with static types. Then you can "duck type" in terms of the shape of the input as long as it conforms to some subset of data+type.
I disagree. Time spent debugging is time wasted. It's a non-repeatable sunk cost. Don't get me wrong, I love debugging - it's like solving a mystery in real-time - but the competitor to existing debuggers is not a better debugger, it's to obviate the need for one.
I have to fully agree with this. At least here in HN, I see all the time comments "language is good, but does not have static typing." As it was THE thing needed.
Of course it helps, but I think is greatly exaggerated.
I think many people code as some of my colleges did Physics in the university: they looked at the data available in the problem description, and searched formulas to plug the data, just looking at the units, where the output unit was the correct for the answer required. In a similar way I see people smashing things at APIs without reading the documentation, using bad naming, having tens of variables in 10 line functions, all because "no problem, if something is wrong, it won't compile!".
I have written tens of thousands of lines of code in dynamic typed languages, and I can count and remember the few times I had a problem related to types. Out of those, only 2 times I had a somewhat difficult time debugging (couple of hours).
"Omniscient debugging" as seen in https://pernos.co/ is the holy grail. Time-travel debugging would also be great.
People are far too obsessed with static type checking. A lot of this time would be better spent invested in live debugging tools.
When I'm editing my code I want to see exactly what _value_ each variable contains, the type really doesn't matter so much. Wallaby.js/Console.ninja is a great example of this.
Good debugging, especially deterministic record/replay is usually complicated by the OS. I often wonder what an OS would look like if designed with debugging as a top priority.