0% found this document useful (0 votes)
49 views85 pages

Principles of Programming Languages Undergraduate Topics in Computer Science 1st Edition by Gilles Dowek ISBN 1848820321 9781848820326 PDF Download

The document provides an overview of various textbooks related to programming languages and computer science, authored by experts in the field. It highlights the series 'Undergraduate Topics in Computer Science' which aims to deliver high-quality instructional content for undergraduate students. Additionally, it discusses the principles of programming languages, focusing on the Java language while comparing it to Caml and C to help students understand universal programming concepts.

Uploaded by

liessbrien8n
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
49 views85 pages

Principles of Programming Languages Undergraduate Topics in Computer Science 1st Edition by Gilles Dowek ISBN 1848820321 9781848820326 PDF Download

The document provides an overview of various textbooks related to programming languages and computer science, authored by experts in the field. It highlights the series 'Undergraduate Topics in Computer Science' which aims to deliver high-quality instructional content for undergraduate students. Additionally, it discusses the principles of programming languages, focusing on the Java language while comparing it to Caml and C to help students understand universal programming concepts.

Uploaded by

liessbrien8n
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 85

Principles of Programming Languages

Undergraduate Topics in Computer Science 1st


Edition by Gilles Dowek ISBN 1848820321
9781848820326 pdf download
https://ebookball.com/product/principles-of-programming-
languages-undergraduate-topics-in-computer-science-1st-edition-
by-gilles-dowek-isbn-1848820321-9781848820326-19844/

Explore and download more ebooks or textbooks


at ebookball.com
Get Your Digital Files Instantly: PDF, ePub, MOBI and More
Quick Digital Downloads: PDF, ePub, MOBI and Other Formats

Introduction to the Theory of Programming Languages 1st Edition by


Gilles Dowek, Jean Jacques Levy ISBN 0857290762 9780857290762

https://ebookball.com/product/introduction-to-the-theory-of-
programming-languages-1st-edition-by-gilles-dowek-jean-jacques-
levy-isbn-0857290762-9780857290762-9896/

A Concise Introduction to Data Compression Undergraduate Topics in


Computer Science 1st Edition by David Salomon ISBN 1848000715
9781848000711

https://ebookball.com/product/a-concise-introduction-to-data-
compression-undergraduate-topics-in-computer-science-1st-edition-
by-david-salomon-isbn-1848000715-9781848000711-19848/

Introduction to Computer Graphics Using Java 2D and 3D Undergraduate


Topics in Computer Science 1st Edition by Frank Klawonn ISBN
1447127323 9781447127321

https://ebookball.com/product/introduction-to-computer-graphics-
using-java-2d-and-3d-undergraduate-topics-in-computer-
science-1st-edition-by-frank-klawonn-
isbn-1447127323-9781447127321-19850/

Theory of Computer Science Automata Languages and Computation 3rd


Edition by ISBN KLP Mishra, N Chandrasekaran ISBN 9788120329683

https://ebookball.com/product/theory-of-computer-science-
automata-languages-and-computation-3rd-edition-by-isbn-klp-
mishra-n-chandrasekaran-isbn-9788120329683-15850/
Concepts in Programming Languages 1st Edition by John Mitchell ISBN
051103492X 9780511034923

https://ebookball.com/product/concepts-in-programming-
languages-1st-edition-by-john-mitchell-
isbn-051103492x-9780511034923-12500/

Schaum's Outline of Principles of Computer Science 1st Edition by Carl


Reynolds, Paul Tymann ISBN 0071510370 9780071510370

https://ebookball.com/product/schaum-s-outline-of-principles-of-
computer-science-1st-edition-by-carl-reynolds-paul-tymann-
isbn-0071510370-9780071510370-19798/

IEEE Standard Glossary of Computer Languages 1st Edition by IEEE ISBN

https://ebookball.com/product/ieee-standard-glossary-of-computer-
languages-1st-edition-by-ieee-isbn-9110/

Concepts of Programming Languages 9th Edition by Robert Sebesta ISBN


0136073476 9780136073475

https://ebookball.com/product/concepts-of-programming-
languages-9th-edition-by-robert-sebesta-
isbn-0136073476-9780136073475-13490/

Object Oriented Programming Languages Interpretation 1st Edition by


Iain Craig ISBN 184628774X 9781846287749

https://ebookball.com/product/object-oriented-programming-
languages-interpretation-1st-edition-by-iain-craig-
isbn-184628774x-9781846287749-19842/
Undergraduate Topics in Computer Science
Undergraduate Topics in Computer Science (UTiCS) delivers high-quality instructional 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.

Also in this series

Iain D. Craig
Object-Oriented Programming Languages: Interpretation
978-1-84628-773-2
Max Bramer
Principles of Data Mining
978-1-84628-765-7
Hanne Riis Nielson and Flemming Nielson
Semantics with Applications: An Appetizer
978-1-84628-691-9
Michael Kifer and Scott A. Smolka
Introduction to Operating System Design and Implementation: The OSP 2 Approcah
978-1-84628-842-5
Phil Brooke and Richard Paige
Practical Distributed Processing
978-1-84628-840-1
Frank Klawonn
Computer Graphics with Java
978-1-84628-847-0
David Salomon
A Concise Introduction to Data Compression
978-1-84800-071-1
David Makinson
Sets, Logic and Maths for Computing
978-1-84628-844-9
Orit Hazzan
Agile Software Engineering
978-1-84800-198-5
Pankaj Jalote
A Concise Introduction to Software Engineering
978-1-84800-301-9
Alan P. Parkes
A Concise Introduction to Languages and Machines
978-1-84800-120-6
Gilles Dowek

Principles
of Programming
Languages

123
Gilles Dowek
École Polytechnique
France

Series editor
Ian Mackie, École Polytechnique, France

Advisory board
Samson Abramsky, University of Oxford, UK
Chris Hankin, Imperial College London, UK
Dexter Kozen, Cornell University, USA
Andrew Pitts, University of Cambridge, UK
Hanne Riis Nielson, Technical University of Denmark, Denmark
Steven Skiena, Stony Brook University, USA
Iain Stewart, University of Durham, UK
David Zhang, The Hong Kong Polytechnic University, Hong Kong

Undergraduate Topics in Computer Science ISSN 1863-7310


ISBN: 978-1-84882-031-9 e-ISBN: 978-1-84882-032-6
DOI: 10.1007/978-1-84882-032-6

British Library Cataloguing in Publication Data


A catalogue record for this book is available from the British Library

Library of Congress Control Number: 2008943965

Based on course notes by Gilles Dowek published in 2006 by L’Ecole Polytechnique with the following
title: “Les principes des langages de programmation.”

c Springer-Verlag London Limited 2009


Apart from any fair dealing for the purposes of research or private study, or criticism or review, as
permitted under the Copyright, Designs and Patents Act 1988, this publication may only be repro-
duced, stored or transmitted, in any form or by any means, with the prior permission in writing of the
publishers, or in the case of reprographic reproduction in accordance with the terms of licenses issued
by the Copyright Licensing Agency. Enquiries concerning reproduction outside those terms should be
sent to the publishers.
The use of registered names, trademarks, etc., in this publication does not imply, even in the absence of
a specific statement, that such names are exempt from the relevant laws and regulations and therefore
free for general use.
The publisher makes no representation, express or implied, with regard to the accuracy of the infor-
mation contained in this book and cannot accept any legal responsibility or liability for any errors or
omissions that may be made.

Printed on acid-free paper

Springer Science+Business Media


springer.com
The author wants to thank François Pottier, Philippe Baptiste, Julien
Cervelle, Albert Cohen, Olivier Delande, Olivier Hermant, Ian Mackie, François
Morain, Jean-Marc Steyaert and Paul Zimmermann for their remarks on a first
version of this book.
Preface

We’ve known about algorithms for millennia, but we’ve only been writing com-
puter programs for a few decades. A big difference between the Euclidean or
Eratosthenes age and ours is that since the middle of the twentieth century,
we express the algorithms we conceive using formal languages: programming
languages.
Computer scientists are not the only ones who use formal languages. Op-
tometrists, for example, prescribe eyeglasses using very technical expressions,
such as “OD: -1.25 (-0.50) 180◦ OS: -1.00 (-0.25) 180◦ ”, in which the parenthe-
ses are essential. Many such formal languages have been created throughout
history: musical notation, algebraic notation, etc. In particular, such languages
have long been used to control machines, such as looms and cathedral chimes.
However, until the appearance of programming languages, those languages
were only of limited importance: they were restricted to specialised fields with
only a few specialists and written texts of those languages remained relatively
scarce. This situation has changed with the appearance of programming lan-
guages, which have a wider range of applications than the prescription of eye-
glasses or the control of a loom, are used by large communities, and have allowed
the creation of programs of many hundreds of thousands of lines.
The appearance of programming languages has allowed the creation of ar-
tificial objects, programs, of a complexity incomparable to anything that has
come before, such as steam engines or radios. These programs have, in return,
allowed the creation of other complex objects, such as integrated circuits made
of millions of transistors, or mathematical proofs that are hundreds of thou-
sands of pages long. It is very surprising that we have succeeded in writing
such complex programs in languages comprising such a small number of con-
structs — assignment, loops, etc. — that is to say in languages barely more
sophisticated than the language of prescription eyeglasses.
vii
viii Preface

Programs written in these programming languages have the novelty of not


only being understandable by humans, which brings them closer to the scores
used by organists, but also readable by machines, which brings them closer to
the punch cards used in Barbarie organs.
The appearance of programming languages has therefore profoundly im-
pacted our relationship with language, complexity, and machines.
This book is an introduction to the principles of programming languages.
It uses the Java language for support. It is intended for students who already
have some experience with computer programming. It is assumed that they
have learned some programming empirically, in a single programming language,
other than Java.
The first objective of this book will then be to learn the fundamentals
of the Java programming language. However, knowing a single programming
language is not sufficient to be a good programmer. For this, you must not
only know several languages, but be able to easily learn new ones. This requires
that you understand universal concepts like functions or cells, which exist in
one form or another in all programming languages. This can only be done by
comparing two or more languages. In this book, two comparison languages have
been chosen: Caml and C. Therefore, the goal is not for the students to learn
three programming languages simultaneously, but that with the comparison
with Caml and C, they can learn the principles around which programming
languages are created. This understanding will allow them to develop, if they
wish, a real competence in Caml or in C, or in any other programming language.
Another objective of this book is for the students to begin acquiring the
tools which permit them to precisely define the meaning of the program. This
precision is, indeed, the only means to clearly understand what happens when
a program is executed, and to reason in situations where complexity defies
intuition. The idea is to describe the meaning of a statement by a function
operating on a set of states. However, our expectations of this objective remain
modest: students wishing to pursue this goal will have to do so elsewhere.
The final objective of this course is to learn basic algorithms for lists and
trees. Here too, our expectations remain modest: students wishing to pursue
this will also have to look elsewhere.
Contents

1. Imperative Core . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Five Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.1 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.2 Variable Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.3 Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.4 Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1.5 Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2 Input and Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.1 Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.2 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3 The Semantics of the Imperative Core . . . . . . . . . . . . . . . . . . . . . . . 8
1.3.1 The Concept of a State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3.2 Decomposition of the State . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3.3 A Visual Representation of a State . . . . . . . . . . . . . . . . . . . 10
1.3.4 The Value of Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.5 Execution of Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2. Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.1 The Concept of Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.1.1 Avoiding Repetition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.1.2 Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.1.3 Return Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.1.4 The return Construct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.1.5 Functions and Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.1.6 Global Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.1.7 The Main Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

ix
x Contents

2.1.8 Global Variables Hidden by Local Variables . . . . . . . . . . . . 27


2.1.9 Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.2 The Semantics of Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.2.1 The Value of Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.2.2 Execution of Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.2.3 Order of Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.2.4 Caml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.2.5 C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.3 Expressions as Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.4 Passing Arguments by Value and Reference . . . . . . . . . . . . . . . . . . 37
2.4.1 Pascal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.4.2 Caml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.4.3 C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.4.4 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

3. Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.1 Calling a Function from Inside the Body of that Function . . . . . 47
3.2 Recursive Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.2.1 Recursive Definitions and Circular Definitions . . . . . . . . . . 48
3.2.2 Recursive Definitions and Definitions by Induction . . . . . . 49
3.2.3 Recursive Definitions and Infinite Programs . . . . . . . . . . . . 49
3.2.4 Recursive Definitions and Fixed Point Equations . . . . . . . 51
3.3 Caml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.4 C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.5 Programming Without Assignment . . . . . . . . . . . . . . . . . . . . . . . . . 55

4. Records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.1 Tuples with Named Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.1.1 The Definition of a Record Type . . . . . . . . . . . . . . . . . . . . . 60
4.1.2 Allocation of a Record . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.1.3 Accessing Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.1.4 Assignment of Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.1.5 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.1.6 The Semantics of Records . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.2 Sharing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4.2.1 Sharing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4.2.2 Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.2.3 Wrapper Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.3 Caml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.3.1 Definition of a Record Type . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.3.2 Creating a Record . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.3.3 Accessing Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Contents xi

4.3.4 Assigning to Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74


4.4 C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.4.1 Definition of a Record Type . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.4.2 Creating a Record . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.4.3 Accessing Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
4.4.4 Assigning to Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
4.5 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
4.5.1 Array Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
4.5.2 Allocation of an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
4.5.3 Accessing and Assigning to Fields . . . . . . . . . . . . . . . . . . . . 80
4.5.4 Arrays of Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
4.5.5 Arrays in Caml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
4.5.6 Arrays in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

5. Dynamic Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85


5.1 Recursive Records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
5.1.1 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
5.1.2 The null Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
5.1.3 An Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
5.1.4 Recursive Definitions and Fixed Point Equations . . . . . . . 88
5.1.5 Infinite Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.2 Disjunctive Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.3 Dynamic Data Types and Computability . . . . . . . . . . . . . . . . . . . . 92
5.4 Caml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
5.5 C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.6 Garbage Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
5.6.1 Inaccessible Cells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
5.6.2 Programming without Garbage Collection . . . . . . . . . . . . . 98
5.6.3 Global Methods of Memory Management . . . . . . . . . . . . . . 100
5.6.4 Garbage Collection and Functions . . . . . . . . . . . . . . . . . . . . 102

6. Programming with Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103


6.1 Finite Sets and Functions of a Finite Domain . . . . . . . . . . . . . . . . 103
6.1.1 Membership . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
6.1.2 Association Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
6.2 Concatenation: Modify or Copy . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
6.2.1 Modify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
6.2.2 Copy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
6.2.3 Using Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
6.2.4 Chemical Reactions and Mathematical Functions . . . . . . . 111
6.3 List Inversion: an Extra Argument . . . . . . . . . . . . . . . . . . . . . . . . . . 112
6.4 Lists and Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
xii Contents

6.5 Stacks and Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114


6.5.1 Stacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
6.5.2 Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
6.5.3 Priority Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

7. Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
7.1 Exceptional Circumstances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
7.2 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
7.3 Catching Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
7.4 The Propagation of Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
7.5 Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
7.6 The Semantics of Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
7.7 Caml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

8. Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
8.1 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
8.1.1 Functions as Part of a Type . . . . . . . . . . . . . . . . . . . . . . . . . 127
8.1.2 The Semantics of Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.2 Dynamic Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.3 Methods and Functional Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
8.4 Static Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
8.5 Static Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
8.6 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
8.7 Caml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

9. Programming with Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139


9.1 Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
9.2 Traversing a Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
9.2.1 Depth First Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
9.2.2 Breadth First Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
9.3 Search Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
9.3.1 Membership . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
9.3.2 Balanced Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
9.3.3 Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
9.4 Priority Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
9.4.1 Partially Ordered Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
9.4.2 Partially Ordered Balanced Trees . . . . . . . . . . . . . . . . . . . . . 153

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
1
Imperative Core

1.1 Five Constructs


Most programming languages have, among others, five constructs: assignment,
variable declaration, sequence, test, and loop. These constructs form the im-
perative core of the language.

1.1.1 Assignment

The assignment construct allows the creation of a statement with a variable x


and an expression t. In Java, this statement is written as x = t;. Variables are
identifiers which are written as one of more letters. Expressions are composed
of variables and constants with operators, such as +, -, *, / — division — and
% — modulo.
Therefore, the following statements
x = y % 3;

x = y;

y = 3;

x = x + 1;

G. Dowek, Principles of Programming Languages, 1


Undergraduate Topics in Computer Science, DOI 10.1007/978-1-84882-032-6_1,

c Springer-Verlag London Limited 2009
2 1. Imperative Core

are all proper Java statements, while


y + 3 = x;

x + 2 = y + 5;
are not.
To understand what happens when you execute the statement x = t; sup-
pose that within the recesses of your computer’s memory, there is a com-
partment labelled x. Executing the statement x = t; consists of filling this
compartment with the value of the expression t. The value previously contained
in compartment x is erased. If the expression t is a constant, for example 3,
its value is the same constant. If it is an expression with no variables, such as
3 + 4, its value is obtained by carrying out mathematical operations, in this
case, addition. If expression t contains variables, the values of these variables
must be looked up in the computer’s memory. The whole of the contents of the
computer’s memory is called a state.
Let us consider, initially, that expressions, such as x + 3, and statements,
such as y = x + 3;, form two disjoint categories. Later, however, we shall be
brought to revise this premise.
In these examples, the values of expressions are integers. Computers can
only store integers within a finite interval. In Java, integers must be between
-231 and 231 - 1, so there are 232 possible values. When a mathematical op-
eration produces a value outside of this interval, the result is kept within the
interval by taking its modulo 232 remainder. Thus, by adding 1 to 231 - 1, that
is to say 2147483647, we leave the interval and then return to it by removing
232 , which gives -231 or -2147483648.
Exercise 1.1
What is the value of the variable x after executing the following state-
ment?

x = 2 * 1500000000;

In Caml, assignment is written x := t. In the expression t, we designate


the value of x, not with the expression x itself, but with the expression !x. Thus,
in Caml we write y := !x + 1 while in Java we write y = x + 1;.
In C, assignment is written as it is in Java.
1.1 Five Constructs 3

1.1.2 Variable Declaration

Before being able to assign values to a variable x, it must be declared, which


associates the name x to a location in the computer’s memory.
Variable declaration is a construct that allows the creation of a statement
composed of a variable, an expression, and a statement. In Java, this statement
is written {int x = t; p} where p is a statement, for example {int x = 4;
x = x + 1;}. The variable x can then be used in the statement p, which is
called the scope of variable x.
It is also possible to declare a variable without giving it an initial value,
for example, {int x; x = y + 4;}. We must of course be careful not to use
a variable which has been declared without an initial value and that has not
been assigned a value. This produces an error.
Apart from the int type, Java has three other integer types that have
different intervals. These types are defined in Table 1.1. When a mathematical
operation produces a value outside of these intervals, the result is returned to
the interval by taking its remainder, modulo the size of the interval.
In Java, there are also other scalar types for decimal numbers, booleans,
and characters. These types are defined in Table 1.1. Operations allowed in the
construction of expressions for each of these types are described in Table 1.2.
Variables can also contain objects that are of composite types, like arrays
and character strings, which we will address later. Because we will need them
shortly, character strings are described briefly in Table 1.3.

The integers are of type byte, short, int or long corresponding to the
intervals [-27 , 27 - 1], [-215 , 215 - 1], [-231 , 231 - 1] and [-263 ,
263 - 1], Respectively. Constants are written in base 10, for example, -666.

Decimal numbers are of type float or double. Constants are written in sci-
entific notation, for example 3.14159, 666 or 6.02E23.

Booleans are of type boolean. Constants are written as false and true.

Characters are of type char. Constants are written between apostrophes, for
example ‘b’.

Table 1.1 Scalars types in Java

To declare a variable of type T, replace the type int with T. The general
form of a declaration is thus {T x = t; p}.
4 1. Imperative Core

The basic operations that allow for arithmetical expressions are +, -, *, /


— division — and % — modulo.

When one of the numbers a or b is negative, the number a / b is the quotient


rounded towards 0. So the result of a / b is the quotient of the absolute values
of a and b, and is positive when a and b have the same sign, and negative if
they have different signs. The number a % b is a - b * (a / b). So (-29) /
4 equals -7 and (-29) % 4 equals -1.

The operations for decimal numbers are +, -, *, /, along with some transcen-
dental functions: Math.sin, Math.cos, ...

The operations allowed in boolean expressions are ==, != — different —, <,


>, <=, >=, & — and —, &&, | — or —, || and ! — not.

For all data types, the expression (b) ? t : u evaluates to the value of t if
the boolean expression b has the value true, and evaluates to the value of u
if the boolean expression b has the value false.

Table 1.2 Expressions in Java

Character strings are of type String. Constants are written inside quotation
marks, for example "Principles of Programming Languages".

Table 1.3 Character strings in Java

In Caml, variable declaration is written as let x = ref t in p and it isn’t


necessary to explicitly declare the variable’s type. It is not possible in Caml to
declare a variable without giving it an initial value.
In C, like in Java, declaration is written {T x = t; p}. It is possible to
declare a variable without giving it an initial value, and in this case, it could
have any value.
In Java and in C, it is impossible to declare the same variable twice, and
the following program is not valid.
int y = 4;
int x = 5;
int x = 6;
y = x;
In contrast, nothing in Caml stops you from writing
1.1 Five Constructs 5

let y = ref 4
in let x = ref 5
in let x = ref 6
in y := !x
and this program assigns the value 6 to the variable y, so it is the most recent
declaration of x that is used. We say that the first declaration of x is hidden by
the second.
Java, Caml and C allow the creation of variables with an initial value that
can never be changed. This type of variable is called a constant variable. A
variable that is not constant is called a mutable variable. Java assumes that
all variables are mutable unless you specify otherwise. To declare a constant
variable in Java, you precede the variable type with the keyword final, for
example
final int x = 4;
y = x + 1;
The following statement is not valid, because an attempt is made to alter the
value of a constant variable
final int x = 4;
x = 5;
In Caml, to indicate that the variable x is a constant variable, write let x
= t in p instead of writing let x = ref t in p. When using constant vari-
ables, you do not write !x to express its value, but simply x. So, you can write
let x = 4 in y := x + 1, while the statement let x = 4 in x := 5 is in-
valid. In C, you indicate that a variable is a constant variable by preceding its
type with the keyword const.

1.1.3 Sequence

A sequence is a construct that allows a single statement to be created out of two


statements p1 and p2 . In Java, a sequence is written as {p1 p2 }. The statement
{p1 {p2 { ... pn } ...}} can also be written as {p1 p2 ... pn }.
To execute the statement {p1 p2 } in the state s, the statement p1 is first
executed in the state s, which produces a new state s’. Then the statement p2
is executed in the state s’.
In Caml, a sequence is written as p1 ; p2 . In C, it is written the same as it
is in Java.
6 1. Imperative Core

1.1.4 Test

A test is a construct that allows the creation of a statement composed of a


boolean expression b and two statements p1 and p2 . In Java, this statement is
written if (b) p1 else p2 .
To execute the statement if (b) p1 else p2 in a state s, the value of
expression b is first computed in the state s, and depending on whether or not
its value is true or false, the statement p1 or p2 is executed in the state s.
In Caml, this statement is written if b then p1 else p2 . In C, it is writ-
ten as it is in Java.

1.1.5 Loop

A loop is a construct that allows the creation of a statement composed of a


boolean expression b and a statement p. In Java, this statement is written
while (b) p.
To execute the statement while (b) p in the state s, the value of b is first
computed in the state s. If this value is false, execution of this statement is
terminated. If the value is true, the statement p is executed, and the value
of b is recomputed in the new state. If this value is false, execution of this
statement is terminated. If the value is true, the statement p is executed, and
the value of b is recomputed in the new state... This process continues until b
evaluates to false.
This construct introduces a new possible behaviour: non-termination. In-
deed, if the boolean value b always evaluates to true, the statement p will
continue to be executed forever, and the statement while (b) p will never
terminate. This is the case with the instruction
int x = 1;
while (x >= 0) {x = 3;}
To understand what is happening, imagine a fictional statement called
skip; that performs no action when executed. You can then define the state-
ment while (b) p as shorthand for the statement
if (b) {p if (b) {p if (b) {p if (b) ...
else skip;}
else skip;}
else skip;}
else skip;
So a loop is one of the ways in which you can express an infinite object using a
1.2 Input and Output 7

finite expression. And the fact that a loop may fail to terminate is a consequence
of the fact that it is an infinite object.
In Caml, this statement is written while b do p. In C, it is written as it
is in Java.

1.2 Input and Output


An input construct allows a language to read values from a keyboard and other
input devices, such as a mouse, disk, a network interface card, etc. An output
construct allows values to be displayed on a screen and outputted to other
peripherals, such as a printer, disk, a network interface card, etc.

1.2.1 Input

Input constructs in Java are fairly complex, so we will use an extension of Java
created specially for this book: the class Ppl1 .
Evaluation of the expression Ppl.readInt() waits for the user to type a
number on her/his keyboard, and returns this number as the value of the
expression. A typical usage is n = Ppl.readInt();. The class Ppl also contains
the construction Ppl.readDouble which allows decimal numbers to be read
from the keyboard, and the construction Ppl.readChar which allows characters
to be read.

1.2.2 Output

Execution of the statement System.out.print(t); outputs the value of ex-


pression t to the screen. Execution of the statement System.out.println();
outputs a newline character that moves the cursor to the next line. Execution
of the statement System.out.println(t); outputs the value of expression t
to the screen, followed by a newline character.
Exercise 1.2
Write a Java program that reads an integer n from the keyboard, com-
putes the value of 2n and outputs it to the screen.
1
The file Ppl.java is available on the author’s web site. Simply place it in the
current directory to use the examples described here.
8 1. Imperative Core

Exercise 1.3
Write a Java program that reads an integer n from the keyboard, and
outputs a boolean indicating whether the number is prime or not.

Graphical constructs that allow drawings to be displayed are fairly complex


in Java. But, the class Ppl contains some simple constructions to produce
graphics. The statement Ppl.initDrawing(s,x,y,w,h); creates a window
with the title s, of width w and of height h, positioned on the screen at co-
ordinates (x,y). The statement Ppl.drawLine(x1,y1,x2,y2); draws a line
segment with endpoints (x1,y1) and (x2,y2). The statement Ppl.drawCircle
(x,y,r); draws a circle with centre (x,y) and with radius r. The state-
ment Ppl.paintCircle(x,y,r); draws a filled circle and the statement
Ppl.eraseCircle(x,y,r); allows you to erase it.

1.3 The Semantics of the Imperative Core


We can, as we have below, express in English what happens when a statement
is executed. While this is possible for the simple examples in this chapter, such
explanations quickly become complicated and imprecise. Therefore, we shall
introduce a theoretical framework that might seem a bit too comprehensive at
first, but its usefulness will become clear shortly.

1.3.1 The Concept of a State

We define an infinite set Var whose elements are called variables. We also define
the set Val of values which are integers, booleans, etc. A state is a function that
associates elements of a finite subset of Var to elements of the set Val.
For example, the state [x = 5, y = 6] associates the value 5 to the vari-
able x and the value 6 to the variable y. On the set of states, we define an
update function + such that the state s + (x = v) is identical to the state s,
except for the variable x, which now becomes associated with the value v. This
operation is always defined, whether x is originally in the domain of s or not.
We can then simply define a function called Θ, which for each pair (t,s)
composed of an expression t and a state s, produces the value of this expression
in this state. For example, Θ(x + 3,[x = 5, y = 6]) = 8.
This is a partial function, because a state is a function with a finite domain
while the set of variables is infinite. For example, the expression z + 3 has no
1.3 The Semantics of the Imperative Core 9

value in the state [x = 5, y = 6]. In practice, this means that attempting


to compute the value of the expression z + 3 in the state [x = 5, y = 6]
produces an error.
Executing a statement within a state produces another state, and we define
what happens when a statement is executed using a function called Σ. Σ has a
statement p, an initial state s and produces a new state, Σ(p,s). This is also
a partial function. Σ(p,s) is undefined when executing the statement p in the
state s produces an error or does not terminate.
In the case of a statement p having the form x = t;, the Σ function is
defined as follows
Σ(x = t;,s) = s + (x = Θ(t,s)).
For example, Σ(x = x + 1;,[x = 5]) = [x = 6]. This is equivalent to
saying ‘Executing the statement x = t; loads the memory location x with the
value of expression t’.

1.3.2 Decomposition of the State

A state s is a function that maps a finite subset of Var to the set Val. It will be
helpful for the next chapter if we decompose this function as the composition
of two other functions of finite domains: the first is known as the environment,
which maps a finite subset of the set Var to an intermediate set Ref, whose
elements are called references and the second, is called the memory state, which
maps a finite subset of the set Ref to the set Val.
Var Ref Val

e m

This brings us to propose two infinite sets, Var and Ref, and a set Val of
values. The set of environments is defined as the set of functions that map a
finite subset of the set Var to the set Ref. The set of memory states is defined as
the set of functions mapping a finite subset of the set Ref to the set Val. For the
set of environments, we define an update function + such that the environment
e + (x = r) is identical to e, except at x, which now becomes associated with
10 1. Imperative Core

