3 ms·
His idea is that the way to understand a large computer program is by running it, testing it. So he's made (what I understand) a very nice UI for introspection
by ktRolster 11y ago
His idea is that the way to understand a large computer program is by running it, testing it. So he's made (what I understand) a very nice UI for introspection of a running computer program. You can see what is happening while it's running.
Designing a programming language is kind of like a 'rite of passage.' I think most of us have at least thought about how to make languages better.
- akkartik 11y agoHeh, I've already had my programming language rite of passage[1]. Mu was my attempt to not build yet another language. Hence the lack of syntax. Thanks for your kind words! I'm gratified that somebody understood what I'm trying to do in spite of my crappy writing skills. [1] http://akkartik.name/post/wart http://akkartik.name/post/wart
- ktRolster 11y agoI'm glad I got it right :) I like your idea, and I think there's room for improved introspection in debugging. At the same time, I think that if a program can't be understood without being executed, then it's already lost (in terms of readability). Certainly, for example, if you have a threaded program, you need to be able to visually inspect and verify that there will be no deadlocks or race conditions when the program is run, because you won't be able to test every possible condition in a debugger.
- akkartik 11y agoIt might partly be a personality-type thing. I can't imagine visually inspecting and verifying anything if I didn't write it to begin with. I wouldn't know where to begin thinking of possible ways to break it. On the other hand, it seems far more natural for the author to say, "here are the race conditions I considered, these points where a context switch would be maximally inconvenient. And still lo the program works." This way the reader doesn't have to recreate such situations from scratch. He or she just has to verify the provided situations, or notice a scenario that was missed. That seems like an easier ask from someone new to the project. (Mu scenarios can't insert context switches yet, but it's planned.) Perhaps it would help to think of the dichotomy as between the rules and the state space of inputs they handle, rather than between reading and running. Seemingly simple code can often hide surprising subtleties. Why is this line written just like so and not thus? How does everything turn out just right in this one situation? Tests help to record the right questions for the reader to ask.
- ktRolster 11y ago> I can't imagine visually inspecting and verifying anything if I didn't write it to begin with. It's a skill, you need to develop it. You develop it by doing it :) > I wouldn't know where to begin thinking of possible ways to break it. For deadlocks, look at every single lock used. Show that one of the Coffman conditions doesn't apply, and you've proven that there can never be a deadlock. For race conditions, look at every piece of shared memory (or other shared resource). That is where race conditions always occur. For understanding a program, the key is to understand the structure. That is why people put things in subdirectories, to help communicate the structure of the program, and show which things are closely related.
- akkartik 11y agoDo you really look at every single piece of shared memory? When you inherit a large codebase from someone? How do you reconcile that with having to deliver changes in the first weeks? Everywhere I've been, people half-ass these things, with inevitable bugs. I think you're under-estimating the possibility that you're just a better programmer than me :/
- ktRolster 11y ago> Do you really look at every single piece of shared memory? Yes > When you inherit a large codebase from someone? If the codebase has lots of threading errors, then yes, it's the only way. If it's a large program, it can take months to go through and check every piece of shared memory (and removing threads along the way, removing shared stuff); but the alternative could take years. In one case, I moved every single lock/unlock to the top of a file so I could quickly see all the locks and unlocks, and that each lock had a matching unlock, even in error conditions.
- akkartik 11y agoHow did you get into such issues? Were there classes where you got started, or was it all on the job? I think I'm not concerned so much about inheriting a codebase with lots of threading errors. It's more about a codebase that's almost perfectly right, but where I'm scared to change anything because I don't have a big-picture model of the concurrency in my head.. Do you have any code samples I can try to learn from? For example, I'm not sure how you would move lock/unlock pairs to the top of a file from different functions/scopes. Unless you were doing some sort of literate programming as well?
- vmorgulis 11y ago> Wart's infix operators have only one hard-coded precedence rule: operators without whitespace are evaluated before operators with whitespace. > n * n-1 # does what you expect Very good idea!