PDF Programming Language Concepts Peter Sestoft download
PDF Programming Language Concepts Peter Sestoft download
com
https://textbookfull.com/product/programming-language-
concepts-peter-sestoft/
OR CLICK BUTTON
DOWNLOAD NOW
https://textbookfull.com/product/java-precisely-third-edition-the-mit-
press-peter-sestoft/
textboxfull.com
https://textbookfull.com/product/the-language-of-surrealism-peter-
stockwell/
textboxfull.com
https://textbookfull.com/product/programming-php-4th-edition-peter-
macintyre/
textboxfull.com
https://textbookfull.com/product/concepts-of-programming-languages-
twelfth-edition-sebesta/
textboxfull.com
Concepts of programming languages 11th Edition Sebesta
https://textbookfull.com/product/concepts-of-programming-
languages-11th-edition-sebesta/
textboxfull.com
https://textbookfull.com/product/basics-of-language-for-language-
learners-2nd-edition-peter-w-culicover/
textboxfull.com
https://textbookfull.com/product/xcalablemp-pgas-programming-language-
from-programming-model-to-applications-mitsuhisa-sato/
textboxfull.com
https://textbookfull.com/product/experience-design-concepts-and-case-
studies-peter-benz-editor/
textboxfull.com
https://textbookfull.com/product/programming-in-15-language-muhammad-
allah-rakha/
textboxfull.com
Undergraduate Topics in Computer Science
Peter Sestoft
Programming
Language
Concepts
Second Edition
Undergraduate Topics in Computer Science
Series editor
Ian Mackie
Advisory Board
Samson Abramsky, University of Oxford, Oxford, UK
Karin Breitman, Pontifical Catholic University of Rio de Janeiro, Rio de Janeiro, Brazil
Chris Hankin, Imperial College London, London, UK
Dexter C. Kozen, Cornell University, Ithaca, USA
Andrew Pitts, University of Cambridge, Cambridge, UK
Hanne Riis Nielson, Technical University of Denmark, Kongens Lyngby, Denmark
Steven S. Skiena, Stony Brook University, Stony Brook, USA
Iain Stewart, University of Durham, Durham, UK
Undergraduate Topics in Computer Science (UTiCS) delivers high-quality instruc-
tional content for undergraduates studying in all areas of computing and information
science. From core foundational and theoretical material to final-year topics and
applications, UTiCS books take a fresh, concise, and modern approach and are ideal
for self-study or for a one- or two-semester course. The texts are all authored by
established experts in their fields, reviewed by an international advisory board, and
contain numerous examples and problems. Many include fully worked solutions.
Programming Language
Concepts
Second Edition
123
Peter Sestoft
IT University of Copenhagen, Computer
Science Department
Copenhagen
Denmark
What is Covered
Topics covered include abstract and concrete syntax; functional and imperative
programming languages; interpretation, type checking, and compilation; peep-hole
optimizations; abstract machines, automatic memory management and garbage
collection; the Java Virtual Machine and Microsoft’s .NET Common Language
Runtime; and real machine code for the x86 architecture.
Some effort is made throughout to put programming language concepts into their
historical context, and to show how the concepts surface in languages that the
students are assumed to know already; primarily Java or C#.
We do not cover regular expressions and parser construction in much detail. For
this purpose, we refer to Torben Mogensen’s textbook; see Chap. 3 and its references.
Apart from various updates, this second edition adds a synthesis chapter, con-
tributed by Niels Hallenberg, that presents a compiler from a small functional
language called micro-SML to an abstract machine; and a chapter that presents a
compiler from a C subset called micro-C to real x86 machine code.
The book’s emphasis is on virtual stack machines and their intermediate languages,
often known as bytecode. Virtual machines are machine-like enough to make the
central purpose and concepts of compilation and code generation clear, yet they are
much simpler than present-day microprocessors such as Intel i7 and similar.
v
vi Preface
Why F#?
Supporting Material
There are practical exercises at the end of each chapter. Moreover, the book is
accompanied by complete implementations in F# of lexer and parser specifications,
abstract syntaxes, interpreters, compilers, and runtime systems (abstract machines,
in Java and C) for a range of toy languages. This material, and lecture slides in PDF,
are available separately from the book’s homepage: http://www.itu.dk/people/
sestoft/plc/.
Acknowledgements
This book originated as lecture notes for courses held at the IT University of
Copenhagen, Denmark. I would like to thank Andrzej Wasowski, Ken Friis Larsen,
Hannes Mehnert, David Raymond Christiansen and past students, in particular
Niels Kokholm, Mikkel Bundgaard, and Ahmad Salim Al-Sibahi, who pointed out
mistakes and made suggestions on examples and presentation in earlier drafts. Niels
Kokholm wrote an early version of the machine code generating micro-C compiler
presented in Chap. 14. Thanks to Luca Boasso, Mikkel Riise Lund, and Paul
Jurczak for pointing out misprints and unclarities in the first edition. I owe a lasting
debt to Neil D. Jones and Mads Tofte who influenced my own view of program-
ming languages and the presentation of programming language concepts.
Niels Hallenberg deserves a special thanks for contributing all of Chap. 13 to this
second edition.
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Files for This Chapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Meta Language and Object Language . . . . . . . . . . . . . . . . . . . 1
1.3 A Simple Language of Expressions . . . . . . . . . . . . . . . . . . . . 2
1.3.1 Expressions Without Variables . . . . . . . . . . . . . . . . . 2
1.3.2 Expressions with Variables . . . . . . . . . . . . . . . . . . . . 3
1.4 Syntax and Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.5 Representing Expressions by Objects . . . . . . . . . . . . . . . . . . . 6
1.6 The History of Programming Languages . . . . . . . . . . . . . . . . . 8
1.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2 Interpreters and Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.1 Files for This Chapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2 Interpreters and Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3 Scope and Bound and Free Variables . . . . . . . . . . . . . . . . . . . 14
2.3.1 Expressions with Let-Bindings and Static Scope . . . . . 15
2.3.2 Closed Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.3.3 The Set of Free Variables . . . . . . . . . . . . . . . . . . . . . 17
2.3.4 Substitution: Replacing Variables by Expressions . . . . 17
2.4 Integer Addresses Instead of Names . . . . . . . . . . . . . . . . . . . . 20
2.5 Stack Machines for Expression Evaluation . . . . . . . . . . . . . . . 22
2.6 Postscript, a Stack-Based Language . . . . . . . . . . . . . . . . . . . . 23
2.7 Compiling Expressions to Stack Machine Code . . . . . . . . . . . 25
2.8 Implementing an Abstract Machine in Java . . . . . . . . . . . . . . . 26
2.9 History and Literature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.10 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3 From Concrete Syntax to Abstract Syntax . . . . . . . . . . . . . . . . . . . 31
3.1 Preparatory Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2 Lexers, Parsers, and Generators . . . . . . . . . . . . . . . . . . . . . . . 32
ix
x Contents
This chapter introduces the approach taken and the plan followed in this book. We
show how to represent arithmetic expressions and other program fragments as data
structures in F# as well as Java, and how to compute with such program fragments.
We also introduce various basic concepts of programming languages.
File Contents
Intro/Intro1.fs simple expressions without variables, in F#
Intro/Intro2.fs simple expressions with variables, in F#
Intro/SimpleExpr.java simple expressions with variables, in Java
function, recursion, list, pattern matching, and datatype. Several books give a more
detailed introduction, including Hansen and Rischel [1] and Syme et al. [6].
It is convenient to run F# interactive sessions inside Microsoft Visual Studio (under
MS Windows), or executing fsharpi interactive sessions using Mono (under Linux
and MacOS X); see Appendix A.
First, let us consider expressions consisting only of integer constants and two-
argument (dyadic) operators such as (+) and (*). We represent an expression as a
term of an F# datatype expr, where integer constants are represented by constructor
CstI, and operator applications are represented by constructor Prim:
type expr =
| CstI of int
| Prim of string * expr * expr
A value of type expr is an abstract syntax tree that represents an expression. Here
are some example expressions and their representations as expr values:
Now, let us extend our expression language with variables such as x and y. First, we
add a new constructor Var to the syntax:
type expr =
| CstI of int
| Var of string
| Prim of string * expr * expr
Next we need to extend the eval interpreter to give a meaning to such variables.
To do this, we give eval an extra argument env, a so-called environment. The role
of the environment is to associate a value (here, an integer) with a variable; that is,
the environment is a map or dictionary, mapping a variable name to the variable’s
current value. A simple classical representation of such a map is an association list:
a list of pairs of a variable name and the associated value:
let env = [("a", 3); ("c", 78); ("baf", 666); ("b", 111)];;
This environment maps "a" to 3, "c" to 78, and so on. The environment has
type (string * int) list. An empty environment, which does not map any
variable to anything, is represented by the empty association list
let emptyenv = [];;
As promised, our new eval function takes both an expression and an environment,
and uses the environment and the lookup function to determine the value of a
variable Var x. Otherwise the function is as before, except that env must be passed
on in recursive calls:
let rec eval e (env : (string * int) list) : int =
match e with
| CstI i -> i
| Var x -> lookup env x
| Prim("+", e1, e2) -> eval e1 env + eval e2 env
| Prim("*", e1, e2) -> eval e1 env * eval e2 env
| Prim("-", e1, e2) -> eval e1 env - eval e2 env
| Prim _ -> failwith "unknown primitive";;
Note that our lookup function returns the first value associated with a variable, so
if env is [("x", 11); ("x", 22)], then lookup env "x" is 11, not 22.
This is useful when we consider nested scopes in Chap. 2.
1.4 Syntax and Semantics 5
We have already mentioned syntax and semantics. Syntax deals with form: is this
program text well-formed? Semantics deals with meaning: what does this (well-
formed) program mean, how does it behave – what happens when we execute it?
The distinction between syntax and static semantics is not clear-cut. Syntax can tell
us that x12 is a legal variable name (in Java), but it is impractical to use syntax
to check that we do not declare x12 twice in the same scope (in Java). Hence this
restriction is usually enforced by static semantics checks.
In the rest of the book we shall study a small expression language, two small
functional languages (a first-order and a higher-order one), a subset of the imperative
language C, and a subset of the backtracking language Icon. In each case we take
the following approach:
In addition we study some abstract stack machines, both homegrown ones and
two widely used so-called managed execution platforms: The Java Virtual Machine
(JVM) and Microsoft’s Common Language Infrastructure (CLI, also known as .Net).
Note that each Expr subclass has fields of exactly the same types as the arguments
of the corresponding constructor in the expr datatype from Sect. 1.3.2. For instance,
class CstI has a field of type int just as constructor CstI has an argument of
type int. In object-oriented terms Prim is a composite because it has fields whose
type is its base type Expr; in functional programming terms one would say that type
expr is a recursively defined datatype.
How can we define an evaluation method for expressions similar to the F# eval
function in Sect. 1.3.2? That eval function uses pattern matching, which is not
available in Java or C#. A poor solution would be to use an if-else sequence that
tests on the class of the expression, as in if (e instanceof CstI) and so on.
1.5 Representing Expressions by Objects 7
Since 1956, thousands of programming languages have been proposed and imple-
mented, several hundred of which have been widely used. Most new programming
languages arise as a reaction to some language that the designer knows (and likes
or dislikes) already, so one can propose a family tree or genealogy for programming
languages, just as for living organisms. Figure 1.1 presents one such attempt. Of
course there are many many more languages than those shown, in particular if one
counts also more domain-specific languages such as Matlab, SAS and R, and strange
“languages” such as spreadsheets [5].
In general, languages lower in the diagram (near the time axis) are closer to
the real hardware than those higher in the diagram, which are more “high-level”
in some sense. In Fortran77 or C, it is fairly easy to predict what instructions and
how many instructions will be executed at run-time for a given line of program. The
mental machine model that the C or Fortran77 programmer must use to write efficient
programs is close to the real machine.
Conversely, the top-most languages (SASL, Haskell, Standard ML, F#, Scala)
are functional languages, possibly with lazy evaluation, with dynamic or advanced
static type systems and with automatic memory management, and it is in general
difficult to predict how many machine instructions are required to evaluate any given
expression. The mental machine model that the Haskell or Standard ML or F# or
Scala programmer must use to write efficient programs is far from the details of a
real machine, so he can think on a rather higher level. On the other hand, he loses
control over detailed efficiency.
It is remarkable that the recent mainstream languages Java and C#, especially their
post-2004 incarnations, have much more in common with the academic languages
of the 1980’s than with those languages that were used in the “real world” during
those years (C, Pascal, C++).
SASL HASKELL
F#
LISP ML STANDARD ML
Scala
CAML LIGHT OCAML
SCHEME C# 2 C# 4
PROLOG GJ Java 5
BETA
SMALLTALK JAVA C# VB.NET 10
Go
SIMULA VISUAL BASIC
ALGOL 68 C++
ALGOL
CPL BCPL B C
FORTRAN FORTRAN77
1.7 Exercises
Exercise 1.1 (i) File Intro2.fs contains a definition of the expr expression
language and an evaluation function eval. Extend the eval function to handle
three additional operators: "max", "min", and "==". Like the existing operators,
they take two argument expressions. The equals operator should return 1 when true
and 0 when false.
(ii) Write some example expressions in this extended expression language, using
abstract syntax, and evaluate them using your new eval function.
(iii) Rewrite one of the eval functions to evaluate the arguments of a primitive
before branching out on the operator, in this style:
let rec eval e (env : (string * int) list) : int =
match e with
| ...
| Prim(ope, e1, e2) ->
let i1 = ...
let i2 = ...
match ope with
| "+" -> i1 + i2
| ...
(iv) Extend the expression language with conditional expressions If(e1, e2,
e3) corresponding to Java’s expression e1 ? e2 : e3 or F#’s conditional
expression if e1 then e2 else e3.
10 1 Introduction
You need to extend the expr datatype with a new constructor If that takes three
expr arguments.
(v) Extend the interpreter function eval correspondingly. It should evaluate e1, and
if e1 is non-zero, then evaluate e2, else evaluate e3. You should be able to evaluate
the expression If(Var "a", CstI 11, CstI 22) in an environment that
binds variable a.
Note that various strange and non-standard interpretations of the conditional
expression are possible. For instance, the interpreter might start by testing whether
expressions e2 and e3 are syntactically identical, in which case there is no need to
evaluate e1, only e2 (or e3). Although possible, this shortcut is rarely useful.
Exercise 1.2 (i) Declare an alternative datatype aexpr for a representation of arith-
metic expressions without let-bindings. The datatype should have constructors CstI,
Var, Add, Mul, Sub, for constants, variables, addition, multiplication, and subtrac-
tion.
Then x ∗ (y + 3) is represented as Mul(Var "x", Add(Var "y", CstI
3)), not as Prim("*", Var "x", Prim("+", Var "y", CstI 3)).
(ii) Write the representation of the expressions v − (w + z) and 2 ∗ (v − (w + z))
and x + y + z + v.
(iii) Write an F# function fmt : aexpr -> string to format expressions
as strings. For instance, it may format Sub(Var "x", CstI 34) as the string
"(x - 34)". It has very much the same structure as an eval function, but takes no
environment argument (because the name of a variable is independent of its value).
(iv) Write an F# function simplify : aexpr -> aexpr to perform expres-
sion simplification. For instance, it should simplify (x + 0) to x, and simplify (1 + 0)
to 1. The more ambitious student may want to simplify (1 + 0) ∗ (x + 0) to x. Hint:
Pattern matching is your friend. Hint: Don’t forget the case where you cannot simplify
anything.
You might consider the following simplifications, plus any others you find useful
and correct:
0+e −→ e
e+0 −→ e
e−0 −→ e
1∗e −→ e
e∗1 −→ e
0∗e −→ 0
e∗0 −→ 0
e−e −→ 0
Exercise 1.3 Write a version of the formatting function fmt from the preceding
exercise that avoids producing excess parentheses. For instance,
Mul(Sub(Var "a", Var "b"), Var "c")
is formatted as "a-(b-c)".
Hint: This can be achieved by declaring the formatting function to take an extra
parameter pre that indicates the precedence or binding strength of the context. The
new formatting function then has type fmt : int -> expr -> string.
Higher precedence means stronger binding. When the top-most operator of an
expression to be formatted has higher precedence than the context, there is no need
for parentheses around the expression. A left associative operator of precedence 6,
such as minus (-), provides context precedence 5 to its left argument, and context
precedence 6 to its right argument.
As a consequence, Sub(Var "a", Sub(Var "b", Var "c")) will be
parenthesized a-(b-c) but Sub(Sub(Var "a", Var "b"), Var "c")
will be parenthesized a-b-c.
Exercise 1.4 This chapter has shown how to represent abstract syntax in functional
languages such as F# (using algebraic datatypes) and in object-oriented languages
such as Java or C# (using a class hierarchy and composites).
(i) Use Java or C# classes and methods to do what we have done using the F# datatype
aexpr in the preceding exercises. Design a class hierarchy to represent arithmetic
expressions: it could have an abstract class Expr with subclasses CstI, Var, and
Binop, where the latter is itself abstract and has concrete subclasses Add, Mul
and Sub. All classes should implement the toString() method to format an
expression as a String.
The classes may be used to build an expression in abstract syntax, and then print
it, as follows:
Expr e = new Add(new CstI(17), new Var("z"));
System.out.println(e.toString());
(ii) Create three more expressions in abstract syntax and print them.
(iii) Extend your classes with facilities to evaluate the arithmetic expressions, that
is, add a method int eval(env).
(iv) Add a method Expr simplify() that returns a new expression where alge-
braic simplifications have been performed, as in part (iv) of Exercise 1.2.
12 1 Introduction
References
1. Hansen, M.R., Rischel, H.: Functional Programming Using F#. Cambridge University Press
(2013)
2. Hoare, C.: Hints on programming language design. In: ACM SIGACT/SIGPLAN Symposium
on Principles of Programming Languages 1973, Boston, Massachusetts. ACM Press (1973)
3. Landin, P.: The next 700 programming languages. Commun. ACM 9(3), 157–166 (1966)
4. Milner, R., Tofte, M., Harper, R.: The Definition of Standard ML. The MIT Press (1990)
5. Sestoft, P.: Spreadsheet Implementation Technology. Basics and Extensions. MIT Press (2014).
ISBN 978-0-262-52664-7, 325 pages
6. Syme, D., Granicz, A., Cisternino, A.: Expert F#. Apress (2007)
7. Tennent, R.: Language design methods based on semantic principles. Acta Inform. 8, 97–112
(1977)
8. Tennent, R.: Principles of Programming Languages. Prentice-Hall (1981)
9. Wirth, N.: On the design of programming languages. In: Rosenfeldt, J. (ed.) IFIP Information
Processing 74, Stockholm, Sweden, pp. 386–393. North-Holland (1974)
Chapter 2
Interpreters and Compilers
This chapter introduces the distinction between interpreters and compilers, and
demonstrates some concepts of compilation, using the simple expression language
as an example. Some concepts of interpretation are illustrated also, using a stack
machine as an example.
File Contents
Intcomp/Intcomp1.fs very simple expression interpreter and compilers
Intcomp/Machine.java abstract machine in Java (see Sect. 2.8)
Intcomp/prog.ps a simple Postscript program (see Sect. 2.6)
Intcomp/sierpinski.eps an intricate Postscript program (see Sect. 2.6)
Input
Input
which the interpreter is written, for instance F#). When the program in the interpreted
language L is a sequence of simple instructions, and thus looks like machine code,
the interpreter is often called an abstract machine or virtual machine.
A compiler takes as input a source program and generates as output another
program, called a target program, which can then be executed; see Fig. 2.2. We must
distinguish three languages: the source language S (e.g. expr) of the input programs,
the target language T (e.g. texpr) of the output programs, and the implementation
language I (for instance, F#) of the compiler itself.
The compiler does not execute the program; after the target program has been
generated it must be executed by a machine or interpreter which can execute pro-
grams written in language T . Hence we can distinguish between compile-time (at
which time the source program is compiled into a target program) and run-time (at
which time the target program is executed on actual inputs to produce a result). At
compile-time one usually also performs various so-called well-formedness checks
of the source program: are all variables bound, do operands have the correct type in
expressions, and so on.
The scope of a variable binding is that part of a program in which it is visible. For
instance, the scope of x in this F# function definition is just the function body x+3:
let f x = x + 3
A language has static scope if the scopes of bindings follow the syntactic structure
of the program. Most modern languages, such as C, C++, Pascal, Algol, Scheme,
Java, C# and F# have static scope; but see Sect. 4.7 for some that do not.
Exploring the Variety of Random
Documents with Different Content
jeune fille un regard limpide dont elle se ressouvint plus tard, comme
si, en cet instant-là, un autre « moi » eût pris possession d’elle-
même.
La figure de Julien, longue, plutôt fine que robuste, était dominée
par un front d’une ampleur éclatante. Une force de réflexion
tranquille s’accumulait en ses yeux, des yeux d’un brun clair, devant
qui tout semblait doux et fraternel. Sa moustache n’empêchait pas
de voir au coin de sa lèvre une fossette pleine de grâce. Il avait le
teint vermeil, la main effilée, les signes d’une élégance native qu’un
fond sanguin de vigueur pondérait.
Pauline cependant tourna aussitôt son attention vers Edmée
Rude ; ravie de délier sa langue avec elle, car, depuis sa venue à
Sens, elle vivait sans aucune compagne. Edmée, rose et fluette, le
menton enfoncé dans une étole de fourrure, présentait une vivacité
de minois toute bourguignonne. Pauline se pencha pour baiser les
joues de Marthe, la cadette ; celle-ci, avec un battement de cils, la
dévisageait de son œil hardi, profond.
— La gentille petite sœur que vous avez, dit Pauline bonnement.
— Oui, gentille, même trop, repartit Edmée tandis qu’elle
caressait les cheveux déliés et blonds de Marthe. Elle a de ces idées
parfois qui nous font peur. Hier soir, elle regardait, derrière la vitre,
les étoiles : On ne peut pas les attraper avec des échelles ? nous a-
t-elle demandé. Le bon Jésus saura bien me mener là-haut. Est-ce
qu’il m’y mènera bientôt ? Tu viendras m’y trouver, Edmée, et Julien
aussi. J’aurai des ailes, n’est-ce pas, maman ?
Une surprise altéra le sourire de Pauline ; elle ne pouvait
comprendre cette curiosité du Paradis ; aux premières paroles
d’Edmée, l’obstacle chrétien se posait entre elles. Edmée ne savait
pas encore Pauline irréligieuse ; mais elle devina qu’une chose
inconnue les séparait ; et, sans s’attarder sur des intimités vaines
pour une étrangère, elle lui parla du paysage qu’elles surplombaient,
« bien vilain sous son capuchon gris ».
— C’est au printemps qu’il faudra le voir et à l’automne. D’ici,
vers la mi-octobre, la plaine est délicieuse. Je ne sais si vous êtes
comme moi ; j’aime tant l’automne, l’odeur des feuilles tombées, les
peupliers légers, tout en feu comme des tabernacles !
— Moi, répondit Pauline, toute saison me va ; mais j’adore l’été.
Quand le soleil chante, que les oiseaux chantent, je me sens plus de
cœur à chanter.
— Vous devez être musicienne…
— J’ai de la voix, répondit simplement Pauline, dédaignant de se
faire valoir ; et vous ?
Edmée lui déclara qu’elle se passerait de pain plus volontiers que
de son piano ; son père jouait du violon, son frère, du violoncelle ;
chaque dimanche, après leur promenade, et le soir, de temps à
autre, ils exécutaient des trios.
Cette découverte d’une affinité précieuse charma Pauline
davantage qu’Edmée, parce que sa solitude lui rendait une amie
plus désirable. Tout en causant, elles se dirigeaient vers une butte
d’où, jadis, suivant la tradition, les sentinelles romaines observaient
au loin la vallée.
— Si nous grimpions là-haut, insinua Marthe à sa sœur.
— Allons-y, fit Pauline. Elle entraîna Marthe par une main, Edmée
s’empara de l’autre, et toutes trois prirent leur élan jusqu’au faîte du
glacis ; puis, riant et courant, elles redescendirent.
— Vous êtes, mademoiselle, plus leste que les chèvres, dit à
Pauline M. Rude qui survint avec son fils et M. Ardel.
— J’ai eu des aïeux montagnards, répliqua-t-elle en manière de
badinage, je suis faite pour les cimes !
Julien, au son de ces derniers mots, la fixa, se tut une seconde,
et reprit la conversation qu’il avait entamée sur le livre de M. Ardel.
L’auteur jouissait de s’entendre commenter par ce jeune homme
avec une ferveur ingénue.
— Vous allez me trouver sentimental, poursuivit Julien ; mais un
des traits que j’admire en Saint-Simon, c’est d’avoir ordonné, dans
son testament, qu’on liât après sa mort son cercueil à celui de sa
« chère épouse » par des anneaux et des crochets de fer, afin que
leurs corps fussent unis jusqu’à la Résurrection. Pour ma part, si je
me marie jamais, je ne voudrais qu’un amour de cette trempe, long
et fort comme l’éternité…
Pauline n’entendit pas sans étonnement un langage si nouveau
pour elle ; mais elle s’étonna peu de voir, à mesure que Julien
s’animait, le professeur plisser sa bouche d’une moue d’ironie
sceptique.
— Voyez, dit tout à coup M. Rude, le joli rayon, derrière nous, là-
bas !
En effet, à la chute du jour, tandis que les coteaux de l’Est et la
plaine succombaient sous un brouillard de plus en plus dense où
des cheminées d’usines brandissaient leurs fumées sombres, les
nuées du couchant se fendirent, le soleil apparut, tel qu’un prêtre en
chape rutilante qui s’en va dans l’abside illuminée d’une basilique, et
au-dessus de Saint-Martin un peu de ciel flotta, fugitif et doux. La
coloration de l’air froid communiquait aux visages une sorte de
pureté diaphane. Julien, pour Pauline, en fut transfiguré.
— Voici l’heure, dit-il, que nous aimons en hiver, celle où
s’allument les lampes des boutiques, et les réverbères, un à un,
dans la brume, le long des quais…
— Et l’heure, acheva Edmée, où des étincelles pétillent sur les
fourneaux des marchands de marrons.
Tous rirent de cette saillie et ils reprirent ensemble le chemin de
la ville. Les deux jeunes filles descendaient en avant ; Julien suivait,
et Marthe, lasse de la course un peu longue pour des jambes de
cinq ans, se pendait à sa main. Plus haut, dans l’étroit sentier,
sonnait le pas martelé des deux professeurs ; la grosse voix de M.
Rude roulait comme un grondement. Il expliquait à son collègue
qu’après avoir surveillé cinq ou six heures par jour les barbouillages
de ses élèves, il reprenait, chaque soir, dans la belle saison du
moins, avec une joie d’enfant, son labeur de peintre :
— Mais, ajoutait-il, je conçois l’exécution d’un tableau comme
l’aurait conçue un disciple de Memling, et vous pensez que de temps
j’y mets.
M. Ardel ne lui cacha point qu’à sa place il se fût hâté de produire
des toiles faciles et fructueuses ; de la sorte, il vivrait indépendant et
se donnerait tout à son art :
— Non, mon cher, répliqua M. Rude tranquillement. Je suis un
pauvre passeur qui mène d’une rive à l’autre les générations ; quand
personne ne vient me quérir sur la berge, je rentre dans ma cahute
et je songe à mes pinceaux.
Pauline, en descendant, contait à Edmée son uniforme existence
entre un père tyrannisé par ses livres et un grand-oncle célibataire,
maniaque et morose, qu’ils avaient recueilli. Elle l’entretenait de leur
peine à trouver une domestique, du logis où ils étaient encore assez
mal installés :
— Votre rue me plairait, observa Edmée, parce que l’église est à
deux pas de chez vous.
Pauline, après un court intervalle, confessa :
— Nous n’avons que faire d’une église ; mon père n’est pas
croyant, ni moi non plus…
Elle regarda Edmée, aperçut dans ses yeux affables une
désillusion subite ; et pourtant elle ne regretta point de l’avoir avertie
sans réticence ; une pointe d’orgueil exaltait sa franchise ; si Edmée
la voulait pour amie, elle l’accepterait comme elle était. Mais Julien,
à deux pas derrière, émit d’une voix paisible et pénétrante :
— Si vous saviez quel don c’est de croire !
Elle tourna la tête et riposta durement :
— Ce don-là m’est aussi étranger que les chimères d’un fumeur
d’opium.
Julien se rapprocha : bien qu’une émotion vibrât dans sa gorge, il
se maintenait calme au dehors :
— Des chimères ! Pour les aveugles-nés, le soleil aussi est une
chimère, ou le serait, s’ils ne croyaient en ceux qui voient.
— C’est possible, trancha Pauline, je suis une aveugle-née.
Un silence d’embarras aurait succédé à ces chocs imprévus,
sans une diversion qui s’offrit.
Ils attendaient au bas de la montée M. Rude et M. Ardel. Un
prêtre, venant de la campagne, passa dans le crépuscule, sur la
route. Un paysan, venant de la ville, ivre et hors d’état d’aller plus
loin, s’était assis au bord du fossé. A la vue de l’ecclésiastique, il
montra le poing, grogna des invectives. Le prêtre s’arrêta en face de
cet homme avec une attitude compatissante :
— Mon ami, lui dit-il, d’où êtes-vous ? Voulez-vous que je vous
aide à rentrer ? Le froid de la nuit va vous prendre. On vous
ramassera mort demain.
L’ivrogne tenta de se dresser, et tomba sur les genoux ; mais il
vociférait :
— Viens ici, feignant de corbeau, que je te fasse ton affaire !
Le prêtre immobile le considéra tristement, puis il s’éloigna.
Avant de disparaître sous le pont du viaduc, il se retourna une fois
encore.
Du talus, M. Ardel avait pu l’examiner ; un étonnement anxieux
l’attachait à suivre la forme noire qui s’en allait ; dès qu’il ne la vit
plus, il dit à M. Rude :
— Tout de même, il y a des rencontres inexplicables. Zoroastre,
d’après la légende, croisa, dans une allée de son jardin, sa propre
image, son double qui déambulait. Ce qui m’arrive est autre. J’ai un
frère vicaire à Lyon ; or, ce prêtre, là-bas, lui ressemble comme son
fantôme. C’est son encolure, sa taille, son profil. Matériellement, ce
ne peut être lui, et pourtant c’est lui…
— Il serait facile de s’en assurer, offrit Julien. Si vous me
permettez, je le rattrape et lui demande son nom.
M. Ardel s’y opposa : alors même que son frère, par une
fantastique coïncidence, visitant la région, se fût promené, à cette
heure, sur cette route, il ne tenait pas à le revoir ; depuis longtemps
ils étaient brouillés.
Cependant, on se remit en marche. Au passage à niveau, le
sifflet furieux d’un rapide arrivant de Paris les arrêta. Devant eux, les
deux lampes du chariot brûlant coururent le long des parallèles
d’acier ; le train roula, trépida, comme un ouragan, dans la fumée, et,
avant qu’ils eussent traversé la voie, le fanal du dernier wagon se
perdait au fond de la nuit tombante.
Pauline en prit occasion pour confier à Edmée son désir des
grands pays lointains que, sans doute, elle ne connaîtrait jamais ;
elle se divertissait en lisant des récits exotiques, de même qu’en
chantant : Cet asile aimable, d’Orphée, elle trouvait l’illusion d’irréels
bocages élyséens.
Leur propos revint à la musique, comme à un des points solides
où leurs enthousiasmes concordaient. Il fut décidé que, le dimanche
suivant, M. Ardel et sa fille iraient en écouter chez les Rude. Pauline
se sépara d’eux, le cœur dilaté d’une joie naïve ; avide d’affection,
elle s’élançait à cette sympathie neuve. M. Rude l’attirait par une
largeur de bonté dont son propre père semblait incapable. Elle voyait
déjà en Edmée une sœur élue, et si tendre, si délicate ! Quant à
Julien, plus distant, elle ne lui gardait nulle rancune de sa légitime
réplique à une parole vexante : Nous sommes quittes, pensait-elle.
Sans être troublée de son image, elle lui reconnaissait une
mystérieuse supériorité, une âme loyale, ardente que, malgré leurs
contradictions, elle aimerait.
Dans le soir funèbre et glacial, elle rentra tout en fête ; sa vie
prochaine s’ouvrait comme un champ de roses sous une lune de
printemps.
II
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
textbookfull.com