Modern Computer Science is obscurantism disguised as science

Recently I decided to get back to the basics and question my use of classes/frameworks.

I tried to find a definition of the word framework but weirdly this word is a tautology, no one knows what it is, but it refers at itself for something people use to get the work done through the use of external knowledge. But can you manipulate knowledge you do not understand?

This word has been broadening so much that it globally is a synonym of a shortcut for standing on the giant's shoulder without having to do the painful process of climbing painfully all the way up by learning. Framework are actually for me a synonym for an intellectual shortcut ; they are the foundation of cargo cult programming. And I want to illustrate it with a python code example to draw a wall clock without libraries except for importing constant (exponential and PI) and drawing.

So I will introduce an anti-framework that makes you have less dependency based on taking no shortcuts : science. Not the ones of computer science and university, the one that also is useful in the real world, hence a more useful tool than framework. Something that can help you compute solution with a pen and paper fast. And for which you can check the results of your code. The science taught in high school that requires no degrees and that we are supposed to know when we are given the responsibility to vote. The one that help you make enlightened decisions as a citizen for the future.

For the example I will use a simple use case with code: an analogic wall clock. I will treat different problems: 2D & 1D geometry, sexagesimal basis, drawing the hands, computing time without datetime.

Scientific reasoning to be understandable before coding requires that you explain what you are doing and how. To introduce the problem in a simple, yet consistent way so people do not understand the code, but the mental process to interpret the code, thus to define rigorously your concepts and definitions. The stuff Agile hates : explicit requirements and clear definitions of concepts, rigor.
 
What is time?

Time in its usual form hour/minute/second is inherited from Sumerian civilization. A civilization that was localted in Irak -whose archeological wonders occidental civilization took part in destroying- that has brought mathematical knowledge to the world thousands years ago. It was designed by people having no computers but knowledge of the fact earth is round, having simple use of fractions and basic geometry. Time cannot be manipulated without understanding that earth is round and that it revolves around the sun and that noon is dependent from your location.  12:00am is set on when the sun is at its zenith for a given place. Which is basically an invariant on a meridien. Giving time, is giving a relative position of earth according to the maximum potential exposition to the sun.

The base of 60/60 is useful for astronomers using sticks/shadows and is quite powerful in low tech context. 360° (minutes * seconds) is a measure of the rotation of the earth according to a reference (noon) and since the angular speed of earth is constant, it is linearly related to time. Time measure the relative angle from your position according to noon in a referential where earth is rotating around its north/south pole axis. It is periodic. It is thus a measure of phase/space. Usual time is a space measure.

The python time() function is an expression in a base 10 of the time elapsed since 1/1/1970 according to your geographical position without all political biases (except TZ).
Localtime is the correction with leap seconds, DST .... and politics. Something defined by arbitrary rules that is far to be a one best canonical way.

Each hand on a wall clock rotates with a speed according to its rank in the base.

Seconds rotates at the speed of a 60th of a turn per seconds.
Minutes are 60 time slower
Hours ... are 24 times slower, but by convention, we prefer to make it with a period of half.
Basis conversion be it base 10, 2, or sexagesimal is a CORE concept of computer science. It is a core requirement every developers should be able to do it without libraries.

I am gonna introduce a convenient tool for doing geometry : the Moivre formula that will do the heavy lifting :

exp( i * theta) = cos(theta) + i * sin(theta)
https://en.wikipedia.org/wiki/Complex_number

To understand the following code, understanding the geometrical relationship between complex notation, cartesian/polar coordinates requires learning and rigor. And there is not shortcut for it.

I don't know why, python is confusing j and i. And I hate IT, it is like a slap to the face of people using science.
i is defined by i² = -1 python decided to call it j
j is traditionally defined by a number such as  j**3 = -1 for which the imaginary part is positive. Thank you python for not respecting mathematical conventions, it makes this confusing.

I guess it falls into the tao of python
There should be one– and preferably only one –obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.



That is not the first time I have a beef with python community when it comes to respecting mathematical notations and their consistent use. I could dig this topic further, but it would be unfair to python which is not even the community with the worst practices. 

So without further ado here is the commented code without the noise of colors. Brutal code.
(Colored version here)


import matplotlib.pyplot as plt
from time import sleep, time, localtime

# Constant are CAPitalized in python by conventionfrom cmath import  pi as PI, e as E
# correcting python notations j => I  
I = complex("j")

# maplotlib does not plot lines using the classical
# (x0,y0), (x1,y1) convention
# but prefers (x0,x1) (y0,y1)
to_xx_yy = lambda c1,c2 : [(c1.real, c2.real), (c1.imag, c2.imag)] 

# black magic
plt.ion()
plt.show()

# fixing the weired / behaviour in python 2 by forcing cast in float

# 2 * PI = one full turn in radians (SI) second makes a
# 60th of a turn per seconds
# an arc is a fraction of turn
rad_per_sec = 2.0 * PI /60.0
# 60 times slower
rad_per_min = rad_per_sec / 60
# wall clock are not on 24 based because human tends to
# know if noon is passed
rad_per_hour = rad_per_min / 12