the reference r. For the set of memory states, we define an update function +
such that the memory state m + (r = v) is identical to m, except at r, which
now becomes associated with the value v.
However, constant variables complicate things a little bit. For one, the envi-
ronment must keep track of which variables are constant and which are mutable.
So, we define an environment to be a function mapping a finite subset of the
set Var to the set {constant, mutable} × Ref. We will, however, continue
to write e(x) to mean the reference associated to x in the environment e.
Then, at the point of execution of the declaration of a constant variable
x, we directly associate the variable to a value in the environment, instead of
associating it to a reference which is then associated to a value in the mem-
ory state. The idea is that the memory state contains information that can be
modified by an assignment, while the environment contains information that
cannot. To avoid having a target set for the environment function that is overly
complicated, we propose that Ref is a subset of Val, which brings us to pro-
pose that the environment is a function that maps a finite subset of Var to
{constant, mutable} × Val and the memory state is a function that maps
a finite subset of Ref to Val.
Var Val

Ref

1.3.3 A Visual Representation of a State

It can be helpful to visualise states with a diagram. Each reference is represented


with a box. Two boxes placed in different positions always refer to separate
references.

Then, we represent the environment by adding one or more labels to certain


references.
1.3 The Semantics of the Imperative Core 11

a x b

Even though each label is associated with a unique reference, nothing prevents
two labels from being associated with the same reference, since an environment
is a function, but not necessarily an injective function. Finally, we represent
the memory state by filling each square with a value.

a x b

4 5

When a variable is associated directly with a value in the environment, we


do not draw a box and we put the label directly on the value.

1.3.4 The Value of Expressions

The function Θ now associates a value to each triplet composed of an expres-


sion, an environment, and a memory state. For example, Θ(x + 3,[x = r1 ,
y = r2 ],[r1 = 5, r2 = 6]) = 8.
For Java, this function is then defined as
– Θ(x,e,m) = m(e(x)), if x is a mutable variable in e,
– Θ(x,e,m) = e(x), if x is a constant variable in e,
– Θ(c,e,m) = c, if c is a constant, such as 4, true, etc.,
– Θ(t + u,e,m) = Θ(t,e,m) + Θ(u,e,m),
– Θ(t - u,e,m) = Θ(t,e,m) - Θ(u,e,m),
12 1. Imperative Core

– Θ(t * u,e,m) = Θ(t,e,m) * Θ(u,e,m),


– Θ(t / u,e,m) = Θ(t,e,m) / Θ(u,e,m),
– Θ(t % u,e,m) = Θ(t,e,m) % Θ(u,e,m),
– if Θ(b,e,m) = true then

Θ((b) ? t : u,e,m) = Θ(t,e,m),

if Θ(b,e,m) = false then

Θ((b) ? t : u,e,m) = Θ(u,e,m).

At first glance, this definition may seem circular, since to define the value
of an expression of the form t + u, we use the value of expressions t and u.
But the size of these expressions is smaller than that of t + u. This definition
is therefore a definition by induction on the size of expressions.
The first clause of this definition indicates that the value of an expression
that is a mutable variable is m(e(x)). We apply the function e to the variable x,
which produces a reference, and the function m to this reference, which produces
a value. If the variable is a constant variable, on the other hand, we find its
value directly in the environment.
The definition of the function Θ for Caml is identical, except in the case of
variables, where we have the unique clause
– Θ(x,e,m) = e(x),
where the variable x is either mutable or constant.
For example, if e is the environment [x = r] and m is the memory state
[r = 4] and that the variable x is mutable in e, the value Θ(x,e,m) is 4 in
Java, but is r in Caml.
Caml also has a construct ! such that
– Θ(!t,e,m) = m(Θ(t,e,m)).
If x is a variable, then the value of !x is Θ(!x,e,m) = m(Θ(x,e,m)) =
m(e(x)) that is the value of x in Java. This explains why we write y := !x +
1 in Caml, where we write y = x + 1; in Java.
In Caml, references that can be associated to an integer in memory are of
the type int ref. For example, the variable x and the value r from this example
are of the type int ref. In contrast to the variable x, the expressions !x, !x +
1, ... are of the type int.
The definition of the function Θ for C is the same as the definition used for
Java.
1.3 The Semantics of the Imperative Core 13

Exercise 1.4
Give the definition of the function Θ for expressions of the form t & u
and t | u.
Unlike the boolean operator & that evaluates its two arguments, the
operator && evaluates its second argument only if the first argument
evaluates to true. Give the definition of the function Θ for expressions
of the form t && u.
Answer the same question for the boolean operator ||, which only eval-
uates its second argument if the first argument evaluates to false.

1.3.5 Execution of Statements

The function Σ now associates memory states to triplets composed of an in-


struction, an environment, and a memory state. The function Σ in Java is
defined below.
– When the statement p is a mutable variable declaration of the form {T x =
t; q}, the function Σ is defined as follows

Σ({T x = t; q},e,m) = Σ(q,e + (x = r),m + (r = Θ(t,e,m)))

where r is a new reference that does not appear in e or m.


– When the statement p is a constant variable declaration of the form {final
T x = t; q}, the function Σ is defined as follows

Σ({final T x = t; q},e,m) = Σ(q,e + (x = Θ(t,e,m)),m).

– When the statement p is an assignment of the form x = t;, the function is


defined as follows

Σ(x = t;,e,m) = m + (e(x) = Θ(t,e,m)).

– When the statement p is a sequence of the form {p1 p2 }, the function Σ is


defined as follows

Σ({p1 p2 },e,m) = Σ(p2 ,e,Σ(p1 ,e,m)).

– When the statement p is a test of the form if (b) p1 else p2 , the function
Σ is defined as follows. If Θ(b,e,m) = true then
14 1. Imperative Core

Σ(if (b) p1 else p2 ,e,m) = Σ(p1 ,e,m).

If Θ(b,e,m) = false then

Σ(if (b) p1 else p2 ,e,m) = Σ(p2 ,e,m).

– This brings us to the case where the statement p is a loop of the form while
(b) q. We have seen that introducing the imaginary statement skip; such
that Σ(skip;,e,m) = m, we can define the statement while (b) q as a
shorthand for the infinite statement

if (b) {q if (b) {q if (b) {q if (b) ...


else skip;}
else skip;}
else skip;}
else skip;

When dealing with these types of infinite constructs, we often try to ap-
proach them as limits of finite approximations. We therefore introduce an
imaginary statement called giveup; such that the function Σ is never de-
fined on (giveup;,e,m). We can define a sequence of finite approximations
of the statement while (b) q.
p0 = if (b) giveup; else skip;
p1 = if (b) {q if (b) giveup; else skip;} else skip;
...
pn+1 = if (b) {q pn } else skip;.
The statement pn tries to execute the statement while (b) q by completing
a maximum of n complete trips through the loop. If, after n loops, it has not
terminated on its own, it gives up.
If isn’t hard to prove that for every integer n and state e, m, if Σ(pn ,e,m)
is defined, then for all n’ greater than n, Σ(pn ,e,m) is also defined, and
Σ(pn ,e,m) = Σ(pn ,e,m). This formalises the fact that if the statement
while (b) q terminates when the maximum number of loops is n, then it
also terminates, and to the same state, when the maximum number of loops
is n’.
There are therefore two possibilities for the sequence Σ(pn ,e,m): either it is
never defined, or it is defined beyond a certain point, and in this case, it is
constant over its domain. In the second case, we call the value it takes over
its domain the limit of the sequence. In contrast, the sequence does not have
1.3 The Semantics of the Imperative Core 15

a limit if it is never defined. We can now define the function Σ in the case
where the statement p is of the form while (b) q

Σ(while (b) q,e,m) = limn Σ(pn ,e,m).

Note that the statements pi are not always shorter than p, but if p contains
k nested while loops, pi contains k - 1. The definition of the function Σ is
thus a double induction on the number of nested while loops, and on the size
of the statement.
Exercise 1.5
What is the memory state Σ(x = 7;,[x = r],[r = 5])?
The definition of the function Σ for Caml is not very different from the
definition used for Java. In Caml, any expression that evaluates to a reference
can be placed to the left of the sign :=, while in Java, only a variable can appear
to the left of the sign =. The value of the function Σ of Caml for the statement
t := u is defined below:
– Σ(t := u,e,m) = m + (Θ(t,e,m) = Θ(u,e,m))
In the case where the expression t is a variable x, we have Σ(x := u,e,m)
= m + (Θ(x,e,m) = Θ(u,e,m)) = m + (e(x) = Θ(u,e,m)) and we end up
with the same definition of Σ used for Java.
The definition of the function Σ for C is not very different from the defini-
tion used for Java. The main difference is in case of variable declaration
Σ({T x = t; q},e,m) = (Σ(q,e+(x=r),m + (r = Θ(t,e,m))))|Ref−{r}
where r is a new reference that does not appear in e or m, and the notation
m|Ref−{r} designates the memory state m in which we have removed the ordered
pair r = v if it existed. Thus, if we execute the statement {int x = 4; p} q
in the state e, m, we execute the statement p in the state e + (x = r), m +
(r = 4) in C as in Java. In contrast, we execute the statement q in the state
e, m + (r = 4) in Java and in the state e, m in C.
As, in the environment e, there is no variable that allows the reference r
to be accessed, the ordered pair r = 4 no longer serves a purpose sitting in
memory. Thus, whether it is is left alone, as in Java or Caml, or deleted, as
in C, is immaterial. However, we will see, in Exercise 2.17, that this choice in
C is a source of difficulty when the language contains other constructs.
Exercise 1.6
The incomplete test allows the creation of a statement composed of a
boolean expression and a statement. This statement is written if (b)
p. The value of the function Σ for this statement is defined as follows. If
Θ(b,e,m) = true then
16 1. Imperative Core

Σ(if (b) p,e,m) = Σ(p,e,m).

If Θ(b,e,m) = false then

Σ(if (b) p,e,m) = m.

Show that it is possible to define this construct using a complete test


and the statement skip;.
Exercise 1.7
The loop do allows the creation of a statement composed of a boolean
expression and a statement. This statement is written do p while (b).
This is a shorthand of the statement {p while (b) p}. Give the defini-
tion of the function Σ for this construct.
Exercise 1.8
The loop for allows the creation of a statement composed of three state-
ments and a boolean expression. This statement is written for(p1 ; b;
p2 ) p3 . It is a shorthand for the statement p1 ; while (b) {p3 p2 ;}.
What does the following statement do?

{y = 1; for(x = 1; x <= 10; x = x + 1) y = y * x;}

Exercise 1.9
Give the definition of the Σ function for the declaration of a variable
without an initial value.
Exercise 1.10
Imagine an environment e — which cannot be created in Java — [x =
r, y = r], m, the memory state [r = 4], p, the statement x = x + 1;,
and m’, the memory Σ(p,e,m). What is the value associated with y in
the state e, m’? Answer the same question for the environment [x =
r1 , y = r2 ] and memory [r1 = 4, r2 = 4].
Draw these two states.
Exercise 1.11
Imagine that all memory states have a special reference: out. Define the
function Σ for the output construct System.out.print from the Section
1.2.
Exercise 1.12
In this exercise, imagine a data type that allows integers to be of any
size. To each statement p in the imperative core of Java, we associate the
1.3 The Semantics of the Imperative Core 17

partial function from integers to integers that, to the integer n, associates


the value associated to out in the memory state Σ(p,[x = in, y =
out],[in = n, out = 0]).
A partial function f, from integers to integers, is called computable if
there exists a statement p such that f is the function associated with p.
Show that there exists a function that is non computable.
Hint: use the fact that there does not exist a surjective function of N in
the set of functions from N to N.
2
Functions

2.1 The Concept of Functions


2.1.1 Avoiding Repetition

System.out.print("Flight ");
System.out.print("819");
System.out.print(" to ");
System.out.print("Tokyo");
System.out.print(" takes off at ");
System.out.println("8:50 AM");
System.out.println();
System.out.println();
System.out.println();

System.out.print("Flight ");
System.out.print("211");
System.out.print(" to ");
System.out.print("New York");
System.out.print(" takes off at ");
System.out.println("8:55 AM");
System.out.println();
System.out.println();
System.out.println();

G. Dowek, Principles of Programming Languages, 19


Undergraduate Topics in Computer Science, DOI 10.1007/978-1-84882-032-6_2,

c Springer-Verlag London Limited 2009
20 2. Functions

In this program, the block of three statements System.out.println();,


which skips three lines, is repeated twice. Instead of repeating it there, you can
define a function jumpThreeLines
static void jumpThreeLines () {
System.out.println();
System.out.println();
System.out.println();}
And use it in the main program
System.out.print("Flight ");
System.out.print("819");
System.out.print(" to ");
System.out.print("Tokyo");
System.out.print(" takes off at ");
System.out.println("8:50 AM");
jumpThreeLines();

System.out.print("Flight ");
System.out.print("211");
System.out.print(" to ");
System.out.print("New York");
System.out.print(" takes off at ");
System.out.println("8:55 AM");
jumpThreeLines();
The statement jumpThreeLines(); that is found in the main program is
named the call of the function jumpThreeLines. The statement that is found in
the function and that is executed on each call is named the body of the function.
Organising a program into functions allows you to avoid repeated code,
or redundancy. As well, it makes programs clearer and easier to read: to un-
derstand the program above, it isn’t necessary to understand how the function
jumpThreeLines(); is implemented; you only need to understand what it does.
This also allows you to organise the structure of your program. You can choose
to write the function jumpThreeLines(); one day, and the main program an-
other day. You can also organise a programming team, where one programmer
writes the function jumpThreeLines();, and another writes the main program.
This mechanism is similar to that of mathematical definitions that allows
you to use the word ‘group’ instead of always having to say ‘A set closed under
an associative operation with an identity, and where every element has an
inverse’.
2.1 The Concept of Functions 21

2.1.2 Arguments

Some programming languages, like assembly and Basic, have only a simple
function mechanism, like the one above. But the example above demonstrates
that this mechanism isn’t sufficient for eliminating redundancy, as the main
program is composed of two nearly identical segments. It would be nice to
place these segments into a function. But to deal with the difference between
these two copies, we must introduce three parameters: one for the flight number,
one for the destination and one for the take off time. We can now define the
function takeOff

static void takeOff


(final String n, final String d, final String t) {
System.out.print("Flight ");
System.out.print(n);
System.out.print(" to ");
System.out.print(d);
System.out.print(" takes off at ");
System.out.print(t);
System.out.println();
System.out.println();
System.out.println();}

and to use it in the main program, we write


takeOff("819","Tokyo","8:50 AM");
takeOff("211","New York","8:55 AM");
The variables n, d and t which are listed as arguments in the function’s
definition, are called formal arguments of the function. When we call the func-
tion takeOff("819","Tokyo","8:50 AM"); the expressions "819", "Tokyo"
and "8:50 AM" that are given as arguments are called the real arguments of
the call.
A formal argument, like any variable, can be declared constant or mutable.
If it is constant, it cannot be altered inside the body of the function.
To follow up the comparison, mathematical language also uses parameters
in definitions: ‘The group Z/nZ is ...’, ‘A K-vector space is ...’, ...
In Caml, a function declaration is written let f x y ... = t in p.
let takeOff n d t =
print_string "Flight ";
print_string n;
print_string " to ";
print_string d;
22 2. Functions

