davidad

18-year-old Ph.D. student at MIT,
studying the nature of human cognition through programming language theory;
amateur photographer and musician

permalink

Sense vs. Denotation, Interpreted vs. Compiled, and other false dichotomies

This post is about a deep, yet subtle, philosophical point. It’s being written at 8am by an author who hasn’t slept the previous night, and who admits that his idea is highly underdeveloped, but certainly merits more investigation. In short, it has all the marks of a meaningless crackpot theory that is hardly suitable for public consumption, and threatens the credibility of its author.

But, here I go writing it anyway, for this blog provides at least the illusion of an audience (hi!), and that will motivate me to organize my thoughts, which I believe might very well become my doctoral thesis. Please excuse the imperfect organization of thoughts here - I hardly expect this to be my best essay…

I’ll begin with a simple example, from Frege, to present the tip of the iceberg. Suppose we have an equation a=a. That doesn’t mean very much - without even knowing what a is, we can verify its truth. Now suppose we had an equation a=b. Intuitively, that must say something meaningful about a and b, which may or may not be true, depending on what they are. Yet if a=b, then the equation a=b should be equivalent to a=a - but we already determined that equation is significantly less meaningful. Frege resolves this as follows: “What is intended to be said by a=b seems to be that the signs or names a and b designate the same thing, so that those signs themselves would be under discussion; a relation between them would be asserted. But this relation would hold between the names or signs only in so far as they named or designated something.” In short, there is an important distinction between the name a (called a sense) and the object to which a might refer in a given context (called a denotation).

Here’s a much more concrete example (to me, at least) of a very similar distinction: programming languages can offer a call by name or a call by value feature. If a function is called by name with some argument foo, then the name foo is passed to the function, and it can use this name to locate a certain object in memory, which it can then process in some way. If, instead, the function is called by value with argument foo, the name foo is immediately interpreted, in the context of the calling function, and the resulting object copied to a new location in memory, which is directly passed to the called function.

A slightly less obvious connection to programming language theory can be made as follows. Some programming languages are compiled; others are interpreted. A program written in a compiled language must first be passed to a special program called a compiler, which parses the notation of the programming language into an abstract syntax tree, applies some transformations on it, and finally returns a natively executable machine code object (e.g., an .exe file) which has the behavior specified by the original program (known as the source code). On the other hand, a program written in an interpreted language is parsed into notation and executed at the same time, with a special program called an interpreter directly performing the specified behaviors as soon as it has extracted the relevant syntax. (In many interpreted languages, an error in syntax will go completely unnoticed by the interpreter until such time as the program is asked to perform the function in which the error is contained.) In this case, an interpreted-language program would correspond to the “sense” form, while the compiler would focus on the “denotation” of its compiled-language program.

[Aside: There is a somewhat newer model, followed by Java and the .NET languages, of compiling to an intermediate format, usually called bytecode, which is later interpreted by an interpreter (when the program is run). This way, syntax errors can be caught before the program is shipped, but it also does not need to be recompiled for every platform it needs to be used on (as purely compiled code usually does).]

In linguistics, the words syntax and semantics are often taken to refer to sense and denotation, respectively.

In mathematical logic, rewrite rules and algebraic equations correspond to sense and denotation. Rewrite rules must have a finite dynamics leading to some normal form, such that two expressions are equal iff the repeated application of the rewrite rules on each of them yields identical expressions in the normal form (we apply some syntactic processing to the senses of the expressions, and see if equal senses are derived). On the other hand, algebraic equations work both ways, and by purely random application of algebraic equations to two expressions denoting the same integer, one is unlikely to derive the same single number; yet the algebraic equations have the significant advantage of expressibility and mathematical clarity, since they do not rely on a particular notational standard.

It is now my goal to establish a coherent, cross-disciplinary middle ground between sense and denotation. In a couple rather narrower cases, some way forward is clear.

  • For instance, in compiled vs. interpreted programming languages, there is a natural sense of a partially compiled program, in which any computations that are well-specified to perform without knowledge of the program’s input should be pre-computed at compile-time, and likewise, any optimizations that can be applied given knowledge of the program’s input and target platform should be applied at run-time, thus largely eliminating the distinction between the two phases. This is not fully satisfactory, as there is still a clear distinction between “compiling-like” processes and “interpeting-like” processes; but I suspect it will be possible to blur this distinction significantly in implementation.
  • In a fascinating intersection between philosophy of mind and ontology, Daniel Dennett puts forward a position in his essay Real Patterns that is nicely between “materialism” and “realism” with respect to abstract objects, by making reference to information theory, and Kolmogorov complexity in particular. He claims that the degree to which an abstract object is real is the extent to which its description is a more compact representation of the underlying configuration. This nicely puts to rest, for instance, the classic philosophical question of “whether that table exists.”

That’s about all I have to say right now. In summary, I see a lot of distinctions as being reflections in various ways of the underlying sense-denotation dichotomy:

  1. Dynamic vs. static typing
  2. Interpreted vs. compiled languages
  3. Syntax vs. semantics
  4. Rewriting vs. algebra
  5. Brain vs. mind
  6. Behaviorism vs. functionalism
  7. Micro-states vs. macro-states
  8. Copenhagen vs. many-worlds
  9. Reactive vs. proactive

Furthermore, I don’t see these distinctions as fundamentally necessary. Finally, I believe that resolving all of them at a single stroke would be a truly significant achievement, and I am interested in applying myself to this problem.

If I am committing any apparent fallacies here, or overlooking an obvious resolution, please let me know. Thanks!

blog comments powered by Disqus