7 Writing programs

7.1 Rhetorics and programming

In the previous chapters, we have been primarily examining programmers’ working processes: that is, how they do their jobs. In this chapter, we take a closer look at the programmers’ primary work product: program code.

In Chapters 4 (Game programming) and 5 (Safety critical programming) we saw how hermeneutical theory can be used to understand programming processes. In Chapter 6 (Programming culture) we used cultural form theory to look at the differences between programming in different situations. As we saw, these forms of theory are well suited to study programming in order to understand better what happens in the programming process. However, the ultimate goal of understanding programming better is that we might be able to program better; and in order to do that, our understanding of programming needs to be applied in practice to programming tasks.

For that reason, we will in this chapter apply rhetorical theory to an analysis of program code. Program code is the medium in which programmers work, and is therefore of interest to a practical approach to programming tasks. Rhetorical theory is the classical body of learning about how to write and deliver a speech in practice. The practical element of rhetorics means that it is a more direct route to practical application than hermeneutics, which is more concerned with understanding texts than with creating them.

A rhetorical analysis of program code should be seen in contrast to the conventional forms of analysis that are associated with the thinking described in Chapter 3 (Programming theories). We did not, in that chapter, go into detail about the ways program code is analysed, but it is in line with the overall priorities of mainstream programming theory and usually focuses on mathematical properties, quantification, efficiency, program organization and modularization, and business value. As we shall see, rhetorical analysis provides a perspective on source code that is quite different from all these, yet is closer to the practical everyday experience that a programmer has when working with code.

The relationship between rhetorics and hermeneutics is close. Essentially, rhetorics is the practical side of hermeneutics, as the philosopher of hermeneutics Hans-Georg Gadamer has explained in a 1976 lecture. It is a central principle of hermeneutics that understanding depends on application – a cultural phenomenon can only be understood correctly through understanding its purpose.

Corresponding to this principle is, in rhetorics, the notion that communication should be purposeful. An act of communication must be judged according to whether it achieves its intended purpose. The theories of hermeneutics and rhetorics together constitute a philosophy in which the concepts of application and purpose are deeply connected; whereas hermeneutics is primarily concerned with understanding, rhetorics is primarily concerned with applying knowledge.

Applying a rhetoric perspective to programming is a rarity in the literature. In his 2002 book The Art of Interactive Design, computer game designer Chris Crawford regards programming as essentially a matter of interactivity, which he defines as: “a cyclic process in which two actors alternately listen, think, and speak” 1 – the two actors being the user and the machine. His main metaphor is that of a conversation. The use of conversation as an image of programming, and its division into three species – listening, thinking, and speaking – places his work in the domain of rhetorics, even though his starting point is not classical rhetorical theory but rather a non-academic and very practical approach.

Popular handbooks in practical programming, such as Code Complete, provide much advice that can easily be understood in a rhetorical way. Examples in Code Complete are an explanation of the importance of metaphors in understanding programming; advice on how to structure code so that the meaning is clear to a reader; and advice on how to use layout and indenting in order to communicate the intent of the code better.2 None of this is presented in connection with rhetorical theory, but rather as things that are self-evidently good to do. Nevertheless, these topics fall within the domain of rhetorics.

Donald Knuth invented the concept of “literate programming” in his 1984 article, in which he argues that programs are potentially works of literature. The rhetorical connection is obvious: “The practitioner of literate programming can be regarded as an essayist, whose main concern is with exposition and excellence of style.” 3 Most of Knuth’s writing on literate programming is devoted to a computer system that can intertwine program code and documentation.

Informatics professor Antony Bryant speaks for an approach that, while not exactly rhetorical, can easily be understood in rhetorical terms: he argues that metaphors for understanding are a central part of software engineering. Metaphor is a central concept not only to literature but also to rhetorics, and speaking of metaphors as playing a part in how we perceive things, as opposed to merely a way of making speeches more colourful, fits well with an approach called “new rhetorics” that was developed by Chaïm Perelman and Lucie Olbrechts-Tyteca in the 1950s.

1  Crawford 2002 p. 5.

2  McConnell 1993 chp. 2, chp. 13, chp. 18.

3  Knuth 1984 p. 97.

7.2 Audience

