Programming for non-programmers

A thread over on the PLT mailing list that LtU-ers may find interesting.

The thread isn't very technical, and the title may be a bit misleading: It's more about programming skills than about programming by non-programmers.

I wonder how many people outside the PL community would agree with the statement that Programming is just another name for the lost art of thinking. Perhaps a better formulation would be Programming, done right, is just another name for the art of thinking.

And by done right I mean using the right languages, of course.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

UML...

i'm stuck in a hotel in a tucson with a stinking cold, partly because i've been on a short course to learn a particular development process using uml. it confirmed my prejudices that these things are (useful) tools for getting people to think clearly - something that seems to be very difficult for many people (i realise i'm not the brightest of the bunch round here, but even i'm amazed by how people can hold so many different, conflicting ideas at the same time until they are forced to draw express them in a way that makes this clear).

one of the things i was wondering about, as i worked through the course and the meetings afterwards, was how oo-specific the approach was. it seems to me that you could use the process we were shown (iconix) for developing codes in functional languages too. the domain and robsutness analysis would be pretty much the same. things only break down when you get to sequence diagrams, really, and that's pretty late in the design.

anyway, i think you'd find several people in the department i work with (including some non-programmers) who'd agree that analysis/high-level design is largely the art of thinking clearly. programming itself probably includes a fair amount of additional rote learning and experience in various annoying practical matters.

programming itself ...

I comment here through my "typical business application" filter.

Once the architect has chosen how we are going to do things, and applying code generation and DSL techniques to these patterns, programming now consists of:

* select from the allowable variations
* compose these (course grained) pieces into applications
* add business rules

I think that this way programming now becomes less annoying and less rote (and more productive).

Programming in the small / Programming in the large

Strange. You guys seem to be focusing on programmng n the large and high level design as "thought" while mere programming is about details. My perspective was exactly the opposite: programming in the small is about expressing algorithmic ideas, and that's where you find jewls of thought. Programming large systems, the kind that are designed with UML etc., is often messy with details.

I guess it's just a matter of perspective, since you can easily argue for both sides, but in my experience elegant sw architecture is even rarer than elegant code.

Programming in the small / Programming in the large

Even in "my world" the "progamming in the small ... algorithmic ideas" still needs to be done. It is now often done as a part of building the code generation patterns and DSL (yet still on occasion in the final stage where business rules can be quite "algorithmic").

(BTW, I am not a great believer in UML. I find DSLs to be "more productive".)

I am not a great believer in

I am not a great believer in UML

neither am i - i think it's the process that's important, and i presume you could find a zillion different ways to force someone to structure their thoughts more clearly.

