Skip to content

Commit

Permalink
Merge pull request PhilippeSigaud#14 from ntrel/minor-fixes
Browse files Browse the repository at this point in the history
Minor fixes, mostly typos
  • Loading branch information
PhilippeSigaud committed Aug 2, 2012
2 parents 166fa5a + 79e8f3d commit d21f504
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 17 deletions.
17 changes: 9 additions & 8 deletions templates_advanced.tex
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ \subsection{Constraints, Specializations and \D{static if}:}
\end{dcode}

What were the D designers thinking? Well, they got specializations (\ref{specializations}) from D's cousin, C++\index{C++}. The two other subsystems were added a few years later, as the power of D compile-time metaprogramming\index{compile-time!introspection} became apparent and more powerful tools were needed. So, the 'modern' subsystems are constraints and \D{static if} (\ref{staticif})\index{static if@\D{static if}}. Constraints are much more powerful than specializations, as anything you can test with specialization, you can test with an \D{is} expression in a constraint\index{is expression@\D{is} expression!in a constraint}. And \D{static if} is wonderfully useful outside of template instantiation, so these two are well implanted in D and are there to stay.
What about specializations, now? First, they are quite nice to have when porting some C++\index{C++} code. Second, they have a nice effet that constraints do \emph{not} have: when more than one definition could be instantiated, priority is given to the more specialized. You saw the explanation in the previous subsection.
What about specializations, now? First, they are quite nice to have when porting some C++\index{C++} code. Second, they have a nice effect that constraints do \emph{not} have: when more than one definition could be instantiated, priority is given to the more specialized. You saw the explanation in the previous subsection.

So in the end, the conclusion is a bit of \emph{D Zen}\index{D Zen}: you are given tools, powerful tools. As these are powerful, they sometimes can do what other options in your toolbox can do also. D does not constrain (!) you, chose wisely.

Expand All @@ -214,15 +214,15 @@ \subsection{Testing for a member}
\begin{dcode}
module isserializable;

template isSerialazable(Type)
template isSerializable(Type)
{
static if (__traits(compiles, {
Type type;
size_t num = type.serialize;
}))
enum bool isSerialazable = true;
enum bool isSerializable = true;
else
enum bool isSerialazable = false;
enum bool isSerializable = false;
}
\end{dcode}

