Bereitschaftsbeitrag

Zur Front

7. Februar 2019

Anthropomorphy in algorithms

When I was 21, I was wondering how to improve programming languages, for I felt that there were certain wearisome obstacles, when formulating an algorithm in MC68000 assembler. It so happens I just did that recently, so we can ponder that as a very simple example.

I was playing around with some self-invented macros yesterday, and eventually that algorithm took on the following form:

main    feed    %101111,d0
        qfeed   -1,d1
        keep    d0,d2
.srch   count   d1
        lsr.l   #1,d0
        search  cc
        pstop
        double  d0
        oadd    d0   
        bfall   +2
.end    rts


where the following macros are included:

keep    MACRO
        move.l  \1,\2
.o\1    SET     '\2'
        ENDM
oadd    MACRO           ; old add

        IFEQ    .o\1-'d0'
        IFC     \2,''
        add.l   d0,\1
        ELSE
        add.l   d0,\2
        ENDC
        ENDC
        IFEQ    .o\1-'d1'
        IFC     \2,''
        add.l   d1,\1
        ELSE
        add.l   d1,\2
        ENDC
        ENDC
        IFEQ    .o\1-'d2'
        IFC     \2,''
        add.l   d2,\1
        ELSE
        add.l   d2,\2
        ENDC
        ENDC
        IFEQ    .o\1-'d3'
        IFC     \2,''
        add.l   d3,\1
        ELSE
        add.l   d3,\2
        ENDC
        ENDC

        IFEQ    .o\1-'d4'
        IFC     \2,''
        add.l   d4,\1
        ELSE
        add.l   d4,\2
        ENDC
        ENDC
 
        IFEQ    .o\1-'d5'
        IFC     \2,''
        add.l   d5,\1
        ELSE
        add.l   d5,\2
        ENDC
        ENDC
 
        IFEQ    .o\1-'d6'
        IFC     \2,''
        add.l   d6,\1
        ELSE
        add.l   d6,\2
        ENDC
        ENDC
 
        IFEQ    .o\1-'d7'
        IFC     \2,''
        add.l   d7,\1
        ELSE
        add.l   d7,\2
        ENDC
        ENDC
 

        ENDM
feed    MACRO
        move.l  #\1,\2
        ENDM
qfeed   MACRO           ; quick feed
        moveq.l #\1,\2
        ENDM
adjust  MACRO
        move.l  #\2,\1
        ENDM
qadjust MACRO           ; quick adjust
        moveq.l #\2,\1
        ENDM

radjust MACRO           ; relative adjust
        lea     \2(pc),\1
        ENDM
track   MACRO
        move.l  \1,(\2)+
        ENDM
btrack  MACRO           ; back track
        move.l  \1,-(\2)
        ENDM
count   MACRO
        addq.l  #1,\1
        ENDM
bcount  MACRO           ; back count
        subq.l  #1,\1
        ENDM
double  MACRO
        add.l   \1,\1
        ENDM
astop   MACRO           ; ante stop
        bcs.s   .end
        ENDM
pstop   MACRO           ; post stop
        beq.s   .end
        ENDM
search  MACRO
        IFC     \1,'cc'
        bcs.s   .srch\2
        ENDC
        IFC     \1,'ne'
        beq.s   .srch\2
        ENDC
        IFC     \1,'cs'
        bcc.s   .srch\2
        ENDC
        IFC     \1,'eq'
        bne.s   .srch\2
        ENDC
        ENDM
bfall   MACRO           ; back fall
        bra.s   .srch\1
        ENDM
handle  MACRO
        cmp.l   \1,\2
        beq.s   .case\3
        ENDM
 
shandle MACRO           ; short handle
        cmp.b   \1,\2
        beq.s   .case\3
        ENDM

lhandle MACRO           ; lower handle
        cmp.w   \1,\2
        beq.s   .case\3
        ENDM
bhandle MACRO           ; bit handle
        btst    \1,\2
        bne.s   .case\3
        ENDM
nhandle MACRO           ; no bit handle
        btst    \1,\2
        beq.s   .case\3
        ENDM
catch   MACRO
        b\1.s   .case\2
        ENDM


This is of course somewhat pathetic, owing to the fact that you can only equate but not set aliases for registers, but let us concentrate on the general transformation of the algorithm and the purpose of the invented macros.

1. Replacing general notions by notions that contain assertions regarding the use of the object of the operation.

The main problem with assembler programs is the ubiquity of the move command. Much is gained by more specifically pointing out, what the object is being set for, that is by breaking down the move command into adjust, feed, keep and track as done above, where adjust is used, when its first argument is not being changed in the dynamic part of the algorithm, i.e. the variably repeated part, or if the value it is being adjusted to doesn't influence the outcome of the algorithm, in which case we speak of a technical adjustment, and where feed is used otherwise.

2. Creating references to values during the formulation of the algorithm.

When we come across the command count d0, we think d0 is now one more, that is we create a new reference during the execution of the algorithm. This a compiler cannot do, only an interpreter could, but a compiler can do the next best thing and create a new reference during the formulation of the algorithm, in the above example through the SET directive, and oftentimes the order of formulation is the same as the order of execution, although by no means necessarily so, but one can after all see to it that the two agree.

Of course, using a pair of commands like keep and oadd sets you up for some really weird bugs, owing to the possibility of jumping into a code segment with changed settings, but the imperfection of the method is not the issue here, the pursued ideal is, and that is the anthropomorphy of the algorithm.

We define references in real time and we remember references that we have used before, and when we want to single out a specific memory, we again define a reference in real time: this memory, this association is the old association. And hence we expect a computer language to understand these kind of declarations and the keep-oadd-pair exemplifies what that means for MC68000 assembler.

3. Bundling several commands in a single one.

This case really is a special case of the previous one, namely when the referenced value is a command. This too, we declare in real time, but here we hardly ever change our declarations. So whenever we want to do this, we can simply define another macro.

Conclusion.

A perfectly anthropomorphic programming language must be processed by an interpreter. It has to allow the definition of rules for the further use of the objects of its commands and control the observation of those rules during the processing of its commands, for instance make sure that the keep command really keeps the old value until a designated time or that adjust and feed are used properly or that astop and pstop occur, when they're supposed to (to claim that that is equivalent with checking the carry, respectively the zero flag is a bit audacious, of course, yet probably in some 98% of all cases true). The object of these jumps is the pc, the program counter, for which the defined rules have to hold.

Commenting should not be necessary, all truly relevant comments should be contained in the notions of the commands of the programming language.

And if that is achieved, we have found a formalism that captures our thoughts on the formulation of algorithms. This is a point worth noting:
We don't have to teach a computer how to understand us, we only have to remove the obstacles on the way of the translation of our thoughts into a form that a computer can process by choosing a form for which there are no such obstacles.

Labels: , , , , , , ,