On 12/31/12 6:36 PM, Marcus G. Daniels wrote:
2. The programmer has a belief or preference that the code is easier to
work with if it isn't abstracted.
It's all right in front of them in the context they want it. Perhaps
they are copying the code from foreign modules they don't maintain and
don't want to.  They don't think in terms of global redundancy and the
cost for the project but just their personal ease of maintenance after
they assimilate the code.  If they have to study any indirect
mechanisms, they become agitated or lose their momentum.

A lot of programmers don't seem to get abstraction (I say this having taught programming at the college level), and that is probably a major reason code has more duplication and lack of conciseness than it should. Nonetheless, a lot of programmers who don't really get abstraction (including ideas like recursion) can still get a lot of useful-to-them stuff done by writing programs within their own comfort zone. My guess is that 80% to 90% or more of people who actually make their living "programming" these days fall into this category of not really being able to deal well with abstraction to any great degree much beyond being able to write a class to represent some problem domain object. So, such developers would not be very comfortable thinking about writing the code to compile those classes etc. -- even if many of them might understand a problem domain very well. These are the people who love Visual Basic. :-) And probably SQL. :-) And they love both of them precisely for all the reason that probably many people on this list may feel very constrained and unhappy when using either of those two -- stuff like abstraction or recursion in the case of SQL is hard to do in them. So, code in such languages in practice tends to stay within the abstraction limits of what such programmers can understand without a lot of effort.

Still, those who do get abstraction eventually realize that every layer of abstraction imposes its own cost -- both on the original developer and any subsequent maintainer. One can hope that new computer languages (whatever?) and new programming tools (like for refactoring) and new cultural habits (unit tests) could reduce those costs, but it does not seem like we are quite there yet -- although there are some signs of progress. Often invention is about tradeoffs, you can have some of this (reduced redundancy) if you give up some of that (the support code being straightforward). True breakthroughs come when someone figures out how to have lots of both (reduced redundancy and the supporting code being straightforward.

Related:
  http://en.wikipedia.org/wiki/Indirection
"A famous aphorism of David Wheeler goes: "All problems in computer science can be solved by another level of indirection";[1] this is often deliberately mis-quoted with "abstraction layer" substituted for "level of indirection". Kevlin Henney's corollary to this is, "...except for the problem of too many layers of indirection.""

My programming these days is a lot less abstract (clever?) than it used to be, and I don't think that is mostly because I am less sharp having programmed for about thirty years (although it is true that I am indeed somewhat less sharp than I used to be). I'm willing to tolerate somewhat more duplication than I used to because I know the price that needs to be paid for introducing abstraction. Abstractions need to be maintained. They may be incomplete. They may leak. They are often harder to debug. They can be implemented badly because a couple examples of something are often not enough to generalize well from. And so on (much of this known from personal experience). So, these days, I tend more towards the programming language equivalent of the "Principle of least privilege", where I would like a computer language where, somewhat like DrScheme, I could specify a "language level" for every section of code to reduce the amount of cleverness allowed in that code. :-) That way, the "Visual Basic" like parts might be 90% of the code, and when I got into sections that did a lot of recursion or implemented parsers or whatever, it would be clear I was in code working at a higher level of abstraction. Considering how you can write VMs in Fortran, maybe that idea would not work in practice, but it is at least a thing to think about. Related:
http://en.wikipedia.org/wiki/Principle_of_least_privilege
http://c2.com/cgi/wiki?PrincipleOfLeastPrivilege

