Do you know where your variables are? PerlMonks

Meditations

 ( #480=superdoc: print w/replies, xml ) Need Help??

If you've discovered something amazing about Perl that you just need to share with everyone, this is the right place.

This section is also used for non-question discussions about Perl, and for any discussions that are not specifically programming related. For example, if you want to share or discuss opinions on hacker culture, the job market, or Perl 6 development, this is the place. (Note, however, that discussions about the PerlMonks web site belong in PerlMonks Discussion.)

Meditations is sometimes used as a sounding-board — a place to post initial drafts of perl tutorials, code modules, book reviews, articles, quizzes, etc. — so that the author can benefit from the collective insight of the monks before publishing the finished item to its proper place (be it Tutorials, Cool Uses for Perl, Reviews, or whatever). If you do this, it is generally considered appropriate to prefix your node title with "RFC:" (for "request for comments").

User Meditations
Coding Challenge: Find 6 sided polygon covering 4x4 grid
5 direct replies — Read more / Contribute
by LanX
on May 31, 2019 at 09:38
There was a recent request* for coding challenges, and I stumbled over this quiz.

Given are 16 equidistant points in a 4x4 grid.

The coordinates are given with with @set = ([0,0],[0,1],...[3,3])

```  y

3  o  o  o  o <- [3,3]

2  o  o  o  o

1  o  o  o  o

0  o  o  o  o <- [3,0]

0  1  2  3  x

Task: Find a polygon° with 6 edges, crossing each grid-point exactly once.

@polygon = ([x0,y0],...[x6,y6])

Example: the edge ([-1,4],[3,0]) is crossing 4 points.

Hints:

• The vertices [x_i, y_i] don't need to be part of the integer grid.
• There is a solution where the polygon is closed - i.e. [x0,y0]=[x6,y6] .
• Use fractions or a scaling factor in case floating-point accuracy is posing problems.

Disclaimer: I didn't code it yet, but I saw existing solutions.

Have fun! :)

PS: Extra points for generalized solutions for bigger grids. While this can be solved with paper and pen, I'm expecting code to solve it.

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

update

Changed orientation of coordinate system to have 0,0 at the left lower corner like in math convention.

• bliako: Are polygon sides allowed to intersect? -> Yes !
• bliako: Aren't all polygons closed? -> in math: yes, in computer graphics: depends ;-)
s/Polygon/Polygonal_chain/ if you want.
I'll be off for the weekend, sorry if I can't reply earlier.

footnotes

°) or rather Polygonal_chain

*) See Coding challenges to PM

git-push target for Makefile (via ExtUtils::MakeMaker)
2 direct replies — Read more / Contribute
by bliako
on May 21, 2019 at 09:22

I was trying to automate more (=keep as far away as possible) the process of pushing to github through a Makefile and I came up with the following simplistic approach. It basically creates a make target called git-push via MY::postamble provided by ExtUtils::MakeMaker. I got the postamble idea from pryrt's answer to Benchmarks target in Makefile

```perl Makefile.PL
make all
make git-push

At first it creates a .gitignore file which whitelists the files/dirs to push, then calls git init, git add ., git commit ... and finally git push ... (I hope it's correct, it works for me).

As it is, it works for me but I am sure there are lots and lots of improvements and safeguards. Also, it does not proceed unless the target repository already exists remotely - there is no git-cmdline-only way to create a repository as I understand.

Possible major improvement would be to use Git::Repository instead of make shelling out git commands. But this is the idea I wanted to share.

Deviations from the normal Makefile.PL are designated by ADD this:

bw, bliako

security and Perl
4 direct replies — Read more / Contribute
by zentara
on May 08, 2019 at 13:18
Hi, long time no see. I didn't die, just off checking out other planets. :-) My meditation came about as I tried to think of ways to make Perl economically useful. I thought the most useful tool one could have now, is some sort of end-to-end encrypted communications system, written in Perl, yet really can't be tampered with without proper keys, etc. Much like Microsoft's new voting system. :-)
Anyways, how secure is a properly compiled and sha-checked source install of Perl and its core sockets modules. Are they prone to breaking, are there obvious security flaws that would preclude it from being used for encrypted end-2-end messaging scheme. Are there problems in Perl's buffers that make it vulnerable to text-mining core dumps etc. Would you buy a working end-2end port-specific encryption system written is Perl? Would you trust it in encrypted communications? This idea is probably my last attempt to make use of Perl, but would Perl stand up in court as being a viable software choice? Could I be shown to be negligent by using Perl? :-)
I expect this meditation to go on for awhile. :-)

I'm not really a human, but I play one on earth. ..... an animated JAPH
RFC: 101 Perl PDL Exercises for Data Analysis
2 direct replies — Read more / Contribute
by thechartist
on May 06, 2019 at 19:36

101 Perl PDL Exercises for Data Analysis (May 2019 with PDL 2.019)

Before "data science" became a fashionable topic in computing, Perl hackers have been cleaning and analyzing data since Perl was written. The following tutorial provides Perl examples to the problems posed in: 101 NumPy Exercises for Data Analysis

My purpose is to demonstrate that Perl has the necessary tools to complete common data analysis tasks with minimal effort.

The philosophy of Perl has always been "There is more than one way to do it." Data analysis is no exception. While PDL has excellent functionality "out of the box", you might find it more effective to use individual CPAN modules to solve particular problems.

This document assumes you know some basic programming -- loops, conditionals, variables, etc. Perl syntax is similar to any C derived language. Perl has a few fundamental data types:

• 1. Scalar: single items, such as strings of characters, and sequences of numbers -- Prefixed by '\$'
• 2. Lists/Arrays: a collection of items in order -- Prefixed by '@' Arrays are variables. The values of an array are lists.
• 3. Hashes: a collection of key/value pairs. -- Prefixed by '%'. Hashes can be converted to lists, and vice versa.
• Examples:

```\$foo = 99; # Assigns the integer 99 to \$foo.  Scalar context.
@Foo = ('Jack', 5, 'Jill', 4, 'John', 7); # A list assigned to @foo, v
+alues separated by commas.
%foo = ('Jack', 5, 'Jill', 4, 'John', 7); # A list as key, value pairs
+. Better ways to write this exist.

There are others (typeglobs and references), but they will not be needed for the exercises that follow.

As always in Perl, there is more than one way to do anything. For PDL, one can enter simply invoke the Perl interpreter at the command line (like any other Perl script), or use a REPL (Read, Evaluate, Print, Loop) interface for interactive analysis. This exercise will show the Perl PDL one liner entered at the command line, but code in between quotation marks should work at the REPL also.

Exercise 1 1. Import PDL and print the version.

```\$ perl -MPDL -e "print \$PDL::VERSION;"

2. Create a 1D array of numbers from 0 to 9

```\$ perl -MPDL -e "\$arr = sequence(10); print \$arr;"

3. Q. Create a 3×3 numpy array of all True’s

```\$ perl -MPDL -e "\$arr = ones(3,3), print \$arr;"

4. Q. Q. Extract all odd numbers from arr = [0,1,2,3,4,5,6,7,8,9].

```\$ perl -MPDL -e "\$arr = sequence(10); \$odd = where(\$arr, (\$arr%2) == 1
+); print \$odd;"

5. Q. Replace all odd numbers in arr (from question 4) with -1.

```Input:  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Output: [ 0, -1,  2, -1,  4, -1,  6, -1,  8, -1]

Answer:  perl -MPDL -e "\$arr = sequence(10); \$odd = \$arr->where(\$arr % 2 == 1); \$odd .= -1 ; print \$arr;"

6.Replace all odd numbers in arr with -1 without changing arr

```Input:  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [ 0, -1,  2, -1,  4, -1,  6, -1
+,  8, -1]

Answer: \$ perl -MPDL -e "\$arr = sequence(10); \$out = sequence(10); \$odd = \$arr->where(\$arr %2 == 1); \$odd .= -1; print \$out, \$arr;"
Note: the '.=' operator is a special type of assignment operator in the PDL context. Ordinarily this is used for string concatenation.

7. Q. Convert a 1D array to a 2D array with 2 rows.

```Input: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Output: [ [0, 1, 2, 3, 4],
[5, 6, 7, 8, 9] ]

```\$ perl -MPDL -e "\$seq = sequence(10); \$seq_1 = \$seq->reshape(5,2); pri
+nt \$seq_1;"

8. Q. Stack arrays a and b vertically

```Input: a = [0,1,2,3,4,5,6,7,8,9]
b = [1,1,1,1,1,1,1,1,1,1]

Output: [[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]]

```\$ perl -MPDL -e "\$arr_a = sequence(10); \$arr_b = ones(10); \$out = pdl(
+ \$arr_a, \$arr_b )->reshape( 5,4 ) ; print \$out; "

9. Q. Stack the arrays a and b horizontally.

```Output: [[0, 1, 2, 3, 4, 1, 1, 1, 1, 1],
[5, 6, 7, 8, 9, 1, 1, 1, 1, 1]]

```perl -MPDL -e "\$arr_a = sequence(10)->reshape(5,2); \$arr_b = ones(10)-
+>reshape(5,2); print append( \$arr_a, \$arr_b );"

Iis it possible to smear paint on the wall without creating valid Perl?
by holli
on Apr 29, 2019 at 17:52
I just came across this gem of a paper with the promising title 93% of Paint Splatters are Valid Perl Programs. If you're looking for a good weekend read for the sunday morning movement, look no further.

Money Quote:
Figure 6 represents the string “gggijgziifiiffif”, which by pure coincidence happens to accurately represent the authors’ verbal reaction upon learning that “unquoted strings” were a feature intentionally included in the Perl language.

holli

You can lead your users to water, but alas, you cannot drown them.
RFC: OO Perl using Moo/Moose book
2 direct replies — Read more / Contribute
by Perl300
on Apr 25, 2019 at 12:25

Hello Monks,

Somehow, I found this comments page on Chromatic's modernperlbooks website: http://modernperlbooks.com/mt/2010/12/perl-books-i-want.html

I would love to buy second book in the list, "Modern Perl OO with Moose" (or Moo)

Does anyone know if there is any book like this? If not then is there any way to motivate Chromatic or other esteemed Monks to think about writing it?

Modern Perl book by Chromatic really enlightened me.

I crashed 99 bottles.. the dot was the point (multiconcat)
3 direct replies — Read more / Contribute
by Discipulus
on Apr 19, 2019 at 15:25
Hello folks!

recently I visited code-golf.io and i found my (terrible) 99 bottles of beer marked as broken. A lot of glass on the floor..

I tried it locally and it was correct on perl 5.24 (and 5.26) but no more on 5.28 Basically the heart of the code was:

```\$n=4;
print \$n." -- ".(--\$n||'no more'),".\n" while \$n;

# output on perl 5.26 5.24 and before
4 -- 3.
3 -- 2.
2 -- 1.
1 -- no more.

# output on perl 5.28
3 -- 3.
2 -- 2.
1 -- 1.
0 -- no more.

I tried looking in perldelta if something changed in autoincrement autodecrement between versions, but nothing.

The rule of thumb in official docs goes: This also means that modifying a variable twice in the same statement will lead to undefined behavior.

But I supposed this was not the case: I was using and modifying it, not modifying it twice.

The cloister was empty and only brother Eily was here to help (thanks) pointing me to undefined behaviour associated with some case of autodecrement.

Then I knocked the irc door where (when I finally was able to reduce the failing code to the above) the wise Grinnz bet on the issue was due to multiconcat performance enhancement. Tadàaaa!

Is not the autoincrement/autodecrement to had changed but the time where concatenation happens: infact the above code with commas behaves the same across versions:

```\$n=4; print \$n." -- ",(--\$n||'no more'),".\n" while \$n;
#^--- is a comma now!

# output on perl 5.28
4 -- 3.
3 -- 2.
2 -- 1.
1 -- no more.

So, be aware of the above my friends! From 5.28 onward the dot can be the point!

L*

PS

the above provoked a small flame on irc but a wise named integral posted an interesting piece of code (I admit I do not understand it, but look for concat/multiconcat):

```use B::Concise;
sub sample { \$n=4; print \$n." -- ".(--\$n||'no more'),".\n" while \$n; }
+
B::Concise::compile('-exec', "sample", \&sample)->();

__DATA__

# output in perl 5.24

main::sample:
1  <;> nextstate(main -12 99bottles.pl:2) v:{
2  <\$> const[IV 4] s
3  <#> gvsv[*n] s
4  <2> sassign vKS/2
5  <;> nextstate(main -12 99bottles.pl:2) v:{
6  <0> enter
7  <#> gvsv[*n] s
8  <|> and(other->9) K/1
9      <0> pushmark s
a      <#> gvsv[*n] s
b      <\$> const[PV " -- "] s
c      <2> concat[t3] sK/2
d      <#> gvsv[*n] s
e      <1> predec sK/1
f      <|> or(other->g) sK/1
g          <\$> const[PV "no more"] s
h      <2> concat[t5] sKS/2
i      <\$> const[PV ".\n"] s
j      <@> print sK
k      <0> unstack s
goto 7
l  <@> leave K*
m  <1> leavesub[1 ref] K/REFC,1
B::Concise::compile(CODE(0x5ef428))
1  <;> nextstate(main -12 99bottles.pl:2) v:{
2  <\$> const[IV 4] s
3  <#> gvsv[*n] s
4  <2> sassign vKS/2
5  <;> nextstate(main -12 99bottles.pl:2) v:{
6  <0> enter
7  <#> gvsv[*n] s
8  <|> and(other->9) K/1
9      <0> pushmark s
a      <#> gvsv[*n] s
b      <\$> const[PV " -- "] s
c      <2> concat[t3] sK/2
d      <#> gvsv[*n] s
e      <1> predec sK/1
f      <|> or(other->g) sK/1
g          <\$> const[PV "no more"] s
h      <2> concat[t5] sKS/2
i      <\$> const[PV ".\n"] s
j      <@> print sK
k      <0> unstack s
goto 7
l  <@> leave K*
m  <1> leavesub[1 ref] K/REFC,1

# output in 5.28

main::sample:
1  <;> nextstate(main -8 99bottles.pl:2) v:{
2  <\$> const[IV 4] s
3  <#> gvsv[*n] s
4  <2> sassign vKS/2
5  <;> nextstate(main -8 99bottles.pl:2) v:{
6  <0> enter
7  <#> gvsv[*n] s
8  <|> and(other->9) K/1
9      <0> pushmark s
a      <#> gvsv[*n] s
b      <#> gvsv[*n] s
c      <1> predec sK/1
d      <|> or(other->e) sK/1
e          <\$> const[PV "no more"] s
f      <+> multiconcat(" -- ",-1,4,-1)[t5] sK
g      <\$> const[PV ".\n"] s
h      <@> print sK
i      <0> unstack s
goto 7
j  <@> leave K*
k  <1> leavesub[1 ref] K/REFC,1
B::Concise::compile(CODE(0x4fe6e0))
1  <;> nextstate(main -8 99bottles.pl:2) v:{
2  <\$> const[IV 4] s
3  <#> gvsv[*n] s
4  <2> sassign vKS/2
5  <;> nextstate(main -8 99bottles.pl:2) v:{
6  <0> enter
7  <#> gvsv[*n] s
8  <|> and(other->9) K/1
9      <0> pushmark s
a      <#> gvsv[*n] s
b      <#> gvsv[*n] s
c      <1> predec sK/1
d      <|> or(other->e) sK/1
e          <\$> const[PV "no more"] s
f      <+> multiconcat(" -- ",-1,4,-1)[t5] sK
g      <\$> const[PV ".\n"] s
h      <@> print sK
i      <0> unstack s
goto 7
j  <@> leave K*
k  <1> leavesub[1 ref] K/REFC,1

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Google Code Jam 2019 Round 1A Problem 1: Pylons
5 direct replies — Read more / Contribute
by choroba
on Apr 14, 2019 at 16:56
The round 1A happened at unreasonable hours (around 3AM) for my timezone, so I skipped it. The next day, I checked the problems to see what I could expect in the 1B or 1C rounds. The first problem was called Pylons and it took me a whole day to solve.

It starts simply. We have a grid of a given size and we want to visit each cell in it exactly once. In each turn, we can move in any direction, we just can't stay in the same row, column, or diagonal.

I started with a brute force solution just to see what's possible. After several hours, I was able to guess whether any solution was possible for the given size of the grid, but I wasn't able to find a solution within the time limit for the larger grids.

In the end, I gave up and started to read the Analysis. When they mentioned "random solution should work", I stopped reading and returned to my code. In the brute force solution, I changed the loops

```for my \$row (1 .. \$row_size) {
for my \$column (1 .. \$column_size) {
...
}
}

into

```use List::Util qw{ shuffle };

# ...

for my \$row (shuffle(1 .. \$row_size)) {
for my \$column (shuffle(1 .. \$column_size)) {
...
}
}

but my program was still timing out. I created a special input file to test all the possible inputs (the maximal size was 20×20) just to notice the program got stuck at a different size every time. I thought: "Maybe there's a random seed that would go through all the inputs smoothly." And I started testing srand \$RAND for 0, 1, 2, 3, ... When \$RAND was 48, my program solved the first 93 input lines before getting stuck!

And then I had another idea: maybe there's no universal random seed for all the inputs, but each input can have one good random seed. So I wrote a testing program that tried to find the solution for every given size with various random seeds. It set up an alarm timeout of 1 second before trying a solution and only continued in trying the following seed if it timed out.

To my surprise, most of the inputs performed well with the random seed 1. So I used it as the default and specified the exceptions in a hash:

```my %srand = ('3 16' => 2,
'4 10' => 2,
'4 17' => 3,
'4 19' => 3,
'5 15' => 5,
# ...
);

I then just adjusted the srand before I started populating the grid.

```srand (\$srand{"\$rows \$columns"} || 1);
\$grid = solve(\$rows, \$columns);

And this solution passed the tests.

map{substr\$_->[0],\$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
18 and life to go...
2 direct replies — Read more / Contribute
by atcroft
on Apr 09, 2019 at 03:05

As I sit in this darkened room
I pass my time with strangers
But this code's my only friend

I logged in to see if there was anything I might find interesting, and was pleasantly surprised when I saw this on my profile:

 User since: Apr 09, 2001 at 03:59 CDT (18 years ago) Last here: Apr 09, 2019 at 00:52 CDT (1 second ago)

Eighteen years a PerlMonk.

It doesn't feel that long ago that I created an account and asked how to light individual pixels on a Tk Canvas. Well, in ways it does but in ways it doesn't. Back then I was playing with a pet project, a crude visual simulation. Being only a few years out of a C.S. program at the time, that was truly an ugly bit of code (at the time, I didn't even know about perl hashes-it used strings of concatenated sets of coordinates/vectors, and housed those strings in an array to act as a queue to be processed). Yes, I admit I knew much less than I thought I did about the language at the time. (I still find myself learning things about the language to this day.) Quite frankly, that code is my nemesis-maybe once or twice a year or so I pull that script out, run it (it runs, but terribly slowly), start to re-write it based on what I know now, and fail after maybe a week or two of tinkering in my off time. Yes, that I freely admit that whatever I thought of my code at the time, it was crap code. It may have worked at the time, but it was still crap code. Today, I admit there is still a high likelihood that my code is crap, but hopefully I am starting to show a little improvement. (Maybe if I am here that many years hence I'll be able to say that I've gotten to be almost somewhat okay.)

In the mean time, I want to say a deeply heart-felt "thank you" to all those who have given of their time and patience with my questions and responses. What improvement I have shown in this time is due in large part to you, my fellow Monks. (I'll take the credit blame for the bugs that remain.) I hope I didn't, but if I neglected to say it at the time, I will now-it has been greatly appreciated.

Thank you for reading this far. I'll wrap this up with this. I have met a few of my fellow Monks in the big blue room (with the really bright light), but most of you have been at the other end of a post, comment, or CB response. I hope I have remembered that you were human too, and, if not I could not be positive, at least I hope I kept any negative comments aimed only at the code. I hope I have been more help than a cause of confusion or error. And, remembering those who were, those who are, those who will be, and those who are no longer with us (whether due to the ebb and flow of life, or to "going beyond the rim"), here is to you-thank you, one and all.

(With apologies to Richard Sambora and Jon Bon Jovi, for "Never Say Goodbye", and to Rachel Southworth and Michael David for "18 and Life".)

Refactoring complex module into set of specialized sub modules?
2 direct replies — Read more / Contribute
by LanX
on Apr 05, 2019 at 10:44
Hi

I'm having a project which is growing more complex by the day, and I'm thinking of refactoring it into smaller distributions, but I'm puzzled about the best strategy to do so.

This architectural worries are stopping me now²...

(Update: to make things worse I'm also thinking into refactoring into a super module, because the name doesn't fit anymore to the functionality)

Motivation

-pro
• some techniques* are experimental/very magic and should be isolated
• future replacements of failed approaches become easier
• there doesn't seem to be much support for those special techniques on CPAN so modules could be reused elsewhere
• it's easier to test those features in isolation

-contra
• more dependencies lower attractiveness
• testing the whole project becomes more complex
• a branch on GitHub would need to branch all sub projects
• I need to publish all partial products at the same time to CPAN
• finding good names for distributions is not easy

Strategy

I think now it's better to go step by step, and to first refactor it into separate modules inside the same distribution, before transfering them into separate distribution.

Is there a best practice to do so?

For instance shall I create a dedicated top-level directory for this or put it directly into /lib ?

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

PS: in hindsight this should rather be a meditation not a SOPW, gonna move it right away after posting.

*) which are

• source filter
• attributes
• INC-hooks
• ...

²) i.e. getting it right instead of getting it done...

5 direct replies — Read more / Contribute
by stevieb
on Mar 31, 2019 at 20:03

In some of my microcontroller testing code, I find it necessary to save things so that if I make a mistake, I can go back to a previously known-good configuration.

On a microcontroller, it's not as simple as grabbing a password/passphrase from an environment variable or file from disk, so until I get all of my code working, I set up temporary wifi/other-comms channels and embed the creds within the source (and subsequently save to Github (insert other online repo location if necessary)).

I understand completely how this is insecure, but throughout testing, I one-off my communication channel names, and flick out passphrases for them, then when I go to prod for real, I write code that will write to EEPROM, save the prod connection info, then go from there.

For me, if you're in my area (unlikely), you might bite on one of my SB5, SB9, SB66, SBx (etc) wifi (or 433MHz RF) networks, which is routed to a null VLAN, so my case is an easy one; I don't care about creds.

In the real world, if you *must* have creds in your source files (even initially), how do you deal with it?

Do you mask creds each push to your repo (prone to forgetting)? Do you set up temporary and fake comm channels until you go to production? Or do you first create the back-end compilation and storage of your creds somewhere else that isn't in a repo?

The last question in that last paragraph was loaded... even if you store creds to disk or otherwise, you *still* have to store them somehow... how do you maintain the code that does this within your Distributed Version Control System?

This might all seem like a smartass thing, but I've been fighting with committing/pushing code with passphrases and not, and the difference is that my efficiency goes downhill if I decide not to include them. I find myself without the commits to backtrack to after a major mistake because I haven't committed in some time, due to 'fear'.

Sick of banging my head due to lack of committing because of this nonsense. What do you do?

So, it is what it is
by stevieb
on Mar 22, 2019 at 20:37

Was doing my every-few-day look on CPAN to see what's come through, and saw something interesting.

I poked, and was enlightened as an articulate, detailed and responsive person got back to me.

It's nice to know there are Perl 'people' out there, even beyond the areas you ever would expect.

Got in touch, spoke about next steps, and had an overall good 'talk', about how to move forward on a Perl project.

Doesn't mean much, but this is my 2,500'th post here, and I thought I'd use it to say that I had met someone outside of the Perlmonks realm, who I'm going to work with to forward [Pp]erl in areas that it almost doesn't seem plausible.

That's my 0x9C4'th story.

Antiquitates - liber II - De trivio atque quadrivio
2 direct replies — Read more / Contribute
by Discipulus
on Mar 06, 2019 at 06:26

Antiquitates - liber II - De trivio atque quadrivio

2772 AB URBE CONDITA / 9317 September 1993

Introduction

This is the follow up of the Antiquitates - liber I where i described the goal of these meditations: to profit of ancient wisdom to see and ponder our work as programmers in a new light.
In this second liber I'll try to focus on which place our programming activity has to be placed in respect to other professions or techniques, sciences, arts as they were in ancient world.
I will also try to describe how the knowledge was organized and taught in the past and in which way we can, today, profit this ancient wisdom.

Programming is an art

It's since longtime we know that programming is an art: it was the year 1974 when Computer Programming as an Art appeared. Please take your time to read the above text because it will be the starting point of the current writing.
The first think I like to underline is how a general concept we all have in our minds, we can say a platonic idea, can be better profited if we operate a trichotomy on it. Infact sometimes words can hide a meaning, like a wood hiding trees, but on other hand, to analyze areas where words overlap can cast a new light of understanding.

τέχνη - ars - science

A great, positive energy ties these three words togheter and while τέχνη (tèkne) and art were stackable in meaning, if not the same thing, during ancient times, nowadays they are used in a very distinct way. But they shade into each other if we use them in relation to programming, if we, as programmers, are seeking the creation of something beuatiful, in a very personal sense of the word. Is evident that programming causes both intellectual and emotional pleasure.

A big difference from technique or skill and art will appear if comes the time to teach programming and while to teach a technique can be hard but is anyway feasible, to teach the research of intrinsic quality and the beauty of a task is more like a guidance to lead the pupil to discover their own way to feel such beauty and to be emotionated by their work. This makes programming an art.

In the Knuth's article is shown a driving force put in the transition from art of programming to the science of programming. He describes this as the positive intention to standardize programming knowledge to make possible programming automation. The process must be seen as an enrichment of our colture, not as a lessen. Even in the most extreme future scenario, when artificial intelligence will eventually write better programs than us, this intelligence will need to be instructed with good quality specifications, and we know how hard can be, and with big data arranged in a proper way: this will be for sure an art, even if very different from what we are used today.
So programming is an art, which kind of art?

Mechanic and liberal arts

Arts needed to live as a free citizen in the community were liberal arts, while others arts (notice: not techniques) were considered mechanic ones, more tied to a job or occupation and not strictly related to public life in the community.

Is programming a liberal art or a mechaninc one? Many people not involved in programming will opt for the latter. I disagree. It was told once that all technologies are an extensions of some human faculty or an amputation of one of these faculties, physical or psychic.

In our digital era I find programming one of the few, if not the only, sane interaction with the machine: we instruct the machine directly, extending our will into the area of calculation cycles and memory addresses. We are bound only by the depth of our skills and, obviously by the reality, being this reality the OS, the kernel and the various media types and by the limits of the tool we choosen to program with.

Programming and possibly many collateral knowldges due to the programming activity, makes us a little more free, in our digital era, than other types of workers: we are seen as wizards of arts in the modernity and in this false progress fulling everyone's mouth.

We have to underline the adjective liberal: it comes from libertas, the Latin word for freedom. What a great word. It was used in our case to differentiate liberal arts from mechanincs ones.
Such freedom is not a gift but more a terrain to defend with tooth and claw. The system, the money profit, will always tries to cut this terrain under our feet: we have seen in which direction internet and programming evolved in last decades.

Art of programming is definitely a liberal one. Now we have to identify which of the seven liberal arts can be programming and if we can take advantage by an eventual analogy.

Seven liberal arts

Liberal arts were the first programme of high education in the western colture and they are found in the Latin litterature since the age of Cicero, but for sure they were present before him and the trivium (divided into three parts) was called in this way during the Roman Empire and it was the basic programme of the school, ie the study of grammatica, dialectica and rhetorica.
But arts were not strictly classified into seven distinct fields until Middle Ages. Was Martiano Capella in his Satyricon or De nuptiis Philologiae et Mercurii (On the Marriage of Philology and Mercury) also known as De septem disciplinis (On the seven disciplines) who made a clear distinction about arts giving a definition of the quadrivium (divided into four parts) in opposition to the above mentioned trivium. With the Insitutiones by Cassiodorus this division became the standard of educational thought and passed from Middle Ages to the modernity.
The quadrivium was the latter part of the study programme including: arithmetica, geometria, harmonia and astronomia.

We can probably profit the analogy between trivium and programming education and activity.

Grammatica

Grammar was the first step for ancient pupils in the trivium. What grammatica can be in relation to programming? It is the set of rules that make a lanuage and its syntax but also word knowledge. Words are parts of the speech, little tiny objects tied up using rules and an appropriate syntax.
While the syntax of a programming language is the first thing taught nowadays, not enough importance is given to words.

In natural languages practice we can profit all words spoken around us during our childhood and this thesaurus can be extended reading books, learning poetry or songs. The objects of a natural language are all around us everytime, they are natural: starting from mother, father and food all these words acquire their sense in our brains. At some point we are taught about rules governing these little objects.

The situation would be very different if we were born alone in a black, empty room where, after some years a teacher of a natural language would arrive.

In programming nothing is natural and we born in a black room nor the experience as end user of a computer system can give us the understanding of what happens under the surface of a point and click user interface.

So while teaching the grammar of a programming language would be important to expand the thesaurus of objects to play with, in parallel. What is bit and what a byte? Why there is the notion of an octet of bits? What a file really is and how it is different from a link? What memory is? Which kinds of memory exist? What programs are? Where they live? What is an environment? What a shell? What protocol means? What happens when I open my browser and I search for something? How can a computer understand floating point numbers or chinese characters?

We all started programming during the first or second generation of the internet era: we mounted large floppy drivers with our first operating systems. Nowadays the hardware ships with its OS and if this goes out of run a tecnichian has to be phoned.

So we have to profit of what is propedeutic to the programming activity, the syntax and general concepts but without forgiving we all born in a black empty room, alone.

Dialectica

In our acception dialectica has to be seen not only as the discourse between two people arguing with different opinions, but more as minor logic. So we discuss this part of the trivium meaning dialectic and logic.

Logic is propedeutic to programming and must be taught before any serious attempt to program. From a programming point of view logic can be seen as all methodologies that can be used to create algorithms. There are general principles, shared by many programming languages that can be taught in abstract: iteration, callback and recursion, the cache mechanisim, depth and width first search, sorting and parsing, abstraction of behaviours, boolean logic and many others.

Programming patterns and good practices are general logic mothods to be studied per sé before going into the depth of a particular programming language.

On other hand, strictly speaking, the art of testing is purely dialectic. We learn how to stress our code with the flames of the real world, when will be not sure what it will come into functions we wrote. Tests describes, literally, our code, marking what our code does and what it does not. Testing techinques can be taught separatly as general practices without focusing on a particular programming language.

So with the above two studies, grammatica and dialectica we are well prepeared to the great art of programing.

Rhetorica

Programming is the rhetoric of the internet era. It's a general purpose art to solve problems. Where rhetoric aims to persuade, or motivate particular audiences, programming goal is to get the job done, to persuade the machine to act after our will.
Rhetoric moves its steps from grammatica and dialectica and, under the light we have analyzed them, the same thing does programming.
Rhetoric is the art of speaking and has its own theory and tecniques but it will be empty without the support of other sciences like geography, history, law and literature among others. The same is for programming: it would be a sterile excercise without the understanding of operating systems, networking, mathematic, statistic, natural languages, data storages, world wide web and others.

Conclusions

Programming is an art as long we seek the creation of objects of beauty, as long we are emotionated by it, as long it remains not completly automatable.
Programming is a liberal art because it permits a sane interaction with the machine, an exstension of our abilities, not an amputation of faculties. Such freedom must be defended or programming will eventually fall among mechanic arts.
Finally if we accept the analogy between trivium and information technology we can profit of what would be propedeutic to programming and we discover how many affinities are between programming and rhetorica.

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
External event loop for Curses::UI
No replies — Read more | Post response
by cavac
on Feb 27, 2019 at 07:02

Since i've been stumped by this before, and so have probably many others, i want to show how to do external event loops (main loops) when using Curses::UI.

By external i mean using your own, not the one provided by Curses::UI.

This is somewhat loosely based on some of the tutorial code included in the package to make the window as well as some quickly hacked together code. Sorry about that. Control-X opens the menu, Control-Q quits the application.

First of all, we need to make sure we got a read timeout for the input. So, make sure this is set correctly right after getting a new UI instance:

```use Curses::UI;
my \$cui = new Curses::UI( -color_support => 1);

In our (rather simple) main loop, whenever we update the screen, we call draw() and do_one_event(). In every loop, we also call do_one_event() after our sleeping period to handle any user input:

```
my \$last = time;

while(1) {
\$cui->do_one_event();
my \$now = time;
if(\$last != \$now) {
\$last = \$now;
foreach my \$sensor (@sensors) {
my \$newtext = int(rand(1000) * 100) / 100;
\$sensor->text(\$newtext);
}
\$cui->draw();
\$cui->do_one_event();
} else {
sleep(0.01);
}
}

Just for reference, here is the complete, runable example, in all its indent-mismatched-copy-and-paste glory:

perl -e 'use MIME::Base64; print decode_base64("4pmsIE5ldmVyIGdvbm5hIGdpdmUgeW91IHVwCiAgTmV2ZXIgZ29ubmEgbGV0IHlvdSBkb3duLi4uIOKZqwo=");'
[OT] Recruiting Non-English Speakers for a Perl-based Web Project
4 direct replies — Read more / Contribute
by golux
on Feb 21, 2019 at 22:55
Hi all,

I'm not sure if this is the best section in which to post this, as it's arguably off-topic, and not a question so much as a request for help.

I've created this website golux.atwebpages.com for hosting a project I call "Polyglot" using Perl CGI for all of the scripting. It's my attempt to learn a single English sentence:

```     "When I wake up in the morning, your beautiful smile is the first
+ thing I want to see"

in as many foreign languages as possible. You can read more about this project by clicking on "Goal" at the top of the website page.

One of the things I'm finding helpful with this project is getting friends, colleagues and acquaintances who are fluent in another language to provide me with voice recordings of the sentence in their native language. I can then upload it to my site, and use it for practicing.

I do have some fluency in German, French and Japanese, and a few other languages/alphabets to a lesser extent, but I'm unable to read Arabic, Hebrew, and some of the other "exotic" alphabets (some of which read "right-to-left"). For that reason, I also like to have a native speaker first verify that the translation I've found on the Internet (Google Translate or another source) is a valid translation.

In my quest to meet people from other cultures I've made some truly interesting friendships. One of my closest friends, Sunil, I met less than a year ago, and he kindly gave me the male voice recording for the Nepali voice. Since we first met, I was privileged to go trekking in the Himalayas with him and his friends, and as a result met many other people (from Nepal and other cultures) along the way, some of whom also taught me a lot about their own languages. One of these new friends emailed me just this morning saying she could provide a recording of the Arabic female voice.

So my request is a straightforward one -- if your first language is something other than English, and you'd be interested in providing a sample recording of your voice for my page, please send me a message here and I can give you instructions on how to make recordings of your voice to add to my collection.

say  substr+lc crypt(qw \$i3 SI\$),4,5

text here (a paragraph)

and:  code here to format your post; it's "PerlMonks-approved HTML":

• Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
• Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
• Read Where should I post X? if you're not absolutely sure you're posting in the right place.
• Posts may use any of the Perl Monks Approved HTML tags:
a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
• You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
 For: Use: & & < < > > [ [ ] ]
• Link using PerlMonks shortcuts! What shortcuts can I use for linking?

Create A New User
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (6)
As of 2019-10-24 00:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
In 2019 the site I miss most is:

Results (58 votes). Check out past polls.

Notices?