From 345480d2c0647a1a4bf8b7915d78155a261ea988 Mon Sep 17 00:00:00 2001
From: Bent Bisballe Nyeng <deva@aasimon.org>
Date: Thu, 3 Aug 2023 17:39:59 +0200
Subject: A5: Final

---
 a5/exercise.tex | 139 ++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 104 insertions(+), 35 deletions(-)

(limited to 'a5/exercise.tex')

diff --git a/a5/exercise.tex b/a5/exercise.tex
index 9491afe..2544cff 100644
--- a/a5/exercise.tex
+++ b/a5/exercise.tex
@@ -1,18 +1,24 @@
 \title{A5: Generic Programming}
 \input{preamble.tex}
 
-I decided to use std container for the elements of the matrix and
-initially went with \texttt{std::vector<int>}. But since we were going
-to do arithmentics on the data, and no requirements were made as to
-the arithmentics actually being those of a real matrix, I figure why
-not use \texttt{std::valarray<int>} and have all arithmentic
-operations be per-entry, re-suing the behaviour of
-\texttt{std::valarray} directly.
-
-In the change I discovered that \texttt{std::valarray} and
+In this exercise a matrix class is being developed and gradually
+evolved into a typesafe templated component.
+
+\bigskip
+
+I decided to use one of the standard containers for storing the elements of
+the matrix and initially went with \texttt{std::vector<int>}. But
+since we were going to do arithmentics on the data, and no
+requirements were made as to the arithmentics actually being those of
+a real matrix, I figure why not use \texttt{std::valarray<int>} and
+have all arithmentic operations be per-entry, re-using the behaviour
+of \texttt{std::valarray} directly.
+
+During this change I discovered that \texttt{std::valarray} and
 \texttt{std::vector} ctor args for creating with a size and a default
 value for all items are reversed, which would not be caught by the
 compiler with both of them being integral:
+
 \footnotesize\begin{lstlisting}[language=C++]
 explicit vector( size_type count,
                  const T& value = T(),
@@ -22,9 +28,13 @@ valarray( const T& val, std::size_t count );
 \end{lstlisting}\normalsize
 That, I think, is rather unfortunate.
 
-When using a std container, all memory managing is handled by the
+When using a standard container, all memory managing is handled by the
 container, even when throwing an exception inside the constructor, so
-no need to do anything clever inside the matrix implementation itself.
+tere is no need to do anything clever inside the matrix implementation
+itself. Otherwise a allocating base-class could have been made for
+memory ownership as seen during one of the presentations.
+The implementation for the statically typed \texttt{Imatrix} can be
+seen in the \texttt{imatrix.h} file.
 
 I first wrote the entire \texttt{Imatrix} class with the values
 dynamically allocated inside the \texttt{std::valarray} but wanted to
@@ -33,34 +43,93 @@ explore having the matrix dimenions available at compile-time
 so they should be checkable at compile-time). I did this with template
 size arguments.
 
-This removed a lot of error checks on matrix dimension matching, which
-is part of the type itself - nice!
+First of all, this removed a lot of error checks on matrix dimension
+matching, which is now part of the type itself.
+It also removed the need for the two integer members from the first
+imeplementation, carrying the matrix dimensions, so the change now
+also saved 16 bytes of memory.
 
-It also removed the need for the two integer members carrying the
-width and height - we now also saved 16 bytes of memory!
+And, best of all, we get a compile error if for example we try
+multiplying two matrices where their dimensions doesn't adhere to the
+algebraic rules!
 
-... and we get a compile error if for example we try multiplying two
-matrices where their dimensions doesn't adhere to the algebraic rules!
+For the \texttt{Row()} and \texttt{Column()} I briefly considered
+returning a span to be able to return references to a row or column
+for dynamic iteration, but decided to stick with
+the \texttt{std::vector} as described in the assignment.
+The code for the size-templated \texttt{Imatrix<N,M>} can be seen in
+the \texttt{imatrix\_nm.h} file.
 
