Is Simpler Not Better?

I have a question for you programmers out there. When Rick and I build robots we find on the Web, I am often struck with how unnecessarily complicated the programming is. For instance, our most recent project included programming to make an arm move back and forth. This is the code:

Block 1 tells it to move forward indefinitely. Block 2 waits for the motor to rotate a certain amount. Block 3 stops the movement. Block 4 waits .03 seconds. Block 5 gets it moving indefinitely in the opposite direction. Block 6 waits for a certain rotation amount. Block 7 stops the motor.
I replaced that code with these two blocks, each configured to rotate the motor a certain amount in one direction and stop. It worked just fine:

Why do programmers choose such convoluted ways to do something so simple? Am I missing something? Is there a reason such simplification is not desirable?


Brian Davis said…
"Why do programmers choose such a convoluted way to do something simple?"

Ah, there's a good question. To a large extent, especially at this stage, I'm pretty sure much of it is ignorance - making a program that works (often all that folks are trying to do) is the goal, and figuring out good or efficient ways of doing things takes longer, and more effort.

Yes, there are more efficient ways of programming, and most folks working in NXT-G in particular are new to it. So they just haven't figured out the most efficient ways to do it. I often see this in the way MyBlocks are defined as well, or in when parallel threads are used.

Brian "couldn't agree with you more" Davis
Sometimes it's just wanting to get something to work without doing the math... you should have seen the first program for RaSPy, the Rock-Scissors-Paper robot. It was hideous until Brian Davis cleaned it up :)

But the program was created in 15 minutes or less without any real testing and planning...

David Levy said…
"Why do programmers choose such convoluted ways to do something so simple?"

Here is my take on it. Looking at the first programming example that you included, I'd say it is highly unlikely that someone that is NEW to Mindstorms ( NXT-G being their first Mindstorms programming language) would come up with such a solution. However someone that has had prior experience with RCX programming (i.e. the RIS system) may very well have used such a pattern given that the RCX required separate semantics (as well as physical components) to affect a motor's movement while counting its rotations.
I could be wrong because I jumped right into Lejos without doing much with the RIS programming environment, but I'm pretty sure that would have been an adequate solution at the time.

Still, it is unfortunate that someone would use such a pattern in a new language simply because that is how they did it before. Your example reminds me of a similar complaint in the days when object oriented languages started to gain large scale use. I recall people saying things like "You see better C++ code coming from individuals who have just learned to program than from people well versed in C.
Brian Davis said…
Yes, I'd have to second David on this as well. If I try to "copy" my NQC code or other linear, text-based solutions into NXT-G... I end up with awkward, convoluted code. If I can abandon my preconceptions and met NXT-G "on its own terms", my code comes out much more satisfying.

Brian Davis
Eric D. Burdo said…
I agree with Brian on this. I think it's a case of "it works, so leave it". I bet you'll find many of the people writing NXT code are note professional programmers... they are hobbyists.

Nothing against hobby programmers (they write some great stuff). But frequently, they don't have the experience or the thought-patterns ingrained to go back and clean-up the "smelly" code.
David Levy said…
Brian said:
"If I can abandon my preconceptions and met NXT-G "on its own terms..."

I think we are all guilty of this at some level. I recall a prior conversation I had with this group regarding what I saw as the ad nauseam use of my-blocks. This preconception was entirely based on my experience with text based languages. It wasn't until I started to actively program in NXT-G that I realized how crucial they are to the readability of even a moderately complex program. I still don't know if I am using them the correct way although I am certain that they deserve focus.

Interestingly, I'm reviewing one of Matthias' chapters for his upcoming NXT book that recreates Leonardo Da Vinci designs - he quotes Da Vinci at the chapter's opening: "Simplicity is the ultimate sophistication"


Anonymous said…
What is simple? Is the program with the fewest number of blocks simpler? Is it the program that is easiest to read? How should code reuse factor in?

My approach NXT programming is to write MyBlocks to implement all the fundamental behaviours that the robot will posess. Do I need to position an arm accurately? If so I would write a homing block so I can go to a known location and reset my rotation sensor. Do I want to specify durations in degrees, or is a linear distance a better fit? Do the motor rotate in the desired direction? I hide all this stuff in MyBlocks so I don't have to worry about it anymore.

The end result is a lot more software than is probably needed. Especially for small appplications. But sometimes there is a big payback in the future.

This happened with my daughter's FLL team this year. I strongly urged them to "make their programs more interesting" after judging several tedious NXT programs at a FLL qualifying event. They decided to write their own move blocks that took a duration in millimeters. They also wrote steering blocks where the duration was degrees turned by the robot, not the wheels. They modified their robot before going to the state tournament, changing the wheelbase, motor orientation and tire size. They only had to modify their Drive and Steer MyBlocks to make all their mission programs work again.

What is simple?
David Levy said…
"Is the program with the fewest number of blocks simpler?"

I agree with you and also would assert that in many circumstances counting code is not a good metric. Certainly if one were to count the number of blocks in the program that your FLL team created, I would expect them to ignore all the blocks that were encapsulated within MY-BLOCKS. I suppose that one could then contend that your program is well designed given that the high level flow is represented in such a concise manner ( fewer blocks). My response that however would be "Yes it is very concise but the real elegance in this team's program is the extent of reuse that it provides.

