Arithmetic-PaperAndPencil

 view release on metacpan or  search on metacpan

doc/documentation.en.md  view on Meta::CPAN

which improves the readability and also the speed of code writing.

Another  new feature  I came  to appreciate  is the  fact that  we can
declare a function within another  function (or method). See functions
`check_l_min`,     `l2p_lin`,     `check_c_min`,     `l2p_col`     and
`filling_spaces` in method `html`.

On the  other hand, there is  a feature still missing  from Perl 5.38.
Now  it is  2024, all  programming tools  (source editors,  databases,
compilers) deal correctly with Unicode and UTF-8. Yet, by default, the
Perl 5.38 interpreter still considers  the default encoding for source
files and data  files is ISO-8859-1 or similar. This  can be explained
by back-compatibility with  programmes written in version  5.0 back in
the previous century. But as soon  as a programmer writes `use 5.38;`,
or even  `use 5.10;`,  we know that  the back-compatibility  no longer
extends into times before Unicode. So we could consider that with `use
5.38`, the Perl default would be  using Unicode and UTF-8. This is not
the case and I must still add:

```
use utf8;
use open ':encoding(UTF-8)';
```

Found Problems
--------------

### First problem with `A::P&P::Char`

The first problem appeared when coding the `A::P&P::Char` class and
the `html` method for `Arithmetic::PaperAndPencil`.

In  a few  instances, we  must insert  one or  several columns  at the
beginning of  each line in the  operation, and fill these  new columns
with  spaces (actually  instances  of the  `A::P&P::Char` class).  The
`html`  method   computes  the  number  of   inserted  columns,  named
`$delta_c` (or `$delta-c` in Raku) and then runs:

```
      # Raku
      for @sheet <-> $line {
        prepend $line, space-char() xx $delta-c;
      }
```

Function  `space-char`   is  the   function  giving  an   instance  of
`A::P&P::Char` filled with a space. My first attempt in Perl was:

```
      # Perl
      for my $line (@sheet) {
        unshift @$line, (Arithmetic::PaperAndPencil::Char->space_char) x $delta_c;
      }
```

It   did  not   work.  Test   programme  `01-action.t`   (Raku-to-Perl
translation  of  `06-html.rakutest`) would  write  `133`  where I  was
expecting  `123`. After  some debugging,  I understood  that one  each
line,  the `unshift`  statement would  insert the  same `A::P&P::Char`
instance twice.  On the other hand,  the problem was not  appearing in
Raku. Either  formula `space-char() xx $delta-c`  calls twice function
`space-char` and  gets two  different instances of  `A::P&P::Char`, or
the `prepend` statement deep-copies its argument into the list. Either
way, I had to fix the Perl version and write:

```
      # Perl
      for my $line (@sheet) {
        for (1 .. $delta_c) {
          unshift @$line, Arithmetic::PaperAndPencil::Char->space_char;
        }
      }
```

### Second problem with `A::P&P::Char`

The  `01-action.t` test  programme  generates two  HTML strings.  When
writing class `A::P&P::Char`  and method `html`, I  activated only the
first HTML string  generation until it was  completely implemented and
debugged. Then, when I activated the second HTML string generation, it
was  no  longer working.  With  the  help  of  a few  debugging  trace
messages,  I  pinpointed  an  error  in  at  least  `check_l_min`  and
`l2p_lin` inner functions.  Maybe the same error was  occurring in the
other inner functions:  `check_c_min`, `l2p_col` and `filling_spaces`,
I  did not  check. Here  is the  explanation with  only `l2p_lin`  for
brievety's sake. Here is the function:

```
  # Perl
  sub l2p_lin($logl) {
    my $result = $logl - $l_min;
    return $result;
  }
```

This  function uses  a  formal  call parameter  `$logl`  and a  global
variable `$l_min` (actually a lexical  variable with a scope extending
beyond function `l2p_lin` to the  outer method). During the first HTML
string generation, variable `$l_min`  would have the successive values
0, -1,  -3 and -4  (skipping -2 because we  insert two columns  in one
go). Yet,  during the  second HTML  string generation,  `$l_min` would
have  a strange  behaviour. When  printed from  outside the  `l2p_lin`
function, I would have values 0, -1,  -3 and -4, but when printed from
within the `l2p_lin` function it would always give -4.

Here  is the  hypothetical explanation.  During the  first generation,
function `l2p_lin` would  use the proper value for  `$l_min`, that is,
0, then -1,  then -3 and lastly -4. When  method `html` ends, function
`l2p_lin` is still  alive thanks to the closure  mechanism. And thanks
to the  same closure  mechanism, variable  `$l_min` still  exists with
value  -4 because  it is  used by  `l2p_lin`. Then,  method `html`  is
called a second  time to check CSS usage. This  defines a new instance
of  variable `$l_min`,  initialised  to  0. On  the  other hand,  when
reading the definition

```
  # Perl
  sub l2p_lin($logl) {
    my $result = $logl - $l_min;
    return $result;
  }



( run in 1.481 second using v1.01-cache-2.11-cpan-39bf76dae61 )