Download The art of programmers: an introduction

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

C Sharp syntax wikipedia , lookup

C Sharp (programming language) wikipedia , lookup

Transcript
The art of programmers: an introduction
1. Why study the art of programmers
Information and communication technology (ICT) has practically invaded every aspect of
human life and culture. In life, ultrasound machines watch over us before we are born,
mobile phones and laptops follow us everywhere, and machines such as pacemakers are
with us even in death. Culturally, ICT is revolutionizing communication, collaboration, and
other human practices at work and at home. Children play at their computer for days on
end; the “dot.com”-bubble created and destroyed a new economy; SMS language is
gradually creeping into other linguistic practices; and everybody from US presidential
candidates to religious fanatics communicate and build societies on the internet. ICT has
become part of who we are, and that makes ICT an important area of study in the
humanities.
But, technology itself does not change our culture. It is the men behind the
technological systems who initiate new cultural forms and practices, not the systems
themselves. That makes these men collectively the most disruptive and powerful agents of
cultural change, and studies of ICT and cultural change should therefore scrutinize these
technological systems’ processes of becoming, the men creating them, and these men’s
artistic means and culture.
In ICT, the men behind the technological systems are commonly referred to as
programmers. To study their systems’ processes of becoming and their culture is to study
the art of programmers, and taking this approach can give a glimpse of what goes on behind
the stage of apparent cultural change. From studying the art of programmers we can gain an
understanding of the processes driving ICT, and with this insight we can improve the
practices and ethics of computer systems during development and use.
2. Computer programming as writing
To program computers essentially means to write program texts. These texts greatly
resemble other forms of written communication as alphabetical symbols on an empty slate.
1
But, unlike the ink and paper texts so ingrained in our culture, program texts are embodied
in a new, twinned medium: software and hardware. Program texts live their entire lives as
electronic impulses stored on magnetic tape (software) or as metal fillings etched in silicon
stone (hardware). These new media are foreign to our culture, and so, by the power of
association, computer programming is also regarded as an alien cultural practice.
This introduction aims to break this association and to recast the alien practice of
programming as the familiar practice of writing texts. To reach this goal, a two-part
analysis is performed. First, a computer program and the intertextual relations saturating it
are analyzed. This intertextual analysis illustrates how computer programs literally function
as program texts and how the meaning of program words is reciprocally constructed.
Second, and based on this intertextual analysis, the practice of writing program texts is
analyzed. This analysis shows how computer programmers envisage their program texts as
operating in an intertextual environment and how the conventions of this environment
enable and constrain the programmers’ imaginations.
The analysis in this introduction builds on a simple Prolog program running on a
Prolog interpreter written in Java jTrolog. All example texts can be found at jTrolog’s
homepage (Ørstavik 2008), and interested readers are encouraged to consult jTrolog’s
source code for more details. For details about the Prolog and Java programming languages
see their specification (Gosling 2000; ISO/IEC 1995; Lindholm 1999).
2
3.
An intertextual analysis of a computer program
This intertextual analysis analyzes the relationship between many different program texts.
The analysis revolves around a small Prolog program called “bus.pl” (figure 1) and a
Prolog interpreter written in Java called jTrolog (Ørstavik 2008). As this analysis focus on
the programs presented as text, readers of this analysis are not required to understand the
technical functions of neither bus.pl, jTrolog, Java nor Prolog in detail. The analysis is
performed in the following six steps:
First, a functional description of bus.pl as a computer program is given. This
description explains what bus.pl is likely to do under normal circumstances. The functional
description only presents a superficial reading of the program and serves primarily as an
introduction to the situational context surrounding bus.pl.
Second, two direct links between bus.pl as a program text and another program text
called “BasicLibrary.java” are presented. These two links illustrate how bus.pl interacts
with other programs and how this interaction is mediated through intertextual links. This
step presents a type of intertextual links between program texts: “direct, symbolic links”.
Third, the process of running bus.pl on jTrolog is analyzed. This analysis reveals
how computing machines such as jTrolog literally interprets bus.pl as a program text by
linking symbols and words in some of jTrolog’s program texts with corresponding symbols
and words in bus.pl. This third step presents a second type of intertextual links between
program texts: “direct, literal links”.
Forth, the inner workings of jTrolog are analyzed. Taking an in-depth look at
jTrolog running bus.pl reveals how intertextual links stretch across several layers of texts
and link a many more program texts together indirectly. Grouping many program texts
together creates a large network of indirect links between different program texts spanning
many levels of direct symbolic and literal links. This third type of “indirect, intertextual
links” and the network they make up are instrumental in both giving program words their
semantic potential, while at the same time diluting it.
Fifth, the relationship between real and not-yet-real program texts is discussed.
Computer programs are always written for future use. These future environments room
3
many already written, real programs, but they also anticipate to room not yet written,
imaginary programs. Starting with the bus.pl program, a purely hypothetical webapplication is presented, and a forth type of “imagined, intertextual links” are presented.
Sixth and last, as the number of links that directly and indirectly connect real and
imagined program texts together, grows, the need to establish abstract relationships
between program texts becomes compulsory. Program texts such as bus.pl and jTrolog link
to each other not only through a series of direct links, but also through a set of agreed-upon,
shared, and abstract conventions known as programming languages. Programming
languages establish an abstract intermediary that concrete program texts such as bus.pl and
jTrolog can directly comply with and link to and that indirectly link all program texts
relating to it to each other.
From this analysis, the characteristics of program texts and the intertextual links
permeating them are discussed. This discussion concludes the intertextual analysis and
illustrates how program texts function as both computer programs and texts at one and the
same time.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bus(risvollan, nardo, 8).
bus(nardo, lerchendal, 8).
bus(lerchendal, samf, 8).
bus(samf, dronningen, 8).
bus(dronningen, samf, 5).
bus(samf, berg, 5).
bus(berg, moholt, 5).
bus(moholt, dragvoll, 5).
plan_travel(Arrive, Arrive, Visited, [], Visited).
plan_travel(Depart, Arrive, Visited, [BusLine | RouteN], Route) :bus(Depart, X, BusLine),
not member(X, Visited),
plan_travel(X, Arrive, [X | Visited], RouteN, Route).
Figure 1: A Prolog program called “bus.pl”.
4
3.1 A functional description of bus.pl
As a computer program, bus.pl’s job is to calculate how to travel by bus from one
destination to another. The program works by first listing a set of direct connections
between two bus stops, and these direct connections are then combined into complex travel
plans. This description illustrates where and how this functionality is achieved in the
program text.
On line 1-8 in figure 1, the direct bus connections are formulated as a series of busfacts. Each bus-fact lists three parameters: the point of departure, the point of arrival, and
the bus lines’ number. On line 10-15, two plan_travel-rules describe how several such
direct connections can be joined together to form two lists. The first two parameters of the
plan_travel-rules also function to name the points of departure and arrival; the third
parameter functions as a list specifying previously visited bus stops, mainly for internal
use; and the forth and fifth parameter describes the resulting travel plans as two lists of bus
line numbers and bus stops respectively.
In order to get bus.pl to start running, a query such as “plan_travel(risvollan,
dragvoll, [], X, Y)”
must be passed to the program. First, the program will take this
query and match it with one of its two plan_travel rules. Since this query contains two
separate points of departure and arrival, the plan_travel-rule on line 12 will be invoked.
Then, on line 13, the invoked plan_travel-rule will first try to find a bus-fact that identifies
a direct connection going from “Depart” to an unknown location “X”. Then, on line 14, the
invoked rule will verify that the unknown location “X” is not already part of the travel plan.
The invoked rule accomplishes this by checking that “X” is not a member of the list
“Visited” (this will be described in more detail in chapter 3.2). This check ensures that the
program does not go in endless circles. Lastly, on line 15, the invoked rule then calls itself
recursively to find a route from the unknown location “X” to the specified destination
“Arrive”. This recursive process will continue until one of the following two conditions is
met: One, the unknown location “X” is the same as “Arrive”. This will trigger the
plan_travel-rule on line 10 that effectively halts the program. Upon return, the last two
parameters of the query will describe the resulting travel plans as a list of bus line numbers
5
and a list of bus stops. Two, all possible combinations of bus-facts have been attempted
without finding a route from “Depart” to “Arrive”. The program fails.
Figure 2 below shows the result of running bus.pl with the example query. On line 5
and 6, the two variables “X” and “Y” describe step by step which bus line and which bus
stop that leads from “risvollan” to “dragvoll”. Be aware that the two lists describe the route
in reverse order, from right to left.
1
2
3
5
6
?- plan_travel(risvollan, dragvoll, [], X, Y).
result: plan_travel(risvollan, dragvoll, [], [8, 8, 8, 5, 5, 5],
[dragvoll, moholt, berg, samf, lerchendal, nardo])
X: [8, 8, 8, 5, 5, 5]
Y: [dragvoll, moholt, berg, samf, lerchendal, nardo]
Figure 2: The result of running a query with bus.pl.
This functional analysis illustrates what the program does and how it runs under
normal circumstances. A more in-depth, functional analysis can break down these
processes even further and give us deeper insight into the technical concepts within and
underlying it. However, the purpose of this introduction is not to describe technical process.
This introduction aims to illustrate the human processes of programming. So, instead of
analyzing the behavior of the program, this analysis will now shift and focus on the
behavior of the program texts – the program as their human creator sees it.
3.2
An analysis of direct, symbolic links between two program texts
When bus.pl joins several direct bus connections together to form a compound travel plan,
it faces one logical challenge. As Prolog programs only do what they are told, bus.pl needs
to be told how to avoid creating bus routes that go in circles. In fact, allowing such circles
is very likely to cause the program to crash.
As described above, bus.pl avoids circular travel plans by checking that new bus
stops have not already been visited by stating: “not member(X, Visited)”. However, two
6
words, “not” and “member”, are not described elsewhere in bus.pl, and so another resource
besides the bus.pl program text is needed to make sense of these words.
When running bus.pl on jTrolog, this other resource is another program text called
“BasicLibrary.java”. BasicLibrary.java describes both “not” and “member” as two Prolog
rules (figure 3). The “not” rule states that if the parameter passed to not can be called
successfully, no alternative solutions be made available (“!”, the Prolog cut operator), and
the “not”-rule should “fail”. Otherwise the “not”-rule succeeds. The “member”-rule states
that if its second parameter is a list, and that the first element in this list matches the first
parameter, then it succeeds. Otherwise, if the second parameter is a list that contains two or
more elements, it will remove the first element and try again on the rest of the list.
When bus.pl is read together with BasicLibrary.java, the two words “not” and
“member” in bus.pl can be read as references or calls to the corresponding words and rules
described in BasicLibrary.java. These direct, symbolic links between the two texts
implements the functionality on line 14 in bus.pl, and informs our reading of bus.pl. Figure
3 below illustrate the direct, symbolic links connecting bus.pl and BasicLibrary.java.
7
bus.pl
bus(risvollan, nardo, 8).
bus(nardo, lerchendal, 8).
bus(lerchendal, samf, 8).
bus(samf, dronningen, 8).
bus(dronningen, samf, 5).
bus(samf, berg, 5).
bus(berg, moholt, 5).
bus(moholt, dragvoll, 5).
plan_travel(Arrive, Arrive, Visited, [], Visited).
plan_travel(Depart, Arrive, Visited, [BusLine | RouteN], Route) :bus(Depart, X, BusLine),
not member(X, Visited),
plan_travel(X, Arrive, [X | Visited], RouteN, Route).
...
not(G) :- call(G),!,fail.
not(_).
...
member(E,[E|_]).
member(E,[_|L]):- member(E,L).
...
BasicLibrary.java
line 621-2 and 742-3
Figure 3: Direct, symbolic links between bus.pl and BasicLibrary.java. The red,
dotted lines and circles illustrate the words pointing to each other across the two texts.
3.3
A literal1 analysis of a program text
A computer program cannot run on its own. To run, a program must be presented to a
machine that can interpret its program text and convert it into physical or virtual functions.
One such machine is jTrolog. jTrolog runs Prolog programs such as bus.pl and consists of
about 50 program texts written in Java.
When jTrolog runs a program such as bus.pl, it first categorizes each symbol and
word in the bus.pl program text into one of four groups: syntactic markers, names,
numbers, and variables (figure 4). Names, numbers, and variables are content elements
whose textual value is largely preserved, while syntactic markers are essentially converted
1
Literal means according to the letter and non-figurative, to view signs and words at face value only.
8
into structural organization of the other elements and then virtually erased from the text
(figure 5). This process of recognizing and converting text into an alternative representation
native to the machine constitute a literal interpretation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bus(risvollan, nardo, 8).
bus(nardo, lerchendal, 8).
bus(lerchendal, samf, 8).
bus(samf, dronningen, 8).
bus(dronningen, samf, 5).
bus(samf, berg, 5).
bus(berg, moholt, 5).
bus(moholt, dragvoll, 5).
plan_travel(Arrive, Arrive, Visited, [], Visited).
plan_travel(Depart, Arrive, Visited, [BusLine | RouteN], Route) :bus(Depart, X, BusLine),
not member(X, Visited),
plan_travel(X, Arrive, [X | Visited], RouteN, Route).
Figure 4: The program text bus.pl. Syntactic markers are colored grey, variables
green, numbers red, and names black.
However, in order to achieve this literal interpretation, jTrolog must perform a
series of small, concrete steps that kneads and grinds the text of bus.pl into an acceptable
symbolic form. These small, concrete steps are made through a series of explicit, literal
references between symbols and words in bus.pl and corresponding symbols and words in
the jTrolog program texts. In fact, every single symbol, word, and syntactical structure in
bus.pl is explicitly and literally referenced in two jTrolog program texts: Tokenizer.java
and Parser.java.
9
:risvollan
Depart
nardo
bus
Arrive
8
,
travel_plan
Visited
[]
Route
BusLine
RouteN
,
bus
Depart
X
Route
BusLine
not
travel_plan
RouteN
X
Arrive
member
[]
Visited
X
Visited
X
Figure 5: Two illustrations of the transformation of syntactic markers into
structures of other entities. The plan_travel rule on line 12-15 is depicted as a tree, and the
bus fact on line 1 is presented as containers.
Figures 6 and 7 exemplify some of these explicit, literal references between bus.pl,
Tokenizer.java, and Parser.java. In figure 5, some explicit references surrounding the
comma symbol (“,”) are presented. The circles and lines in the figure illustrate how the
commas literally point to each other and link the three texts together. These direct, literal
links are instrumental in turning the text in bus.pl into syntactic structures in jTrolog. The
commas in this example separate predicate parameters as a list of objects (cf. the box-inbox structure and the grey branches in figure 5). In figure 6, some explicit references
surrounding Prolog variables are presented. The figure illustrate how statements such as
“Character.isUpperCase(firstChar)…” and “variableList(indexOf(…” in Tokenizer.java
and Parser.java literally point to Prolog variables such as ”X” and “Visited” in bus.pl.
These direct, literal links are instrumental in turning some words in bus.pl into Var objects,
an internal, symbolic representation in jTrolog (cf. the green circles in figure 5).
10
11
bus.pl
Parser
Figure 6: A model of some intertextual connections between bus.pl, Tokenizer, and Parser that literally describe
commas.
if (t1.isFunctor()) {
line 301-313
String functor = t1.seq;
Token t = tokenizer.readToken();
//reading left par
LinkedList l = new LinkedList();
do {
l.add(expr(Prolog.OP_HIGH, true));
//adding argument
t = tokenizer.readToken();
if (")".equals(t.seq))
//if right par, return
return new Struct(functor, (Term[]) l.toArray(new Term[0]));
} while (",".equals(t.seq));
//if comma, read next arg
throw new InvalidTermException("Error in argument list syntax.\n" +
"Token: " + t + " not expected at line " + tokenizer.lineno() + ".");
}
plan_travel(Depart, Arrive, Visited, [BusLine | RouteN], Route) :bus(Depart, X, BusLine),
not member(X, Visited),
plan_travel(X, Arrive, [X | Visited], RouteN, Route).
plan_travel(Arrive, Arrive, Visited, [], Visited).
bus(risvollan, nardo, 8).
bus(nardo, lerchendal, 8).
bus(lerchendal, samf, 8).
bus(samf, dronningen, 8).
bus(dronningen, samf, 5).
bus(samf, berg, 5).
bus(berg, moholt, 5).
bus(moholt, dragvoll, 5).
if (typea == ',') return new Token(",", Token.OPERATOR);
Tokenizer
line 166
12
bus.pl
Parser
line 293-299
Figure 7: A model of some intertextual connections between bus.pl, Tokenizer, and Parser that literally describe
variable structures.
if (t1.isType(Token.VARIABLE)){
int pos = variableList.indexOf(t1.seq);
if (pos != -1 && t1.seq != Var.ANY)
return new Var(t1.seq, pos+1);
variableList.add(t1.seq);
return new Var(t1.seq, variableList.size());
}
plan_travel(Depart, Arrive, Visited, [BusLine | RouteN], Route) :bus(Depart, X, BusLine),
not member(X, Visited),
plan_travel(X, Arrive, [X | Visited], RouteN, Route).
plan_travel(Arrive, Arrive, Visited, [], Visited).
bus(risvollan, nardo, 8).
bus(nardo, lerchendal, 8).
bus(lerchendal, samf, 8).
bus(samf, dronningen, 8).
bus(dronningen, samf, 5).
bus(samf, berg, 5).
bus(berg, moholt, 5).
bus(moholt, dragvoll, 5).
Tokenizer
line 178-183
// variable, atom or number
if (typea == TT_WORD) {
char firstChar = svala.charAt(0);
// variable
if (Character.isUpperCase(firstChar) || '_' == firstChar)
return new Token(svala, Token.VARIABLE);
These and several other explicit references between the three texts2 form a series of
direct, literal intertextual links. These links fulfill the intent implied in both the bus.pl and
jTrolog program texts to create a virtual body of lexical and syntactic entities between
them. These direct, literal links inform our understanding of the words in bus.pl in parallel
with the direct, symbolic links between texts such as bus.pl and BasicLibrary.java, and all
of these direct intertextual links come together and complement each other to form an ever
larger and richer textual and functional picture.
3.4 Indirect links between program texts
The direct, literal links between bus.pl, Tokenizer.java, and Parser.java presents a simple,
still image of the variables in bus.pl. However, as described in chapter 3.1, variables in
Prolog programs such as bus.pl are not primarily static entities. Prolog variables plays an
active role in running programs, and so reading only a literal interpretation of bus.pl against
the jTrolog program texts only gives us a piece of the puzzle. To learn more about what
variables do, their purpose, and function, we must therefore read between the lines of
different texts in a wider intertextual context.
In figure 7, the variable “Visited” in bus.pl is linked to both Tokenizer and Parser.
First, words starting with an upper-case letter are recognized as a variable “Token” object.
This interpretation is based on statements such as “Character.isUpperCase(…” and “new
Token(…” on line 182-183 in the Tokenizer text. Second, each variable token is added to a
list, and a new “Var” object is created using each variables position in this list. This
interpretation is based on words such as “variableList.indexOf(…” and “new Var(…” on
line 294-298 in the Parser text.
As can be read from this description, the literal interpretation rests of variables in
bus.pl relies heavily on the use of other program words such as “Token”, “isUpperCase”,
“indexOf”, and “Var”. These words constitute a new set of direct, symbolic links to a new
2
Figures 5 and 6 describe only some key intertextual links surrounding commas and variables in the three
texts. Furthermore, as every symbols, words, and structural organizations in bus.pl can explicitly reference
several different statements in Tokenizer and Parser, a large number of intertextual links that make up the
literal interpretation of bus.pl by jTrolog still remain to be presented. However, to describe all these links
together in a figure or text would be extremely complex or tedious. Therefore, this analysis has chosen only to
exemplify the quality of the intertextual links permeating program texts.
13
group of program texts: “Token”, “Character”, “List”, and “Var”. Tokenizer and Parser are
thus part of a larger web of intertextual links, and these other links are instrumental in
shaping the meaning of the links underlying the literal interpretation. Figure 8 below
illustrates a network of indirect links informing our understanding of the variables in bus.pl.
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
text
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
text
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
public final static String ANY = "_".intern();
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
private String name;
public final int nrInStruct;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
public final static String ANY = "_".intern();
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
text
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
text
private String name;
public final int nrInStruct;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
text
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
public interface List<E> extends Collection<E> {
// Query Operations
List
/**
* Returns the number of elements in this list. If this list contains
* more than <tt>Integer.MAX_VALUE</tt> elements, returns
* <tt>Integer.MAX_VALUE</tt>.
*
* @return the number of elements in this list
*/
int size();
package jTrolog.parser;
import java.io.Serializable;
static final int ATOM = 'A';
static final int SQ_SEQUENCE = 'S';
static final int DQ_SEQUENCE = 'D';
static final int OPERATOR = 'O';
static final int FUNCTOR = 'F';
/**
* Returns <tt>true</tt> if this list contains the specified element.
* More formally, returns <tt>true</tt> if and only if this list contains
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
Token
/**
* This class represents a token read by the prolog term tokenizer
*/
class Token implements Serializable {
// token textual representation
String seq;
// token type and attribute
int type;
/**
* Returns <tt>true</tt> if this list contains no elements.
*
* @return <tt>true</tt> if this list contains no elements
*/
boolean isEmpty();
static final int ATOM_OPERATOR = 'B';
static final int ATOM_FUNCTOR = 'a';
Character
public final
class Character extends Object implements java.io.Serializable,
Comparable<Character> {
/**
* The minimum radix available for conversion to and from strings.
* The constant value of this field is the smallest value permitted
* for the radix argument in radix-conversion methods such as the
* <code>digit</code> method, the <code>forDigit</code>
* method, and the <code>toString</code> method of class
* <code>Integer</code>.
*
* @see
java.lang.Character#digit(char, int)
* @see
java.lang.Character#forDigit(int, int)
* @see
java.lang.Integer#toString(int, int)
* @see
java.lang.Integer#valueOf(java.lang.String)
*/
public static final int MIN_RADIX = 2;
Var
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
/**
* The maximum radix available for conversion to and from strings.
* The constant value of this field is the largest value permitted
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
Parser
line 293-299
if (t1.isType(Token.VARIABLE)){
int pos = variableMap.indexOf(t1.seq);
if (pos != -1 && t1.seq != Var.ANY)
return new Var(t1.seq, pos+1);
variableMap.add(t1.seq);
return new Var(t1.seq, variableMap.size());
}
Tokenizer
line 178-183
// variable, atom or number
if (typea == TT_WORD) {
char firstChar = svala.charAt(0);
// variable
if (Character.isUpperCase(firstChar) || '_' == firstChar)
return new Token(svala, Token.VARIABLE);
bus(risvollan, nardo, 8).
bus(nardo, lerchendal, 8).
bus(lerchendal, samf, 8).
bus(samf, dronningen, 8).
bus(dronningen, samf, 5).
bus(samf, berg, 5).
bus(berg, moholt, 5).
bus(moholt, dragvoll, 5).
bus.pl
plan_travel(Arrive, Arrive, Visited, [], Visited).
plan_travel(Depart, Arrive, Visited, [BusLine | RouteN], Route) :bus(Depart, X, BusLine),
not member(X, Visited),
plan_travel(X, Arrive, [X | Visited], RouteN, Route).
Figure 8: A network of intertextual links between bus.pl, Tokenizer, Parser, and
other program texts in jTrolog and Java supporting a functional interpretation of bus.pl.
The “Var.java” program text plays a pivotal role when jTrolog literally interprets
and runs bus.pl. First, the Prolog variables in bus.pl such as “Visited” are set up as “Var”
objects by the Parser as parts of a predicate (see figure 5). The “Var.java” program text thus
functions as an internal representation of the bus.pl variables that is native to the symbolism
14
of the jTrolog program texts. And we must now look at the role of this program text when
jTrolog runs bus.pl.
When jTrolog solves a query, it does so by building a predicate for the query and
then matching this query predicate with the predicates describing the facts and rules of its
running programs. If the query matches a fact or rule predicate that in turn contains
references to other rules, these rules are then converted to sub-queries and attempted
solved. jTrolog stacks these queries one on top of another until they are all resolved. The
program texts in which these operations are described are among other Prolog.java,
Engine.java, ChoicePoint.java, and LibraryTheoryManager.java.
In this process of iteratively and recursively solving queries the “Var” objects play
an important role. To successfully match two predicates, the two predicates must be
identical except for variables. Variables function as wild cards, and when two predicates
are matched during query resolution, variables on both sides are bound to the corresponding
part of the opposite predicate. This process is described in BindingsTable.java and
LinkTable.java. Several other program texts in jTrolog such as Struct.java, Term.java, and
GarbageCan.java, as well as program texts on the Java platform such as HashMap.java,
List.java, and Iterator.java, are also involved in handling Prolog variables such as “Visited”
in bus.pl within the environment described in the jTrolog program texts.
As all of these texts refer in turn to several other texts, the number of texts indirectly
involved in any interpretation of variables in jTrolog grows exponentially. To further
complicate this image, two texts can refer to each other several times in different settings
depending on the state of the running system. Since the list of questions grows for each
answer, often tautologically, a complete, step by step rendering of the intertextual links
informing the concept of Prolog variables in bus.pl and jTrolog thus becomes both
practically and principally impossible. Figure 8 below illustrates a network of indirect,
intertextual links involved in a wider interpretation of “Visited” in bus.pl.
15
package jTrolog.terms;
text
text
package jTrolog.terms;
package jTrolog.terms;
/**
* This class represents a variable term. Variables are identified by a
name
* (which must starts with an upper case letter) or the anonymous ('_')
name.
*
* @see Term
*/
public class Var extends Term {
text
import jTrolog.errors.InvalidTermException;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a
name
* (which must starts with an upper case letter) or the anonymous ('_')
name.
*
* @see Term
*/
public class Var extends Term {
/**
* This class represents a variable term. Variables are identified by a
name
* (which must starts with an upper case letter) or the anonymous ('_')
name.
*
* @see Term
*/
public class Var extends Term {
import jTrolog.errors.InvalidTermException;
text
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
package jTrolog.terms;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
text
ChoicePoint
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a
name
* (which must starts with an upper case letter) or the anonymous ('_')
name.
*
* @see Term
*/
public class Var extends Term {
public interface List<E> extends Collection<E> {
// Query Operations
if (t1.isType(Token.VARIABLE)){
int pos = variableMap.indexOf(t1.seq);
if (pos != -1 && t1.seq != Var.ANY)
return new Var(t1.seq, pos+1);
variableMap.add(t1.seq);
return new Var(t1.seq, variableMap.size());
}
Iterator
/**
* Returns the number of elements in this list. If this list contains
* more than <tt>Integer.MAX_VALUE</tt> elements, returns
* <tt>Integer.MAX_VALUE</tt>.
*
* @return the number of elements in this list
*/
int size();
/**
* Returns <tt>true</tt> if this list contains no elements.
*
* @return <tt>true</tt> if this list contains no elements
*/
boolean isEmpty();
class Engine {
public static final int EVAL = 0;
public static final int RULE = 1;
public static final int BACK = 2;
public static final int TRUE = 3;
public static final int TRUE_ALL = 4;
public static final int FALSE = 5;
Engine
/**
* Returns the number of elements in this list. If this list contains
* more than <tt>Integer.MAX_VALUE</tt> elements, returns
* <tt>Integer.MAX_VALUE</tt>.
*
* @return the number of elements in this list
*/
int size();
text
private Prolog prolog;
BindingsTable bt;
private int stackPos;
private ChoicePoint[] stack;
public static final int STARTUP_STACK_SIZE = 64;
private int initState;
private ChoicePoint query;
private int stackPos;
private ChoicePoint[] stack;
public static final int STARTUP_STACK_SIZE = 64;
private int initState;
private ChoicePoint query;
Engine(Prolog manager, final Struct[] queryBody) throws Throwable {
Engine(Prolog manager, final Struct[] queryBody) throws Throwable {
/**
* Returns <tt>true</tt> if this list contains no elements.
*
* @return <tt>true</tt> if this list contains no elements
*/
boolean isEmpty();
class Engine {
BindingsTable
public static final int EVAL = 0;
public static final int RULE = 1;
public static final int BACK = 2;
public static final int TRUE = 3;
public static final int TRUE_ALL = 4;
public static final int FALSE = 5;
/**
* Returns <tt>true</tt> if this list contains the specified element.
* More formally, returns <tt>true</tt> if and only if this list contains
class Engine {
GarbageCan
public static final int EVAL = 0;
public static final int RULE = 1;
public static final int BACK = 2;
public static final int TRUE = 3;
public static final int TRUE_ALL = 4;
public static final int FALSE = 5;
private Prolog prolog;
BindingsTable bt;
private Prolog prolog;
BindingsTable bt;
private int stackPos;
private ChoicePoint[] stack;
public static final int STARTUP_STACK_SIZE = 64;
private int initState;
private ChoicePoint query;
private int stackPos;
private ChoicePoint[] stack;
public static final int STARTUP_STACK_SIZE = 64;
private int initState;
private ChoicePoint query;
Engine(Prolog manager, final Struct[] queryBody) throws Throwable {
public interface List<E> extends Collection<E> {
// Query Operations
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a
name
* (which must starts with an upper case letter) or the anonymous ('_')
name.
*
* @see Term
*/
public class Var extends Term {
public static final int EVAL = 0;
public static final int RULE = 1;
public static final int BACK = 2;
public static final int TRUE = 3;
public static final int TRUE_ALL = 4;
public static final int FALSE = 5;
private Prolog prolog;
BindingsTable bt;
HashMap
public interface List<E> extends Collection<E> {
// Query Operations
LinkTable
class Engine {
/**
* Returns <tt>true</tt> if this list contains the specified element.
* More formally, returns <tt>true</tt> if and only if this list contains
List
Engine(Prolog manager, final Struct[] queryBody) throws Throwable {
/**
* Returns the number of elements in this list. If this list contains
* more than <tt>Integer.MAX_VALUE</tt> elements, returns
* <tt>Integer.MAX_VALUE</tt>.
*
* @return the number of elements in this list
*/
int size();
/**
* Returns <tt>true</tt> if this list contains no elements.
*
* @return <tt>true</tt> if this list contains no elements
*/
boolean isEmpty();
Var
package jTrolog.terms;
/**
* Returns <tt>true</tt> if this list contains the specified element.
* More formally, returns <tt>true</tt> if and only if this list contains
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
private String name;
public final int nrInStruct;
package jTrolog.parser;
import java.io.Serializable;
Token
static final int ATOM = 'A';
static final int SQ_SEQUENCE = 'S';
static final int DQ_SEQUENCE = 'D';
static final int OPERATOR = 'O';
static final int FUNCTOR = 'F';
static final int ATOM_OPERATOR = 'B';
static final int ATOM_FUNCTOR = 'a';
package jTrolog.terms;
public final static String ANY = "_".intern();
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
/**
* This class represents a token read by the prolog term tokenizer
*/
class Token implements Serializable {
// token textual representation
String seq;
// token type and attribute
int type;
Struct
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
public final static String ANY = "_".intern();
import jTrolog.errors.InvalidTermException;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
public final static String ANY = "_".intern();
text
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a
name
* (which must starts with an upper case letter) or the anonymous ('_')
name.
*
* @see Term
*/
public class Var extends Term {
Parser
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
Term
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
Tokenizer
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
bus(risvollan, nardo, 8).
bus(nardo, lerchendal, 8).
bus(lerchendal, samf, 8).
bus(samf, dronningen, 8).
bus(dronningen, samf, 5).
bus(samf, berg, 5).
bus(berg, moholt, 5).
bus(moholt, dragvoll, 5).
package jTrolog.terms;
text
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a
name
* (which must starts with an upper case letter) or the anonymous ('_')
name.
*
* @see Term
*/
public class Var extends Term {
bus.pl
plan_travel(Arrive, Arrive, Visited, [], Visited).
package jTrolog.terms;
plan_travel(Depart, Arrive, Visited, [BusLine | RouteN], Route) :bus(Depart, X, BusLine),
not member(X, Visited),
plan_travel(X, Arrive, [X | Visited], RouteN, Route).
import jTrolog.errors.InvalidTermException;
text
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
public final static String ANY = "_".intern();
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
private String name;
public final int nrInStruct;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
package jTrolog.terms;
text
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
public final
class Character extends Object implements java.io.Serializable,
Comparable<Character> {
/**
* The minimum radix available for conversion to and from strings.
* The constant value of this field is the smallest value permitted
* for the radix argument in radix-conversion methods such as the
* <code>digit</code> method, the <code>forDigit</code>
* method, and the <code>toString</code> method of class
* <code>Integer</code>.
*
* @see
java.lang.Character#digit(char, int)
* @see
java.lang.Character#forDigit(int, int)
* @see
java.lang.Integer#toString(int, int)
* @see
java.lang.Integer#valueOf(java.lang.String)
*/
public static final int MIN_RADIX = 2;
/**
* The maximum radix available for conversion to and from strings.
* The constant value of this field is the largest value permitted
package jTrolog.terms;
private String name;
public final int nrInStruct;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
if (t1.isType(Token.VARIABLE)){
int pos = variableMap.indexOf(t1.seq);
if (pos != -1 && t1.seq != Var.ANY)
return new Var(t1.seq, pos+1);
variableMap.add(t1.seq);
return new Var(t1.seq, variableMap.size());
}
// variable, atom or number
if (typea == TT_WORD) {
char firstChar = svala.charAt(0);
// variable
if (Character.isUpperCase(firstChar) || '_' == firstChar)
return new Token(svala, Token.VARIABLE);
Character
text
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
private String name;
public final int nrInStruct;
text
import jTrolog.errors.InvalidTermException;
package jTrolog.terms;
/**
* This class represents a variable term. Variables are identified by a
name
* (which must starts with an upper case letter) or the anonymous ('_')
name.
*
* @see Term
*/
public class Var extends Term {
text
import jTrolog.errors.InvalidTermException;
package jTrolog.terms;
text
/**
* This class represents a variable term. Variables are identified by a
name
* (which must starts with an upper case letter) or the anonymous ('_')
name.
*
* @see Term
*/
public class Var extends Term {
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a
name
* (which must starts with an upper case letter) or the anonymous ('_')
name.
*
* @see Term
*/
public class Var extends Term {
Figure 8: The links and semantic spaghetti that surround the Var program text. This
figure illustrates the complexity of indirect, intertextual links connecting program texts.
When several program texts are put together, the direct links between them become
part of a network of links that indirectly connects many more texts together. The function
of a program word cannot be isolated to its direct, intertextual links, but is spread out over
many such indirect links. On the one hand, the indirect links lend each other a semantic
meaning as playing a role in a certain network of texts, while, on the other hand, the need to
interpret words by continuously following yet another indirect link dilutes the semantic
meaning of every word.
3.5 Links between real and imagined program texts
bus.pl was written with the purpose of presenting a simple example of how to use jTrolog.
This example was later fitted to this introduction, and so the actual motive for bus.pl’s
programmer was never to write a real bus-information application. However, this example
16
works better when such a bus-information application is easily imaginable. Reading and
analyzing the program text of bus.pl as if it were to be used by real people wanting a bus
route in Trondheim, makes it easier to understand the functions and technical meaning of
its words. The environments we imagine around programs such as bus.pl are important
tools for our literal and symbolic interpretation of their program texts.
As illustrated in by the example query in chapter 3.1 (figure 2), the imagined
environment of use surrounding bus.pl can be written down. Once formulated, the imagined
query becomes a real text (figure 9), and the imagined, future environment thus includes a
imagined texts. iAll programmers envisage their programs in future use, and so in
anticipation of these future settings, program words are in different ways and in varying
degree composed so as to facilitate other future texts using them. The plan_travel-rules in
bus.pl were for example written so as to simplify the process of formulating future queries.
By making these textual adjustments before the actual query was written, bus.pl linked to
an imagined text.
bus.pl
bus(risvollan, nardo, 8).
bus(nardo, lerchendal, 8).
bus(lerchendal, samf, 8).
bus(samf, dronningen, 8).
bus(dronningen, samf, 5).
bus(samf, berg, 5).
bus(berg, moholt, 5).
bus(moholt, dragvoll, 5).
plan_travel(Arrive, Arrive, Visited, [], Visited).
plan_travel(Depart, Arrive, Visited, [BusLine | RouteN], Route) :bus(Depart, X, BusLine),
not member(X, Visited),
plan_travel(X, Arrive, [X | Visited], RouteN, Route).
example query
plan_travel(risvollan, dragvoll, [], X, Y).
Figure 9: bus.pl and an example query as two texts directly linked together.
All program words in bus.pl can thus be viewed as potential anchors or pointers to
words in other imaginable program texts: The travel_plan-rule can be seen as a resource in
a future web application for Trondheim’s bus service; and the bus-facts can be used by
another Prolog application to list bus lines for individual bus stops. And such imagined
17
links are not restricted to only new situations of use. Words in bus.pl such as “member” can
be imagined linking to a program text part of a different Prolog machine running bus.pl on
a mobile phone.
Some of these imaginable program texts may very concretely be envisaged by the
programmer. Others may appear first long after the program is written. However, regardless
of how specific the foreseen future environment of bus.pl is, it is never final and closed.
New texts may always be imagined surrounding bus.pl, and so the future environment
around bus.pl rooms an infinite number of imagined texts and imaginable intertextual links
between them. Thus, the meaning of bus.pl’s words is never fixed at the time of writing,
but open and rooming evermore imaginable intertextual links. Figure 9 below illustrate
both these real and imagined program texts surrounding bus.pl.
bus.pl
bus(risvollan, nardo, 8).
bus(nardo, lerchendal, 8).
bus(lerchendal, samf, 8).
bus(samf, dronningen, 8).
bus(dronningen, samf, 5).
bus(samf, berg, 5).
bus(berg, moholt, 5).
bus(moholt, dragvoll, 5).
plan_travel(Arrive, Arrive, Visited, [], Visited).
plan_travel(Depart, Arrive, Visited, [BusLine | RouteN], Route) :bus(Depart, X, BusLine),
not member(X, Visited),
plan_travel(X, Arrive, [X | Visited], RouteN, Route).
example query
plan_travel(risvollan, dragvoll, [], X, Y).
imagined Java
web application
imagined Prolog
application
public final
class Character extends Object implements java.io.Serializable, Comparable<Character> {
/**
* The minimum radix available for conversion to and from strings.
* The constant value of this field is the smallest value permitted
* for the radix argument in radix-conversion methods such as the
* <code>digit</code> method, the <code>forDigit</code>
* method, and the <code>toString</code> method of class
* <code>Integer</code>.
*
* @see
java.lang.Character#digit(char, int)
* @see
java.lang.Character#forDigit(int, int)
* @see
java.lang.Integer#toString(int, int)
* @see
java.lang.Integer#valueOf(java.lang.String)
*/
public static final int MIN_RADIX = 2;
bus(risvollan, nardo, 8).
bus(nardo, lerchendal, 8).
bus(lerchendal, samf, 8).
bus(samf, dronningen, 8).
bus(dronningen, samf, 5).
bus(samf, berg, 5).
bus(berg, moholt, 5).
bus(moholt, dragvoll, 5).
plan_travel(Arrive, Arrive, Visited, [], Visited).
plan_travel(Depart, Arrive, Visited, [BusLine | RouteN], Route) :bus(Depart, X, BusLine),
not member(X, Visited),
plan_travel(X, Arrive, [X | Visited], RouteN, Route).
imagined
text
/**
* The maximum radix available for conversion to and from strings.
* The constant value of this field is the largest value permitted
imagined
text
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
package jTrolog.terms;
real text
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
real text
import jTrolog.errors.InvalidTermException;
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
imagined
text
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
package jTrolog.terms;
real text
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term. Variables are identified by a name
* (which must starts with an upper case letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
public final static String ANY = "_".intern();
private String name;
public final int nrInStruct;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
/**
* needed to implement Wrapper Objects. Do not use to stringToStructList ANY Vars
*/
Var() {
type = Term.VAR;
Figure 9: Links between bus.pl and other real and imagined program texts.
18
3.5 Links to concrete and generalized program texts
The last example of relevant program texts informing our figurative concept of the
“Visited” variable in bus.pl and the “Var” objects in jTrolog, that we will look at here, is
the machine responsible for interpreting and running the jTrolog machine. Just as each
symbol and word in the Prolog program text bus.pl is given a literal interpretation and
figurative interpretation by texts in the jTrolog machine, each symbol and word in the Java
program texts that jTrolog is comprised of, is literally and figuratively interpreted by
program texts in a Java machine. The programs responsible for interpreting Java program
texts are called the Java compiler and the Java Virtual Machine (JVM). Several different
versions of the JVM are written for different operating systems, and so the JVM refers to a
generalized description of a design that all these different program texts all comply to. The
different operating systems, such as Windows and Linux, function in turn as machines that
interpret the program texts of different JVM program texts.
When bus.pl functions and creates a new, real travel plan, it does so because jTrolog
functions on a JVM that in turn functions on an operating system, all the way until the most
basic machines of the processor program texts written in cobber, silicone, and electro
mechanics is confronted. Hence, programs resemble layers in an onion: going beneath one
layer of program texts only reveals another layer of program texts, until the program texts
are so small and primitive that there is nothing left. Meaning and function of program texts
cannot be meaningfully deconstructed as atomic entities, but should be understood as
codependent references in different, constantly renewing semantic webs. Figure 10 below
illustrate the many program texts in the different machines that are directly and indirectly
connected to each other.
19
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
package jTrolog.terms;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
package jTrolog.terms;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
bus.pl
jTrolog
JVM
package jTrolog.terms;
import jTrolog.errors.InvalidTermException;
/**
* This class represents a variable term.
Variables are identified by a name
* (which must starts with an upper case
letter) or the anonymous ('_') name.
*
* @see Term
*/
public class Var extends Term {
Windows Processor
Figure 10: Machines of texts like layers in an onion.
These networks show how computer program words derive semantic meaning from
each other as members of a web of texts and intertextual links. Program functionality is
expressed as textual cross references within and between program texts: Series of literal,
intertextual links nested together in long chains of more complex, indirect intertextual
20
references. These intertextual networks can be both particular and generalized intertextual
context, and contain real texts already written as well as imagined texts that might be
written in the future. These networks are principally open, accepting new texts at all levels
that can turn the interpretation of other program texts and their words up side down.
Figurative and metaphorical descriptions of these networks can never be exhaustive;
such descriptions can only scratch the surface and follow only few intertextual links
considered particularly relevant to a particular problem or interpretation and exclude links
to and between texts considered already known or less relevant. In the next section we will
look at how programmers approach these networks and how they imagine and write their
programs. This section will give us an understanding and metaphorical images we can use
to describe the cognitive processes programmers enter into, how they relate to each other to
collaboratively construct the storm of ICT systems invading our lives and culture, and the
role words, texts, and language play in this communicative, writing practice.
3.5 The characteristics of intertextual links in program texts
There are three questions that arise from this literal intertextual analysis. One, do the texts
reference each other concretely or do they allude to each other abstractly? Two, do the texts
reference already written texts, or do they reference texts that might be written in the
future? And, three, do the texts reference each other reciprocally or unilaterally?
A forth question, what is the role of direct vs. indirect intertextual links?
First, when an instance of jTrolog interprets and runs bus.pl, the symbols and words
in the text do literally reference symbols and words in Tokenizer and Parser. There are
therefore literal, intertextual references from bus.pl to Tokenizer and Parser as individual,
concrete texts. However, bus.pl does not exclude other programs from giving their
interpretation of it. On the contrary, bus.pl is written adhering to the Prolog programming
language, and one of the main purposes of the shared textual norms of Prolog is to make
bus.pl interpretable and runnable on more than one individual, concrete Prolog machine. By
choosing to adhere to these norms, bus.pl alludes to other program texts that choose to
conform to these norms. The words and symbols in bus.pl therefore reference both
individual, concrete texts such as Tokenizer and Parser and a “generalized other” of other
21
Prolog machines and other Prolog programs texts that might run it, build on it, and even
misinterpret it.
Second, as a Prolog program, bus.pl can be interpreted by many other Prolog
machines such as SWI or JLog. However, bus.pl can also be interpreted and extended by
programs not yet written. Examples of such programs can be a new and faster Prolog
machine or a new web application for Trondheim’s bus service. The words in bus.pl can
therefore reference individual, concrete program texts such as Tokenizer already written or
a specific web application to be written. Even the “generalized other” has no fixed time and
space boundaries and room both existing and future Prolog machines and other programs.
The intertextual references in bus.pl address other program texts, programmers, and users –
both in the past, present, and future textual settings.3
So far, we have established that program words incorporate both future, generalized
references and concrete, individual references at one and the same time. Using this
perspective to examine the references from bus.pl to the previously written Tokenizer and
Parser, it becomes evident that the references in bus.pl are reciprocated by the two other
texts. As the words and symbols in bus.pl can be seen to reference the previously-written,
individual, and concrete program texts Tokenizer and Parser, the words and symbols in
Tokenizer and Parser can equally be seen as referencing a “generalized other” of existing
and future Prolog program texts. The intertextual links are echoed, anchored, and reflected
by all.4 5 6
3
The program text from Tokenizer and Parser are written in anticipation of program texts such as bus.pl.
Program texts are both written in reference to existing program texts, but also in reference to imagined, future
prolog program texts along which they can run.
4
To avoid a likely misconception, one point needs to be clarified. It is common to perceive these intertextual
references as unilateral, that is, going only one way from the bus.pl and into the Tokenizer and Parser
program texts which in turn only grinds the text up into machine input. But even though for example the
individual, concrete references are more visible than the generalized references going from bus.pl to
Tokenizer and Parser, both anchor-points in both texts include both concrete and abstract references.
Although developed and written against the program texts of jTrolog, the words in bus.pl that links to the
words in jTrolog can also link to other Prolog engines. Similarly, during its development, the words of
Tokenizer and Parser were continuously tested against a test set consisting of several actual, concrete Prolog
programs. Points of reference in neither text are therefore exclusively concrete or abstract, past- or futureoriented, but all points of reference include all these aspects at one and the same time.
5
To view the intertextual relationships between program texts such as bus.pl and jTrolog as reciprocal is a
challenging perspective. If computing machines are written referencing real or imagined applications, then
22
All program words do a little of everything.
4.
An analysis of writing program texts
, and its simplest and most concise description becomes the source code itself
Key in this presentation is how programmers connect their programs. When
programmers write computer programs, they essentially compose their programs as
symphonies of references to and quotes from other program texts. These other texts, real or
imagined, form an environment in which the program lives. However, these texts are
written by many different people, at different times and places, and with different purposes.
To transcend these barriers of difference, programmers develop programming languages
with words and grammars that directly facilitates references to and the arranging of quotes
in program texts. The first two articles of this thesis is based on this description.
Morphology and Power describe in further detail how different programming languages
enable and constrain programmers writing symphonies of program words. Intertextuality
elaborates on how written texts and language in general form intertexts and how
intertextuality can be further studied and understood.
Second, and extending the understanding of what programming languages are and
do, this introduction will describe how different programming languages shape how
programmers envision their programs. When programmers express their own purposes as
functions of other programmers texts, not only the lexical, but also the grammatical
resources made available in the programming language enable and constrain the
programmers. The enabling constraints of the programming languages grammar can be
understood as the implicit rules of the programs environment that come into play when
programs run. But precisely because these rules constrain how programs run, they must
application programs might be perceived as the egg and the machine programs as the chicken. If all
applications reference real or imagined machines, then computing machines are the egg and the applications
the chicken. Taken to its full conclusion, this perspective erases the concept of a “natural” technological
hierarchy placing hardware processors at the top and end-user software applications at the bottom (a hierarchy
usually depicted bottom-up in computer literature).
6
are responsible for making the program text into a functional computer program
23
also constrain what programs programmers can envisage running. As such programming
languages can be understood as not only tools for realizing computer programs, but also as
tools for thinking about - or rather with - computer programs. The thesis third article on
The Forms of Time and Chronotope in computer programming builds on this description
and illustrate how grammatical and literary mechanisms in ordinary languages such as
ancient Greek or English can do the same. 7
The programmer formulating bus.pl chooses his words well aware of how it will
relate to the Tokenizer and Parser program texts. By choosing to place letters and symbols
in a certain way, the bus.pl programmer recognizes, anticipates, and manipulates the
intertextual connections between bus.pl and the jTrolog program texts to achieve a certain
functional-rhetorical effect. But the choice of letters and symbols in Tokenizer and Parser
also recognizes, anticipates, and manipulates texts such as bus.pl. Tokenizer and Parser
only make sense when they are viewed as oriented toward actual, concrete or anticipated,
generalized program texts. That makes the literal references pointing from Tokenizer and
Parser texts to the bus.pl text just as real and non-figurative as those pointing the other way.
7
Before I begin this article I want to share an anecdote with my readers. I was attending a conference called
JavaZone in Oslo in 2006. During a session one of the presenter asked the audience a question: "do you want
to see some code?" To my surprise the otherwise quiet audience immideatly responded with a resounding:
"Yes!" An audience most often only reluctantly giving response to the presenters questions, clearly felt
strongly about this particular question.
Another anecdotal point in the same direction is the humerus, subversive saying that: "the best
documentation is the code itself". Programmers are often told to document their code well, that is to write
meta-text about what a function or class or other piece of code does in plain English. To document program
texts in this way is troublesome in many ways: first, always writing text about text amount to twice the
amount of work; second, it is not always easy to translate what a piece of program code does into a regular
language; and third and not least, when a piece of code is updated, its documentation is often not. All this
makes experienced programmers approach any documentation with a certain degree of distrust, often
preferring to read the actual code itself rather than plain English, possibly outdated stories about what the
code does and how.
The point of these two anecdotes to me is that code is communication. Programmers both write and
read program text code, and they often prefer to read what and how functionality the others express directly in
the actual program texts themselves - directly from the horses mouth. I have further come to believe that this
direct approach also is suited to beginners or newbies as they are called in the technical milieu. And so this
'tell it straight' and 'show as it is' approach will be a guiding principle in this introduction, even though it is not
primarily directed at seasoned programmers.
24
Magic or not
In essence jTrolog does its (auto)magical process by simply connecting every word
and sign in bus.pl with a piece of its own program texts (which in turn are connected to
each other and with yet other program texts). In fact, all the words and signs in bus.pl are
matched at least once with a particular piece of code in jTrolog, and jTrolog has no other
use of bus.pl apart from making these intertextual points of connections between itself and
bus.pl. So, taking the process of interpreting and running bus.pl at face value can therefore
be thought of as a simple process of identifying textual references within bus.pl, between
bus.pl and jTrolog, within jTrolog and between jTrolog and other program texts in turn
surrounding it. We will return to the interplay between jTrolog and its surrounding in the
next chapter, but before we get to that, we will do a complete analysis of what each word
and symbol in bus.pl means for jTrolog.
However, how bus.pl and jTrolog can produce a result can seem an automagical process of modern computer technology. Once the correct mix of program texts,
such as bus.pl and a query, are presented to the computing engine, such as jTrolog, the
computer technology will produce a real result, such as an actual, hitherto unknown travel
plan. The computer seems able to act by itself and based on text alone conjure up new real
output such as moving images, sounds, robotic movements and simple travel plans literally at the blink of an eye. It’s magic.
It might seem flimsical to talk of the process of running a computer program as
auto-magical. After all, few if any actually believe the computer has any supernatural
powers. But, even though little superstition surrounds computers, the process of running a
computer program text and creating a computer program remains for many a black box.
Not knowing how computer programs work, the computer program simply seem to appear
from somewhere, do something, and, voila, fulfill (or revoke) a users wishes. Further, the
25
term magic is not reserved for superstition only; magic is also used to describe card tricks
and stage shows illusions that everyone in advance knows to be technical craftsmanship
and make-believe. Hence, a running computer program often appears as automatic and
magical.
In order to understand computer programs and the practice of writing computer
programs, we need to break down the auto-magical trickery and black-box concept of
computer programs. To do so this introduction will first deconstruct the program text of
bus.pl and show how one program engine such as jTrolog interprets its every word and sign
to conjure up a new travel plan (program text deconstruction). Second, this introduction
will deconstruct one entire intertextual environment in which bus.pl might be interpreted
and run (program intertext deconstruction). Third, this intertextual deconstruction will be
further complicated by highlighting how program texts has its own life cycle placing them
in many different intertextual environments (program text life cycle deconstruction). And
forth and lastly, parallel intertextual environments and settings will be exemplified
illustrating the often diverse and complex dialogical nature of program text. This four-part
analysis will illustrate what program texts are and how they work (at face value).
References
Gosling, J., Joy, B., Steele, G., and Bracha, G. 2000. The Java Language Specification.
Boston: Addison-Wesley.
ISO/IEC 1995. Prolog - Part 1: General core (ISO/IEC 13211-1:1995(E)). Information
technology - Programming languages.
Lindholm, T., and Yellin, F. 1999. The Java Virtual Machine Specification. Boston:
Addison-Wesley.
Ørstavik,
I. 2008.
jtrolog:
http://jtrolog.dev.java.net/.
Project
home
Retrieved
20.09.2008
from
26
i
It is the limits of what text we can foresee surrounding our program texts, which limit our imagination of
future programs. The meaning of the bus-facts and plan_travel-rules in bus.pl is therefore dependent on us
imagining and seeing bus.pl in an intertextual program context of use, and the program texts and setting that
surrounds them informs our understanding of words such as “plan_travel” and “bus”.
27