print_string " takes off at ";


print_string t;
print_newline ();
print_newline ();
print_newline ()
in takeOff "819" "Tokyo" "8:50 AM";
takeOff "211" "New York" "8:55 AM"
Formal arguments are always constant variables. However, if the argument
itself is a reference, you can assign to it, just like to any other reference.
In C, a function declaration is written as in Java, but without the keyword
static.

2.1.3 Return Values

a = 3;
b = 4;
c = 5;
d = 12;
u = Math.sqrt(a * a + b * b);
v = Math.sqrt(c * c + d * d);

In this program, we want to isolate the computation Math.sqrt(x * x + y


* y) in a function called hypotenuse. But in contrast to the function takeOff
that performs output, the hypotenuse function must compute a value and
send it back to the main program. This return value is the inverse of argument
passing that sends values from the main program to the body of the function.
The type of the returned value is written before the name of the function. The
function hypotenuse, for example, is declared as follows.
static double hypotenuse (final double x, final double y) {
return Math.sqrt(x * x + y * y);}
And the main program is written as follows.
a = 3;
b = 4;
c = 5;
d = 12;
u = hypotenuse(a,b);
v = hypotenuse(c,d);
In Caml, the function hypotenuse is written
2.1 The Concept of Functions 23

let hypotenuse x y = sqrt(x *. x +. y *. y)


In C, the function hypotenuse is written as in Java, but without the keyword
static and using C’s square root function which is written as sqrt instead of
Math.sqrt.

2.1.4 The return Construct

As we have seen, in Caml, the function hypotenuse is written


let hypotenuse x y = sqrt(x *. x +. y *. y)
In Java and in C, in contrast, you must precede the return value with the
keyword return. So, in Java, instead of writing
static double hypotenuse (final double x, final double y) {
Math.sqrt(x * x + y * y);}
you should write
static double hypotenuse (final double x, final double y) {
return Math.sqrt(x * x + y * y);}
When return occurs in the middle of the function instead of the end, it
stops the execution of the function. So, instead of writing
static int sign (final int x) {
if (x < 0) return -1;
else if (x == 0) return 0;
else return 1;}
you can write
static int sign (final int x) {
if (x < 0) return -1;
if (x == 0) return 0;
return 1;}
Basically, if the value of x is negative, the statement return -1; interrupts the
execution of the function, and the other two statements will not be executed.
Exercise 2.1
In Java, write a function that takes an integer argument called n and
returns the integer 2n .
Exercise 2.2
In Java, write a function that takes an integer argument called n and
returns a boolean that indicates whether n is prime or not.
24 2. Functions

2.1.5 Functions and Procedures

A function can on one hand cause an action to be performed, such as outputting


a value or altering memory, and on the other hand can return a value. Functions
that do not return a value are called procedures.
In some languages, like Pascal, procedures are differentiated from functions
using a special keyword. In Caml, a procedure is simply a function that returns
a value of type unit. Like its name implies, unit is a singleton type that
contains only one value, written (). In Caml, a procedure always returns the
value (), which communicates no information.
Java and C lie somewhere in the middle, because we declare a procedure in
these languages by replacing the return type by the keyword void. In contrast
to the type unit of Caml, there is no actual type void in Java and C. For
example, you cannot declare a variable of type void.
A function call, such as hypotenuse(a,b), is an expression, while a proce-
dure call, such as takeOff("819","Tokyo","8:50 AM");, is a statement.
There are however certain nuances to consider, because a function
call can also be a statement. You can, for example, write the statement
hypotenuse(a,b);. The value returned by the function is simply discarded.
However, even if a language allows it, using functions in this way is considered
to be bad form. The Caml compilers, for example, will produce a warning in
this case.
In Java and in C, a procedure, that is to say a function with return type of
void cannot be used as an expression. For example, to write
x = takeOff("819","Tokyo","8:50 AM");
the variable x would have to be of the type void and we have seen that there
is no such variable. In Caml, in contrast, a procedure is nothing but a function
with a return type unit and you can easily write
x := takeOff("819","Tokyo","8:50 AM")
if the variable x is of type unit ref. However, if such an assignment is possible,
it is not useful.
In general, no matter what the language, it is considered good form to sep-
arate functions and procedures. Functions return a value, and do not perform
actions such as outputting a value, and are used as expressions. Procedures do
not return a value, can perform actions, and are used as statements.
2.1 The Concept of Functions 25

2.1.6 Global Variables

Imagine that we would like to isolate the statement x = 0; with a function in


the program
int x;
x = 3;
x = 0;
We then would write the function
static void reset () {x = 0;}
and the main program
int x;
x = 3;
reset();
But this program is not correct, as the statement x = 0; is no longer in the
scope of variable x. For the function reset to have access to the variable x, you
must declare a variable x as a global variable, and the access to this variable is
given to all the functions as well as to the main program

static int x;

static void reset () {x = 0;}

and the main program


x = 3;
reset();
All functions can use any global variable, whether they are declared before
or after the function.

2.1.7 The Main Program

A program is composed of three main sections: global variable declarations x1 ,


..., xn , function declarations f1 , ..., fn , and the main program p which is a
statement.
A program can thus be written as

static T1 x1 = t1 ;
...
26 2. Functions

static Tn xn = tn ;

static ... f1 (...) ...


...
static ... fn (...) ...

However, in Java, the main program is placed inside a special function called:
main. The main function must not return a value, and must always have an
argument of type String []. In addition to the keyword static, the definition
of the main function must also be preceded by the keyword public.
In addition, the program must be given a name, which is given with the
keyword class. The general form of a program is:

class Prog {

static T1 x1 = t1 ;
...
static Tn xn = tn ;

static ... f1 (...) ...


...
static ... fn (...) ...

public static void main (String [] args) {p}}

For example
class Hypotenuse {

static double hypotenuse (final double x, final double y) {


return Math.sqrt(x * x + y * y);}

public static void main (String [] args) {


System.out.println(hypotenuse(3,4));}}
In Caml, there is no main function and the syntax of the language separates
functions from the main program

let hypotenuse x y = sqrt(x *. x +. y *. y)


in print_float(hypotenuse 3.0 4.0)
2.1 The Concept of Functions 27

In C, the main program is also a function called main. For historical reasons,
the main function must always return an integer, and is usually terminated with
return 0;. You don’t give a name to the program itself, so a program is simply
a series of global variable and function declarations.

double hypotenuse (const double x, const double y) {


return sqrt(x * x + y * y);}

int main () {
printf("%f\n",hypotenuse(3,4));
return 0;}

2.1.8 Global Variables Hidden by Local Variables

class Prog {

static int n;

static int f (final int x) {


int p = 5;
return n + p + x;}

static int g (final int x) {


int n = 5;
return n + n + x;}

public static void main (String [] args) {


n = 4;
System.out.println(f(6));
System.out.println(g(6));}}

The value of the expression f(6) is 15. The function f adds the global vari-
able n, which has been initialised to 4 in the main program, the local variable
p, with a value of 5, and the argument x, with a value of 6.
In contrast, the value of the expression g(6) is 16, because both occurrences
of n refer to the local variable n, which has a value of 5. In the environment
in which the body of function g is executed, the global variable n is hidden by
the local variable n and is no longer accessible.
28 2. Functions

2.1.9 Overloading

In Java, it is impossible to define two functions with the same name, for example
static int f (final int x) {
return x;}

static int f (final int x) {


return x + 1;}
except when the number or types of their arguments are different. You can, for
example, declare three identically named functions
static int f (final int x) {
return x;}

static int f (final int x, final int y) {


return x + 1;}

static int f (final boolean x) {


return 7;}
At the time of evaluation of an expression of the form f(t1 , ..., tn ), the
called function is chosen based on its name as well as the number and types
of its arguments. The expressions f(4), f(4,2), and f(true) evaluate to 4, 5,
and 7 respectively. In this case, we say that the name f is overloaded.
There is no overloading in Caml. The programs
let f x = x in let f x = x + 1 in print_int (f 4)
and
let f x = x in let f x y = x + 1 in print_int (f 4 2)
are valid, but the first declaration is simply hidden by the second.
There is also no overloading in C, and the program
int f (const int x) {return x;}
int f (const int x, const int y) {return x + 1;}
...
is invalid.
2.2 The Semantics of Functions 29

2.2 The Semantics of Functions


This brings us to extend the definition of the Σ function. In addition to a state-
ment, an environment, and a memory state, the Σ function now also takes an
argument called the global environment G. This global environment comprises
an environment called e that contains global variables and a function of a finite
domain that associates each function name with its definition, that is to say
with its formal arguments and the body of the function to be executed at each
call.
We must then take into account the fact that, because functions can modify
memory, the evaluation of an expression can now modify memory as well. Be-
cause of this fact, the result of the evaluation of an expression, when it exists,
is no longer simply a value, but an ordered pair composed of a value and a
memory state.
Also, we must explain what happens when the statement return is exe-
cuted, in particular the fact that the execution of this statement interrupts the
execution of the body of the function.
This brings us to reconsider the definition of the function Σ in the case of
the sequence
Σ({p1 p2 },e,m,G) = Σ(p2 ,e,Σ(p1 ,e,m,G),G)
according to which executing the sequence {p1 p2 } consists of executing p1 and
then p2 .
Indeed, if p1 is of the form return t;, or more generally if the execution of
p1 causes the execution of return, then the statement p2 will not be executed.
We will therefore consider that the result Σ(p1 ,e,m,G) of the execution of p1
in the state e, m is not simply a memory state, but a more complex object. One
part of this object is a boolean value that indicates if the execution of p1 has
occurred normally, or if a return statement was encountered. If the execution
occurred normally, the second part of this object is the memory state produced
by this execution. If the statement return was encountered, the second part of
this object is composed of the return value and the memory state produced by
the execution. From now on, the target set of the Σ function will be ({normal}
× Mem) ∪ ({return} × Val × Mem) where Mem is the set of memory states,
that is to say the set of functions that map a finite subset of Ref to the set
Val.
Finally, we should also take into account the fact that a function cannot
only be called from the main program — the main function — but also from
inside another function. However, we will discuss this topic later.
30 2. Functions

2.2.1 The Value of Expressions

The evaluation function of an expression is now defined as


– Θ(x,e,m,G) = (m(e(x)),m), if x is a mutable variable in e,
– Θ(x,e,m,G) = (e(x),m), if x is a constant variable in e,
– Θ(c,e,m,G) = (c,m), if c is a constant,
– Θ(t ⊗ u,e,m,G) = (v ⊗ w,m”) where ⊗ is an arithmetical or logical op-
eration, (v,m’) = Θ(t,e,m,G) and (w,m”) = Θ(u,e,m’,G),
– if Θ(b,e,m,G) = (true,m’) then

Θ((b) ? t : u,e,m,G) = Θ(t,e,m’,G),

if Θ(b,e,m,G) = (false,m’) then

Θ((b) ? t : u,e,m,G) = Θ(u,e,m’,G).

– Θ(f(t1 ,...,tn ),e,m,G) is defined this way.


Let x1 , ..., xn be the list of formal arguments and p the body of the function
associated with the name f in G. Let e’ be the environment of global variables
of G. Let (v1 ,m1 ) = Θ(t1 ,e,m,G), (v2 ,m2 ) = Θ(t2 ,e,m1 ,G), ..., (vn ,mn ) =
Θ(tn ,e,mn−1 ,G) be the result of the evaluation of real arguments t1 , ..., tn
of the function.
For the formal mutable arguments xi , we consider arbitrary distinct refer-
ences ri that do not appear either in e’ or in mn . We define the environment
e” = e’ + (x1 = v1 ) + (x2 = r2 ) + ... + (xn = rn ) in which we asso-
ciate the formal argument xi to the value vi or to the reference ri according
to whether it is constant or mutable, and the memory state m” = mn + (r2 =
v2 ) + ... + (rn = vn ) in which we associate to the values vi the references
ri associated to formal mutable arguments.
Consider the object Σ(p,e”,m”,G) obtained by executing the body of the
function in the state formed by the environment e” and the memory state
m”. If this object is of the form (return,v,m”’) then we let

Θ(f(t1 ,...,tn ),e,m,G) = (v,m”’).

Otherwise, the function Θ is not defined: the evaluation of the expression


produces an error because the evaluation of the body of the function has not
encountered a return statement.
2.2 The Semantics of Functions 31

2.2.2 Execution of Statements

We now define what occurs when a statement is executed.

– When the statement p is a declaration of the form {T x = t; p} or {final


T x = t; p}, if Θ(t,e,m,G) = (v,m’) then

Σ({T x = t; p},e,m,G) = Σ(p,e + (x = r),m’ + (r = v),G)

where r is an arbitrary reference that does not appear in e and m, and

Σ({final T x = t; p},e,m,G) = Σ(p,e + (x = v),m’,G).

– When the statement p is an assignment of the form x = t;, if Θ(t,e,m,G)


= (v,m’) then

Σ(x = t;,e,m,G) = (normal,m’ + (e(x) = v)).

– When the statement p is a sequence of the form {p1 p2 }, if Σ(p1 ,e,m,G) =


(normal,m’) then

Σ({p1 p2 },e,m,G) = Σ(p2 ,e,m’,G)

and if Σ(p1 ,e,m,G) = (return,v,m’) then

Σ({p1 p2 },e,m,G) = (return,v,m’).

– When the statement p is a test of the form if (b) p1 else p2 , if Θ(b,e,m,G)


= (true,m’) then

Σ(if (b) p1 else p2 ,e,m,G) = Σ(p1 ,e,m’,G)

and if Θ(b,e,m,G) = (false,m’) then

Σ(if (b) p1 else p2 ,e,m,G) = Σ(p2 ,e,m’,G).

– The definition for loops is unchanged

Σ(while (b) q,e,m,G) = limn Σ(pn ,e,m,G)

where
p0 = if (b) giveup; else skip;
and pn+1 = if (b) {q pn } else skip;.
32 2. Functions

– When the statement p is of the form return t;, if Θ(t,e,m,G) = (v,m’)


then

Σ(return t;,e,m,G) = (return,v,m’).

– Finally, we add the case of functions, which is very similar to the case of
functions in the definition of the evaluation of expressions, except that if the
object Σ(p,e”,m”,G) has the form (normal,m”’), then we let

Σ(f(t1 ,...,tn );,e,m,G) = (normal,m”’)

and if it has the form (return,v,m”’), we let

Σ(f(t1 ,...,tn );,e,m,G) = (normal,m”’)

by ignoring the value v: we have the case where a function is used as a


statement.

For example, when we execute the statement u = hypotenuse(a,b);


