Critique Of Intentional Programming

The following is not really a CritiqueOfIntentionalProgramming, but a critique of its hype and its inventor. Not word is said about the technique itself.

Before jumping on to the IntentionalProgramming bandwagon bear in mind the following sobering points:

I.e. we should not buy into the hype, but rather than assuming it's all B.S., we may as well wait and see what they actually deliver, if and when.

My main concern is that it will all be reasonable stuff, but nothing very novel, but nonetheless they'll get 100 patents that all programmers will then have to worry about -- which would be far worse than merely some people buying into empty hype. (This fear came from reading Simonyi's web site at MS, back when he first left, btw)

Yes, mostly vaporware so far for everyone except a few like CapGemini? but if you take a look at the intentional software site there are presentations and a PDF two that provide some fascinating details. Many of the critical comments on this page don't seem to relate to specific aspects of intentional software and so I have to urge the commenters to revisit the site and click on the links to read the information that has been released to far. --JasonLivesay?

As someone who has spent over 30 years writing and maintaining code, I tend to doubt how feasible IP is, at least for existing code. I once ran into a series of 6 instructions, with no labels or branches, that was totally opaque. I eventually had to turn them into algebra, and found that some of the terms cancelled out. That helped a bit ! --PaulMorrison

Regardless of what IP turns out to be, 'we' (the programming collective) are still going to have to 'learn the language of IP' which means, AFAICT, it's just another programming language, albeit with its head a bit higher up in clouds... dare I ask this... what is *going* to be the difference between IP and a 4GL ???

As I see it, IP is really more than one thing: IP is Of these three only the first one could be considered new (the other two points are well known from SmallTalk). So I assume, that the essence of IP lies in the former.

I think that complex software really could benefit from viewing it in different forms. We can see this in the UML-Tools (that cover only some of the more abstract aspects of a program fragment), in GUI editors (which allow you to modify GUI code graphically; see e.g. the Eclipse VisualEditor). I'd really like to edit large data-tables in my code with a spreadsheet or view a datastructure in a debugger as a graph. But obviously such tools require a GUI and as long as we stay with the source as text - which has a lot of advantages (see PowerOfPlainText), we cannot reap the benefits of such an environment. Thats why IP will fail: It has to share its niche with SmallTalk (closed environment) and even if it were better, it is too new.

-- GunnarZarncke

A Little bit of Magic, A Lot of Buzz

This is a CritiqueOfIntentionalProgramming as a feasible approach to programming.

One way to define the ExpressivePower of a language is: the set of programmer intentions that can be 'directly' expressed in the language. In this case, 'direct' expression means that you just say what you want done with no explanation of how to go about doing it. E.g. if you want to execute some operation for each item currently in a container, 'direct' expression of this intent might be: 'foreach item now in container do operation(item)'. Note that you didn't express any intention as to the ordering or parallelization for which these operations are performed. You didn't need to specify the timings, or how to acquire a 'snapshot' of the container to handle the issues of shared access to the container. If, instead, you needed to build a 'for' loop or 'while' loop, grab locks or use a transaction on the container to get a snapshot, etc. - these would force orderings and actions that weren't part of your higher-level 'intent'. You would no longer be programming at the level of abstraction you desire. You would no longer be 'directly' expressing your intent.