And on top of that, it is quite likely that future maintainers who have more problems with abstractions. So, the code in practice is likely to be less easily maintained by a random programmer. So, I now try to apply cleverness in other directions. For example, I might make tools that may stand outside the system and help with maintaining or understanding it (where even if the tool was not maintained, it would have served its purpose and given a return on time invested). Or I might think harder about achieving clarity about the essence of an issue or problem domain, but still working within the constraints of trying to program things straightforwardly without a new underlying interpreter layer. Smalltalk shined so bright because it had a consistent application of an approachable abstraction (message passing and classes) which made it possible to create great tools to work with it. Lisp, on the other hand, makes creating arbitrary abstractions much easier (including "mini languages") and thus you really never be sure what any small piece of Lisp code really does until you understand the entire system. That can be true in Smalltalk too, but it is much rarer. So, in practice, that moves Lisp closer in practice to the camp of write-only languages like APL and Perl in my opinion (even though people don't have to write Lisp that way, but I'd expect many people whole love Lisp love it precisely because it makes that increased conciseness via macros so easy to do).

While I liked Alan Kay's 1997 OOPSLA talk, I'm not sure that focusing on the book "The art of the meta-object protocol" as he did at the end is really the best way forward, because it bumps into this abstraction problem. There may be something there as far as talking about having good abstractions, and supporting the ability to make good abstractions, but there still seems a huge gulf somewhere between theory and practice. That seems especially true as relates to LISPy languages tending towards write-only when the level of abstraction increases and the numbers of macros proliferates and so on. Related:
http://en.wikipedia.org/wiki/The_Art_of_the_Metaobject_Protocol

As an analogy, Smalltalk-80 succeeded where Smalltalk-72 failed in part because Smalltalk-80 standardized the syntax and calling patterns of how objects talked to each other, rather than leaving things more "flexible". It's a fine line between flexible and flabby sometimes. Also, programmers, even the very best, have limited attention. If they put it into parsing arbitrary mini-languages when they read code, then they are not putting that attention into other areas (like thinking about the problem domain). Manuel De Landa makes an excellent related point here:
http://www.t0.or.at/delanda/meshwork.htm
"Indeed, one must resist the temptation to make hierarchies into villains and meshworks into heroes, not only because, as I said, they are constantly turning into one another, but because in real life we find only mixtures and hybrids, and the properties of these cannot be established through theory alone but demand concrete experimentation. Certain standardizations, say, of electric outlet designs or of data-structures traveling through the Internet, may actually turn out to promote heterogenization at another level, in terms of the appliances that may be designed around the standard outlet, or of the services that a common data-structure may make possible."

So, when Smalltalk-80 standardized to the keyword etc. syntax, it freed up programmer mental capacity for handling more variety at another level. Lisp macros, C macros, Forth "build" commands, and similar things all seem like a great idea for supporting abstraction and domain-specific languages, and can indeed be used by those skilled to make concise notations, but they do that at a cost of maintenance and programmer distraction (as you alluded to when you wrote about loosing momentum). It becomes a judgement call based on expected needs whether the cost is worth paying up-front -- a judgment call that includes the number of future problems to solve in the problem domain and expectations about the type of programmers who will be around to solve them. I feel Smalltalk-80 found a good sweet spot for many problem domains in that sense. Of course, Smalltalk-80 failed to conquer the world (or even most of the tri-state area :-) due to the corporate history of Smalltalk licensing and ParcPlace, PP-Digitalk, etc. sadly whereas languages with communities more with roots in either free licensing like Python or free runtimes like Java stormed ahead.

Here is a related essay I wrote on the follies of domain specific languages (not sure how long that site is going to stay up though, it is no longer in the year of free Amazon EC2 micro instance service and I was just using it mainly to play around with Drupal):
http://twirlip.com/main/?q=on-the-follies-of-crafting-domain-specific-languages
"At a meeting I was at recently, as it was ending a person made a comment on domain specific languages in open source code I had written (originally about fifteen years ago), where my short reply as everyone was leaving was "That was a long time ago...". Here is a longer response to explain what I meant by that, involving four points -- plain text, leveraging interpreted computer languages, using web standards, and the issue that "end users are not programmers". But just as a disclaimer, I think many programs are essentially "domain specific languages" in terms of the set of functions programmers create to solve problems in various domains. So, none of this is to be against doing that; the issue is how we do that effectively. ..."