in the environment e = [a = r1 , b = r2 , u = r3 ], the memory state
m = [r1 = 3.0, r2 = 4.0, r3 = 0.0], and the global environment G com-
posed of the environment e and the function declaration hypotenuse: (x,y),
return Math.sqrt(x * x + y * y);, we start by evaluating the expression
hypotenuse(a,b). To do so, we start by evaluating a and b, which produces
the values 3.0 and 4.0, without changing the memory state. And we cre-
ate an environment e” = [a = r1 , b = r2 , u = r3 , x = r4 , y = r5 ] and
the memory state m” = [r1 = 3.0, r2 = 4.0, r3 = 0.0, r4 = 3.0, r5 =
4.0]

a b u x y

3.0 4.0 0.0 3.0 4.0

Next, we execute the body of the function, which produces the result
(return,5.0,m”) and so Θ(hypotenuse(a,b),e,m,G) is (5.0,m”). The result
of the execution of the statement u = hypotenuse(a,b); is then an ordered
pair composed of a boolean normal and the memory state m”’ = [r1 = 3.0,
r2 = 4.0, r3 = 5.0, r4 = 3.0, r5 = 4.0].
The value of the variable u in the state e, m”’ is 5.0.
2.2 The Semantics of Functions 33

Exercise 2.3
What happens if the formal arguments x and y of the function hypote-
nuse are constant variables?
Exercise 2.4
What happens if you execute the statement u = hypotenuse(a,b);,
with the variables a, b, and u declared in the main function?

Finally, we can give the definition of the Σ function for the entire program.
Let P be a program formed of global variable declarations static T1 a1 = t1 ;,
..., static Tn an = tn ; and of function declarations static U1 f1 (x1 ) p1 ;,
..., static Un fn (xn ) pn ;.
Let v1 , ..., vn be the initial values given to global variables, that is to say the
values of expressions ti . Let e be the environment [a1 = v1 , a2 = r2 , ...,
an = rn ] in which we associate the global variable ai to the value vi or to the
reference ri whether it is constant or mutable, and m is the memory state [r2
= v2 , ..., rn = vn ], in which we associate the references ri associated to
mutable global variables with the values vi . Let G be the global environment
(e, [f1 = (x1 ,p1 ), ..., fn = (xn ,pn )]).
The memory state Σ(P) is defined by
– Σ(P) = Σ(main(null);,e,m,G)
where null is a value of type String [] which we will discuss later.
Exercise 2.5
The function f is defined as follows

static int f (final int x) {


int y = x;
while (true) {
y = y + 1;
if (y == 1000) return y + 1;}}

What is returned from the function call f(500)?


Exercise 2.6
Imagine that all memory states contain two special references: in and
out. Write the definition of the function Σ for the input and output
constructs from Section 1.2.
34 2. Functions

2.2.3 Order of Evaluation

Since expressions can modify memory, consideration must be given to the fact
that in the definition of Σ we have given, arguments of a function are evaluated
from left to right. So, we evaluate t1 in the memory state m, and t2 in the
memory state m1 produced by the evaluation of t1 , ... So, the program
class Prog {

static int n;

static int f (final int x, final int y) {


return x;}

static int g (final int z) {


n = n + z;
return n;}

public static void main (String [] args) {


n = 0;
System.out.println(f(g(2),g(7)));}}
outputs the result 2.

2.2.4 Caml

The definition of the function Σ for Caml is somewhat different from the defini-
tion of Σ used for Java. In Caml, all formal arguments are constant variables,
so new references are never created at the point of a function call.
Also, in Caml, there is only one name space for functions and variables. In
Java, the program
class Prog {

static int f (final int x) {


return x + 1;}

static int f = 4;

public static void main (String [] args) {


System.out.println(f(f));}}
2.2 The Semantics of Functions 35

is valid, and in the expression f(f), the first occurrence of f is a function


name f and the second occurrence of f is a variable name. In Caml, however,
the program
let f x = x + 1 in let f = 4 in print_int(f f)
is invalid. The function f becomes hidden by the variable f. There is there-
fore no global environment: global variables and functions are declared in the
environment, like variables. During the call of a function f, it is impossible
to create the environment in which we must evaluate the body of the function
using the global environment. Thus, in the environment, we must associate the
name f, not only with the list of formal arguments and the body of the function,
but also the environment to extend with the arguments for executing the body
of the function. This environment is the environment in which the function is
defined.
So, the Java program
class Prog {

static int f () {return x;}

static int x = 4;

public static void main (String [] args) {


System.out.println(f ());}}
is valid, and outputs 4, while the Caml program
let f () = x in let x = 4 in print_int(f())
is invalid, because the variable x in the body of f is not part of the environment
of the definition of f. It is necessary to declare this variable before f
let x = 4 in let f () = x in print_int(f())
Another difference is that the Caml compilers evaluate the arguments from
right to left. For example, the program

let n = ref 0
in let f x y = x
in let g z = (n := !n + z; !n)
in print_int (f (g 2) (g 7))

results in 9 and not 2.


However, the definition of the Caml language does not specify the order of
evaluation of the arguments of a function. Different compilers may evaluate
36 2. Functions

arguments in a different order. It is up to the programmer to write programs


whose result is not dependent on the order of evaluation.
Finally, there is no return in Caml, and the result of the execution of a
statement, like the evaluation of an expression, is an ordered pair composed of
a value, possibly (), and a memory state.
Exercise 2.7
Give the definition of the Σ function of Caml, assuming that arguments
are always evaluated from right to left.

2.2.5 C

The definition of the Σ function for C is also somewhat different from the
definition of Σ for Java.
In C, the references created at the moment of a function call are removed
from the memory and the end of the execution of the body of the function.
Like in Caml, there is only one name space for functions and variables, and
functions are declared in the same environment as variables. In this environ-
ment, we not only associate the name f to the list of formal arguments and the
body of the function, but also to the environment e to extend with the arguments
for executing the body of the function. This environment is, like in Caml, the
environment of the definition of the function. For example, the program
int f () {return x;}

int x = 4;

int main () {
printf("%d\n",f());
return 0;}
is invalid.
C compilers also evaluate a function’s arguments from left to right, as in
Java. However, the definition of the language, like that of Caml, does not specify
the order of evaluation of a function’s arguments, and it is up to the programmer
to write programs whose result does not depend on the order of evaluation.
Exercise 2.8
Give the definition of the Σ function for C, assuming that arguments are
always evaluated from left to right.
2.3 Expressions as Statements 37

2.3 Expressions as Statements


Now that we have defined the result of the evaluation of an expression as an
ordered pair composed of a value and a state, we can better understand the
link between expressions and statements.
In C, any expression followed by a semicolon is a statement. The value of
an expression is simply ignored when it is used as a statement. If Θ(t,e,m,G)
is the ordered pair (v,m’) then Σ(t;,e,m,G) is the ordered pair composed
of the boolean normal and the memory state m’. The situation is somewhat
similar in Java, except that only certain expressions are eligible to be used
as statements. For example, if f is a function, then f(t1 ,...,tn ); is, as we
have seen, a statement, but that is not the case with 1;. In Caml, there is
no difference between statements and expressions, since statements are simply
expressions of type unit.
Exercise 2.9
In Java and in C, the expression x = t assigns the value of t to x and
returns this same value. How would you modify the definition of the
Θ function to take into account expressions of this type? What is the
output of the following program?

class Prog {

public static void main (String [] args) {


int x;
int y;
x = (y = 4);
System.out.println(x);
System.out.println(y);}}

2.4 Passing Arguments by Value and Reference


If the initial value of the variable x is 4 and that of the variable y is 7, after
executing the statement {z = x; x = y; y = z;}, variable x has the value 7
and variable y has the value 4. More generally, this statement exchanges the
values of these variables, using the principle of the third glass
38 2. Functions

Observe the behaviour of the following program


class Prog {

static int a;

static int b;

static void swap (int x, int y) {int z; z = x; x = y; y = z;}

static public void main (String [] args) {


a = 4;
b = 7;
swap(a,b);
System.out.println(a);
System.out.println(b);}}
You might expect the values of a and b have been exchanged and that the
numbers 7 and 4 are displayed, but surprisingly, the number 4 is displayed first,
followed by the number 7.
In fact, this result is what is expected based on the definition of the Σ func-
tion given above. We start with an environment e = [a = r1 , b = r2 ] and
a memory state m = [r1 = 4, r2 = 7]. The call of the function swap(a,b);
computes the values of the expressions a and b in the environment e and the
memory state m. It obtains 4 and 7 respectively. Then, the environment [a =
r1 , b = r2 , x = r3 , y = r4 ] and the memory state [r1 = 4, r2 = 7, r3
= 4, r4 = 7] are created.

a b x y

4 7 4 7
2.4 Passing Arguments by Value and Reference 39

The values of the variables x and y are exchanged, which results in the mem-
ory state [r1 = 4, r2 = 7, r3 = 7, r4 = 4, r5 = 4] which returns control
to the main program. The environment is then e = [a = r1 , b = r2 ] with
the memory state [r1 = 4, r2 = 7, r3 = 7, r4 = 4, r5 = 4]. The values
of the variables a and b have not changed.
In other words, the function swap ignores the variables a and b. It can only
use their value at the moment of the function call, and cannot modify their
value: executing the statement swap(a,b); has the same result as executing
the statement swap(4,7);.
The mechanism of argument passing that we have described is called argu-
ment passing by value. It does not allow the creation of a swap function that
changes the contents of two variables. However, most programming languages
have a construct that allows the creation of such a function. But, this construct
is somewhat different in each language. Before seeing how this is done in Java,
Caml, and C, we will look at the much simpler example of the Pascal language.

2.4.1 Pascal

The Pascal language has a built in calling mechanism to pass arguments by


reference, or by variable. In the definition of the swap procedure, we can precede
each argument with the keyword var.
procedure swap (var x : integer, var y : integer) ...
When an argument of a procedure or a function is declared using pass by
reference, we can only apply this procedure or function to a variable. So, we
can write swap(a,b) but not swap(4,7), nor swap(2 * a,b).
When we call the procedure swap(a,b), instead of associating the vari-
ables x and y to new references assigning to these references the values of
the procedure’s arguments, 4 and 7, we associate the variables x and y to
references associated with variables given as arguments to the procedure. So,
we call the procedure swap(a,b) in an environment e = [a = r1 , b = r2 ]
and a memory state m = [r1 = 4, r2 = 7], instead of creating the environ-
ment [a = r1 , b = r2 , x = r3 , y = r4 ] and the memory state [r1 = 4,
r2 = 7, r3 = 4, r4 = 7], we create the environment [a = r1 , b = r2 , x
= r1 , y = r2 ] while keeping the memory state [r1 = 4, r2 = 7].
40 2. Functions

a x b y

4 7

Because of this, the procedure swap exchanges the contents of the references r1
and r2 and not of the references r3 and r4

a x b y

7 4

and after execution of the procedure, the contents of the references associated
with the variables a and b have been exchanged.
Being able to explain the mechanism of passing by reference is the main
motivation for decomposing the state into an environment and a memory state
by introducing an intermediate set of references, as we have done in the previous
chapter.
Exercise 2.10
Give the definition of the Σ function in the case of functions with an
argument passed by reference.

2.4.2 Caml

In Caml, passing by reference is not a primitive construct, but it can be accom-


plished by using the fact that references are also values.
For example, in the environment [x = r] and in the memory state [r =
4], the value of the expression !x is the integer 4, but the value of the expression
x is the reference r. This allows the creation of a function swap that takes
two references as arguments and exchanges the values associated with these
references in the memory.
let swap x y = let z = ref 0 in (z := !x; x := !y; y := !z)
To exchange the values of the variables a and b, you simply apply the func-
tion to the references a and b and not to the integers !a and !b.
Another Random Scribd Document
with Unrelated Content
head fell forward upon her breast. Had Pic looked back, he might
have seen the slim figure sitting upright with head bowed like a lamb
amid a pack of blood-thirsty wolves. But he neither looked back nor
saw, for already he had rounded a bend in the wall and was gone.
XVII

