Hi,
Even though this is intended for learners; a lot of the ideas (and reasons behind them) are applicable for experienced programmers.
Here's a brief summary of the main points from the article:
a) The IDE should show labels when the mouse hovers over various parts of the code; so that a programmer can read brief explanations of keywords, functions, function parameters, etc. This would make it a lot easier for beginners to learn. It would also help experienced programmers understand other people's code. For an example, here's a line of code:
Code: Select all
HTML_rootThread = HTML_THREAD_create(&SCAN_mainThreadOutput, NULL, NULL, "index.txt", THREAD_TYPE_association);
Who can tell me what each of those parameters are? I wrote that line of code yesterday; and by next week I won't remember what those parameters are myself.
Note: A lot of programmers already do write descriptions of parameters, etc. It's just that most languages make it hard/impossible for the IDE to associate the description with the parameter.
b) The IDE should try to explain things in context. Ok, this isn't easy for normal code and only really works for a language/environment designed for learners. That's fine (it's only one thing of many).
c) Fine grained flow control should be tangible. The idea here is fairly simple (making it easy to see the order things are actually executed). This is for everyone that's ever messed up an "if" condition, or forgotten a "break" in a switch statement, or accidentally written an infinite loop. Most IDEs with built in debuggers do this already (e.g. "single step"). The main difference is how well integrated it is into the IDE (e.g. in most cases the debugger is separate thing glued onto the IDE as an afterthought) and the ability to move backward as well as forward.
In general, I don't see any problem in allowing "backward step" where possible (and simply not providing the option if it's not possible); even if "backward step" is limited to the last "n" steps (where "n" depends on how much RAM you've got). For this case, you only have to keep track of the order that lines are executed - e.g. one line number per step.
Note: It's only talking about the control flow within one function, not within the entire program, so it shouldn't be some "millions of lines of code" nightmare.
d) Coarse grained flow control should also be tangible. In this case, you'd only really need to show when functions are being called. For example, you could have a diagram showing which functions call which other functions, and then just highlight the "currently executing" function. The hard part is generating the diagram (but that doesn't sound impossible and there are existing tools that do this already). It'd be easy to allow "backwards" here too (you'd only have to keep track of the order that functions are executed - e.g. one "function identifier" per step). For something massive (e.g. OpenOffice) this would be a nightmare because the diagram would be huge, but I only care about small "agents" (that are about as complex as a class in OOP) and I have no reason to care about huge programs.
e) Data should be shown. This makes perfect sense - we all use educated guesses, and sometimes we get it wrong, and then we use a debugger to actually "see" what we should've been able to see to begin with. Of course when you're writing code you don't want to see all of the data for an entire process all of the time. You'd only really want the data from one function (e.g. input parameters and local variables) when that function is being executed once. Obtaining the data isn't that hard, and recording the last "n" steps of data (where "n" depends on how much memory you can spare) is easy. Displaying the data would also be easy - just display the variable names (and/or structure fields) and their contents (which is either just a boring old integer or a boring old floating point number, or a slightly less trivial address/pointer). The tricky part would be figuring out a nice way to display large arrays (maybe just don't display arrays until/unless the user clicks on it, and then display the array as a grid/table in a separate dialogue box).
f) How data changes over time should be shown. This is the same as above (limited to the data of one function's parameters and local variables, when that function is being executed once); except you'd draw a bar chart or something instead of the current value. You wouldn't even need to show all graphs for all the variables at the same time (maybe when the user hovers their mouse over a variable's current value you'd pop up the "value over time" graph). You also wouldn't necessarily need to display all of a variable's data - you'd display what you can at the time, and (if the function is still running in the background) you'd add more values to it as more data becomes available.
g) Eliminate hidden state. I personally don't agree with this part. The reasoning sounds logical (especially for learners), but it's the opposite of "separation of concerns". Any state that is outside of a class/object/agent should be hidden, and any state outside a method/function's scope should probably be hidden too.
h) Get something the user can react to as soon as possible. This is mostly just auto-completion, except that functions are given default values (e.g. so that you can type 3 letters of a function's name and end up with code that works, rather than a function with missing parameters). I don't think the "default parameters" part is possible in all cases; but I also don't see any reason not to do this for all of the cases where it is possible. The problem here is that existing languages make it hard for programmers to specific default values.
i) Allow the programmer to see all the things they could use. This is what I was planning to do anyway - e.g. a list of keywords, functions, etc. that the user can click on (or drag and drop or something) to add the keyword/function/whatever to their source code. Their demo (where they click on the function name) looks much faster/better than drag and drop. I don't think the demo goes far enough though - I want an "almost typo proof" IDE, where it's impossible to mistype a variable or function name.
j) Start constant, then vary, then add loops. In general writing functions this way makes sense, because it's easier to write code with constants (and see it work), and then add things like variables and loops afterwards. With the assistance of an environment designed for it (default function parameters, buttons to do things like convert constants into variables or surround selected lines with a loop, etc) it looks like it'd be very fast and very easy to use. Again, I don't think the demo goes far enough here either - I want an "almost syntax error proof" IDE, where it's impossible to (for e.g.) forget a curly brace at the end of a loop or end up with the wrong number of brackets in a complex condition; and get a screen full of useless error messages when it's compiled.
Each of these things on their own wouldn't really be that special, and (even with all of these things) for a normal/existing language like C it wouldn't work very well. What I'm thinking of is an IDE that combines all these things with my "agents that communicate via. asynchronous messages" system and a language that is designed for both the IDE and the "agents" system.
Please note that the combination of
i) and
j) make it easy for the IDE to work in tokens rather than text. For example, you might select 4 lines of source code and click the "while" icon, and the IDE would insert the tokens for "while" and "end_while" into your source code and display them according to user preferences (e.g. "terwijl () { }" for Dutch programmers, "wahrend() {}" for German, "alors que () { ... }" for French, "mentre () { ... }" for Italian, and maybe an animation of a mouse on a treadmill for children).
Also, I do want integrated unit tests - I want people to write the code for an "agent" and the unit test for it (and not just the code itself). This means that for
c),
d),
e) and
f) the IDE can use test data (from the unit test) and can show the flow of execution while performing the unit test. Because these "agents" are isolated things, it also means that the IDE could compile an agent and its unit test as a stand-alone program, and instrument that stand-alone program so that it sends any data needed for
c),
d),
e) and
f) back to the IDE when executed. Basically, the IDE doesn't need to care about extracting data from an agent that is running in a full program consisting of many cooperating agents.
Cheers,
Brendan