During the discussion of interfaces last week, Caitilin brought up the idea of implicit interfaces. That is the places where one would need an interface, the IDE can determine what methods a group of objects have in common. This idea seemed both exciting and feasible to the group as it could be useful in contexts other than collision events. For each in __ loops would also benefit from this functionality and having it would hopefully avoid confusion about selecting a type for these loops.
Here is how the creation of a For each in loop looks currently.
In line with text | Fixed position
The changes necessary to make this work with implicit interfaces are mostly straightforward. We essentially take away the item type and get rid of the “new <type>” text before the array. I also thought it made more sense to call the array a collection since in the dialogues, we call it a “Custom Collection”.
Some interesting behavior that needs to be addressed is adding elements to an existing collection. If the loop currently contains invocations of methods that were discovered through the implicit interfaces, then any new element added needs to share that behavior. Here is how editing a custom collection looks now:
Here is a sketch of how it could look with implicit interfaces. Note the new “behavior used” section which will show what methods are called on the objects within the loop. Additionally, the dolphin in the drop down is colored differently (red would make the most sense) and is annotated with what behavior it lacks in terms of what is asked of members of this collection.
There are several routes to go with adding new elements. One would be to only show the options which already have the same behavior and rely on the user to notice this. This puts a little too much burden on the user, and I don’t think it should be used. Another is to display all the options like in the sketch above, but do not allow invalid selections. This would work fairly well in terms of explaining why they can’t select certain objects. The last is to allow them to select invalid objects and explain to them exactly what the issue is. I have this scenario sketched out below. It borrows from the warning provided when you add an argument to a method that is already invoked elsewhere in the program.
The next important problem to address with these interfaces is how to display the available methods to the user. The way things are currently, any variable that is local to a method is added to the dropdown list of available objects when that method’s tab is active. There is no visual indication of this change happening when you switch from tab to tab, so if you did not know the variable was there, you would not be able to see it. One way to draw attention to this would be to select the variable and highlight it after the for each loop is created. Adding an explanatory pop-up would help explain to the user what just happened. Adding the ability to double click on a variable to select it in the left pane would also make it easier to access these variables. That scenario is sketched out below.
One issue with the above design is that I dislike the kind of pop-ups that have “Don’t show this again” when I see them in other programs, so I would feel guilty imposing them on other users. Also, the pop-up feels kind of like a band-aid that tries to make up for a less than intuitive design. Another option would be to put the local variables for a method in the actual tab for the method. This does more to associate the variables with the method they apply to, and allows for easier visual feedback when switching tabs since the local variables will be immediately visible. They could go either above or below the “do in order”. The “below” case is sketched out here:
After reading Kyle’s paper about discoverability, adding the local variables above or below the do in order seems less than ideal. In his study, people struggled to locate the action ordering boxes when they were places above the methods tabs. Additionally, people looked to select objects right around where the Actions and Questions were, which suggests they would not look around the Do In order. One could hope that if the user is creating For Each In loops they are familiar enough with the interface that they would notice the new local variable on the bottom, but I am not confident that would be effective. Here are two more rough ideas of how we could display local vs. global objects. The one on the left would have to tab-like buttons that would switch from global to local objects. This requires the user to understand the difference which may be asking to much.
I need to think more about this discoverability problem. If you have any suggestions or questions on this issue please comment.
Additionally, I need to address a few more edge cases. For instance, when a user adds a parameter or deletes a method from an object when that method is being used in a for each in loop some kind of warning needs to be displayed.