O
nce clear of the Rock-shelter and its sleeping inmates, Pic
cast about him for the best route to complete his escape. The
meadows lay before him to the north and east—broad and
free of all obstacles; therefore the easiest way. He started toward
them but as he emerged from the cliff shadows and stood a
conspicuous object in the brilliant moonlight, he stopped.
“They will soon learn of my escape,” he thought. “I can be seen
and followed across the meadow.” No, the easiest route was not the
best. He glanced up at the cliff behind him. It could be scaled—by
such as he. The plateau with its rocks and underbrush was a
labyrinth where he could hide with little fear of being discovered. At
the worst, his pursuers would be obliged to separate into groups of
two or three to ferret him out and he could then deal with them
separately. Even a dozen half-starved men would find him no easy
prey, armed as he was with the blade of Ach Eul.
He retraced his steps to the shadow of the rock-wall and glided
along its base to a point where the cliff arose almost straight upward
and without overhang. Here he climbed. At such work, Pic excelled.
His flexible hands and feet took advantage of every break in the
limestone to anchor him firmly while he pulled himself upwards with
his muscular arms and shoulders. He was a human fly crawling up
an almost perpendicular wall. A single slip of hand or feet, even a
mis-shift of balance, would have sent him crashing to the ground
below. A stone dislodged and tumbling noisily down would have
betrayed him in an instant. But his head was clear, his heart strong
and his iron muscles stood him in good stead. With jaws clenched on
the haft of his ax, he forged steadily upward without a mishap and
reached the summit.
In a moment, he had scrambled to safety and was peering over
the edge to learn what might be going on in the camp below. No
sound nor movement there gave indication that his flight was
known. He turned away and made off through the underbrush until
he was beyond sight or hearing of the cliffs and therefore reasonably
secure. His enemies might now awake and follow, for all he cared.
Merely to make certain, he continued his way leisurely for some
distance, then mounted a rock-pulpit which afforded him a
commanding view of the surrounding country. Here he lay down to
secure a few moments rest.
It seemed as though he had no more than closed his eyes and
drifted into dreamland when he awoke. A faint glow in the eastern
sky showed that day was breaking and that the night had reached
its close. In the distance from whence he had come, sounded a faint
hum—a low, almost inaudible droning as of angry bees. It might be
the cries of wild beasts; but the sound came from the direction of
the Ferrassie shelter.
Pic yawned, stretched his limbs and chuckled softly to himself.
Yes, the Cave-men were wide awake now. They must know by this
time that their captive had made his escape. Little good would such
knowledge do them. It was amusing to consider that they were
probably dashing over the meadows, never dreaming that their
prisoner had chosen so cleverly to throw them off the scent.
He was safe. His enemies must find other means to break their
fast. There were other means, he suddenly remembered. His blood
chilled at the thought. The old hag had threatened and the time had
come when she might make her threat good. If the prisoner
escaped, his jailer would be held responsible and be compelled to
take his place. Pic’s forehead wrinkled in perplexity. Cave-men were
not cannibals by nature but they must eat the food nearest their
hands or starve. A young woman’s flesh was far preferable to that of
a muscular man. The more Pic considered the matter, the more
dissatisfaction he felt with his own present security. His enemies
would waste little time pursuing him, as long as his hostage
remained in their power. The girl was theirs and would answer the
purpose even better than he. It was all very disconcerting, this turn
of affairs, just when he was congratulating himself that he had
managed so well. He paced up and down among the rocks like a
caged lion, biting his lips and beating his hands together.
The girl would be killed and eaten by her people, simply because
she had permitted him to escape and herself remain behind. She
alone could take his place in the morning’s festivities. This last
notion was the one which so disturbed his peace of mind; and yet he
rebelled at the very idea. Why should this girl cause him so much
concern, simply because she had prolonged his useless life at the
expense of her own?
“Ugh,” he growled. “She must either starve or be eaten and have
to die in either case, so why not let her perish and save the others,
just as she has saved me.”
In spite of this apparently sound logic, Pic failed to convince
himself of its justice. Then, too, the girl had smiled upon him, he
suddenly remembered. It was but the faintest glimmer of a friendly
greeting—but she had smiled.
With a yell that could have been heard for miles, he leaped down
from the rock-pulpit and went bounding off through brake and
thicket, over rock and fallen tree, with the speed of the wind. The
sharp rocks and thorns tore his limbs, the vines and branches
overhead bruised his head and shoulders; but he heeded none of
them. As he sped over the rock-strewn plateau, the one thought in
his mind was: would he reach the Ferrassie shelter before it was too
late? Dazed, bleeding and so exhausted he could hardly stand, at
last he burst into the open and halted on the edge of the cliff
overlooking the meadow and Mousterian camp below.
The Cave-folk were all gathered about the butcher-block. Kneeling
before it, with head bent low, was a slim figure, the sight of which
together with the dark form of a man standing over her with
upraised ax, made Pic’s blood run cold.
Putting hands to his mouth, he uttered a piercing cry that carried
clear and strong to the group below. All looked up quickly and saw
him as he stood outlined against the blue sky. A chorus of wild,
unearthly yells arose:
“The Ape Boy; there he stands! Death to him!” And high and shrill
above the tumult, rang out the screams of the old hag:
“After him, every one of you if you would live to see the next
sunrise. Seize and bring him to the block.”
The Cave-men answered with savage yells and raced to the cliff.
In a moment they were swarming upward like a pack of famine-
maddened wolves. They held their weapons between closed jaws,
leaving their limbs free to cling and climb. High above them, Pic
leaned over the edge with arms held out imploringly.
“Faster, faster, clumsy dolts,” he urged the panting men. “Will you
lag or must I throw down your next meal upon your heads?”
All paused amazed. They had expected him to turn and flee or at
least make some effort to defend himself. He surprised them by
doing neither. He had chosen his fate and was prepared to die as he
had lived—with a smile upon his lips; and then a strange thing
happened.
While Pic was watching the Cave-men swarming up the cliff, he
failed to observe a figure approaching from behind him—a four-
legged animal with shaggy hide and short, curling horns. This
creature was glaring at the man. Its feet were pawing the ground.
The shouts and cries infuriated it. They sounded like a challenge to
battle.
The animal was a wisent or bison, a lover of meadows and grassy
plains. For some reason and by some way unknown, it had strayed
unwittingly to the heights above the Ferrassie Rock-shelter. The
Bison had become nervous amid its unfamiliar surroundings. At sight
of Pic this nervousness increased to vexation. At sound of the other’s
cries, its wrath passed all bounds. With a loud snort, it dashed
blindly forward in a thunderous charge.
But for the warning snort, Pic would have been overwhelmed in an
instant. He glanced quickly behind him and had time only to spring
nimbly to one side. The great brute swept by so closely, its
streaming locks brushed his shoulder. Unconscious of peril and
unable to check its momentum, the doomed beast plunged to the
brink of the precipice. Too late, it saw the destruction awaiting it and
reared high over the abyss in a last frantic effort to escape death;
then with a terrified bellow, down it fell. The forelegs plunged into
space and the huge body followed tumbling head over heels in a
mad death-whirl to the ground below.
The Cave-men had nearly reached the summit of the cliff when
they saw Pic suddenly step back. The next moment, a great hairy
body came flying over their heads. A loud crash; and as they gazed
below, there lay a full-grown bison quivering in the last agonies of
death. All saw and were dumbfounded. They turned to Pic who was
leaning forward with arms outstretched like one petrified as he
peered down upon the brute whose wrath he had so narrowly
escaped. The evidence was clear; he had hurled the bison down.
Had he not urged them to hurry and partake of the feast?
For an instant, they stared in awe at the author of their good-
fortune, then with one accord, back they scrambled pell-mell the
way they had come. As Pic looked down he saw them leap upon the
dead bison like a pack of ravenous beasts. They howled, shrieked,
screeched with joyful anticipation as they cut and chopped the
lifeless animal with their flint-blades. In a jiffy, the hide was ripped
and torn off in a dozen gory fragments, permitting the Cave-men to
set upon the carcass itself. In the meantime, several of the women
with some wits left, ran about shouting to their companions to bring
fuel and prepare the fire for the coming feast. In a few moments the
Rock-shelter was a hive of buzzing activity. The women made ready
the fire, stirring the embers and piling on wood while the men
carried great hunks of flesh and severed limbs to the butcher-block,
licking the dripping blood and meat-shreds to momentarily ease their
hunger until the feast could be prepared and served.
Amid all this excitement and confusion, none thought of Pic. Food,
food was the one thing in their minds and naught else mattered.
Here it was and plenty of it, suddenly come between them and
starvation.
The limbs and body were now dismembered; the head and offal
alone remained. The old hag dashed to the fire, waving the bison’s
heart sucked dry and bearing the imprints of her teeth. One of the
men sprang to the shaggy head and pried open the mouth.
“Stand back,” thundered a voice. “The tongue is mine,” and there
stood Pic with ax held threateningly across his shoulder. The man fell
to his knees and stretched out his arms.
“Killer of the Bison!” he shrieked in a frenzy of joy. “Tamer of
Lions!” his fellows added their exultant yells. “The tongue belongs to
him. Out with it. May the sun ever shine upon him who has this day
saved us from death.”
In a twinkle, Pic had become the man of the hour. By those who
would have rent him asunder, he now was acclaimed. The tongue
was torn from the bison head and presented to him, after which the
mob hurried to the fire to sear the meat as fast as it could be cut up
and passed on from the butcher-block.
Gradually the shouts and yells became hushed as the Cave-men
huddled about the now roaring blaze. While some dashed hither and
thither like mad things, hunting for wooden poles or spits, others
wasted no time but held the gory chunks over the flames in their
bare hands. A few, less fortunate in finding space for themselves
about the fire and impatient of delay, squatted on the outside of the
group and ate their morsels raw.
The sombre gloom of the camp which had been so suddenly
transformed into a bedlam of joy, was again changed to a seething
ferment of sizzling, steaming, crackling flesh and slobbering jaws
while the smell of blood and seared meat filled the air and rose to
heaven through an inferno of black smoke and grease-fed flames.
While the Men of Ferrassie were thus enjoying themselves,
gathered about the fire, feasting and revelling, Pic sought her who
had saved him and who in her turn had so miraculously escaped
death on the butcher-block. While her people hacked and tore the
dead bison, she stood aloof and took no part. As they streamed to
the great stone with their gory trophies, she stepped back and
watched the cutting and pounding with hungry eyes. The last shreds
were stripped from the carcass and the men were crowding about
the fire, leaving her unnoticed when suddenly a broad, thick-set
figure appeared at her side.
“The tongue; see; I have saved it for you. Take and eat, it is
yours.”
It was Pic who spoke. He held the reeking morsel in his
outstretched hands. The girl eyed it longingly, then glanced towards
the fire and hesitated.
“I must wait,” she said timidly. “The men have not yet finished.
You see there is no place for me.”
Without a word, Pic turned and forced his way into the group,
thrusting the greedy feasters roughly aside to make room. A chorus
of wild yells greeted his arrival: “Killer of the Bison! Lion Tamer!
Stand back and let him roast his fare.”
Those nearest Pic made way while he held the great tongue over
the flames until it was well seared. This operation being completed,
he left his place by the fire and strode to the butcher-block. With the
blade of his ax, he chopped the tongue in two.
“Sit down,” he said. The girl came forward obediently and seated
herself upon the great stone. At a sign from Pic, she seized one of
the severed morsels and set upon it with her sharp teeth, all the
time moaning softly as she ate.
Pic sat down beside her and looked on. When her most pressing
hunger-pangs were satisfied, she stopped suddenly and peered up
into his face. “You do not eat. None will dispute your share. You
threw the Bison down,” and she smiled upon him.
Pic smiled in return. “But I am not hungry,” he replied. This was a
fib, for he had fasted since the previous midday and felt hollow to
his toes. The girl was not so easily deceived.
“There is plenty; we can both eat,” she said; whereupon he
awaited no second invitation but pitched in with a vim on that half of
the tongue which as yet remained untouched. From then on, the
two were silent except for the noises that cave-folk were wont to
make when rending and chewing their food. For lack of words and
empty mouths to speak them, they watched each other from the
corners of their eyes.
And thus the last were served. Past winter horrors—cold, hunger
and disease—were one and all forgotten, for the Ape Boy had
suddenly come upon the Men of Ferrassie with food hurled from the
sky. The Rock-shelter was now become a horn of plenty where
starving men might laugh at death and gorge themselves to a surfeit
after their long fast.
XVIII

N
ow that Pic was returned to the fold and his position
established among the Men of Ferrassie, he gave himself up
to all the activities of Mousterian life. With his advent, began
a period of successful hunting. Rarely did the hunters return to the
rock-shelter empty-handed. What with their never-depleted larder,
the Cave-folk became strong of heart and body; the burly chieftain
grew burlier and the girl rounded out like a plump partridge. To her
Pic devoted such of his time as was not required for his hunting; and
thus he cemented their closer acquaintance. For more than a
fortnight, Pic gave himself up heart and soul to his new life until
another chapter suddenly unfolded itself. One morning he and the
men of Ferrassie were creeping along the river bank in search of
game when he caught sight of two great creatures coming towards
him. He sprang to his feet and waved his arms. At this, the pair
came to a sudden halt. For a moment they stood staring at him in
wonder, then came galloping along with loud squeals and bellows.
“The Mammoth! the Woolly Rhinoceros!” yelled the Cave-men and
away they fled like scared rabbits; all but one of them who seemed
to have suddenly lost the use of his legs and was perforce compelled
to face the two great beasts alone. Along came the pair amid a great
rumbling of feet upon the grassy meadow. Squeals, trumpets,
bellows and human shouts rang out over the lowlands to the distant
heights and echoed back again as the opposing forces clashed and
in a moment the duet was become a trio—the Mammoth, the
Rhinoceros and the Ape Boy.
Oh, the joy of that reunion! Hairi jumped up and down, his ears
flapped like fans and his trunk twined about Pic’s body so tightly that
the latter was hard put to keep breath within it. Wulli’s tail rattled
vigorously and he bobbed around like a great bewhiskered shuttle as
he strove to bestow upon the Ape Boy word and act of heart-felt
greeting. The wonder is that Pic survived the twain’s ponderous
exuberance but he managed to weather the storm and after pats
and hugs of his own he got clear of the tangled mass of tusks,
trunk, horn and feet and the two animals quieted down sufficiently
to hear how it was, their long-lost companion had so unexpectedly
come back to life.
Pic’s story was soon told, he being careful to delete such portions
of his adventure with the Neander Giant as might cast a shadow
over the present happy reunion. Then it was the turn of the other
two to give an account of their doings. Pic’s attention was now
centered upon the Mammoth—his neck and shoulders gridded with
ragged scars, which latter were discernible beneath thin hair and
wool-patches—relics of the Spring shedding.
“Fighting?” he inquired.
The Mammoth looked somewhat crestfallen as he answered:
“Um-m, not exactly,” whereat Wulli’s eyes twinkled, and the
Mammoth observing, added:
“Well, we both fared badly, although it all seems comical when
once past and done with.” Then in reply to Pic’s puzzled looks, he
recounted his part in the mystery:
“We saw you climb down to the cave and enter it but you never
came out, although we waited and waited until we were almost
starved, for there was almost no food to be found among the rocks.
Finally we made up our minds that you were lost to us forever, so
we went away. I would have died rather than go alone but Wulli was
with me. We went away together.”
His voice trembled. He was silent for a moment gazing at his toes
which shone like great door-knobs; then he resumed:
“We rambled this way and that, eating, drinking and sleeping
when we had to and not finding much pleasure in it. We poked our
noses into all sorts of out-of-the-way places. One of them that I am
going to tell about was covered with rocks, single and in mass with
scattered patches of trees here and there. Detecting a strange odor
coming from behind some of these rocks, we went over to find out
what it was.
“On nearing the place from where the odor came, we found
ourselves on a ridge with broad stones sticking up edgeways in front
of us. It was too high for us to see over but we managed to find a
cleft, not large enough to squeeze through although it gave us a
glimpse of the party.”
“Party?” asked Pic.
“Yes, a party of flesh-eaters sitting around the half-eaten body of
a reindeer. All were females chatting too busily to hear or smell Wulli
and myself. They were the Leopard, Panther, Lynx and Bobcat. The
Leopard being the largest and fiercest of the four, had the most to
say as well as the choicest portions of the feast. Apparently it was
she who had killed the reindeer. We heard her remark:
“‘Yes, reindeer meat is very nice—the nicest of small game.’
“‘Small?’ her three companions pricked up their ears. Wulli and I
did too. That Leopardess was merely talking for effect.
“‘Yes, small,’ she drawled, ‘although some might say medium-
sized. I had in mind the Woolly Rhinoceros, a fairly large animal,
ugly and stupid but sweet and tender. Have none of you ever tasted
one?’
“You can imagine how vexed Wulli was,” the Mammoth chuckled.
“Then we heard the Lynxess say in an awed voice: ‘No, I never ate a
Rhino. They are a bit too large for me to manage. Do you select
them yourself—live ones?’
“‘Certainly,’ replied the big cat. ‘I eat only food of my own killing.
The Rhinoceros is easy compared with the Mammoth. I find the
latter much more difficult.’
“It was now Wulli’s turn to be amused,” said the Mammoth. “I
thought I would burst with rage when he whispered, ‘Poor little
elephant! I wonder how many she eats each day.’
“‘Do you—yourself—kill all of the rhinos and elephants you eat?’
the Bobcattess now asked most humbly.
“‘Of course; do you suppose I swallow them alive?’ the Leopardess
snarled, whereupon the Bobcattess said no more. ‘Young ones, no
doubt,’ ventured the Pantheress, ‘I—’
“‘Silence,’ the Leopardess screamed in a great rage. We thought
for a moment that she was going to start a fight but just then she
saw the top of my head. The rocks did not conceal quite all of me.
Without a word of warning to her companions, she crawled away
merely saying: ‘Pardon my haste. I had forgotten that Spotty was all
alone.’
“By this time, Wulli and I were both very much annoyed. We
hurried around the rocks to catch that leopardess and punish her.
She sprang into a glade and disappeared. As we followed, her
companions scattered in all directions. We had entered the woods
and I had just lowered my head to avoid colliding with a stout
overhanging branch when something reached down from above and
fastened upon my shoulder hump. As I bounded forward from the
pain of it, my back was raked from nape to tail. Never was I so
enraged as at this unexpected attack. I faced about and saw a lithe
cat-like form ascending rapidly into the tree-top. It was the
Leopardess and she it was who had clawed my back as I passed
beneath the limb upon which she lay; and now I could see her safely
beyond my reach and hear her screeching scorn and derision at
Wulli and myself. Some strands of my own hair still clung to her
waving paw. The sight of them irritated me beyond measure.”
“‘We might hide,’ said Wulli. ‘When the wretch thinks that we have
gone, she will come down; then we can catch and chastise her.’
“It takes much scenery to conceal a pair like us. I did not realize
this at first. No matter how hard we tried to find cover, that
wretched cat could see us and jeered our vain efforts with insulting
cat-calls. It was exasperating.
“‘We can hide among the rocks,’ Wulli now suggested. ‘I see a
cave; something in it too. I smell it.’
“We approached the mouth of the dark hole. Wulli lowered his
head and peered into the darkness. ‘Anybody home?’ he squealed.
“A fluffy little creature resembling an oversized bobcat, came
bouncing to the entrance. At sight of us, it stood stock-still, staring
at us with big wondering eyes, then turned tail and essayed a hasty
retreat to within the sombre recesses. This last move, I prevented by
hooking the little roly-poly back with my trunk gently but firmly,
whereupon it stuck a stubby paw in one eye and screwed up its face
as though about to cry.
“‘Spotty! It is the baby leopard,’ cried Wulli. ‘That is its mother in
the tree. She scratched your back.’
“‘Aha!’ I grit my teeth and took a fresh grip on the young one, so
tight a hold that Spotty yelled as though he were being killed. Back I
marched to the tree waving the young leopard triumphantly on high.
To my great chagrin, the perch which had but recently held the
mother, was now vacant.”
Hairi and the Cave Leopard