In many senses, RealMacros, functions, metaprogramming, and parameter-abstracted procedures can extend a language. They allow you to express intention at a higher level after they are written. However, these cannot increase the ExpressivePower of a language; their use requires that you go about specifying those details that you find irrelevant, thus they do not constitute a 'direct' expression of intent. (That's no reason to knock RealMacros, functions, metaprogramming, and parameter-abstracted procedures, of course. They serve their purpose.) You may question the above conclusion, but consider: the compiler or interpreter of the programming language is incapable of distinguishing those details you (as a programmer) consider to be 'arbitrary but necessary suggestions for strategy' from those parts of the program that describe your 'intent' - the 'goal' fulfilled by said strategy. The compiler or interpreter cannot discern whether the ordering enforced by a 'for' loop is significant to you and your problem domain as opposed to simply being there as an approach to touching every item in a container. As a consequence, the compiler or language interpreter is not free to go about finding its own optimal strategy for performing the desired action because, very simply, it is incapable of distinguishing 'desired action' from the 'arbitrary strategy'.

Anyhow, this means that ExpressivePower, which is direct expression of 'intent', for most languages is limited based upon the keywords, features, and semantics of the kernel of the programming language. Nothing else affects the 'intent' a programmer can directly express. A BrainfuckLanguage program, for example, will only allow you to express 'intent' for cursor movements and cell increment/decrement/input/output. There is no way you could express, in BrainfuckLanguage, the intent to print 'Hello, World!' to the screen. A ForthLanguage program only allows you to express 'intent' for dropping words on a stack and pulling them off a stack via a common set of operations.

As a consequence of this observation, it should be obvious that merely storing code in a database is insufficient to accomplish the goals associated with IntentionalProgramming. Doing so does not allow you to express 'intent' any more effectively explicitly or directly than the kernel language semantics would allow. At best, programming on a graph or in a database allows you to avoid a few syntax and namespace ambiguities. But it doesn't enhance the kernel language. Further, the notion that one (with IntentionalProgramming) might be able to take a program and re-express it in various other languages for the programmer to work with is a pipe dream: even if IntentionalProgramming could translate to an arbitrary language (e.g. Forth), it would never be able to recover the intent of its own 'kernel' language should the programmer edit and upload changes. The problem becomes one of reverse compilation after losing all indicators as to intent. (And while such a system may be able to utilize HotComments to describe said intent, a language with HotComments really isn't the same language).

But not all is lost (yet). Some language features DO allow you to express intent implicitly and explicitly. Two examples are the type system for a language and language-supported assertions. Describing a variable as being of a certain type, for example, explicitly indicates that you want for that variable to possess only a value of the specified type. As such, the compiler or interpreter can know to complain when you do something to violate that expression of intent. Given that types can be inferred, it is also the case that some expressions of intent can be inferred. Of course, a compiler still can't tell whether types express your intent incorrectly (nobody is watching the watchers) but it operates as one indicator and failsafe. But type systems still don't allow a compiler to discern strategy from goals; they should be considered a rather primitive form of 'intent' description.

Language-supported assertions (e.g. for preconditions and postconditions) go a bit further than type systems, and allow expression of some fairly arbitrary intent by way of predicate. E.g. consider:
   assert( screen is valid );
   printf("Hello, World!");
   assert( screen is valid and has "Hello, World!" printed upon it);

Given additional language support, assertions can even allow the compiler to really develop its own strategy. E.g. consider:
   assert( screen is valid );  // also a precondition for 'magic'
   magic; // a new keyword!
   assert( screen is valid and has "Hello, World!" printed upon it ); // also a postcondition for 'magic'

As with types, there is a bit of regression, here: you now must be able to directly express your intent in the form of predicates on the condition one wishes to effect. Writing a predication test to determine that "Hello, World!" has been printed on the screen is not a trivial exercise, and may itself require you go about describing the protocols for communications that ultimately cause a screen to print something (in a sort of ConstraintLogicProgramming). But, of course, writing and expressing one's intent through predicates isn't the real problem. Consider also:
  assert( chessboard constructed and pieces in initial configuration and opponent prepared );
  assert( chessboard in winning configuration for computer );
  shout "I won! I won! muahahahaha!"

The 'real problem', per se, is twofold: (1) implementing 'magic', and (2) solving what is akin to an inverted FrameProblem associated with accomplishing the specified goals (i.e. what else is allowed to be changed?). Implementing 'magic' requires support for some rather advanced artificial intelligence and strategy-planning systems. It is essentially GoalBasedProgramming, which is described briefly as the 'fourth' paradigm in ThereAreExactlyThreeParadigms, and noted as impossible without StrongAi. Solving the inverted FrameProblem is a problem of similar magnitude. Given the above program, for example, the compiler may well decide that the easiest approach is to simply move the opponent's pieces as well as its own directly into a final, winning configuration for the computer before shouting "I won! I won! muahahahaha!".

