Code is Material

‘Code is data’ is a metaphor around which the Lisp communities (and REBOL, and others) have built programming languages. The metaphor is effective in these languages because code is presented and represented as a simple structure which may easily be manipulated and processed as data, or evaluated; this is leveraged for development of macros, fexprs, and DSLs. In context of other languages, e.g. C++ or Java, the ‘code is data’ metaphor is much less effective. Metaphors are useful insofar as they shape our tools, our intuitions, our communities.

‘Code is material’ is a similar metaphor, an alternative to ‘code is data’. I’m not aware of any community that consciously uses the ‘code is material’ metaphor, but it does seem applicable in retrospect to flow-based programming and some visual dataflow languages, and perhaps a few esoteric languages like Snusp. By ‘material’ I mean to invoke the intuitions surrounding physical substances used to build other products – e.g. wood, metal, glass, rope. We have many intuitions surrounding materials:

  • materials are portable and fungible by nature (and often available in bulk)
  • behavior of a material is intrinsic or based on universal physical laws
  • materials can be composed or shaped into new materials (molecules, fabrics, bricks)
  • materials vary widely in quality, robustness, ease of use, etc.
  • we don’t ask whether materials are meaningful, only whether they are useful

Of course, code does have an advantage over physical materials: code can be cheaply and precisely replicated.

‘Code is data’ and ‘code is material’ stand in opposition with respect the presence of an ‘interpreter’. Data is interpreted. It is possible to have multiple interpretations of the same data. Materials aren’t interpreted. The behavior of materials is intrinsic or based on universal laws.

For distributed programming or mobile code systems, I like the idea that my code should have the same behavior everywhere. For reasoning, refactoring, and optimization purposes, I like the ability to transform code in systematic ways while preserving behavior. For modularity and security purposes, I like the possibility of hiding implementation details or information within code and closures. These desiderata are better supported if the behavior of code be universal, independent of interpreter.

I imagine, if we take the ‘code is material’ metaphor far enough, that we would be working with composable bricks or structures of code in a virtual reality or augmented reality programming environment, replicating them as needed. Occasionally we might disassemble and reshape a structure for use in a particular problem (perhaps manipulating embedded literal widgets). There would be very little need for a conventional programming language; programming could be approached more as mechanical tinkering. The resulting code-is-material structures may be given part numbers based on secure hash, or directly shared with friends and communities. Applications would consist of devices or tools, themselves constructed of code, of an appropriate type to be ‘installed’ or ‘equipped’ in the programmer’s environment.

Awelon project is aiming towards such a future. The Awelon Bytecode (ABC) is an excellent foundation for the ‘code is material’ metaphor. Awelon Object (AO) is a Forth-like language, allowing users to define words. But those words do not remain entangled with the environment: every AO word is compiled into a finite and environment-independent sequence of ABC, and thus is easily treated as a named ‘brick’ of material, readily ported to other programming environments.

ABC has many useful properties that make it especially suitable for the ‘code is material’ metaphor:

  1. ABC is highly compositional. Concatenation is sequential composition. Concurrent composition is possible due to the causal commutativity requirement. Composition of conditional behaviors is available because ABC favors sum types instead of closed if/then/else behaviors.
  2. ABC code interacts with its environment locally. Every operator manipulates a local value. ABC lacks the conventional heap, pointers, and remote references. Thus, ABC’s behavior is similar to interactions between physical materials.
  3. ABC has atomic and molecular structure: at the lowest level, there are about forty bytecodes that can be understood as atoms. A small, reusable sequence of bytecodes can be understood as a molecule.
  4. ABC’s molecular structure is very linear, similar to genetic code. It is quite feasible to search for new ABC materials by genetic programming, substituting and mixing reusable ‘genes’ (of appropriate type) in a larger program, which might then construct other objects. We can deeply leverage ABC with biological material metaphors (wood, thatch, etc.).
  5. ABC is streamable, i.e. instead of the common stored program concept. A streamable program cannot jump backwards. ABC cannot jump at all. (Loops are modeled using fixpoint combinators; no jumping required.) This allows ABC to model not just ‘solid’ materials such as bricks, but also unbounded ‘fluid’ materials, such as command streams or user input.

One of the underlying ideas for Awelon project is the ability to extract reusable code – e.g. user macros and tools – from the user input stream. This is a form of programming by example. And the envisioned Awelon project environment is certainly leaning towards the VR/AR system described earlier. I’m happy to have found a simple metaphor to describe almost every idea underlying Awelon project: code is material.