however, uml does at least motivate the existence of tools that integrate this process with the details of your code (assuming you're using an oo language).

I am not a great believer in

UML serves quite well as a documentation tool, which is what I believe it was created for? It does start to come up short if you try to make it the basis for implementation (IMHO). The wrong abstractions exist.

What Kind of UMLer are you?

There's basically three kinds of UML people: The Sketcher, The Blueprinter, and The Programmer.

The Sketcher usually jots a few design details on a whiteboard or even a napkin. They don't really need all the formal baggage that UML has. If UML didn't exist, they'd probably come up with their own shorthand way of doing it.

The Blueprinter is a lot like The Sketcher, but they get the entire high-level overview of the system done in UML. They often use tools to generate source file stubs from the UML (or generate UML from an existing codebase), so they benifit from a formal definition. I think this is where UML was orginally aimed at. Here again, if UML didn't exist, they'd probably have their own shorthand.

The Programmer actually uses UML as their programming language. The complete system is laid out in maticulous detail, and (in theory) they can use tools to generate the complete source code without any human touching it. Obviously, a formal UML definition is absolutely essential.

A lot of the changes in UML 2.0 are there to serve The Programmers. The Sketchers and (to a somewhat lesser extent) The Blueprinters were fine with what was there already.

A good source on all this is http://www.martinfowler.com/bliki/UmlMode.html.

For the record, I tend to lie somewhere in between a Sketcher and a Blueprinter. I prefer to use UML as documentation. Using it as a programming language seems like potential disaster to me. I would like to see languages that move beyond the classic text file method, but I don't think any attempt thus far has produced solid results.

4th Kind of UML Person: the Saleman

The Salesman is by far the most successful of UML People. He has made millions selling UML books, all with fancy graphic bindings that are colorful and that match nicely when placed side-by-side on the programmers' bookshelves. Each year another dozen or so books of this sort, all presumably on UML, are released by a here-unmentioned publisher.

Neither Unified, nor a Model, nor a Language, UML nontheless continues to gain the fascination of programming bookbuyers. One wonders what the thought process of the typical Buyer is like: "Hmm! This looks interesting. Perhaps if I buy this nicely-bound text it will fill in the gaps in my knowledge of UML and I will save my corporate IT division from outsourcing."

The Salesman knows this is false and that UML is not a language at all, but is a marketing ploy, but he sells anyway. We've all got to make a living, after all, and Salesmen are not noted for their upstanding morals.

UML books have sold like hotcakes and the Salesman wants to ride the UML train as far as it will go. The Salesman hasn't seen such a comparably successful book marketing campaign in his career and he hopes this one lasts awhile, at least until he retires.

A point about UML definitions

A point about UML definitions: as I understand it the syntax of UML is specified, it is the semantics that has been left unspecified. Obviously the Programmer needs the second as well as the first.

UML definitions

Class diagrams are OK, but state diagrams are messy. It seems that the syntax is specified with OCL and no tool recognizes all possible diagrams, only subsets.

Hardness and/or Clarity

is the distinction between thinking clearly and thinking hard useful?

programming in the large is emphasises thinking clearly. the mess of details you refer to requires it. i was assuming this is the ability people want to encourage when they say programming should be taught to everyone (see comments in that thread about avoiding details of syntax etc).

programming in the small focuses on a restricted area, with less confusing detail, which allows you to think hard about a very clear, well defined problem. that brings you closer to maths and requires more technical knowledge. i certainly prefer it over programming in the large, but i'm not so sure it's a general skill that the rest of the world should be encouraged to learn.

does that make more sense? i'm not 100% sure that there is a real distinction myself, because in the end both seem to come down to some vague skill related to pattern recognition, at least in what i can see of my own head. but i certainly didn't mean to imply mere anything.

Programming in the small / Programming in the large

I believe programming is indeed based on pattern recognition. I also believe that "small" is composed into an abstraction of "less small" is composed into an abstraction of ... eventually "large".

Thus programming is thinking about the current level of abstraction. You can work up or down the levels of course.

This is why I now focus on DSLs. Putting a level or two of abstraction over C#, Java or whatever. I happen to like using Scheme to do that.

Right

I like the distinction between thinking clearly and thinking hard, but I agree things are more complicated than this dichotomy suggests.

I definitely agree that programming is thinking about the current level of abstraction. That's why I really think working on abstraction skills is so important. You can work up or down the levels of course is an understatemnt. You must be able to do this, and to keep in mind several levels of abstraction.

This is why I now focus on DSLs. Putting a level or two of abstraction over C#, Java or whatever. I happen to like using Scheme to do that.

Now this calls for a demonstration. Please provide more details...

Two turtles at a time

"You can work up or down the levels" of course is an understatemnt. You must be able to do this, and to keep in mind several levels of abstraction.
Agree wholeheartedly. Ideally, one would need to keep in mind no more than two levels of abstraction (meta-Demeter law? :) ). I am not sure this is practicable, though (infamous leak of abstractions).

By the way, unmatching or poorly matching abstractions is what makes UML so unacceptable to me - e.g., classes are glued to state machines as an afterthought, and it shows, getting nowhere close to clear semantics of formal methods.