To make the program work as you intended (but didn't specify explicitly), you need to start specifying what the computer may and (especially) may not do while attempting to reach the desired configuration. This is the inverted FrameProblem when it comes to planning. E.g. for a chess game, you need to describe what the illegal moves are (probably in terms of the legal moves), that the computer cannot move the opponent's pieces, that the computer is not allowed more than one move between opponent's moves, that the computer is not allowed to space the opponent and (<- better make that a logical 'or') sing "Daisy, Daisy", etc. This doesn't mean the computer isn't allowed to taunt the opponent until they cry or use a web-camera to read the opponent's body language and predict future moves, of course - while such strategies are impossible given state-of-the-art, a language fundamentally designed to support direct and explicit expression of intent must not force any particular strategy. Striking a balance between direct and lateral strategy is a very difficult, very non-trivial problem.

Ultimately, 'magic' becomes 'magic(constraints by which computer must abide, heuristics and suggestions for strategy & minimax goals, etc.)' - i.e. a whole bunch of stuff that you didn't really want to explicitly specify.
  assert( chessboard constructed and pieces in initial configuration and opponent prepared );
  magic( constraints: [
           obey tournament chess game rules,
           follow the 3 directives of Isaac Asimov, 
         suggestions: [
           when in doubt, stick with moving pieces around, 
           maybe take out the opponent's queen,
           if losing, consider trying to shake opponent up to weaken his game:
             if opponent human under age 12 then 
               suggest taunting opponent until he cries,
             if opponent human age 12 - 25 then
               suggest talk about baking cakes, 
                       sing 'still alive', 
                       if possible, adjust thermostat to uncomfortably warm for human
             if opponent human over age 30, then 
               suggest singing "Daisy, Daisy" 
                       make opponent believe you're about to space him, 
           planning & conniving systems, etc.]);
  assert( chessboard in winning configuration for computer );
  shout "I won! I won! muahahahaha!"

Now, this little essay isn't intended to be a lesson on languages for logic and goal-based programming. It is, rather, about the futility of IntentionalProgramming. Even if you are given non-existent 'magic' operations and the direct ability to express your goals such that the computer can figure out what you 'intend' and plan a strategy towards accomplishing it, you still cannot go about directly expressing higher-level intents. The inverted FrameProblem forces you to say all sorts of stuff that you would rather not have to go about saying. It may be possible to escape the need for such specification of constraints and strategy if it can be made implicit by context. E.g. 'always' obey Isaac Asimov's rules; 'assume' chess is played by a certain set of rules unless someone says otherwise, etc. - can be made part of some generic behavior database that the compiler can look at when deciding how to do it's magic. One might say that this would be some sort of heuristic, like NearestFittingContext. But doing this essentially requires that the 'compiler' stop being just a compiler, and start being a full StrongAi! I.e. filling in these blanks requires that the compiler itself be an intelligent agent with access to a massive knowledge base and heuristics with which to make 'guesses' as to the programmer's goals. At that point, you might as well start programming in mixed pseudocode and English.

When the need for such StrongAi (given kernel-language support) is combined with the fact that there is nothing special about representing code in a database or any other unambiguous format, it is difficult to regard IntentionalProgramming as much more than a neat little PipeDream. Nothing about IntentionalProgramming escapes the fact that there is ultimately a kernel-language semantics that determines the exact limits of the language's ExpressivePower, and if there is enough ExpressivePower, then the language is such that the implementation is far, FAR beyond state-of-the-art.

IntentionalProgramming will never deliver; it is, much like 'swv' pointed out for ExecutableUml, VaporWare. By the time the necessary artificial intelligence is supported, we won't really need IntentionalProgramming. If something eventually does deliver under the 'IntentionalProgramming' name, it will be but a pale shadow of the original buzz used to describe the benefits of IntentionalProgramming. Nothing short of StrongAi will allow programmers to escape the "inadequate language features" or otherwise support direct and explicit representation of intent.

So don't get your hopes up that IntentionalProgramming will be usefully available within the next five years, the next twenty-five years, or ever.

What might deliver is something closer to LanguageOrientedProgramming, which is one direction in which IntentionalProgramming seems to be headed. LanguageOrientedProgramming is all about creating or extending languages to directly support a particular domain (DomainSpecificLanguages). RealMacros, functions, parameter-abstracted procedures, and metaprogramming are ways such languages might be embedded; and, ultimately, such languages will experience the same limits that were described above. Non-embedded DSLs, however, experience their own set of problems (such as limited support, the need for their own parsers and grammars and semantics which leads to need for special tools for utilizing and refactoring, and requiring specialized knowledge to make of effective use - StumblingBlocksForDomainSpecificLanguages). The LoP movement will probably yield positive results, but it wouldn't quite be 'explicit expression of intent' or fulfill the hype created for IntentionalProgramming.

>> Your argument is irrelevant. The __end__ of intentional programming is about being able to express one's intentions directly. The __means__ is through building abstractions i. e. domain models. IP never claims that one can give it human commands out-of-the-box, it only claims that, as a programming system, it provides linguistic abstraction on graphical steroids. The point is that you can __create__ the language that you want to express your intentions in directly.

I don't believe that ExtensibleProgrammingLanguage really offers IntentionalProgramming - or at least not what the designers of IntentionalProgramming (who do have some right to define what they mean by it) promise when advertising the concept. The ability to play around with syntax and denote semantics within some denotation language mostly offers flexible expression of denotation-language-primitive concepts. I fully support the notion of ExtensibleProgrammingLanguages and the ability to rapidly construct new languages within or atop of older ones that can use the same IDE, syntax highlighter, debugger, programming environment, optimizer, etc. But if a language's syntax and semantics can be extended with the same ease as writing libraries of functions and procedures in modern programming languages, all that means is that one will be developing convenient approaches to expressing intent indirectly through the underlying language primitives. Without that extra ingredient, the GoalBasedProgramming or DeclarativeMetaprogramming or ConstraintImperativeProgramming supported as language primitive, every 'intent' that even can be expressed will be polluted by being forced to carry with it a 'strategy'.

It's the LISP philosophy, but IP decouples presentation of semantics from their storage, and makes the presentation (i.e. syntax) programmable, thus becoming an even more programmable programming language. It's a simple idea: IP = libraries + syntactic sugar on steroids. And as far as goal-based programming is concerned, __of course__ you must logically (for humans, mentally) model a domain before you can reason about it: frame problem = required domain modeling.

You seem to be arguing from the standpoint of intentions being aimed at and processed by a Compiler or Interpreter. You hint a bit otherwise when you say:

At that point, you might as well start programming in mixed pseudocode and English

It would seem to me that IntentionalProgramming (or whatever name you might give to the process) is more about expressing what you want to do in a language and with words, even CompoundWords, which are meant to allow the programmer to investigate and clarify what is meant to be done by 'launching' it in this mixed syntax into a created InformationProcessor (which is built and extended by use, in a manner not unlike the creation of words in Forth) and which would allow discoveries of possible structures and methods ( which might be identified with previously defined Action or Structure Words which are formed from the MixedExpressionOfIntentWords which you have modified by a process of launch and relaunch in this ExtensibleIterativeProcess. When done, i.e. when what you have begins to look like what one might be able to test, code, compile or interpret and execute, the mixed expression then becomes executable in a pre-processor designed for a target language.

Does this look like something possible?

-- ThinkingOutLoud DonaldNoyes 20080129

If you are able to extend the semantics of the kernel language - your set of CompoundWords and their meanings as it were - for every intent you wished to express, IntentionalProgramming might be possible. That requires figuring out exactly what it means to extend the kernel language (one possibility is 'any extension to the whole-program parse-tree processor' - i.e. a whole or partial interpreter). It also requires doing so in a manner that isn't equivalent to enforcing a 'strategy' with which to accomplish the intent (except where the intent == the strategy). This might be possible to accomplish if you choose to 'view' the program doing the interpreting and the program being interpreted as being 'separate' programs, but that is a questionable view when the two must be developed in tandem. Compare it to a program or toolset specific library of procedures and functions: any library API is essentially a language by itself (with the library itself being the language-interpreter). As such, it makes for a very good comparison (for everything but the syntax and grammar extensions, at least).

As far as what I wrote above being aimed at an 'interpreter' - a human reader of any language is also an interpreter of that language, albeit with access to HotComments and the full equivalent of StrongAi already in place. The issues I described above were not specific to the concerns of automated interpretation; even human interpreters can only make a best guess at discerning 'intent' from 'arbitrary strategy to accomplish that intent'. It's worth remembering that the basic claim of IntentionalProgramming is all about direct or explicit representation of intent, such that you don't need to go about expressing strategy to accomplish the intent.



EditText of this page (last edited July 9, 2010) or FindPage with title or text search