Aside: A related metaphor is that ‘programming languages are materials’, occasionally presented in opposition to ‘programming languages are tools’ [1]. But I feel it isn’t just the language that is the material; it’s also the frameworks, the libraries… the code in general.

This entry was posted in Distributed Programming, Language Design, Modularity, Open Systems Programming, UserInterface. Bookmark the permalink.

17 Responses to Code is Material

  1. John Shutt says:

    This seems to me to be a conceptually very useful metaphor. I wonder, now that you mention it, about a couple of points — where it may now occur, and it’s relationship to “code as data”. “Code as material” seems to me to be the essential motivation behind (many? most?) visual programming languages. It was, I think, also behind the concept of flowcharts (which I’ve never used much myself but gather were immensely useful and are probably one of those things that’s been abandoned mainly because it was hit by friendly fire during a past paradigm shift). I suspect “code as material” should be compatible with any language in which executable entities are essentially stable. In particular, it should be somewhat compatible with “code is data”, if one wanted to entertain both metaphors at once — because although “code is data” is the traditional phrase, a more accurate one would be “data is code”. As you say, the interpreter is the key element: it provides a mapping of data to code, which is why data is code. There /is/ usually a complementary mapping from code to data, but it’s trivial: executable objects, such as fexprs, are *first-class objects*, which is to say they are data, but as data they usually have almost no accessible features, and in particular they evaluate to themselves. Indeed, the triviality of the code-to-data mapping is key to Kernel hygiene, and is why Kernel avoids the trivalization of theory described in Wand’s paper “The Theory of Fexprs is Trivial”.

    • dmbarbour says:

      I like your observation that ‘code as material’ is compatible with stable executable entities, though we might add ‘composable’ somewhere. Modern GUI apps are not very good materials, but old command-line apps designed for pipelines weren’t so bad. And I expect agents in a blackboard metaphor could make good materials.

      It is my impression that the phrase “data is code” seems more apt to describe cases like using JavaScript to build the DOM instead of HTML, or procedural generation in video games. I do like this approach in many cases, but it seems very different than your meaning above.

      • John Shutt says:

        Your DOM example surprised me, because it showed me we’ve been thinking of different relationships between the halves of the metaphors. I think your approach (supposing I’m understanding it rightly now) may work better than mine for purposes of comparing the two metaphors.

        So, if I’m now following you, code-as-material means we (the programers) work with code in a form where it has the properties you enumerate, which we dub “material”. Code-as-data means we work with code in a form whose properties are those of “data”. The difference between the two is that data has no intrinsic “meaning”, making the resulting behavior more obviously dependent on the behavior of an interpreter.

        There’s a spectrum here, though. *Source* data, the stuff that can be represented by a text file, has no intrinsic meaning, and indeed this is the very class of data that is subject to Wand’s trivialization of theory. But fexprs are a notable example of “data” that cannot be represented in a text file — the only way to acquire a fexpr object is to evaluate something in a nontrivial environment. Once you’ve done that, you’ve got objects, such as fexprs, that are not source data at all, and this larger class of data is not subject to Wand trivialization. So I would suggest that fexprs — though clearly born from the code-as-data metaphor — are in fact a sort of *material*. The class of “data” includes things that are less material-like, and things that are more material-like; the less material-like something is, the more flexible, or volatile, or unstable, its meaning is (depending on how enthusiastic or unenthusiastic you are about that sort of degree of freedom).

    • dmbarbour says:

      I agree that objects/closures/etc. in some contexts can be considered as decent materials in the runtime. Pure functions, arrows, FRP behaviors and the like in Haskell would also qualify.

      However, I’m assuming some properties of ‘code’ that we would need to address more explicitly in runtime objects. Typically, code is portable (easily serialized) and is trivially fungible (code can be replaced with any behaviorally equivalent representation of itself, including an identical copy). But objects often lack these attributes, e.g. due to entanglement with the environment or aliasing of mutable state.

      • dmbarbour says:

        (addendum) The interpreter is most important for code-as-data vs. code-as-material. But, if we shift away from code to runtime objects, the differences between code and runtime objects are of concern. Code-as-data and code-as-material work in part because, in each case, code already is most of the way there.

      • John Shutt says:

        Ye-es, materials lack the specific entanglement with environment that, say, closures tend to have. Although in my physics speculations latey I’m seriously considering non-local effects (such as, but not limited to, quantum entanglement), so particular instances of materials /might/ sometimes have limited entanglement, though only as an exceptional case. Materials do depend on/interact with their enviornment, just not usually entangling with their /specific environment. But, I note they may interact in a whole bunch of different ways; in the mechanical case one can think right off hand of a variety of fundamental forces, temperature, pressure, torsion, friction (I’ll stop there, but no doubt the list could go on). I suspect one of the reasons visual languages haven’t been runaway successes is that in seeking to exploit the visual medium they oversimplify the interactions.

  2. Karl says:

    I don’t see how materials aren’t interpreted. The behavior of material depends upon it’s environment, and the use values are determined by the people using it. For a program, the interpreter is the environment. I don’t see a fundamental distinction.

    • dmbarbour says:

      Materials can interact with their environment, certainly. If you stick a bar of iron in a pool of salt water, it will rust. If you stick it instead in a pool of acid, it will dissolve. If you stick it in a man, the man will die. But I think these interactions aren’t very analogous to ‘interpretation’ in the sense that code is interpreted. Iron behaves like iron, no matter where you stick it; it’s just that iron has many behaviors.

      We will need to interpret code at some point. We might ask: is there more than one way to interpret it? does the interpretation depend implicitly on ‘versions’ of local libraries and such? are first class objects/closures in the language ‘portable’ like materials? Metaphors aren’t binary things, but they lose utility and effectiveness as we stray.

      • Karl says:

        Iron can be transformed into steel; structure changes over time. Code captures a set of transformations, but is usually limited to that set. More variation can be modeled with more code, or different code, or the same code bound differently. An expanded environment is often necessary for an expanded model.

        On the more/different paths we gain leverage by having code transformers as part of the environment. We gain leverage when we build code with the expectation of alternative bindings (re-interpretation).

        Good code should minimize dependencies, but they always exist. Material is only portable or usable to the extent that you have suitable containers, processing facilities, fuel, etc.

      • dmbarbour says:

        As useful and flexible as code transformers, aspect oriented programming, pattern calculus, etc. might be, I feel they’re a poor fit for the code-as-material metaphor. Those techniques operate upon a representation of code, i.e. the code-as-data. Staged programming is a good fit, though. And code may still depend upon its environment through interactions with it.

        Anyhow, I wouldn’t seek a ‘fundamental’ distinction, but instead a useful one. Code-as-material is useful in part because it requires code have a single, universal interpretation.

  3. John Shutt says:

    Side observation: with my abstraction-theory perspective, I’ve long held that any coherent unit of code modifies the programming language, and thus all programming is language development. So within my conceptual framework, “programming languages are materials” would automatically include libraries, frameworks, etc., implying “code is material”.

  4. ‘Software Engineering Materialism’: (a bit obscure, from 2009). Material is perhaps about three main things:
    * having objective properties (for software, think of sorting being >= O(n log n),
    * being complex or sufficiently interesting,
    * and being usefully applicable.

    But two things particularly about your post: interpretation, and ‘locality’.

    Interpreting still leaves room for intrinsic properties — they are not really opposed. Interpreting does not mean making up anything; you cannot interpret anything into anything. Interpreting is a kind of limited set of operations on something given — operations reacting to something objective. (Wittgenstein-related.).

    The distinctive feature of physical material building blocks might be seen as ‘locality’. Their interactions are limited in a very structured way (mostly by adjacency). But software surrenders too much structure for naming — which has no locality, it allows unlimited complexity of interconnection. And so there is the virtue of tacit, concatenative styles: they turn toward more limited structuring. They seem to have manipulations that are more complexity-constant: adding more code does not increase the *density* of interrelation. (Structured-Programming related — names are like ‘goto’.). (Names still have a very special quality though! …).

    • dmbarbour says:

      Your note on software materialism is interesting and appreciated. From phrases like “designing structures, in the material, for useful ends” and “a ‘grain’ that makes some structures work better”, my impression is that you’re more treating ‘language’ as material. I get the impression of carving wood or rock to create a statue, except you’d be hand-editing and reshaping some existing body of software. In that sense, any software has some sense of materialism, due to our limited ability to reshape it, and language has some sense of materialism because it makes some shapes more difficult to construct than others. However, this concept of software materialism doesn’t seem very strongly aligned with code-as-data vs. code-as-material. The latter metaphors must be supported to some degree by program semantics.

      I do enjoy locality properties, but I don’t really feel it’s intrinsic to tacit concatenative. Programs using names can also have effective locality properties if we constrain our module system a little and eliminate ambient authority. Conversely, some tactic concatenative languages like Forth can have bad locality properties where they permit editing the definition of a word at runtime.

  5. Pingback: Awelon Progress Report VIII | Awelon Blue

  6. Pingback: CODE | the codicalist

  7. Pingback: Hard and soft (code) | the codicalist

  8. Pingback: Out of the Tarpit | Awelon Blue

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s