4 ms·
This is old hat, to a point. Names are escaping me but from time to time there've been structure-editing "text editors" that have you work at the correct "synta
by frig 18y ago
This is old hat, to a point. Names are escaping me but from time to time there've been structure-editing "text editors" that have you work at the correct "syntax" layer, instead of the level of raw text.
What I'm thinking of are various "editors" that are not only syntax-aware (like in the syntax highlighting sense) but that literally enforce the program syntax, and make it difficult-to-impossible to input a "bad" program (bad as in syntax, or bas as in correct-syntax-but-wrong-argument-types).
If that's not what you're getting at you can probably ignore this.
Generally these structure editors haven't been that well-received and most die on the vine as academic projects. I wish I remembered the names but "structure editor" should help you find stuff.
Here's the annoyances I remember:
- You're right, if you already have a mostly-correct program in your head a properly-functioning structure editor should help you get it onto the screen a lot faster, and with fewer stupid typo-level errors creeping in. The more the language has stupid boilerplate like html's close-tags, the more keystrokes you look to save.
- But: the trickier thing to get right is how to handle editing existing code.
If you're just writing html-in-lisp in an ordinary text editor, you don't have much to worry about here.
If you're writing html-in-lisp in a structure editor that makes it hard to get into an invalid (meaning: contrary-to-language-grammar) state, even something as simple as re-ordering lines can become a royal pain; this gets even worse the more you do cutesy things like write macros to auto-generate some types of output, or try to be smart about how you parse the program being written.
Here's an example: I define a format-product-row function that takes an item sku, price, thumbnail url, and product name argument and generates some html output (python notation below):
def FormatProductRow(sku, price, thumbnailURL, productName): BLAH
Your super-helpful structure editor sees this definition and memorizes the function name and required arguments.
I then proceed to write a bunch of code that makes use of FormatProductRow, and each time I use that function in my code your helpful structure editor reminds me of the arguments it takes and doesn't let me make mistakes by having the wrong # of arguments (too many or too few).
Now, later, I am like "oh snap I needed to include the marketingOneLiner argument in that function", and I need to go back through all my source and do the following:
(1) change the definition of FormatProductListing to take that argument (and handle it)
(2) go to every place the function is used, and change the # of arguments that are fed in, while making sure to actually pass in an appropriate value in each spot this guy gets used
(3) where necessary, change a lot of the functions that are calling FormatProductListing (so that are actually in possession of an appropriate value to feed into that argument slot), possibly altering their arguments, etc., until everything is done
When I get done with (1) (2) and (3), the program should be expressible in 100% correct syntax (and whatever semantics you're enforcing like type-checking).
Before I get done, the program's in a "broken" syntactic state:
- if I change the occurrences before the definition, then I've got what'll look like a lot of "misuses" to your syntax-checking logic (b/c the remembered definition != the way i'm using it in the new, fixed usages)
- if I change the definition before the occurrences, then I've got what'll look like a lot of mis-uses, b/c the old usages are incorrect according to the new, updated definition
Regardless of the ordering, you have more problems:
- if you "taint" any part of the parse tree that has errors inside it (eg: FormatProductTables is now "bad" b/c it calls "FormatProductRow", which is "bad" while I'm fixing stuff up), then potentially large parts of the program are broken during these edits. Depending on how rigid your structure editor is wrt allowing "bad" states to exist, this could make your program totally useless.
- if you don't do that kind of "tainting", your program's going to be pretty weak in a lot of ways.
The situation above is just one particular example of a general problem you'll encounter if you go this route: how do you tell "good" errors -- ie, the kind of temporarily broken syntax or semantics you'll get while editing code -- from "bad" errors, in your syntax-and-semantics-enforcing logic?
Unfortunately for you, I'm afraid, a simple mode-toggle doesn't work too great, either, and here's why in a nutshell:
- when you're first writing the program and the editor is forcing you to be "correct", everything that you wind up writing is going to turn out correct (just b/c if it was incorrect it'd not have made it through).
- if you hit the "CHECKING OFF" switch, and then do some mucking about, and turn the "CHECKING ON" switch, two things could happen: your code could be correct, or it could have errors. If it's correct, yay! Parse it again and be done with it. If it's not correct, though, you (the editor writer) have the very fun task of trying to smartly parse enough of it to be helpful (and/or to try and reconcile differences between the current and previous versions, re-using as much as you could from the previous version).
The root of the problem(s) above are this:
- many "semantic" edits (like any refactoring) change many different parts of the program; this is mostly independent of whether or not you're looking @ an abstract syntax tree or the raw text, and mostly independent of how structured or not your code style is. If you write a function, any place it gets used is a long-distance-dependency in the a.s.t.
- your structure editor needs to be smart wrt to such multiple-step editing transactions, while retaining enough power to provide actual benefits over a plaintext editor.
- And: not all languages have structures that are well-defined enough to make building a structure editor a tractable undertaking. C++ is far and away the worst offender here: you can approximate the grammar pretty easily, but a "correct" parsing is pretty nontrivial (see here for some details: http://www.nobugs.org/developer/parsingcpp/ http://www.nobugs.org/developer/parsingcpp/ ).
A good design for a structure editor would somehow make sure that that "approximateness" of the grammar didn't handicap you, in the case that what you were trying to do was running into one of the "approximations".
Lastly: I'm not trying to discourage you, just trying to warn you of the challenges people who go down this route tend to encounter. I'd spend some time thinking about the stuff above, but a lot more time thinking about a sensible user interface for working with your editor; any workable solution you come up with is going to benefit immensely more from an intuitive-and-efficient user interface than from getting the parsing-and-enforcement-model 100% correct on day one.
It's football time got to go.
- Hexstream 18y agoI acknowledge the validity of the concerns you're bringing up here. I've just started thinking about this a few months ago and I haven't spent any time trying to actually implement my ideas yet, so there are indeed quite a few issues I haven't explored very deep or indeed not at all. I had thought a bit about the potential rigidity tradeoffs of correctness VS usability. I hadn't really thought about going so far as enforcing function signatures, though it's the logical next step after enforcing s-expression validity. There are lots of different types of "structure errors" and I think some should be strictly enforced while others shouldn't. In the s-expression case, one example of something that should be enforced strictly is the nesting of parentheses that delimit s-expressions. Fortunately that one is pretty easy. Wereas in a traditional editor you'd do: (| ()| (|) as 3 different steps, in a structure editor you'll simply have one operation that will do all this atomically so you go from one correct state to the next. In the function arity case, I think a much more lax enforcement is de rigueur. There will always be some editing tasks that will require less rigid rules but I think we should value correctness by default and then introduce laxity in controlled ways where it makes sense. It's a tradeoff similar to how limiting side-effects by default is a restriction that can make a program more powerful, yet sometimes you really want to have some mutable state. edit: I'd add that my end goal for a structure editor is that it may better assist the user in his editing tasks by having a better understanding of the context. The validity enforcement is only a means to facilitate this and should be relaxed wherever it impedes the user rather than helping.
- frig 18y agoI'm pretty sure "a text editor that bitches at you and won't let you type incorrect stuff" isn't the answer and I'm pretty sure "a text editor in which clippy pops up and is like "you seem to have forgotten a parentheses. Can I help you figure out where to put it" isn't the answer, either; if I had an inkling about what a good ui would be I'd tell you or be working on this myself, but I don't have any real insight beyond what I've shared. You might want to start by getting a list together of the various refactorings / simple structure transforms you encounter a lot in eg the lisp you write, and then figuring out what the best keyboard interface would be just for manually inputting a sequence of those transformations.