# I == rectangular coordonate (0,1) in complex notation
origin_vector_hand = I

size_of_sec_hand = .9
size_of_min_hand = .8
size_of_hour_hand = .6

# Euler's Formula is used to compute the rotation
# using units in names to check unit consistency
# rotation is clockwise (hence the minus)
# Euler formular requires a measure of angle (rad)
rot_sec = lambda sec : E ** (-I * sec * rad_per_sec )
rot_min = lambda min : E ** (-I *  min * rad_per_min )
rot_hour = lambda hour : E ** (-I * hour * rad_per_hour )

# drawing the ticks and making them different every
# division of 5
for n in range(60):
    plt.plot(
        *to_xx_yy(
            origin_vector_hand * rot_sec(n),
            .95 * I * rot_sec(n)
        )+[n% 5 and 'b-' or 'k-'],
        lw= n% 5 and 1 or 2
    )
    plt.draw()
# computing the offset between the EPOCH and the local political convention of time
diff_offset_in_sec = (time() % (24*3600)) - localtime()[3]*3600 -localtime()[4] * 60.0 - localtime()[5]   
n=0

while True:
    n+=1
    t = time()
    # sexagesimal base conversion
    s= t%60
    m = m_in_sec = t%(60 * 60)
    h = h_in_sec = (t- diff_offset_in_sec)%(24*60*60)
    # applying a rotation AND and homothetia for the vectors expressent as (complex1, ccomplex2)
    # using the * operator of complex algebrae to do the job
    l = plt.plot( *to_xx_yy(
            -.1 * origin_vector_hand * rot_sec(s),
            size_of_sec_hand * origin_vector_hand * rot_sec(s)) + ['g']  )
    j = plt.plot( *to_xx_yy(0, size_of_min_hand * origin_vector_hand * rot_min( m )) + ['y-'] , lw= 3)
    k = plt.plot( *to_xx_yy(0, size_of_hour_hand * origin_vector_hand * rot_hour(h)) +[ 'r-'] , lw= 4)
    plt.pause(.1)
    ## black magic : remove elements on the canvas.
    l.pop().remove()
    j.pop().remove()
    k.pop().remove()
    if not n % 1000:
        ### conversion in sexagesimal base
        print int(h/60.0/60.0),
        print int(m/60.0),
        print int(s)
    if n == 100:
        n=0
   


My conclusion is frameworks, libraries make you dumb. It favors monkeys looking savant as much as pedantism in academic teaching is. People may try to point THIS is pedantic, but pedantism is about caring about the words and formalism, not the ideas and concept. It is like focusing on PEP8 instead of the correction of the code. Pedantism is not saying correction is important, it is annoying developers with PEP8.

My code is saying the earth is round, that it revolves around the sun with a constant rotational speed, that noon is when the sun is at its zenith and happens periodically, that I have an harmonic oscillator in my computer that is calibrated to deliver me time with a monotonic growing functions, that we use a 60/60 base since millennials to represent time, that most of the problem we encounter with times are either political or due to an insufficient understanding of its nature. And that we can use complex numbers to do powerful 2D geometry operation in a compact, yet exact way that does not require libraries or framework. Complex numbers operations USED to be hardwired in CPU. They became useless, because people stopped using them by ignorance, not because they stopped being useful.

Our actual problem is not computer raw power, but education. Every coders using datetime modules should be sacked : datetime operations are (out of the TZ insanity) basic base conversion and 1D operations of translations projections. If a coder do not understand what numbers are, what time is, the difference between representations and concepts why do you entrust them manipulating your data in the first place? What do you expect?

That a thousands monkey will write you the next Shakespeare novel if you throw enough bananas at the monkeys?

We live in a time of obscurantists people using advanced concepts that looks like science, but are not.



5 comments:

Unknown said...

Troll is an apt label for this post since j is commonly used in electrical engineering instead of i

In engineering, you either learn the tools you use or make a shoddy job.

jul said...

In micro electronics I learned i instead of j. Maybe because smaller currents require smaller letters.
It is all about the Babel tower effect, and that is why specifications and requirements with definitions are okay.

Btw, I would strongly would urge electricians to use i since j is still a common notation for the cubic root of -1 and that triphased current may involve this number.

And still j is not the obvious notation for most complex number users.

thepld said...

Rails against frameworks...and the first line of code is an import for matpylib. This is brilliant trolling.

jul said...

@thepld I don't have access to the framebuffer anymore since 15 years. The graphics drivers are so fucked on modern OS I cannot go anymore to the pixel level.

But if you give me a frambuffer I can do it with blitters. It is easy.

inconnu said...

All ranty/trolly tones. I felt a huge burden lift just considering writing code without libraries. I'm of the kind who only feels 'understanding' through making. And I've ran away from programming (figure of speach) because the trends, economy and industry is valuing being a 'caller' or 'user' [1] who tickle black boxes understanding nothing rather than solve problems with his mind. I understand their goals, but it makes me feel empty to the point of sickness.

[1] libraries are a gateway drug.