A fundamental concern of rhetorics is the audience for an utterance. This raises the question of who the audience is for a piece of program code. Ultimately, the audience for a computer program is of course the intended user, who will experience the program’s behaviour. However, much as a playwright does not manipulate a theatre play directly but rather by instructing the play’s actors through a manuscript, the programmer does not manipulate the program’s behaviour directly but rather through instructions to the machine that will be executed later. The theatre manuscript and the program code are both indirect representations of acts of communication that will be realized later. The theatre manuscript is to be read by the actors, not the theatre audience, and therefore it has to be written for the actors rather than the audience.

Thus although the audience for a program’s behaviour is the eventual user, the audience for program code is other programmers. Who, then, are these other programmers? First of all, the programmer needs to write his code so that it is understandable by his colleagues. It is a very real possibility that a programmer other than the author will have to make modifications to the code at some point, perhaps at a time when the author has left the company and is not available to answer questions; the recipient colleagues may even be future colleagues, not presently known to the author. This means that the audience of programmer colleagues, for whom the author is writing code, is a case of what Perelman and Olbrechts-Tyteca call “the universal audience”;1 and in the case of program code we can call the audience “the universal programmer”. The universal programmer is the author’s idea of what a reasonable and intelligent programmer would be like – writing code to be read by the universal programmer means writing code that is orderly and proper, “the way it should be”.

One more programmer is going to read and understand the program code – the author himself. Consequently, when the author writes the program code he thinks not only of how potential future colleagues or the universal programmer might perceive his code – he also deliberates with himself on how to best understand the code he is writing. According to Perelman and Olbrechts-Tyteca, the private deliberations one silently has with oneself is a special case of general argumentation, and can be understood as yet another address to the universal audience.2

Figure 7.1 – A screenshot of the tablet computer game with the working title Flower. Tribeflame 2014.

We notice that the members of the audience for the program code – the author himself, his colleagues, and the universal programmer – all are included because they might modify the program code in the future. Recalling the analysis in Chapter 4 (Game programming), this is because program code is seldom written in one go, never to be modified again. If this were the case, program code could be written in any way accepted by the machine, and it would not matter if the code were neat or understandable. But program code is written to be modified; and this is because of the hermeneutical process of writing the code, where adjustments are carried out and errors corrected in a slowly evolving hermeneutical circle that moves in cycles between program creation and experience with the program’s behaviour.3

#ifndef GAME_SCENE2_HPP
#define GAME_SCENE2_HPP

TF_DECLARE_CLASS(      Light );
TF_DECLARE_CLASS(      Mirror );
TF_DECLARE_CLASS(      Room );
TF_DECLARE_CLASS(      Flower );

#include    "UI/Scene.hpp"
#include    "Util/Geometry.hpp"
#include    "Levels/LevelInfo.hpp"
#include    "Game/Updater.hpp"
#include    "Game/RoomDefinitions.hpp"