“And so she escaped?” Pic inquired.


“Not exactly,” was the grim response. “I was looking about and wondering
what to do next when something descended upon my shoulders with terrific
force. It was the mother leopard of course. She alighted upon my back and
anchored herself with her hooked paws. The matter might have ended then
and there, had I but known. You see she merely wanted her cub. My back
smarted so that I would have been only too pleased to be rid of both of them.
Spotty put in his time scratching and biting my trunk. He got too hot to hold
so I dropped him and off he ran.”
“And the mother leopard—what did you do with her?” Pic asked.
“What could I do but run?” replied the Mammoth. “That was the only way I
could think of to shake her off. She dug her claws deep into my back to keep
from falling and that made me run all the harder. Disgraceful, I must admit,
but she was as frightened as I was. Finally I became exhausted. As I slowed
up, the Leopardess jumped and ran to cover. I let her severely alone.”
“And Wulli—what was he doing all this time?” Pic demanded.
The Mammoth appeared greatly amused. “Come Wulli, it’s your turn now,”
he chuckled. “You might as well confess everything.”
The Rhinoceros was visibly embarrassed. “I wanted to help,” he said, “but
the Mammoth ran too fast for me. I hurried after him but soon became so
tired that I was about to give up the chase, when Crash! down I tumbled into
a deep hole. It was covered with branches so that I could not see it, but they
eased my fall and no bones were broken. The hole was too deep for me to
climb out of and so there I stayed until darkness came and finally the light
again. By that time, I was so cold, tired and hungry I could scarcely stand. I
was brooding over my misfortune, when there sounded a low hum as of
something stirring outside. The hum became cries, then yells coming nearer
and nearer. They were the voices of Trog-men. Help was at hand. I fairly
danced with joy.”
“Help indeed; what a disappointment,” Pic murmured consolingly.
“Yes, the Trog-men were coming. I could hear them plainly and I vowed to
myself that they would be my good friends henceforth and forever more. I
squealed as loudly as I could for fear they might overlook the spot and pass
me by. Their voices rang about the pit-mouth. I——”
“Oh guileless one!” Pic exclaimed bitterly. “Had you forgotten those who
hunted you beyond the great Channel Valley? These men but exulted over
their quarry the Woolly Rhinoceros caught in the trap of their own making.”
“I did not know then what I know now,” Wulli resumed. “I never thought of
them as enemies. Only friends would be interested in a poor Rhino caught in
a deep hole; but when I saw their faces ranged above me, my mistake
dawned upon me. Every mouth was wide open with teeth bared. Every hand
bore stick or stone. I bowed my head in despair and awaited the end.”
“End?” cried Pic springing to his feet. “You are here and alive. How could
there have been an end?”
The Rhinoceros took keen relish in the dramatic effect of his recital. He
continued with exasperating deliberation:
“While awaiting the end, I thought over many events of my past life and
while thus musing, it suddenly dawned upon me that I was alone. The pit-
mouth was vacant; the Trog-men had gone.”
“Whoow! how simple,” breathed Pic, settling back upon his haunches.
“Gone? What drove them away?”
“I was alone,” Wulli continued. “For a time, all was still; then sounded a dull
thump, thump and the breaking of snow-crust. The sounds ceased abruptly
and a great shadow settled over me. I looked up and saw——”
“The Mammoth!” shouted Pic.
“Even so—the Mammoth; and—and that is about all. I was saved. Nothing
more of moment happened to us until we came here and met you.”
“But you left yourself in the pit,” Pic remonstrated. “It was too deep for you
to climb. How did you get out?”
“The Mammoth; ask him.”
Hairi now took the center of the stage to put the finishing touch on his
partner’s thrilling narrative.
“I pulled him out—like this.” Raising his trunk, the huge Elephant curled its
flexible tip around the Rhino’s horn. Securing a firm grip, he settled back with
his full weight and power. Wulli’s neck elongated like that of a turtle. The
Mammoth’s trunk stretched taut like a tow-line. Neck and trunk held fast
under the strain and in a moment, the Rhinoceros was being dragged over the
ground.
“Pulled him out? You? How wonderful!” Pic was in truth astounded by this
remarkable engineering feat. The Mammoth released his hold.
“Yes, I pulled him from the pit. And now, what next? I believe we have told
about all there is to tell.”
“All but one thing,” Wulli reminded him. “The cave and—and, you know.”
Hairi flapped his ears and wriggled like a school-girl filled with a secret too
big to hold. “There is a mountain near here,” he began in a voice burdened
with mystery. “High upon the mountain is a cave; in the cave, is——”
“Treasure,” replied Pic, suddenly stirred by the news. “Where is this cave?”
“Up the river,” answered the Mammoth. “The mountain is too high for either
Wulli or me to climb. We need you to help us.”
“Did you see the treasure?”
“No, but we are sure it is there.”
“Ugh!” grunted Pic; but he felt ripe for a lark and so followed his friends
without further argument.
XIX

T
he three friends crossed a stream which flowed into the Vézère from
the west and continued up the border of the valley, over meadow and
rock-land and through almost impenetrable thickets. Finally the
Mammoth halted and gazed at the limestone cliffs above his head.
“This is the place,” he said. “If you look closely, you will see a dark hole in
the rock.”
Pic looked and saw. His curiosity rose to a high pitch. “Wait here while I
climb up,” he directed and then set his ax-handle between his teeth.
“Ha-ha, wa-ho!” laughed a voice from on high.
Hairi and Wulli jumped. Pic gazed along the face of the cliffs.
“What was that? It sounded like a man’s voice. Perhaps a man is in the
cave.”
All three held still and listened, but the cry was not repeated.
Pic again made ready to ascend. He gripped his ax between his jaws and
started off.
The approach to the cave was but a pile of broken rocks and easily scaled—
particularly by one inured to ascending almost perpendicular walls; and so Pic
made rapid headway to the top. As he neared the cave, a foul odor greeted
his none too sensitive nostrils. The rocks were strewn with freshly-gnawed
bones.
“The owner of that grotto must be a big meat-eater,” he thought as he
examined the wreckage. “And such mighty jaws.” Some of the big limb-bones
were bitten in two. One in particular, a bison thigh, was minus the lower end.
It had been chewed off, as the tooth-marks plainly showed.
“Ha-ha,” the uncanny laugh rang out once more. Pic braced his feet and
stood on the defensive. A hideous face leered down upon him from the cave-
mouth. Another and yet others crowded forward from behind until a dozen or
more big-eared heads were gathered awaiting his coming.
Pic lowered his ax and laughed back: “Ha-ha;” but he was wise and
advanced no farther. He knew these creatures well enough and now felt
ashamed because they had so startled him. The cave was a den of hyenas;
cowards at heart except when at home as now where they were fully
prepared to fight any and all intruders.
There was nothing left for Pic but to go back and rejoin his friends. This he
proceeded to do without delay. When the Mammoth and Rhinoceros became
advised of how matters stood, they were much disturbed.
“Why should a few hyenas frighten you?” Wulli snorted in disgust. “Only
yesterday I walked close by a whole pack of them.”
“Were they in their cave?”
“No—out in the meadow eating a dead ox,” replied the Rhinoceros.
“That is different,” said Pic. “Now they are at home. You might go up
yourself and drive them out if you can.”
Wulli glanced up the slope and cocked his head thoughtfully. Such a climb
would more than tax his fullest powers. “Hyenas never stay at home nights,”
the Mammoth now remarked. “If we wait here until dark, they will come out;
then you”—looking at Pic—“can climb up and find the treasure.”
This sounded reasonable, so the three waited. The hours dragged slowly by
and it seemed as though night would never come; but it did, of course. As the
sun finally sank behind the cliffs, Pic and his companions saw dark figures
emerge from the cave, one by one, and seat themselves on the rocks about
the entrance. The brutes laughed and growled noisily but not a single one of
them showed any inclination to descend.
“They will not come down while we remain here,” said Pic as his comrades
began to stamp their feet and show other signs of impatience. “They do not
need to see; they smell us. Hyenas have sharper noses than any other
animals I know of.”
“Particularly for dead things,” said the Mammoth.
“And sick ones, too,” the Rhinoceros added. “Once when I had a sore on my
hind leg, I thought they never would stop following me around; nor did they
until I was well again. I have seen droves of them trailing after sick animals
that they could have killed without trouble, had they courage and sense
enough to do it. One cannot have a tooth-ache but these beasts will soon
know of it.”
“If you were only sick now, you might persuade the lot of them to come
down and follow you,” said the Mammoth. “How is your health at this
moment?”
“Good,” Wulli was obliged to admit. Hairi despaired.
“He might only pretend to be sick,” Pic suggested. “Perhaps the hyenas
would not know the difference.”
“I am willing to try anything,” said the Rhinoceros. “What shall I do and
how shall I do it?”
In a few moments, Pic mapped out a plan of strategy as follows: He and
Hairi would withdraw and hide somewhere within earshot while the
Rhinoceros remained where he was. At a pre-arranged signal—the caw of a
crow—Wulli was to feign mortal illness. The details and manner of so doing
would be left to him. However it was important that he drag himself down the
valley and draw the hyenas after him. In the meantime, Pic would steal back,
enter the empty cave and secure the treasure. It sounded simple. All three
conspirators were confident of success. Wulli, the star performer was the
most impatient to begin.
“Be sure to act as though you were terribly ill,” were Pic’s final instructions.
“The sicker you seem, the faster will they follow. Groan, squeal, make all the
noise you can; the louder the better. Now if we are all agreeable, let us
begin.”
Pic and Hairi thereupon marched off in the darkness making all of the noise
they could, so that the hyenas would know of their departure. The Rhinoceros
was left behind. After waiting for several minutes,—which seemed to him,
hours—the night silence was broken by a distant cry—the caw of a crow. At
the sound, Wulli emitted a piercing wail and followed it with loud, deep
groans. In a moment, the rocks above him bustled with activity—snarls,
growls and the clatter of clawed feet. The hyenas were descending the slope.
Pic’s clever scheme was bringing quick returns.
As he saw the dark figures coming towards him, Wulli set himself in motion;
staggering, reeling, stumbling along the foot of the cliffs and ever continuing
to vent his bodily anguish with piteous groans and squeals.
A mass of dark figures streamed down the slope to the valley and followed
after him. Their ears told them that a fat rhinoceros could be had for the
taking—a terribly sick rhinoceros or they were very much mistaken. Having no
doubts about the matter and not suspecting any double-dealing, they trailed
leisurely after him like a flock of sheep. They were in no particular hurry.
Judging from the cries they heard, the Rhinoceros would be in proper
condition for them within a reasonably short time.
For some distance, the forlorn procession continued in this manner. Only
Wulli’s despairing cries broke the stillness of the night. “They surely must be
far enough from that cave now,” he said to himself. “Oo-wee; it is about time
to stop. I wonder how long I am supposed to entertain these brutes.”
He selected a spot at the base of the cliffs where he could set his back to
the rock and have foes to watch on three sides only; then flopped down
heavily upon his haunches and groaned. The hyenas squatted in a semi-circle
about him. Apparently the artful Wulli now observed them for the first time.
“Will any of you help me,” he wailed. “Oo-wee! I am so sick! Cannot you see?”
“Are you too sick to fight?” inquired a sympathetic voice.
“Not quite,” replied the Rhinoceros cautiously. “I can still poke with my horn
a bit; but I fear I am going to die. My insides hurt terribly. They have not held
food for a week. Please stay with me,” he whined piteously.
A chorus of rude “Ha-has” greeted this touching appeal. “Trust us to stay,”
growled one of the brutes nearest him. “We will be with you to the end; then
you can be with us.”
At this merry quip, all ha-haed again.
Wulli began to weary of his task. Acting was not his specialty; furthermore
he was growing tired and sleepy. He closed his eyes and nodded. The hyenas
crowded up closer, thinking their turn was coming, whereupon the Rhinoceros
was compelled to bestir himself with his moaning and groaning until they fell
back to their proper places.
They were queer, uncanny brutes—these hyenas. Their stock of patience
seemed inexhaustible. They could sit around and wait all night if necessary.
The idea of attacking a full-grown living rhinoceros was contrary to their
training. No hurry at all, but it behooved Wulli to keep things moving.
The Time Came When Wulli Failed to Respond

