Hacker News new | ask | show | jobs
by vaughan 1047 days ago
Someone needs to design a programming language and an IDE (and possibly a new OS too) with great debugging as the primary goal. Debugger and IDE support is always just thrown on later in every new language these days.

"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.

11 comments

> People are far too obsessed with static type checking. A lot of this time would be better spent invested in live debugging tools.

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.

I agree. Even with excellent debugging, I think types will allow me to need to debug less. This seems ideal, because debugging means things are breaking.

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.

Types have always been a hard sell for me. I honestly never have issues with types being wrong when I write code, and I understand that this is missing the point. The point is that the types define a very concrete interface and we know up front when the interfaces break, and can statically check that the interface is correct everywhere.

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've worked with too many people who insist there's nothing wrong with the way they are coding, while I've had conversations with 4 different people who have gotten tired of having to clean up after them.

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.

Yeah I don’t think that my point was that I don’t need types, but more closer to yours that I’ll never really have an objective way to know if I need types.
it feels like a category error of sorts too.

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.

Types are just human and machine readable documentation - orthogonal to debugging IMO.

Great typing, like great documentation or great design, helps with debugging - but that’s not the main goal.

> Types are just human and machine readable documentation

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.

Type theory has applications far beyond readable documentation. It is the basis for modern science.
If you're trying to simulate a combinatorial explosion of possible states, reigning in the possible values would certainly help with maintaining that illusion.
We started off as a time travel debugger for Java coders and failed to gain any traction. (our hn launch: https://news.ycombinator.com/item?id=31286126)

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

Very cool! Any specific reason you started with Java?
time travel debugger for Java, since we worked in financial domain where Java was predominant. We couldn't debug on remote machines for the lack of access. We had to log a lot and it felt like guesswork. Having a debugger with a back button made a lot of sense. We logged everything by default and reverse mapped it with the code, so that we could reverse-F8.
What about Smalltalk?

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...

SmallTalk was so visionary. Someone needs to do a modern take on it.
The original Dart language designers gave Dart Smalltalk semantics with JavaScript syntax. But Dart’s users rebelled and forced Dart to adopt a more compile-time-type-checked type system.

Some of the original Dart designers have developed a new language Toit that is Smalltalk-like: https://toit.io/company/about

And previously Resilient Smalltalk.

https://news.ycombinator.com/item?id=27353255

There's Pharo, which I understand to be a spiritual successor.

https://pharo.org/features

https://mooc.pharo.org/

There’s Objective-S https://objective.st/Language
Yup. The OS contains the debugger process contains a copy of the debugger contains a copy of the runtime contains a copy of the program state contains a copy of the linked system libraries and such and, somewhere, in some tiny section of the executable behemoth, the code that I wrote to print hello world.

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.

> 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!

pretty neat. But what I need the most right now is a way to visualize information. I work on computer fluid dynamics and there I have:

- 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)

What if Jupyter was ok for code with hundreds of thousands of lines? I suspect it might be.. I think nbdev ameliorates my major gripes with jupyter: it lets you easily maintain a bidirectional jupyter <-> (library as standard python files) mapping, while also giving you the excellent presentational flexibility of Jupyter. Plus a good looking docs site, for free. Since the code is exported as scripts, you can just `pip install -e .` and get all your IDE integration as normal.
I'll look at it.

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)

Could you have special markdown cells that have mixed python code blocks and other inline media that gets converted to stripped python cells? You might be able to write an ipython ‘magic’ for something like that
Charles Simonyi's Intentional Software was doing that back in the days of Windows NT https://www.youtube.com/watch?v=tSnnfUj1XCQ But, they stayed insular and enterprise right up until Microsoft bought them back.

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.

Whoa this is incredible. The things you find on HN!

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.

Good software development implies writing code that is easy to debug, including writing your own tools to debug your own niche-specific code!
Yeah sure but I'd like to sprinkle lots of little codes in many different places, ad hoc. This happens while I'm debugging issues 'cos I have to integrate information from various places. Note also that it's not like trying to figure a clearly visible bug: sometime sI have to wander through literally hundreds of data arrays just to find what's going wrong. Since I do that close to the code (modifying bits here and there to see how it influences things), it'd be nice to have a "data analysis debug context" very close to the code.

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.

I had an idea to trace all usages of values. So you can see the entire history of how a value came to be. All the places it went. All the transformations too.

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.

Indeed, on top of stacktraces it would be great to have 'value traces' (with functional programming I suppose those would be the same). Especially in testing, what's important are the inputs with the system under test.
Pernosco has that!
You should have a look at Tomorrow Corps custom Toolchain[1]. It opened my eyes about how good things could be.

[1]https://tomorrowcorporation.com/posts/how-we-make-games-at-t...

Thanks for sharing, absolutely mad! I now feel like I'm 20 years behind with my current tooling...
That was amazing.
> People are far too obsessed with static type checking.

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've been working on an OS for a few years now that addresses this pretty much directly. Not ready to announce anything but there are certainly a group of people doing OSdev along these lines, myself included.
> Someone needs to design a programming language and an IDE (and possibly a new OS too) with great debugging as the primary goal. Debugger and IDE support is always just thrown on later in every new language these days.

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:

DBG https://vimeo.com/363434798

OS https://vimeo.com/833395245

>> People are far too obsessed with static type checking.

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).

> People are far too obsessed with static type checking. A lot of this time would be better spent invested in live debugging tools.

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.