|
@@ -17050,7 +17050,7 @@ dynamically typed languages such as \LangDyn{}, a particular
|
|
|
expression may produce a value of a different type each time it is
|
|
|
executed. Consider the following example with a conditional \code{if}
|
|
|
expression that may return a Boolean or an integer depending on the
|
|
|
-input to the program.
|
|
|
+input to the program:
|
|
|
% part of dynamic_test_25.rkt
|
|
|
{\if\edition\racketEd
|
|
|
\begin{lstlisting}
|
|
@@ -17065,18 +17065,18 @@ not (False if input_int() == 1 else 0)
|
|
|
|
|
|
Languages that allow expressions to produce different kinds of values
|
|
|
are called \emph{polymorphic}, a word composed of the Greek roots
|
|
|
-``poly'', meaning ``many'', and ``morph'', meaning ``form''. There
|
|
|
-are several kinds of polymorphism in programming languages, such as
|
|
|
+\emph{poly}, meaning \emph{many}, and \emph{morph}, meaning \emph{form}.
|
|
|
+There are several kinds of polymorphism in programming languages, such as
|
|
|
subtype polymorphism and parametric polymorphism
|
|
|
-(aka. generics)~\citep{Cardelli:1985kx}. The kind of polymorphism we
|
|
|
-study in this chapter does not have a special name but it is the kind
|
|
|
+(aka. generics)~\citep{Cardelli:1985kx}. The kind of polymorphism that we
|
|
|
+study in this chapter does not have a special name; it is the kind
|
|
|
that arises in dynamically typed languages.
|
|
|
|
|
|
Another characteristic of dynamically typed languages is that
|
|
|
-primitive operations, such as \code{not}, are often defined to operate
|
|
|
+their primitive operations, such as \code{not}, are often defined to operate
|
|
|
on many different types of values. In fact, in
|
|
|
\racket{Racket}\python{Python}, the \code{not} operator produces a
|
|
|
-result for any kind of value: given \FALSE{} it returns \TRUE{} and
|
|
|
+result for any kind of value: given \FALSE{} it returns \TRUE{}, and
|
|
|
given anything else it returns \FALSE{}.
|
|
|
|
|
|
Furthermore, even when primitive operations restrict their inputs to
|
|
@@ -17085,7 +17085,7 @@ instead of during compilation. For example, the tuple read
|
|
|
operation
|
|
|
\racket{\code{(vector-ref \#t 0)}}
|
|
|
\python{\code{True[0]}}
|
|
|
-results in a run-time error because the first argument must
|
|
|
+results in a runtime error because the first argument must
|
|
|
be a tuple, not a Boolean.
|
|
|
|
|
|
\section{The \LangDyn{} Language}
|
|
@@ -17213,23 +17213,23 @@ be a tuple, not a Boolean.
|
|
|
\end{figure}
|
|
|
|
|
|
|
|
|
-The concrete and abstract syntax of \LangDyn{} is defined in
|
|
|
-figures~\ref{fig:r7-concrete-syntax} and \ref{fig:r7-syntax}.
|
|
|
+The definitions of the concrete and abstract syntax of \LangDyn{} are
|
|
|
+shown in figures~\ref{fig:r7-concrete-syntax} and \ref{fig:r7-syntax}.
|
|
|
%
|
|
|
-There is no type checker for \LangDyn{} because it only checks types
|
|
|
+There is no type checker for \LangDyn{} because it checks types only
|
|
|
at runtime.
|
|
|
|
|
|
The definitional interpreter for \LangDyn{} is presented in
|
|
|
\racket{figure~\ref{fig:interp-Ldyn}}
|
|
|
-\python{figures~\ref{fig:interp-Ldyn} and \ref{fig:interp-Ldyn-2}}
|
|
|
-and its auxiliary functions are defined in
|
|
|
+\python{figures~\ref{fig:interp-Ldyn} and \ref{fig:interp-Ldyn-2}},
|
|
|
+and definitions of its auxiliary functions are shown in
|
|
|
figure~\ref{fig:interp-Ldyn-aux}. Consider the match case for
|
|
|
\INT{n}. Instead of simply returning the integer \code{n} (as
|
|
|
in the interpreter for \LangVar{} in figure~\ref{fig:interp-Lvar}), the
|
|
|
interpreter for \LangDyn{} creates a \emph{tagged value}\index{subject}{tagged
|
|
|
value} that combines an underlying value with a tag that identifies
|
|
|
what kind of value it is. We define the following \racket{struct}\python{class}
|
|
|
-to represented tagged values.
|
|
|
+to represent tagged values:
|
|
|
%
|
|
|
{\if\edition\racketEd
|
|
|
\begin{lstlisting}
|
|
@@ -17255,11 +17255,11 @@ class Tagged(Value):
|
|
|
\python{The tags are \code{'int'}, \code{'bool'}, \code{'none'},
|
|
|
\code{'tuple'}, and \code{'function'}.}
|
|
|
%
|
|
|
-Tags are closely related to types but don't always capture all the
|
|
|
+Tags are closely related to types but do not always capture all the
|
|
|
information that a type does.
|
|
|
%
|
|
|
\racket{For example, a vector of type \code{(Vector Any Any)} is
|
|
|
- tagged with \code{Vector} and a procedure of type \code{(Any Any ->
|
|
|
+ tagged with \code{Vector}, and a procedure of type \code{(Any Any ->
|
|
|
Any)} is tagged with \code{Procedure}.}
|
|
|
%
|
|
|
\python{For example, a tuple of type \code{TupleType([AnyType(),AnyType()])}
|