I had a discussion with someone at OOPSLA 97 about one of the values of Smalltalk, including the keyword syntax, that Smalltalk supported creating mini-languages natively in a sense. So, it is fairly easy to create classes that let you define a datastructure for some domain by using plain easy to read Smalltalk, where you could then easily debug the construction process and you did not have to write any special parser. You can do that to some extent in any language, but the keywork syntax lends itself to more expressiveness and better documentation. Smalltalk does it well enough that even though you could write an even more concise mini-language, it is less often worth it in Smalltalk than in other languages that are less clear. So in that sense, that is a key aspect of Smalltalk as a breakthrough for the redundancy vs. support complexity tradeoff mentioned above -- something that is that widely appreciated.

Some ideas that have recurred in different languages though -- of which JSON is an emergent example looking a lot like what one could do in VisualWorks years ago to define nested data structures at compile time. I guess once something like that becomes a common place abstraction for defining some data, and then that data can be easily parsed, then it reduces the general cognitive burden across the programming community when people use that. Ideally we'd have a widely shared set of standards like that, and perhaps we are seeing them emerge. JavaScript, HTML, and CSS being potentially another set, where now more people get the notion of modifying behavior at runtime, and so that reduces the cost to the community of using those ideas. RDF is another example that is popularizing the notion of working with triples. In that sense, common abstractions used in web programming may be part of new directions for the memetic center of gravity of the programming community as it relates to abstractions that can be used effectively in code that other programmers are going to be likely to have to maintain. It's sad though that it was not something more like Smalltalk the language instead though. Still, bright people are ever at work on that; example, like with a Smalltalk on top of Javascript and HTML:
http://amber-lang.net/

But if one was going to generalize from this to issues about new computing, having better languages and tools for working with multiple levels of abstractions is important. But how that translates into practice is the hard part. I posted some metaphorical comments on that posted to the FONC list a couple years ago, using an analogy to creating the microscope and telescope for computing abstractions: "On inventing the computing microscope/telescope for the dynamic semantic web"
http://www.mail-archive.com/fonc@vpri.org/msg01445.html

Those reprised some of my comments on the original FONC proposal (made in 2007) although were a bit more narrowly focused:
http://mail.python.org/pipermail/edu-sig/2007-March/007822.html

In any case, a manager confronted with this situation can choose to
reward individuals who slow this type of proliferation.  An objective
justification being an increase in the percentage of lines touched by
coverage analysis profiles across test suites, unit tests, etc.

Good points. Although, as above, there are still judgement calls involved. I've found it easier (read, more enjoyable) to maintain code that has multiple cut-and-paste copies of a class with minor variations than code that has poorly thought out and badly named abstractions. I have not yet seen any code analysis tools that tell me whether most variables, functions, and classes/prototypes are well-named for the problem domain. I'd much rather maintain code with three or four or event ten slightly different copies of classes but with well chosen names and well-thought out algorithms than code that has only one of everything but each one has cryptic variables and problematical algorithms.It would be a great to have some tool that would be able to rate code based on that -- well, assuming that code would not also replace all programming jobs because it would probably be an advanced AI. :-) (Although event that might be OK if we had a "basic income" from taxes on the robots and AIs like Marshall Brain talked about in "Manna".)

So, I guess there is some limits defining the shape of these tools of new computing and where they are going if humans are going to continue to be part of the programming loop. And those limits may be imposed at this point more by the relatively-fixed-in-capacity human psychological side than the exponentially increasing computing side.

--Paul Fernhout
http://www.pdfernhout.net/
====
The biggest challenge of the 21st century is the irony of technologies of abundance in the hands of those thinking in terms of scarcity.
_______________________________________________
fonc mailing list
fonc@vpri.org
http://vpri.org/mailman/listinfo/fonc

Reply via email to