Another problem in UML (for me) is its ignorance of anything not OOP (with an exception of CBD, which is treated by UML as having "only subtle differences" from OOP). It's amusing that word "functional" is used as meaning either a kind of requirements or "monomorphic style of invocation". Should not UML be called OML, or even COBOL (Class-Oriented Basically Objective Language)?

Levels of abstraction

I think the ability to think at parallel levels of abstraction at once is crucial for programming.

So much in fact that years ago I create a simple jigsaw puzzle that had a picture on both sides. The solver had to look at the pieces and then try to solve the puzzle (without turning the pieces over, or doing so as little as possible) so that both sides were solved simultaneously. The top side could be solved in several ways, but only one also solved the bottom side.

I used it to test people (how long it took them, how good they were). In most cases good solvers were good programmers and vice versa (but this is "research" quality, just anecdotal evidence).

It takes two to be parallel

I think the ability to think at parallel levels of abstraction at once is crucial for programming.

Cannot two levels be parallel? ;-)

I don't get it...

Cannot two levels be parallel?
They can. I am not sure I see your point.

Misunderstanding

Sorry, I jumped to a conclusion that you imply that two levels at a time are not enough.

Ehud wrote: Now this calls fo

Ehud wrote: Now this calls for a demonstration. Please provide more details...

Just a point: the Scheme folk, at least as represented by Olin Shivers, appear to have a slightly different take on DSLs to most people: Olin's SRE (scheme regexp language) is an example of this. According to Olin it is a little language because it makes sense in several different use contexts and does not rely on the semantics of scheme, but I think most people think DSLs mean programming languages with their own interpreter/compiler, which SREs are not.

A Simple Example

This Domain is Outsource Fulfullment - we have warehouses and hard drives (pdfs) of many clients' marketing materials. We define items, receive, put away, take orders (browser, web services,...), print, pick, pack, ship, invoice and report.

Task 1 - in production we look up print orders. We enter search criteria and list the matching print jobs. We pick one (or more) and a) review the detail and/or b) send the job to the printer farm.

Task 2 - in account support we look up a booklet. We enter search criteria and list matching inventory. We pick one (or more) and a) review the structure, b) edit the structure, c) edit the top level attributes...

But wait, there is a pattern here. Once I have decided on the pattern of how to do this, I need only program at a very high level.

An example for task 1:

Build for View PrintLine a ListManage Form with Search and TaskBar. (Annotations on the schema denote data fields, types, foreign key relationships, indexes for search...). The Grid Displays [grid-cols (list "Client_Id" "Order_Id" "Line_Id" "Stock_Number" "Single" "Inserts" "Order_Quantity" "Pages")]. The TaskBar Navigation is to (ShowDetail PrintJob).

Well I hope you get the idea. I actually do this in PLT Scheme. The output is C# that is quite human readable.

I am not sure I understand th

I am not sure I understand the need for program generation here.

Couldn't you jusr write a general purpose table-drivven C# program?

The need?

There are always several ways to solve any problem.

In this case I see several benefits to "compile time" vs. "run time" work. Not least of which is the simplicity of recognizing refactoring opportunities.

Just asking

;-)

Which language would you rather think in?

In my experience, writing this kind of generic code is much easier, and more pleasant, in a language like Scheme. That's really what Scheme excels at. The "more pleasant" part actually translates to a business benefit, in that the result is easier to extend and maintain, too.

