For me it comes down mostly to simplicity and comprehension. I don’t want things to be overcomplicated, especially when the compiler can do a lot of the heavy lifting. Writing your own header files? Forget about it.
The editor, too, should be a big part of the coding experience, doing heavy lifting that goes beyond just text editing. Artists don’t (usually) type in the coordinates of all the paths of an Illustrator graphic. The authoring program provides tools to make the creation of those graphics easier. Why should coders?
Now I’m not saying I want blockly, but I think code editors still have room for advancement as far as code organization goes.
First things first. Everything’s dynamic, reflective and every line or block is expression that can resolve to some value. Variables don’t have to be declared; this is done automatically when first defined. Types are inferred.
Syntax and core API. They should be easy to read, even for those with no experience with the language, but not too verbose that makes it feel too wordy or cluttered. It would be a familiar C-style syntax with some possible exceptions like not needing parens for if statements.
if x > y {
doSomething()
}
Operators should be one character where possible (e.g. prefer dots (.) to arrows (->) for member access). Why type more than you have to?
Speaking of arrows, I’m not entirely sure what function syntax would look like, but I think having the keyword function
or func
is redundant. A function block would be defined by {}
, but I’m not sure what separates it from any other code block. Objective C uses a caret (^) prefix, but I’m not sure I like it. Is there enough information for the compiler to know the difference based on usage?
Function blocks are closures, a la Javascript, but you should be able to specify how values are captured. Let’s say this can be done with an at (@).
x = 1
y = 2
myFunc = {
log(@x)
log(y)
}
myFunc() // 1, 2
x = 3
y = 4
myFunc() // 1, 4
Similarly, you should be able to specify context of the block, again we’ll say that an at (@) can be used for that. If not specified, this
is assumed.
myFunc = {
log(this.toString()) // myObj.toString()
}@myObj
Function parameters are optional, defaultable and can be named. Same with return values, with support for multiple values.
Iteration should be consolidated as much as possible. Avoid iterator APIs and run it all through a common syntax which you can code against for custom iteration styles. In other words, if you’re looping, you’re pretty much always going to see something like
for key as value in myObj {
// do stuff
}
// or
for condition {
// do stuff
}
Other kinds of data can be embedded in the code. Long strings, XML, JSON, whatever.
myXML = <foo>
<bar />
</foo>
Without getting into too much of this minutia lets move on to the IDE. The IDE needs to continue to help with simplification and comprehension. A lot of this would be facilitated through code hiding and consolidation into named, expandable macros. Something like what Brackets does:
This can and should be applied to inner functions and lengthy condition statements - anything that could benefit from readability or consolidation. Consider something like the following.
if x > 0 && x < 100 && y > 0 && y < 100 {
// ...
}
This could be consolidated into something like
if withinBounds {
// ...
}
where withinBounds
could be expanded into the condition otherwise hidden by the editor.
Function definitions could behave similarly, especially as far as private methods, or functions that abstract implementation go. This allows high level logic to be more organized and readable.
if hiddenCondition {
hiddenMethod()
}else{
if hiddenCondition2 {
hiddenMethod() // same as first hidden method; hidden is also reusable
}else{
hiddenMethod2()
}
}
When you boil it down, its basically a private function in the source whose definition is hidden away, but when you’re writing your code - condition or reusable block - you don’t have to leave your current context to define it. The editor handles this for you. The idea is to have code consolidation that results in highly readable code (note that “hiddenMethod” etc. aren’t good names for this, you should really have something that describes what is happen… could the editor even be smart enough to recommend naming?). And maybe as far as the source goes, this could all be handled through meta to prevent too much separation of code through abstraction.
The IDE should also be able to visually show object relationships and code flow. Something like integrated UML or flow diagrams. It should be easy to navigate between these relationships. If you’re in an if condition, you should be able to see how you got there, and where its going.
Error handling should be recognizable and missing handles identified. Organization of different error paths should be consolidated and clear, resolving any of that “callback hell” you might see around. The hiding mechanism can help with this, exposing “happy paths” above all others. Not entirely how this would look but the idea is to keep possible outcomes of an action together for better organization and understanding. You should be able to easily tell what happens when, and where it goes when it does.
So readable (and easily writable), organized, navigable code with a high visibility into behavior.