TF_CLASS(GameScene) : public Scene, public tf::TouchClientMixin {

public:

     /**
      * Creates an instance of the scene.
      *
      * @return a new instance.
      **/
     static sGameScene create (sRoom room, sLevelInfo level_info);

     GameScene ();

     ~GameScene ();

     void init ();

     /**
      * Signal used to tell that the game scene is done, i.e. the
          game has finished through the user quitting it manually
      **/
     boost::signals2::signal quitSignal;
     boost::signals2::signal nextLevelSignal;

protected:

Figure 7.2 – Part of the C++ header file “GameScene.hpp” from the tablet computer game with the working title Flower. Only the start of the file is shown.

1  Perelman & Olbrechts-Tyteca 1958 §7.

2 “L’individualisme des auteurs qui accordent une nette prééminence à la façon de conduire nos propres pensées et la considèrent comme seule digne de l’intérêt du philosophe – le discours adressé à autrui n’étant qu’apparence et tromperie – a été pour beaucoup dans le discrédit non seulement de la rhétorique, mais, en général, de toute théorie de l’argumentation. Il nous semble, par contre, qu’il y a tout intérêt à considérer la délibération intime comme une espèce particulière d’argumentation.” Perelman & Olbrechts-Tyteca 1958 [2008] §9, p. 54.

3 See Section 4.2 (Hermeneutical analysis).

7.3 Programming conventions

Figures 7.2, 7.3, and 7.4 show parts of the program code for a computer game for tablet computers made by the company Tribeflame. This game, which they worked on during my time observing the company, had the working title Flower. The game shows a living room in a house seen from above, as shown in Figure 7.1. The living room is dark, and in the corner, amidst chairs and tables, stands a neglected, sad-looking flower. A ray of sunshine falls through the living room window but does not reach the unfortunate flower. The player’s task is to place one or more mirrors in the living room and make sure that they reflect the ray of light in such a way that the sunlight hits the flower and restores its health and happiness.

The program code file shown in Figure 7.2 is named “Game-
Scene.hpp”. It is a so-called header file. A header file does not itself contain any functional program code; it merely lists the contents of another file. Technically, a header file is not strictly necessary for the program to function, but it serves some practical purposes and has come to be expected in any reasonably-sized program. This means that the use of a header file has become a rhetorical convention – much like a list of contents in a book. The mere presence of a header file, therefore, does not tell us a lot about the game; but the specific way it is written, its style and arrangement, can tell us something about the priorities of the game’s creation.


First of all, the lines:

    TF_DECLARE_CLASS(     Light );
    TF_DECLARE_CLASS(     Mirror );
    TF_DECLARE_CLASS(     Room );
    TF_DECLARE_CLASS(     Flower );

and

     TF_CLASS(GameScene)

are written in an unusual way for C++ code. They are macros written by Tribeflame’s programmers, as the letters “TF”, standing for “Tribeflame”, show. They indicate that not all conventions of writing C++ code are preferred by the programmers.


The line

     TF_CLASS(GameScene) : public Scene, public tf::TouchClientMixin {

tells us that the program module GameScene is related to the more general module Scene, meaning that there is more to the computer game than just the game part – there are additionally modules for selecting a level, showing the high score, and changing the settings of the game. The bit

     tf::TouchClientMixin

tells us that the game works on a tablet computer (“TouchClient”). It also tells us that Tribeflame has made its own collection of modules that can be used for developing tablet computer games – again “tf” stands for “Tribeflame”. It would be possible to make a game without such a collection of modules. This is a more direct technique, but it would result in more disorderly program code. Tribeflame has spent a large amount of energy on making orderly program modules that makes it possible for them to run games on different brands of tablet computers, in addition to the most common, Apple’s iPad.


The line

     public:

marks the part of the code that is available to other program modules. This means that the following lines show the most important parts of this program module in terms of interaction with other parts of the code. This particular program module is not meant to do more than to be started and then run the computer game. The lines

    GameScene ();

    ~GameScene ();

are the conventional ways in the programming language C++ of starting and ending a program module.1 The line

     static sGameScene create (sRoom room, sLevelInfo level_info);

is an alternative way of starting a module that Tribeflame has chosen instead of the C++ convention.2 It does not matter to the machine where in the file this line is placed.3 By placing the line near the beginning of the program code, the programmer emphasizes, for the benefit of the human reader, that the program goes beyond the C++ conventions in this way.

The only parts of the programming module that are accessible to other modules and do not have to do with starting and stopping the module are the lines

     boost::signals2::signal quitSignal;
     boost::signals2::signal nextLevelSignal;

These lines both have to do with the player controlling the game by quitting it, or moving on to another game level. The prominence of these lines show that the player’s ability to control the game is an important part of the design of the whole game. A part of the entertainment value of the game is that the player should be able to enjoy it in a way he chooses himself.

1 Technically, for constructing and destroying an object.

2 The conventional way is to use new to create an instance of the class.

3 Within some limits.

7.4 Tone and purpose

When conducting a rhetorical analysis of a text it is often helpful to determine the exigence of the text. In rhetorics, exigence means a situation that demands an answer.1 One comparable example of exigence is a judge’s accusation of a defendant, which demands that he answer the charge in order to defend himself. The exigence for the program code as a whole is the company’s decision to develop a game that can succeed commercially. However, each program module has an exigence of its own. The exigence for the module GameScene is to organize the code that has to do with displaying and interacting with the game, and to provide a starting point for running the game.

Even smaller parts of code inside a module have their own exigence. Frequently, each single line of code has an exigence, and sometimes the programmer records the exigence in comments in the code. At other times, the programmer records the exigence in a version control system, a program that keeps track of all changes made to the code. Examples of comments entered in a version control system are “bonus items”,2 “linux compat[ibility], do not log if NDEBUG is defined”,3 and “added some debug code for a single sun showing up on the first ray every time we update”.4 When using a version control system, the exigence for a given line of code and for all changes made to it can be found. This is an important tool for programmers whenever they try to understand some code, which is not surprising since exigence is often essential to understanding the meaning of a text.

#include 

#include    "Game/GameScene.hpp"
#include    "Game/Mirror.hpp"
#include    "Game/Room.hpp"
#include    "Game/Light.hpp"
#include    "Game/Flowers/Flower.hpp"
#include    "Game/Sensor.hpp"
#include    "Game/LevelCompletedNode.hpp"
#include    "Game/Obstacles/Obstacle.hpp"
#include    "Game/Obstacles/Animal.hpp"
#include    "Game/Obstacles/Firefly.hpp"
#include    "UI/MenuButton.hpp"
#include    "Textures/Textures.hpp"
#include    "Util/Audio.hpp"

Figure 7.3 – Part of the C++ program file “GameScene.cpp” from the tablet computer game with the working title Flower. Only the start of the file is shown.

In a rhetorical analysis, the matter of concern is how purposeful program code is – which is determined not by technical criteria, but by its meaning. Figure 7.3 shows the start of the program file “GameScene.cpp”, the file that contains the implementation of the code which is listed in the file “GameScene.hpp”, which we examined above. This file, like the last one and indeed almost all C++ files, starts with a list of other files to be included (“#include”). Technically, this means that the contents of the other files are “copied” to this place, so that their contents are accessible to the program code. We could go more into detail about how this is accomplished and what technical consequences it has. However, for the purpose of rhetorical analysis, it is more interesting to see what the inclusions can tell us about the program’s meaning.

The first inclusion of the module “Flower” signifies that the file is part of the Flower game. The rest of the inclusions indicate which modules and which parts of the game are conceptually most important. To analyse them, we can use the concepts called the “three species of rhetorical expression”. These are simple but effective categories for classifying the “tone” of an expression.5 The historical names for the species are judicial speech, epideictic speech, and deliberative speech.6

Judicial speech is that which has to do with the past. It is often concerned with recording and stating what has happened, and with passing judgment on past actions. It is so named because the archetype for judicial speech is the speech of accusation or defence offered in a court of law. Epideictic speech has to do with the present, and is often concerned with setting the mood and stating values. Epideictic speech has been a little overlooked in modern times: its archetype is the speech of praise delivered at a public ceremony, such as, for example, a graduation speech. Deliberative speech has to do with the future. It tries to convince the audience to make a choice or to take a certain action, and its archetype is the political speech aimed at convincing voters.

Looking at the inclusions, most of them are primarily in the epideictic species. “Mirror”, “Room”, “Light”, “Flowers/Flower”, “Sensor”,
“Obstacle”, “Animal”, “Firefly”, “Textures”, and “Audio” are all modules that have to do with establishing the “present” of the game, with setting the right mood for the player and presenting him with a game that looks interesting. That so many inclusions are in the deliberative species indicate that constructing an interesting “present”, a game ambience, is a task that demands much work.

Only one inclusion seems to be squarely in the judicial species:
“LevelCompletedNode”. Though the game records certain things – the “history” of the game in the form of a high score list – the game is not a program that is primarily oriented toward recording and judging the past, as with, for example, a database or an accounting system. The primary use of records and judgement in this game is to restrict what levels the players can access.

The deliberative species is represented by “Mirror” and “MenuButton”. These are the things in the game that the player can manipulate. If the sheer amount of code is counted, these elements do not seem to be as important as the epideictic elements. However, while they might not require huge amounts of code, it is important that the few lines required are just right. This is because the whole point of the game is to present the player with a situation that can be manipulated, an interesting choice. If this dimension is missing in a game, it becomes less of a game and more of an interactive movie or animation.

void GameScene::init () {
   // superclass initialization
   Scene::init();

    // now we're again playing
    game_state = State::Playing;

    // play game music
    audio->setMusicType( Audio::GameMusic );

    // report it as a statistic too
    //tf::Flurry::get_flurry_instance()->start_timed_event( game_\
        mode->getLeaderBoardId() );

    // now we want touch events, this allows the player to immedi\
        ately "tap to continue"
    set_enable_touch_dispatch( true, 10 );

    // first add the room
    add_child( m_room );

    sGameScene self = TF_GET_SHARED_THIS( GameScene );
    tf::signal_weak_connect( m_room->obstaclesMoving, boost::bind(
        &GameScene::obstaclesMoving, self.get(), _1 ), self );

    // create a button for an in game menu
    sMenuButton quit_button = TF_VAL( MenuButton, getMenu(),
        tp_game_quit_button, tp_game_quit_button_pressed,
        tf::Point2F( 0, 0 ) );
    quit->button->init();

    // left corner
    tf::Size2F size = tf::get_screen_native_bounds();
    quit_button->set_position( -1024 / 2.0 + 25, 768 / 2.0 - 25 );
    tf::signal_weak_connect( quit_button->signal_activate,
        boost::bind( &GameScene::quit, self.get()), self);

    // initial ray
    updateLights();
}

Figure 7.4 – Part of the C++ program file “GameScene.cpp” from the tablet computer game with the working title Flower. Only part of the file is shown.

The program code shown in Figure 7.4 shows the part of “GameScene.cpp” that is run whenever a new game is started – “init” stands for “initialization”. The line

     Scene::init();

again is a sort of rhetorical convention in C++. The next statement

     game_state = State::Playing;

simply records that the game is now playing. The first thing that happens that is noticeable to the player is that the game music is started with the line

     audio->setMusicType( Audio::GameMusic );

This shows that the music is very important to set the ambience of the game. Music creation is one of the only creative functions in Tribeflame that is bought from an external provider. The task is not big enough to warrant a regular employee, but it is still of such importance to get music of high quality that it is necessary to hire a professional.


The next line

     //tf::Flurry::get_flurry_instance()->start_timed_event( game_\
         mode->getLeaderBoardId() );

is supposed to assist with keeping a record of the player’s activities. However, we notice that the line starts with the characters “//” which means that it is a comment – from the computer’s perspective it is as if the line had been deleted. So why has the programmer not simply deleted the line?

There are several reasons the programmer might like to keep some code as a comment. A primarily technical reason would be to make the line a comment for a short time, try out the program, and then uncomment the code again. There are also more rhetorical uses of code as comments. One is that the programmer has begun to create some functionality in the code but decided to postpone it to a later time, when the commented code will serve as a reminder of what the programmer originally thought up or, if another programmer has taken over the code, it indicates what the programmer thinks is a good way to solve the problem. Another use is essentially the opposite: the code might be kept around as a comment to show that a particular point has been considered, tried out, and then rejected. This might save the programmer or his future colleagues some trouble later on. In both cases, the commented code serves a purely rhetorical purpose since it has no effect on the program’s behaviour.


The next line

     set_enable_touch_dispatch( true, 10 );

makes the game responsive to the player’s gestures. That this happens before the game is even fully prepared for playing suggests that letting the player manipulate the game has high priority, as mentioned above.


The line

     add_child( m_room );

establishes the “room”, meaning a game level containing a puzzle for the player to solve.


The lines

     sGameScene self = TF_GET_SHARED_THIS( GameScene );
     tf::signal_weak_connect( m_room->obstaclesMoving, boost::bind(
         &GameScene::obstaclesMoving, self.get(), _1 ), self );

establish a connection between the game and the room. In the first line, a variable called “self” is declared with the help of a macro of the company’s own called “TF_GET_SHARED_THIS”. With this line the company again circumvents the rhetorical programming conventions of C++. The programming language has a built-in mechanism called “this”, but the programmers have chosen not to use it and instead make their own, similar mechanism called “self”. “Self” does not do exactly the same thing as “this”, but the name seems to be chosen in order to emphasize the similarities between the two mechanisms.7


The lines

    sMenuButton quit_button = TF_VAL( MenuButton, getMenu(),
       tp_game_quit_button, tp_game_quit_button_pressed,
       tf::Point2F( 0, 0 ) );
    quit->button->init();

and

     tf::signal_weak_connect( quit_button->signal_activate,
         boost::bind( &GameScene::quit, self.get()), self);

create a button on the screen that the player can press in order to control the game. The lines

     tf::Size2F size = tf::get_screen_native_bounds();
     quit_button->set_position( -1024 / 2.0 + 25, 768 / 2.0 - 25 );

determine where on the screen the button is placed. Interestingly, in the first line a variable called “size” is declared, which is never used. Instead the calculation “–1024 / 2.0 + 25, 768 / 2.0 – 25” is used to determine where the button is placed. Apparently, the programmer first thought of using “size” in this calculation but then for some reason abandoned this approach. That “size” is left in place in the code might either be deliberate, as in the case of the commented code above, or it might be an oversight. In either case the rhetorical effect on the reader is to indicate that this small piece of code is probably not completely finished.


The final line of this part of the code is

     updateLights();

which has the effect of letting a ray of sunshine shine through the window in order to begin the game.

1  Kennedy 1984 p. 35.

2  Field diary, 30th August 2011, 15:47.

3  Field diary, 31st August 2011, 16:08.

4  Field diary, 31st August 2011, 16:22.

5 The rhetorical species are seldom found in pure form.

6 See for example Kennedy 1984 p. 19, Perelman & Olbrechts-Tyteca 1958 [2008] §4, p. 28.

7 In the programming language Smalltalk, the mechanism that is called “this” in C++ is indeed called “self”. Stroustrup 1985 [1997] p. 231.

7.5 Rhetorical understanding

In this chapter we have gained a taste of how to approach a rhetorical analysis of program code. Several rhetorical concepts have been used in the analysis, and more could be added: the rhetorical concept of audience;1 the concept of rhetorical convention;2 the importance of choosing the right unit as a starting point for the analysis – whole program, program file, program module, or a single line of code;3 the concept of exigence;4 the three rhetorical species: judicial, epideictic, and deliberative rhetorics;5 the rhetorical concepts of style and arrangement.6

An experienced programmer reading this chapter will have noticed that, apart from using some specific rhetorical terms, what is going on in the rhetorical analysis above is very much like what is going on whenever a programmer reads and tries to understand a unfamiliar piece of program code. This is no coincidence. Classical rhetorics is, properly understood, the study of what people already and always do when they express themselves well – whether or not they have a theoretical understanding of what they are doing. Gadamer writes:

“Now, rhetorics and hermeneutics are in a certain point closely connected: the ability to speak and the ability to understand are natural human abilities that can be fully developed also without conscious use of learned rules, as long as a natural talent and the proper care and use of it coincide.” 7

The point of learning rhetorical theory is, as a matter of course, to become more aware of what we are doing and thereby become better at it. The most important lesson from rhetorics is that everything that is written, in program code or otherwise, must be purposeful – and not only this, but it furthermore has to serve the right purpose. Deliberations over what purpose a program has and how best to express it is what distinguishes an excellent programmer from a merely competent one.

A lesson to take away from the rhetorical analysis above is the importance of context when analysing program code. Much of the discussion above depends on information that is not found in the code itself. Because I was present during the development of the code, or at least some of it, it is much easier for me to understand the code than it would be for someone whose only source of information is the code. This observation shows the folly of trying to study program code in isolation, disregarding the context in which it is developed.

The great benefit of using rhetorical concepts in analysis of program code is that they are general, so that the analysis can easily be related also to phenomena outside the code. The advice for program code layout in a handbook such as Code Complete,8 for example, is very specific to just program code, which means that it is hard to relate to bigger themes in the program creation. In contrast, rhetorical concepts like exigence and the rhetorical species are not limited to program code. They can be applied to any form of communication, and this means that all the parts of the software development effort, including meetings, discussions, and the like, can be made to relate to each other within a rhetorical analysis.

Only a small part of the game’s program code is analysed above, and not in depth. The purpose of this chapter has merely been to give a demonstration of how to carry out a rhetorical analysis. The analysis presented here is incomplete; a more thorough rhetorical analysis of program code would deserve a book of its own. Fields other than programming have examples of rhetorical analysis of a practical bent. Of interest is Kennedy’s analysis of New Testament texts.9

A further illustrative example is the 1979 study by Bruno Latour and Steve Woolgar of the work of neuroendocrinologists, a branch of the natural, or “hard”, sciences. The study shows how scientific facts consist not only of observations from the laboratory, but also of rhetorical efforts to establish the explanations of observations as facts.10 The rhetorical aspect of the scientists’ work has the important function of persuading their colleagues, in order to strengthen the credibility of the scientists.11

1  Perelman & Olbrechts-Tyteca 1958 §4.

2 See for example the discussion of rhetorical figures in Perelman & Olbrechts-Tyteca 1958 §41.

3  Kennedy 1984 p. 33.

4  Ibid. p. 35.

5  Ibid. p. 19.

6  Kennedy 1984 p. 13. Perelman & Olbrechts-Tyteca 1958 §29.

7 “Nun sind in einem Punkte Rhetorik und Hermeneutik zutiefst verwandt: Redenkönnen und Verstehenkönnen sind natürliche menschliche Fähigkeiten, die auch ohne bewußte Anwendung von Kunstregeln zu voller Ausbildung zu gelangen vermögen, wenn natürliche Begabung und die rechte Pflege und Anwendung derselben zusammenkommen.” Gadamer 1976 p. 8.

8  McConnell 1993.

9  Kennedy 1984.

10  Latour & Woolgar 1979 [1986] p. 240.

11  Ibid. p. 200.