-Final step is to templatize the underlying typeof the matrix. Done so
-by simply replacing int with T and all the places where 0 is assigned
-to the value type, replacing it with the default value T{}
+\bigskip
+
+Next step was to templatize the underlying type of the matrix. This
+was more or less done by simply replacing \texttt{int} with \texttt{T}
+and all the places where 0 is assigned to the value type, replacing it
+with the default value \texttt{T\{\}}.
+For the \texttt{Move()} function a $0$ assignment was needed and this
+I replaced with an empty initializer list, \texttt{\{\}}.
+The new templatized class is called \texttt{Matrix} and can be found in
+the \texttt{matrix.h} file.
 
 When instantiating a template only the required/used functions are
 generated (or so it appears).
-In other words, I can instante a \texttt{Matrix<Chess\_piece,2,2> c1}
-without getting any compile errors because I don't actually call
-anything on it.
-If I add a \texttt{c1 + 1} somewhere it will complain about not being
-able to add, but not any of the other unused operations.
-When adding the requirements of concepts, I will get errors for all
-the uses, not just the ones I use. In other words, concepts might end
-up requirering more work to be done by a developer than strictly
-needed. This I think is actually not that good.
-Adding the requirement to each of the member functions might be
-better.
-
-
-I actually made some errors in the matrix subscripts in the matrix
-multiplication/division code, which was shown to me by an assertion.
+In other words; a \texttt{Matrix<Chess\_piece,2,2> c1} can be instantiated
+without getting any compile errors as long as no algebraic methods are
+being called on it.
+If the line \texttt{c1 + 1} is added somewhere it will complain about
+not being able to add with \texttt{int}, but not any of the other unused
+operations.
+When adding the requirements of concepts, I expect to get errors for
+all the uses, not just the ones used in the program.
+In other words, concepts might end up requirering more work to be done
+by a developer than strictly needed. This might not always be
+desirebale - or at least it is something that should be thought about
+when designing a new component.
+One option to mimic the same behaviour, but with concepts, could
+perhaps be to add requirements to each of the member functions. This
+is however not what I did in this exercise.
+
+I made a concept, \texttt{supports\_modulo<T1,T2>}, used for only
+``activating'' the modulo operator if the underlying type supports it.
+
+I made an extensive, templated, test function that exercised all
+operator types of any of the matrix types - and here the compiler errors
+for \texttt{Chess\_piece} were not very helpful (the same goes
+for \texttt{std::string}). This can be seen in the \texttt{matrix.cc}
+file.
+In the test program, to prevent performing modulo operations on
+matrices that doesn't support them, I used
+the \texttt{supports\_modulo} concept together with a \texttt{if
+constexpr} to only try to call the module operator when enabled for
+the class.
+
+I made another concept, \texttt{supports\_matrix<T>}, used for the
+underlying type of the \texttt{Matrix<T>} class itself, requirering
+algebraic functionality on the underlying type.
+
+After adding requirements for all the needed operators,
+the \texttt{Chess\_piece} and \texttt{std::string} matrices now failed
+as expected but this time with a much shorter and to-the-point error
+message telling me exactly what would be needed for them work.
+
+I added empty dummy operator functions to fulfill the requirements (and
+commented out the \texttt{std::string} one) and now the program
+compiles and runs as expected.
+
+In hindsight, using the \texttt{std::valarray} may have resulted in me
+writing less code in the \texttt{Matrix} implementation, but because
+of implementation details inside \texttt{std::valarray} I may have
+ended up having to write more algebraic operators
+on \texttt{Chess\_piece} to get it to work.
+
+\bigskip
+
+The approach of first writing the statically typed class, then
+templatizing it, and finally analyzing the actual requirements of the
+underlying type and expressing those as a concept requirements, was a
+nice way to ``eat the elephant'', being able to focus on just one
+aspect of the code at one time. My guess is also that it would have
+been hard to foresee what the actual type requirements would end up being
+without having written the code yet.
+
 \end{document}
-- 
cgit v1.2.3