I do think that the second example that was provided in the original post is a better design simply because it does the same thing with fewer blocks. However I don't think that the programmer who coded the first example was violating the KISS method ( Keep It Simple Students). I just think that they were relying on a familiar pattern that may now be obsolete given the features of the NXT motor.

AlexD said…
Dean touches on a good point. Once you are solving a big project, a very useful technique is to develop a project-specific language, and then just write the solution in that language. It usually means defining routines (MyBlocks) in terms appropriate for the project, just like Dean's team (and mine) did for the FLL competition: it's a lot easier to tell the robot where to go in mm and degrees, rather than rotations through trial and error. But, one has to increase the program complexity in order to achieve simplicity of solution.

And yeah, there are a few people out there that remember every single comma they put in their code. For the rest of us, some organization is of use.

David Levy said…

So to answer Dean's question of "What is Simple?" -

I believe your statement: "to increase the program complexity in order to achieve simplicity of solution. " fits into those parameters.

Maybe that's what Da Vinci meant when he made that quote. After all, he was probably cutting up cadavers at the time :)
Brian Davis said…
Hmm. I have a slightly different view on this. for instance, it's not uncommon that I have MyBlocks nested 4 or 5 levels deep, for some projects. If I built a "project specific language" for each project, the number of Myblocks (not to mention my memory of exactly how they work) would rapidly start to become a problem. So instead, I actually try for the reverse: general (but small) MyBlocks that can be tuned (usually via passed parameters), for reuse, and almost always end up being subsumed into higher level MyBlocks, etc. The result is a drastic savings in code space, but it does take a lot more thought when "designing" those MyBlocks.

Should "size of code" be THE metric? I'd agree this is not the desired goal. But it is one of the things to consider, and I don't think it should be discounted. For one thing, under NXT-G size of code corresponds rather closely with the amount of time it takes to compile and download, which is a significant part of the development time. Also, it's not at all uncommon that in minimizing the size of the program I'm increasing its speed of execution (why? Because I need to look at it closely to find what is needed and what isn't, which more often than not leads to identifying inconsistancies or inefficiencies I'd missed previously).

Brian "That's Jus-telegant" Davis
I haven't been participating, but enjoying the back-and-forth discussion... but I want to add something that I learned in my early programming courses while at University:

During a programming theory class called Data Structures, the instructor proposed that for any basic function (square root, for example), that there could always be many varieties of code to get the job done, but that there was also a "prime solution" that could be considered the most unique and elegant solution and that no further changes or improvements could be made - but then he flips and said that even with code, beauty is always in the eye of the beholder. So is a "prime solution" completely mythical? If one person believes a program is ideal and beautiful, another might find it blocky or too recursive or something else that bothers the eye...

Anonymous said…
I flip back and forth on the "application specific vs generic" design of MyBlocks. As a software engineer I prefer creating generic software components that I can use again and again. But sometimes then NXT-G software model argues against doing this.

Take the Drive and Turn example from my daughter's FLL team. They could have written these to take parameters for converting the duration and setting the motor polarity. But then they would not have gotten the data hiding benefit. A change to wheel size would require changing that parameter in each block.

They could have gotten around this by writing a generic component and hiding the parameter settings inside of a configuration MyBlock; one who's only purpose is to call another MyBlock and set some (or all) of the parameter values. But they didn't think of that one. Maybe next year.

They thought about using variables to solve that problem. They toyed with using wheelbase, tireDiameter and motorPolarity variables. But they (and I) find variables difficult to work with in NXT-G. When you add a MyBlock to your program the GUI should scan it for any variables it uses and add these to list of available variables. Instead you have to manually add variables each time you want to manipulate a variable defined outside the local scope. What a great way to introduce very hard to find errors. And I don't like that there isn't a way to specify a variable's scope. It sure would be handy to have a local static variable.

This is not to say that we don't like generic MyBlocks. My girls used those too. They wrote Abs, Min, Max, Clip, Fraction, ShowNumber and several others. They also nested MyBlocks. Clip for example uses Min and Max. The duration conversion routines in Drive and Turn used Fraction. They saw the benefit to this approach and they also saw its pitfalls. And they understood the issues well enough to defend their design philosophy to the programming judges. Not bad for fourth graders.

I love FLL!
Ram said…
"Why do programmers choose such a convoluted way to do something simple?"

Well, I don't think they choose any approach by design. It just happens. Those new to programming just go on writing code to achieve the desired objective / goal. They dont have the concept of refinement or optimization. They are not experienced.

Also they dont go thru the planning phase. No one puts pencil to paper to draw some block diagrams and sketchs. Its all extempore.

This applies, actually, to all categories of new programmers. There is a bit of ego element also which prevents them from revisiting their own code.

Only the utmost desire to excel would drive one to write most efficient, compact, structured, object oriented code (assuming of corse that they are also exposed to some of these concepts ...!!!).

Ram Bhagwat
Anonymous said…
This comment has been removed by a blog administrator.

Popular Posts