Expand Down Expand Up @@ -767,7 +767,7 @@ \section{Operator Overloading} \label{operatoroverloading}
\unfinished{Oh yes, that's quite not finished. I'm afraid I find D syntax for operator overloading a bit heavy for my tastes. As D code in \LaTeX, it's becoming \emph{very} cumbersome to write.}
D allows users to redefine some operators to enhance readability in code. And guess what? Operator overloading is based on templates. They are described \href{www.dlang.org/operators.html}{here} in the docs.
D allows users to redefine some operators to enhance readability in code. And guess what? Operator overloading is based on templates. They are described \href{www.dlang.org/operatoroverloading.html}{here} in the docs.
\subsection{Syntax}
Expand Down Expand Up @@ -1210,11 +1210,12 @@ \section{\DD{opDispatch}} \label{opdispatch}
\subsection{Syntax}\label{opdispatchsyntax}
\DD{opDispatch} is a sort of operator overloading (it's in the same place in the \href{www.dlang.org/operator.html}{online documentation}) that deals with members calls (methods or value members). Its definition is the same than an operator:
\DD{opDispatch} is a sort of operator overloading (it's in the same place in the \href{www.dlang.org/operatoroverloading.html#Dispatch}{online documentation}) that deals with members calls (methods or value members). Its definition is the same as an operator:
\index{syntax!opDispatch@\DD{opDispatch}}
\begin{dcode}
... opDispatch(string name, Args)(Arg arg)
... opDispatch(string name)()
... opDispatch(string name, Arg)(Arg arg)
... opDispatch(string name, Args...)(Args args)
\end{dcode}
Expand Down Expand Up @@ -1617,7 +1618,7 @@ \section{Templates in Templates}\label{templatesintemplates}
{ ... }
\end{dcode}
Halas, two template parameters tuples do not make sense (see \autoref{declarations}). But it's not a dead-end. First, you could try to write:
Alas, two template parameters tuples do not make sense (see \autoref{declarations}). But it's not a dead-end. First, you could try to write:
\begin{dcode}
template(AB...)
Expand Down
10 changes: 5 additions & 5 deletions templates_around.tex
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ \subsection{\DD{identifier}}
\DD{identifier} gives you a symbol's name as a string. This is quite interesting, since some symbols are what I'd call \emph{active}: for example, if \DD{foo} is a function, \DD{foo.stringof} will try to first call \DD{foo} and the \DD{.stringof} will fail. Also, \DD{.stringof}, though eminently useful, sometimes returns strangely formatted strings. \DD{identifier} is much more well-behaved.
Let's get back to one of the very first template in this doc, \DD{nameOf} on page \pageref{templatedeclarationexamples}. Initially, it was coded like this:
Let's get back to one of the very first templates in this doc, \DD{nameOf} on page \pageref{templatedeclarationexamples}. Initially, it was coded like this:
\begin{dcode}
template nameOf(alias a)
Expand Down Expand Up @@ -761,7 +761,7 @@ \subsection{\DD{allMembers}}
"opEquals", "Monitor", "factory"]);
\end{dcode}
If you remember one of the very first use we saw for templates in \ref{instantiating}, that is as a named, parameterized scope,\index{scope} this can give rise to interesting introspection:\index{introspection}
If you remember one of the very first uses we saw for templates in \ref{instantiating}, that is as a named, parameterized scope,\index{scope} this can give rise to interesting introspection:\index{introspection}
\begin{dcode}
module templateintrospection;
Expand All @@ -783,7 +783,7 @@ \subsection{\DD{allMembers}}
As you can see, you also get aliases' names. By the way, this is true for structs and templates also\ldots
Another fun fact is that D modules\index{module!modules as aggregates} are amenable to \D{\_\_traits}'s calls, though that's true only for packaged module (that is, \D{import }\DD{pack.mod;} imports the \DD{pack} and \DD{mod} symbols, but \D{import }\D{mod;} imports nothing).
Another fun fact is that D modules\index{module!modules as aggregates} are amenable to \D{\_\_traits}'s calls, though that's true only for packaged modules (that is, \D{import }\DD{pack.mod;} imports the \DD{pack} and \DD{mod} symbols, but \D{import }\D{mod;} imports nothing).
\begin{dcode}
module allmembersmodule;
Expand All @@ -803,15 +803,15 @@ \subsection{\DD{allMembers}}
}
\end{dcode}
In the previous code, you see that among \DD{a} members, there is \DD{"object"} (the implicit \DD{object.d} module\index{module!implicit object.d module@implicit \DD{object.d} module} imported by the runtime), and \DD{"std"}, the global package that shows here whenever you import a \DD{std.*} module. It would be easy to imagine a template that recursively explore the members, find the modules and try to recurse into them to get a complete import-tree with a template. Halas \DD{"std"} blocks that, since the package itself do not have a member.\footnote{ If someone finds a way to determine with a template that \DD{b} imports \DD{std.algorithm}, I'd be delighted to see how it's done!}
In the previous code, you see that among \DD{a} members, there is \DD{"object"} (the implicit \DD{object.d} module\index{module!implicit object.d module@implicit \DD{object.d} module} imported by the runtime), and \DD{"std"}, the global package that shows here whenever you import a \DD{std.*} module. It would be easy to imagine a template that recursively explores the members, finds the modules and tries to recurse into them to get a complete import-tree with a template. Alas, \DD{"std"} blocks that, since the package itself does not have a member.\footnote{ If someone finds a way to determine with a template that \DD{b} imports \DD{std.algorithm}, I'd be delighted to see how it's done!}
\aparte{introspection}{I'm pretty sure auto-introspection (a module calling \DD{allMembers} on its own name) used to work in Fall 2011. Now it's 2012 and this doesn't work anymore. Hmmm\ldots}
Like for the other aggregates, you get the aliased names also, and the unit tests defined in the module.\footnote{ For those of you curious about it, they are named \DD{\_\_unittestXXX} where \DD{XXX} is a number. Their type is more or less \D{void delegate}\DD{()}}\footnote{ I didn't try static constructors in modules. Don't hesitate to play with them and tell me what happens.}
\aparte{What's the point of inspecting a module?}{ Well, first that was just for fun and to see if I could duplicate a module or create a struct with an equivalent members list (all forwarding to the module's own members). But the real deal for me was when using string mixins to generate some type. If the user uses the mixin in its own module, it could create conflicts with already-existing names. So I searched for a way for a mixin template to inspect the module it's currently being instantiated in.
Then, I wanted to write a template the, given a class name, would give me the entire hierarchy it's in (as the local module scope would see it, that was enough for me). This \DD{Hierarchy} template should be shown in this document.
Then, I wanted to write a template that, given a class name, would give me the entire hierarchy it's in (as the local module scope would see it, that was enough for me). This \DD{Hierarchy} template should be shown in this document.
Then, while testing \stdanchor{traits}{ParameterTypeTuple}, I saw that it gives the parameter typetuple of \emph{one} function, even when it's overloaded. So inspecting a module is also a way to get the full list of functions with a particular name and getting the parameter typetuple for each of them.}
Expand Down
8 changes: 4 additions & 4 deletions templates_examples.tex
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ \subsubsection{Filtering Type Tuples}\label{staticfilter}
static assert(is(OnlyIntegrals == TypeTuple!(int, byte)));
\end{dcode}
What about separating types from non-types? First, let creates a template that is \D{true} for pure types and \D{false} on non-types:
What about separating types from non-types? First, let's create a template that is \D{true} for pure types and \D{false} on non-types:
\begin{dcode}
module istype;
Expand Down Expand Up @@ -326,7 +326,7 @@ \subsubsection{Example: building a \DD{Graph}}
\subsubsection{Folding Type Tuples}\label{staticreduce}
With mapping and filtering, folding (aka, reducing) is the third standard operation on sequences.\footnote{ In fact, it's the mother of all operations on sequences, since map and filter can be defined using reduce.} The idea is the same than \stdanchor{algorithm}{reduce}: given a seed \DD{S} and a binary function \DD{bin}, calculate \DD{bin(bin(bin(S, T[0]),T[1],T[2],...))}: apply \DD{bin} on the seed and the first type of the tuple, then take the resulting type as a new seed and re-apply \DD{bin} to this and the second type of the tuple, and so on, until the entire tuple is used.
With mapping and filtering, folding (aka, reducing) is the third standard operation on sequences.\footnote{ In fact, it's the mother of all operations on sequences, since map and filter can be defined using reduce.} The idea is the same as \stdanchor{algorithm}{reduce}: given a seed \DD{S} and a binary function \DD{bin}, calculate \DD{bin(bin(bin(S, T[0]),T[1],T[2],...))}: apply \DD{bin} on the seed and the first type of the tuple, then take the resulting type as a new seed and re-apply \DD{bin} to this and the second type of the tuple, and so on, until the entire tuple is used.
So, what's the use of such a function? It's used to \emph{collapse} a type tuple into one type. This one type can a simple type (for example, the 'biggest' type in the tuple, for some definition of big) or a complex structure built iteratively step by step along the tuple: a binary tree holding all the types, for example, or the reverse of the tuple, or even all the types but sorted according to a predicate.
Expand Down Expand Up @@ -392,7 +392,7 @@ \subsubsection{Sorting Types}\label{sortingtypes}
\item easily getting rid of duplicates (transforming a tuple into a set of types).
\end{itemize}
I'll focus on the third use, comparing two type tuples. See for example the \stdanchor{variant}{Algebraic} template struct. \DD{Algebraic!(Type0, Type1, ... TypeN)} can hold a value of one of \DD{Type0}, \ldots \DD{TypeN}. But of course, in a certain sense, the previous type is also the same than \DD{Algebraic!(Type1, TypeN, ... Type0)} or any other reordering of the types. But that's not the case currently:
I'll focus on the third use, comparing two type tuples. See for example the \stdanchor{variant}{Algebraic} template struct. \DD{Algebraic!(Type0, Type1, ... TypeN)} can hold a value of one of \DD{Type0}, \ldots \DD{TypeN}. But of course, in a certain sense, the previous type is also the same as \DD{Algebraic!(Type1, TypeN, ... Type0)} or any other reordering of the types. But that's not the case currently:
\begin{dcode}
module variant_error;
Expand Down Expand Up @@ -2200,7 +2200,7 @@ \section{Statically-Checked Writeln}\label{staticallycheckedwriteln}
else static if ({ alias Checks[0] C; return C!(Args[0]);}()) // recurse
\end{dcode}
We want to apply the first checking constraint, \DD{Check[0]}, on the first argument type, \DD{Args[0]}. Halas, the D grammar does not allow the following construct:
We want to apply the first checking constraint, \DD{Check[0]}, on the first argument type, \DD{Args[0]}. Alas, the D grammar does not allow the following construct:
\begin{dcode}
else static if (Checks[0]!(Args[0])) // recurse
Expand Down

0 comments on commit d21f504

Please sign in to comment.