The hours passed. For the Rhinoceros, they were an eternity of tortuous
effort to keep awake and play his part. Time and time again, his eyes closed,
his head drooped and the hyenas moved up closer; and each time he came to
with a start on sensing the nearness of his ghoulish visitors. Then his
despairing cries took a fresh spurt and the hyenas backed off, only to return
when he again became quiet.
But the time finally came when Wulli failed to respond. His admirers
crowded forward, amazed at his wonderful hold on life. His cries were stilled
so they hitched up closer, discreetly refraining from any unseemly haste. They
could hear his hard breathing and knew him to be still alive although the end
must be very near. For such a sick rhinoceros, he had lasted unusually long,
they thought; not that they felt impatient; but even a second must not be
wasted when once it was time to commence.
One of them—a coarse, unmannered individual without proper hyena
training—reached out and tried his jaws on the Rhino’s rump. It was not a real
bite—a mere touch of the teeth; but his fellows resented this taking an unfair
advantage and growled angrily. Even these sounds failed to arouse Wulli.
Things were looking dark for him. Even hyenas had limits. One and all
crowded up closely with their noses touching those portions of his body on
which they planned to begin operations—and still, he slept on.
Suddenly the hyenas pricked up their ears. The faint crashing of brush and
thump of ponderous feet could be heard coming up the valley. All arose and
slunk slowly away in the opposite direction for a score of paces and then sat
down again. Their eyes accustomed to the darkness, made out a great,
towering figure coming rapidly towards them.
The newcomer was the Mammoth. With his two friends gone about their
business and himself wearied by his long wait, he had followed the
Rhinoceros and come upon him and the hyenas in the nick of time.
Suddenly he perceived a dark mass, half-seated, half-lying on the ground.
His heart almost stopped beating. He recognized his partner’s form and was
filled with sinister foreboding. He was in the presence of death. At that
moment, Wulli heaved his fat sides, uttered a deep sigh and began to snore.
Hairi breathed again. He recognized the symptoms. His friend merely slept.
Having thus assured himself that no harm had come to the Rhinoceros and
that he was only exhausted, the Mammoth lay down beside him to secure his
own night’s rest. Undecided just what course to pursue and unwilling as yet to
give up all hope, the hyenas seated themselves in a semi-circle about the pair
and waited.
XX

A
fter allowing Wulli ample time to decoy the hyenas a safe distance from
their stronghold, Pic left the Mammoth to his own devices and set about
to carry out his portion of the programme.
He reached the foot of the slope, ascended part way and paused. No dark
forms appeared to mock him with their hideous laughter; so he went on until
he reached the cave. No sound issued from within; only foul odors which in
themselves were enough to repel any less determined invader than he. The
hyenas were gone and now he had the place all to himself. So far, so good; he
stepped inside.
The darkness was almost impenetrable so he was obliged to depend upon
his sense of touch, groping about the floor with his hands and feet. Bones,
bones, everywhere; but no stone. He searched about the entrance, then
along the side-walls and finally the rear of the cave, carefully covering every
inch of space; but without success. He repeated this performance; going over
the ground a second time with the utmost care. Failure again; the stone was
nowhere to be found nor the treasure which must be lying beneath it.
Pic’s patience was ebbing fast. He had begun this adventure in high spirits
but as his quest yet remained barren of results, he grew fearful that it must
soon end in total failure.
“My father would not have lied to me,” he strove to reassure himself.
“Perhaps the stone has been accidentally removed. The treasure if it lies
buried here, must be somewhere near the entrance.”
This last thought aroused his fading hopes and he resumed his search along
new lines, chopping the dirt floor with his ax until not a spot near the cave-
mouth remained untouched. His efforts were of no avail. Neither stone nor
treasure came to light. This was the wrong cave.
Nothing remained to be done but leave and rejoin the Mammoth and
Rhinoceros. It suddenly occurred to him that it was high time he was so
doing. Night was drawing to a close and the hyenas would soon return. He
stepped to the cave-mouth, then as quickly stepped back again at sight of
some animals coming up the valley. His foot encountered an obstacle. His ax
flew from his hand and he fell heavily upon its upturned edge.
A sharp pain shot through the rear of his thigh where the keen flint had
inflicted a deep gash. He was up again in a moment, clutching the wound
with one hand to stop the flow of blood. His injury although painful was not
disabling. The hyenas were returning and it was necessary—for his own safety
—that he be not caught intruding in their den.
He descended the slope with all possible haste, leaving a trail of blood-
stains on the rocks behind him. He arrived at the foot of the slope none too
soon. The hyenas were but a few paces distant. They came on growling and
sniffing the air. Pic raised his ax and prepared to defend himself; whereupon
they held back and showed no intention of proceeding further.
Pic retreated a step; the hyenas followed. He took several more steps and
the foul beasts kept pace with him; halting when he halted; advancing as he
retreated, threatening but ever hesitating to close in. None of them showed
any interest in the cave. Not one climbed up the slope. It might be time to go
home; but they were hungry. They smelled blood in the air and on the
ground. Pic’s wound was not a dangerous one, but it gave promise; the odor
of blood was alluring and so the hyenas followed. The Rhinoceros had proven
a grievous disappointment; but now the scent of an injured man filled them
with renewed hope.
Pic’s position was becoming decidedly unpleasant. He was being hounded
by a pack of ferocious brutes who dared not attack him openly but who were
prepared to take advantage of any opportunity offered them. He made off up
the valley and the hyenas trailed behind at a respectful distance.
Their uncanny attention and particularly their persistence filled him with
growing alarm. He was beginning to feel weary and faint; but to lie down; to
lose his senses even for a few moments, meant death. His enemies were now
gradually closing in; behind and on both sides. If they kept on, he would soon
be completely surrounded. He must seek refuge among the rocks, in a cave or
some place where he could defend himself without danger of attack from the
rear. He scanned the cliffs—and there before him loomed a great rock which
thrust its rugged flanks far into the valley. His heart quickened with renewed
hope. It was the Rock of Moustier.
“Once I reach the grotto, I can make a stand against these beasts,” he
encouraged himself; “unless”—and his spirits fell again like lead—“the Lion is
there.”
However he must take his chance on that score. Things could not long
continue as they were. A night of fruitless tramping up and down the valley
was rapidly driving his enemies to desperation. Hyenas might be patient but
even their patience could not forever endure the protests of empty stomachs.
They quickened their pace and pressed on more closely. Some of them grew
bold enough to walk ahead of him on either side.
The party drew up before the base of Moustier. Pic took a deep breath, grit
his teeth and began the ascent. The hyenas hesitated, then followed after
him. As he neared the middle terrace and came within sight of the grotto, he
paused. For him, this was the turning-point—a situation fraught with fearful
consequence. If the Lion were at home, he was lost—caught between two
fires and hopelessly overmatched; but if the cave were unoccupied, he could
make his stand in the entrance and fight off those who trailed behind him. All
depended upon whether the grotto was or was not now occupied by its fierce
tenant.
While he hesitated, one of his trackers, a huge beast with a ghoul-grinning
face, lunged forward and snapped at his wounded limb, so closely that Pic felt
the brute’s hot fetid breath. He turned like a flash just as the hyena sprang
upon him a second time. A quick swing-back; and the blade of Ach Eul
descended in a wide arc with all the power of arm and shoulder behind it. A
terrible howl and the brute fell crashing down the slope with half of the flint
buried in his skull. The other half and handle yet remained in Pic’s grasp; but
the blade of Ach Eul was lost forever—shattered, destroyed by the violence of
the blow.
Its owner gazed at the broken ax in dismay. He stood defenceless—armed
only with a flimsy stick. Discarding his now useless weapon, he seized a
jagged rock and raised it above his head, just as the other hyenas turned tail
and scrambled down the steep slope after their stricken comrade. In a few
moments, Pic heard them growling and snarling horribly as they fought and
struggled over the dead body. Then sounded the ripping and tearing of flesh,
followed by a more subdued clatter as of snapping and slopping jaws.
Pic was left alone. Below him, his enemies were devouring the one of their
number he had slain. Now for the Cave Lion. With the rock still raised above
his head, he took a last step upward and stood upon the platform fronting the
grotto. No response came from within—no low growls nor angry snarls. He
could see beyond the entrance and make out the interior, free of dark form
and fiery eyes. The Lion was not inside. Pic glanced fearfully about him, then
glided to the cave-mouth. It exuded no foul odor common to dens habitated
by beasts of prey. The place was untenanted; and from all appearances it had
been so for a considerable time.
Pic breathed more freely. Nothing was to be feared at the moment from the
Lion. After assuring himself on that point, he stole across the rock-platform
and peered down at the hideous group below. Already the dead hyena was
but a framework of white bones and his fellows were straggling away down
the valley. He returned to the cave and stepped boldly within.
Apparently the Lion had abandoned his winter quarters at the approach of
Spring. His nest remained as he left it—a broad, shallow depression scooped
from the floor. The brute had clawed out the dirt to the bare rock leaving the
debris piled around the sides, thus forming a crater or enclosed receptacle
shaped to his curled form. Its sides were covered with spiders’ webs and
fungus growth. A single mushroom sprouted from the bottom—from the rock
laid bare by the Lion’s claws. Pic looked curiously at this mushroom which
could sprout from the hard limestone. He sank to his knees and bent low to
examine it.
The stone from which it grew was not limestone but granite—a material
foreign to the surrounding rock—of substance unlike that composing the cave-
walls and roof; furthermore, the mushroom grew not from the stone but from
a crack extended around it. The crack was filled with dirt and the mushroom
sprang from the dirt.
Pic gazed thoughtfully at the mushroom, the dirt-filled crack and the granite
stone. How did these three come there? Answer: because of the stone itself
and no other reason; because of a stone in the floor—near the entrance—of a
cave—on a mountain.
Pic trembled as this chain of circumstances ran through his mind. He
reached down with shaking hand and scraped out the dirt which filled the
encircling crack.
In a short time he had deepened it sufficiently to insert his fingers. One
mighty heave—the stone yielded and came free. He raised it from the
depression and tossed it to one side.
The hollow in which the stone had lain embedded, was filled with dirt. Pic
set about to remove this by loosening and scraping it out with his fingers.
While so doing, his knuckles encountered something hard and sharp. He pried
the dirt from around the object, plucked it forth and held it to the light.
The object was a large flint-blade, flaked and chipped with edges so
straight and keen, Pic could only stare and marvel. His experienced eye noted
not the large flaking but the fine marginal chipping which gave the flint its
finely-finished lines. It was a counterpart—a duplicate of his own ax so
recently destroyed—the blade of Ach Eul.
Pic’s breath came loud and fast. The hot blood mounted to his temples. He
set the flint carefully down beside him and turned once more to the hollow
from whence it came. The dirt was soft and easily removed with his fingers.
The ground beneath where the stone had lain, was a cavity filled with loose
earth—and other objects as he discovered when once the loose material was
removed.
The objects were flints—similar in form and finish to the first. The cavity
was filled with them. He brought them forth one by one until he had secured
more than could be counted upon the fingers of his two hands. Further search
disclosed the cavity’s hard bottom but no more flints; nothing but a piece of
bone.
“Part of the Cave Lion’s fare,” thought Pic. “It shows his tooth-marks and
where he has licked it clean and smooth.” He was about to cast it aside, then
checked the impulse and set it on the rock beside him where it soon passed
from his thoughts. He turned again to the flints. The treasure of Moustier was
now in his possession.
And it was indeed a treasure which had long lain buried in the floor of the
grotto. Pic made a grimace as he thought of how many times he had stood,
squatted, reclined over the very spot where it lay concealed. The stone—the
guiding mark—had become buried in some unaccountable manner, thereby
throwing him off the scent. It was but natural, he reflected, that Moustier—his
father’s former home—should have been the cave which concealed the
treasure; but who would have thought that the stone itself as well as the
treasure might be hidden from sight?
Pic chuckled softly as he meditated over the element of chance that had
brought about his good-fortune. But for the Cave Lion, he might have vainly
hunted the world over until his dying day. He could thank Grun Waugh for this
one thing, if nothing else. The treasure had been laid bare—or rather the
stone which covered it—by a scratch of his big paw.
Pic gathered up the flints and carried them to the ledge outside. Here he
squatted to feast his eyes on a dozen or more of the finest blades ever seen
by mortal man—great almond-shaped flints, the size and form of his own
hand—a sight to make the hunter and warrior’s heart beat fast with wonder at
their great size and beautiful finish. The treasure of Moustier was priceless
and beyond compare.
His first excitement having passed, Pic devoted himself to a more detailed
inspection of the flints. They were all very much alike—great hand-axes;
pointed and edged on one end; blunt on the other to accommodate the grip
of the hand. They differed little from each other, in size, form, manner of
chipping and even the material from which they were made. All bore the same
evidence of retouch—the tiny chipping which made the margins so straight
and keen. In them was none of the rude flaking and that, only on one side as
characterized the wavy, irregular edges of Mousterian blades.
Wonderful indeed! Nothing could be more wonderful; but strange to say Pic
turned from them and gazed wistfully at the sky. He sighed. The treasure of
Moustier was incomparable with anything in all the world; but its owner now
found himself a victim of baffled hope and bitter disappointment.
Why? Simply because they taught him nothing. A knowledge of the art itself
and not the finished product was what he sought.
“How were they made?” had been and yet was the question uppermost in
his mind; but on this point, the cold lustrous flints remained pitilessly silent.
Pic was undisputed master of the treasure; but as far as the manner of its
making was concerned, he knew no more now than he did before.
XXI

P
ic continued gazing wistfully at the sky. He was thinking of former days;
of his search for the Terrace Man which had availed him nothing; of the
treasure which after repeated failure, he had now so unexpectedly
discovered. The latter pertained to that which he sought above all things—a
knowledge of the art whereby men formerly retouched their hammered flakes.
But the flints themselves taught him nothing. The knowledge which had
seemed almost within his grasp, had now slipped as it were, through his
fingers, leaving him as far from his goal as ever. He picked up one of the
blades with his left hand.
“This work was not done entirely with the hammer-stone” he reflected
bitterly. “Some other means was used to strike off these tiny chips. What it
was, I would give my life to know.”
He was about to lay the flint down with its fellows when his eyes fell upon
the piece of bone lying upon the rock where he had placed it. Strange, that
such a trifling object should intrude itself upon him at this moment. He picked
it up and examined it.
The bone was polished and notched on one end. It was strangely hard and
heavy. The notched end in particular seemed most peculiar. Pic regarded it
curiously.
“That mark was not made by a lion’s tooth,” he reasoned. “The bone has
been neither roughly scratched nor chewed, nor would the brute’s tongue
have smoothed it down so nicely.”
His thoughts were now centered upon the bone fragment. He had forgotten
the flints entirely.
The bone was in his right hand; the blade which he had been examining,
still remained in his left. More by accident than design, he set the notched
end of the bone against one edge of the flint and pressed strongly downward.
A tiny chip flew off. More astounding things may have happened in the world
but not to the Ape Boy of Moustier. A look of bewilderment spread over his
face. He pressed again with the same result.
Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!

ebookball.com

You might also like