I had the experience of developing a fairly general user interface framework in Java, and later implementing roughly the same design in Scheme (although the Scheme version didn't generate Java code). The Java version had me using UML diagrams just to get a high-level view of the code - although the design of the system was not that complex, by the time it was actually all coded in Java, it was quite unwieldy. The Scheme version ended up "feeling" a lot simpler - the high-level code is closer to the design.

No one great language

We are obviously of like mind on Scheme.

And actually I implemented subsets in Common Lisp and Erlang and experimented with Oz and OCaml - all quite doable.

What I miss is all the component support of .NET in a language like Scheme, so I could implement all in one powerful language.

R6RS

Scheme modules (a la PLT), anyone?

Why are computer people so qu

Why are computer people so quick to "mold" people into Good Coders? I have little doubt that the most dangerous people are those who know what's right and expect people to fit into their molds.

Computer people are not good at playing the role of tailor, where they use their voluminous knowledge and experience to help people choose computing environments which suit them well. There are certainly exceptions, of course; Alan Kay seems to advocate tools which facilitate thought rather than mold it, with his discussions of how symbolic, intellectualized thought may not be something to directly strive for as an end.

Tayssir John Gabbour: Why are

Tayssir John Gabbour: Why are computer people so quick to "mold" people into Good Coders? I have little doubt that the most dangerous people are those who know what's right and expect people to fit into their molds.

Oh, this one's easy, at least if you've spent any time in industry.

Whether with or without any kind of formal background in Computer Science—but it's much easier to get there with than without—a reasonably thoughtful working programmer will come to the realization that there are approaches to the craft that tend to result in products whose development and maintenance results in bugs, misfeatures, schedule overruns, cost overruns, etc. and approaches to the craft that minimize the same. Like many people, I loosely refer to programmers who employ the latter as "good programmers," and those who employ the former as "bad programmers." Note that this leaves totally open the question as to whether the "bad programmers" can become "good programmers," either of their own volition as they see what bad practices result in, or by being taught the difference. It also leaves open the question as to what the specific sets of bad practices and good practices are. In the extreme case, one might switch from C++ to Erlang or Haskell or O'Caml or Oz for a given project that would benefit from such a switch; in the far more likely case, you might just promulgate the idea that minimizing member functions that side-effect the object is desirable, as is declaring member functions that don't to be "const." Accumulate enough such principles over time, and you may actually end up reducing defects even though you're still in the horrible position of developing a reliable, highly-available distributed system in C++, perhaps the worst possible tool for the job.

People tend to get too bent out of shape over being told they're "good" or "bad" at what they do. It's only a problem if the point is coupled with the belief that you can't do better. The alternative is not to apply any quality standards to people's work. Unfortunately, that seems to be a popular view in the industry, as elsewhere.

When you say, "Oh, this one's

When you say, "Oh, this one's easy, at least if you've spent any time in industry," that raises a warning flag. I personally think this response I'm writing is quite simple and mechanical, but I wouldn't have told you. ;)

Let's clarify my point. You can come to any issue with preconceptions, and cite evidence that happens to support those preconceptions. We all know this is not good science, and we merely need to listen to Dick Feynman's talk for the reason why.

In the same way, you can "make" someone an incrementally better programmer by teaching them computer "science," but that's just like saying you can stamp out a better slave by giving them five teachers, a couple of whom might be pretty good. Of course there will be incremental results, which you can cite as evidence. That gets us no further in the topic of this article, which is, "Programming, done right, is just another name for the art of thinking."

Please, do not retort that giving someone a better tool is better. This is noncontroversial and uninteresting. We are talking about the art of thinking, not about how well someone can code before her job is offshored. I would rather you directly speak in terms of Alan's talk I pointed out, and how that interacts with the Arctic Fidelity post we're all responding to. Do you find Alan's point flawed, and agree with Arctic Fidelity that a programming language shouldn't be a set of finger paints, but rather something that comes into play after deliberate precise thought?

If you accept that people should be taught how to think, how would you want to do this? Please cite evidence. I don't want to debate this point, but rather learn more.

Both. Programming is both painting and composing.

I do exploratory finger-paint first. How else can I be confident that I understand the problem?

Even when I am convinced I know the correct solution, I compare multiple solution prototypes.

All the prototypes influence the final solution by giving more detail about what is good and bad about the various approaches. Only then do I have enough information for deliberate precise thought.



Programming languages are both tools for thought, and tools for solutions. Programming is the Magic Executable Poetry.

----

Shae Erisson - www.ScannedInAvian.org