Recent

Author Topic: Immutable data types  (Read 9562 times)

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: Immutable data types
« Reply #90 on: October 07, 2022, 06:17:57 pm »
Okay, old f...riends. Friday time.

So, C is totally NOT predating PDP brand, while it MIGHT do predate PDP-11 computer.
Bacause, you know, PDP-11 computers were produced for maaany years, including after C language was published.
Notice: PDP-x computers were very diverse. PRobably not as diverse, as early IBM computers, but still - verily so.

The PDP-7 and the Birth of UNIX

In 1969 Ken Thompson wrote the first version of UNIX in assembly language using an otherwise little-used PDP-7 at Bell Labs, the research arm of AT&T, the former U.S. telecommunications monopoly.
   ....
However, the PDP-7 was already obsolete when it was used for creating the first version of UNIX, and thus in 1970 the UNIX group proposed purchasing a PDP-11 for $65,000. The PDP-11, which had just been launched that year, incorporated some important advances (including greater ease of programming), and it became a highly successful and influential model. It was DEC's first and only 16-bit system.

In 1971, the group used their new PDP-11 to rewrite UNIX in a high-level language, instead of its original assembly language, so that it could more easily be ported to (i.e., transferred to) other types of computers. They briefly tried using Fortran before creating their own language based on BCPL (Basic Combined Programming Language), which they called B. They then extended B to produce the C language, which is still in widespread use today, after which they rewrote the UNIX source code in C. This made it easier to port UNIX to run on new hardware, as all that was needed was a C compiler to convert its C source code into the machine code for the specific type of computer.

If this timeline is correct, then C design was made by persons very fluent in specifically "diff" between PDP-7 and PDP-11 instruciton sets.
That does not mean that PDP engineers invented it. It is quite possible this was a common idea "in the air" that everyone and his dog dreamed about, but lmited hardware and software could not deliver yet. It is plausible PDP-11 engineers were trying to "wire out" at least some of what programmers dreamed off, so the ideas flow was reverse.

Thompson used TMG in 1970 as a tool to offer Fortran, but due to memory limitations of PDP-7 ended up creating the B programming language which was much influenced by BCPL
This might be important, or not.
Some "UNIX dialect of TMG" seems ot already have inc/dec operators: https://en.wikipedia.org/wiki/File:Brainfuck_to_C_translator_in_Unix_TMG.png
The allegedly 1972 TMG manual describes those operators in chapter 5.2 - https://amakukha.github.io/tmg/TMG_Manual_McIlroy_1972.html

TMG'66 though seems to lack ++ and -- - https://www.multicians.org/tmg.html

One interesting caveat there is the language having TWO set of arythmetic operators, for 1-complement and 2-complement binaries. This produces some eerie feeling. It is one thing to read about historical concepts, and other seeing them actually "fleshed out" in pracitcal tools.
https://delightlylinux.wordpress.com/2014/10/13/binary-lesson-12-ones-complement-and-twos-complement/


Quote from: wikipedia
The PDP-7 is the third of Digital's 18-bit machines, with essentially the same instruction set architecture as the PDP-4 and the PDP-9.
....
PDP-4 .. was a compromise: "with slower memory and different packaging" than the PDP-1

So, basically, PDP 1/4/7/9 was one lineage of computers, and PDP-11 is different one, a sibling.
Surely, early hackers given a bonanza of two different systems made by mostly same team - were arguinh about differences of them no less than we argue about C vs Pascal. Or how IBM PC introduction probably ignited i8085 vs Z80 vs i8086 assembler flame wars. This perhaps would be closer. PDP-7 vs PDP-11 probably is similar in preseption to Intel 80 vs 86 or Motorole 6800 vs 68k.

There seems to be PDP-8 and PDP 6/10 lines, that were also entirely different designs: https://www.soemtron.org/downloads/decinfo/decdigital1957tothepresent1978102630349.pdf

So what was that PDP-1/4/7 assembler then? The trove gives way too much loot - http://www.bitsavers.org/pdf/dec/pdp7/
I'd highlight four documents.

http://www.bitsavers.org/pdf/dec/pdp7/DIGITAL-7-40-U_MasterTapeDuplicator_Dec64.pdf
Utility listing. The look and feel of the language.
Funny is how the lables seem to be both position-dependent (like in punch-cards Fortran) yet comma-separated (like in freeform post-cards languages). But not all, "LEFT" label is without comma. We seems ot see a convention being crystallized, first informally and not mandatory.

http://www.bitsavers.org/pdf/dec/pdp7/PDP7_Instruction_list.pdf
The name felt very promising, but.... It really is just a set of lists, set of "dictionary tables" with almost no description.
Damn it, even very structure of documentaiton kit is (was) non-orthodox!
Would not mention it, if not for eerie feeling seeing most of the list beingone-purpose commands wired into the processor just for interfacing one specific peripheral device.
I instantly started tinking about RISC-V much touted promicefor eveyr processor to have instrucitons custom-tailored for specific end hardware.
Well i was wrong yet again.


http://www.bitsavers.org/pdf/dec/pdp7/PDP-7_AsmMan.pdf
"PDP-7   SYMBOLIC ASSEMBLER   PROGRAMMING MANUAL"  (c) 1965
Finally getting "close to metal" aren't we?
We aren't !!!
Old DocKits structure bites me again.

This is merely an auxillary, supplementary side-not about how to use alien symbolic language to express well-known and well-inderstood machine codes.
Ouch!
Again, one thing is to vaguely know "there were prehistoric times when people..." and another to see it "in the flesh".
The "assembler manual" has almost no list of instructions and few decriptions of the instruction used.


Caveats, though.

The notation C (A) means contents of A.
Bah! So both un-assembly and un-highlevelly, i had ot struggle to parse it again and again!

...yet the content of the manual, again, not immediately relatable to the increment invention subtopic, is swinging between sheer lunacy and exotically delicious :-)

Would post it later. Too delicious a delirium to skip, yet too massive for the ++-discussion.


http://www.bitsavers.org/pdf/dec/pdp7/PDP-7_Brochure.pdf

The brochure. What should it have?
Well, obviously, glossy....

[ large chunk retroactively removed to a later post, sadly i could not remove the rest, it would've been a spoiler. But, if you feel amused by offtopic and do not like spoilers, scroll down to read brochure musigns sequentially :-) ]

....8. Now, you may call me an idiot. Mark would certainly have his chance at a brash newbie.
But i DID spent quite a few minutes trying to find any "return from subroutine" opcode. What the hell they named it and in which group they sticked it too. Yes, i did.

Caveat: there is NO return instruction. At all.

9. So, how are you supposed to return from a procedure? You are not.
Okay, you are.
You can read JMS instruction descripion. Then again. Then again. Then again.
Until THAT sinks in.
I would not even start to describe HOW wrong and twisted was what it did.

10. Then you go back to page 6 and read that "The PDP-7 Programming System inludes advanced FORTRAN Compiler".  And something starts wrigglign in the darkest corners of your memory. You start to kinda sorta (but not for certain) remembewr that early computers were built to and sold for running Fortran, like the recent computers were sold to run Windows and newer computers are sold to run Android. You kinda-sorta-maybe remember that it Fortran does not allow for nested functions calls. Or was it recursive? Or reentrant? Googles is of little help, sendign you to som manual and tutorials mentioning no this crucial limitation. But Fortran 77 demands you to opt-in recursive funcitons with special "compiler directive", giving away that "decent funcitons do not play with themselves". Wikipedia (this time it was the last thing to refer to, call me an idiot again) is blunt that Fortran the program was invented before hardware vendors invented the stack, and recursive calls were not possible and were not part of the language indeed.

Make it sink.

UNIX was coded on a computer that progibited functions to be called more than once, and that stored the return address in the function body itself.
B/C languages were mostly designed by persons who matured on computers lacking stack and lacking funcitons reentrancy.

Obscene...

BCPL'67 manual was preserved at https://www.bell-labs.com/usr/dmr/www/bcpl.html

Quote
An LVALUE is a bit pattern representing a storage location containing an Rvalue.
An Lvalue is the same size as an Rvalue and is a type in BCPL.
Make of it what you want. They still were struggling to invent the very language to describe ther languages :-)

Quote
Assignment Commands
Syntactic form: L1, L2, ... Ln := R1, R2, ... Rn
Both C and Pascal and other practical imperative languages jetissonned it. Functional language mostly retained it.
found OCR typo there, wanted to drop a notice, but i guess it won't be delivered any more

BCPL'67 is amusing... No wonder K&R loathed idea that procedure and funciton is something different. I would too.
But before i started (rather instead), it explicitly had recursive routines (procedures) and did not have ++ or --

Per wikipedia, B language was developed in 1969, but the report is dated 1972, https://www.bell-labs.com/usr/dmr/www/kbman.pdf
The report stresses language to be recursive, but it also stresses to only appliy to PDP-11 B not PDP-7 B.

If PDP-7 B was recursive, then it had to use ad hoc trampolines, making multi-threading unthinkable of, not just unimplementable.
B language did have ++ and -- operators, both prefix and postfix, so they were madei nto the languages in between 1969 and 1972.

OTOH, this speculation probably should be ignored, as B on PDP-7 was not true compiler: "The B compiler on the PDP-7 did not generate machine instructions, but instead ‘threaded code’ [Bell 72]"  (DMR's "C history")


Side note: BCPL language explicitly claims removing the data types facility from CPL language, as one prohibitively ocmplex to implement. C language later re-introduced data types syntax but NOT data type checks. Data types were tolerated by the compiler by ignoring them. Makes sense from the history of it. "OId C"/Fortran style of retroactively adding type to parameter variables surely was aiding C parser to ignore them.

Back to the sub-topic finally.

Quote from: C History
Thompson went a step further by inventing the ++ and -- operators, which increment or
decrement; their prefix or postfix position determines whether the alteration occurs before or after
noting the value of the operand. They were not in the earliest versions of B, but appeared along
the way.
People often guess that they were created to use the auto-increment and auto-decrement
address modes provided by the DEC PDP-11 on which C and Unix first became popular. This is
historically impossible, since there was no PDP-11 when B was developed. The PDP-7, however,
did have a few ‘auto-increment’ memory cells, with the property that an indirect memory reference through them incremented the cell. This feature probably suggested such operators to Thompson; the generalization to make them both prefix and postfix was his own. Indeed, the
auto-increment cells were not used directly in implementation of the operators, and a stronger
motivation for the innovation was probably his observation that the translation of ++x was
smaller than that of x=x+1.

It is perfectly plausible, that idea of auto-incrementing was "in the air" and everyone spanning from hardware designers to compiler designers dreamed of it.
Then PDP-7 could somewhat implement a very reduced version of that dream in those special memory cells.
Then PDP-11 could implement more of it (still only part) into post-incrementing and pre-decremeniting (if i remember correctly) addressing modes, and thenindependently Thomson would add it to the language, having premonition that "time is right" and the next-gen hardware would soon make this workable.

OTOH the timeline seems to be like this

1965: PDP-7 has only direct and indirect (pointer datatype) addressing, no inc/dec
1966: TMG (B's generator) has no ++
1969: Thomson creates early UNIX in PDP-7 asm, learning of auto-inc memory cells
1969: Thomson drafts early B language. Maybe in paper-only, maybe cross-compiling from GE "real machine". Generated threadded code, based upon TMG parser, having no ++ yet
1970: DEC announces PDP-11 machine. BL(Bell Labs) UNIX group starts lobbying to putchase it. This heavily implies they read through the manuals and were salivating, and where capable to explain with convincing details to money gatekeepers how much better the new system was.
1971: PDP-11 arrives to BL and Thomson immediately jumps into the peers queue to work on it. BTW, the Ritchie's "C History" seems to imply this already happenned in mid-to-late 1970, not even 1971.
1971: NB language (or "embryoni C"). Rithchie: In 1971 I began to extend the B language by adding a character type and also rewrote its
compiler to generate PDP-11 machine instructions instead of threaded code.
1972: B report explicitly quotes both PDP-11-only and ++ operator
1972: TMG (the specialized language used to generate early version of B) has ++ operator
1972: C language is quickly getting shape, but is not suitabl for makign any real program yet
1973: C is born. Ritchie: "By early 1973, the essentials of modern C were complete. The language and compiler were strong enough to permit us to rewrite the Unix kernel for the PDP-11 in C during the summer of that year. (Thompson had made a brief attempt to produce a system coded in an early version of
C (before structures) in 1972, but gave up the effort.)"

Quote
and a stronger motivation for the innovation was probably his observation that the translation of ++x was smaller than that of x=x+1.

Please, demonstrate me in PDP-7 or PDP-11 asm/opcodes that both are met:

* ++int is translated shorter, than int := int + 1
* int++ is NOT translated shorter, than int := int + 1

I believe what DMR reproduced here was blurred old memory of him overhearing some Thomson's hearsay, that was not of immediate interest to him.
I speculate: Thomson, probably, enjoyed bit-feedling much more than Ritchie, who more enjoyed fiddling higher-level concepts.

Quote
Values stored in the cells bound to array and pointer names were the machine addresses,
Ritchie Development of measured in bytes, of the corresponding storage area. Therefore, indirection through a pointer
implied no run-time overhead to scale the pointer from word to byte offset. On the other hand,
the machine code for array subscripting and pointer arithmetic now depended on the type of the
array or the pointer: to compute iarray[ i ] or ipointer+i implied scaling the addend i by
the size of the object referred to.

The whole paragraph dedicated to this, and indeed, this seems to be a big innovation of PDP-11 machine, that Thomsone and Ritchie were transitioning to in 1971. Making copiler for PDP-11 surely required getting to terms with it.

Sorry, with all my respect to Ritchie and his loylty to Thomson - this was wishful thinking and retransmition of hearsay he did not cared much about.

I wonder if Thomson ever gave his own, first hand and detailed report on ++ invention.

I mantain that ++ was either a generalization of what they learnt in 1970 form PDP-11 manuals.

Alternatively it could be a common idea that was known by everyone already in 1960-s, yet materialization in hardware impossible yet, and enshrining in the languages made little sense in "close to metal languages" (late B and C) and "considered harmfull" for high-level languages design (Pascal).
« Last Edit: October 07, 2022, 06:39:09 pm by Arioch »

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: Immutable data types
« Reply #91 on: October 07, 2022, 06:19:27 pm »
For those, whom i failed to bore into hibernaiton yet, the supplementary.

http://www.bitsavers.org/pdf/dec/pdp7/PDP-7_AsmMan.pdf
"PDP-7   SYMBOLIC ASSEMBLER   PROGRAMMING MANUAL"  (c) 1965

TL;DR

Notable is how octal opcodes are first class citizens, only optionally subtstituted by symbolic mnemo-codes.
In later Intel 86 assembler you would have to have a special "DB" or "DW" or "DD" psaudo-command to stream in raw data.
In PDP-11 MACRO it would be ".WORD" or ".DWORD" if i remember right.
In PDP-7 you would just key digits in.

This clearly coming from times when primary mean to write a program was exactyly a self-made memory dump (like Inel .HEX files, but octal)

Quote
The Assembler has, in its permanent symbol table, definitions of the symbols for all the PDP-7
operation codes, operate commands, and many lOT commands

Keywords? What keywords??? Just #define-like constants/macros!

...could only be made so in an "assembler" where octal literals were primary means to code instucitons, and symbolic ones were optional add-ons.

Quote
The user may also request the Assembler to assign variable storage for him by placing a # within
the first six characters of the variable. A symbol which includes this character is automatically
assigned a register at the end of the program, and a zero is placed in that register.

1. We see # symbol already havng a special place in the hearts oif DEC engineers aearly on. But the meaning of the symbol was very different yet. On PDP-11 it would mean "absolute non-relocatable constant, not using PC register current value as its origin"
2. We see the word "register" mentioned but isn't it use confusing?  Oh, my...

Quote
The Assembler also handles literals for the user. The value of the expression contained in parentheses is called a constant and is automatically placed in an unused location by the Assembler. The address of that location is inserted into the instruction. In the example below, the address of the register containing 1 is substituted in place of (1).

Literal constant was assigned an address and placed forever into a register.
How's that to you, Pascal guys? Literal is no distinct from initialized variable :-D
This is a bit exoitic even from i8086 assembler perspective.

Quote
Variables
The user may request the Assembler to assign storage registers for him. These registers, whose
value may be changed while the program is running, are designated as variables. A symbol
(permanent symbols and pseudo-instructions must not be used) containing # or $ as one of its
first six characters, which is not explicitly defined elsewhere by use of a comma or equal
sign, is a variable. A symbol may contain a # any number of times without becoming multidefined, but this character is required only once, not necessarily on the first occurrence of the variable.

...any place...
...not necessarily on the first occurrence...

If i parse it right, i might user some VARNAME many times in the prohram, then just mention anywhere VARNA#ME once (yes, infix!) to have its "storage class" altered. But would i use VARNAME# or VARNAM#E instead, and - oh, the dreaded Off By One - it is silently ignored, with no errors emitted.

Times, they are a changing!

Quote
A storage register whose contents remain the same throughout the running of a program is designated as a constant. A constant can be represented by using a literal: an element or expression contained in parentheses. This type of element causes a register to be reserved in the constants table by the Assembler.

....a register to be reserved in the constants table...

My head goes PUFFF!!!

But so, the "Register"" term in 1960-s hardware meant just a memory location designated to have some specific data. Todayt we would call it a global variable.

Man, i feel lucky not trying to search for something like "list of registers of PDP-7 processor" - because neither processors nor registers (as we undertand the terms) existed yet!!!
Which, again, is common as a theoretic background knowledge, but running into it like into a wall leaves quite an aftertaste.

Quote
Currently unassigned variables are defined as the addresses of successive registers at the occurrence of the pseudo-instruction VARIABLES. The pseudo-instruction VARIABLES may be used repeatedly in a program.
Quote
If the pseudo-instruction VARIABLES is not used, the table of variables is automatically assigned
a storage block at the end of the program. Upon loading the program, the contents of all locations assigned by use of the variable facil ity are zeros.

Proto-DATA segment !!!  But on that old hardware there was no distinction between RW and R/O data yet.

Quote
A variable containing $ causes a multiple number of registers to be reserved. The number of
registers to be reserved may be controlled by the pseudo-instruction BAR n. The element or
expression  N specifies how many locations are to be allocated for $ variables. N is initially
set to three.

Proto-static-array !!!

Also feesls like predating BASIC's notion of declaring variable datata type by the postfix symbol.

Quote
If any symbols remain undefined at the termination of assembly, they are automatically defined
as the addresses of successive registers following the variables storage block and their definitions printed. That is, they are treated as variables containing #, but the user is informed of the assignment.

....when i was coming from school BASIC and "pen and paper ForTran" to Pascal - the rude demand to make varible declaations was infuriating. That daaamn stupid gatekeeper having nothing better to do than asking me to show my Variable IDs again and again? Go get some real job to feel your time!!!

LAC TST  -  loads the AC with the contents of register 477
LAC (TST  -  loads the AC with the value 477


NOT a typo, there is no "close parenthesis" concept yet! Parenthesis is a prefix, nothing more. Making a "recursive parser" to recognize paretheses was wastefully complex for then hardware.

...Except for snippets like (1) creatign a constant register. HEre we suddenly need both open and closing parentheses and parser does care. C is for consistency.

EXIT = JMP I 20

Remember me being lost about a stack and nested calls above? :-)

Oh, the "i" there...

Quote
Indirect Addressing
If bit 4 in the binary representation of a memory reference instruction is 1, instead of taking
the memory location referenced as the effective address of the operand, the contents of the
location referenced are taken as the effective address of the operand. Indirect addressing is
represented in the source language by the character I following the operation symbol thus:
LAC I 500

Not sure if i should cry "unconventional" or see it as precursor to MASM type qualifiers like MOV AX, QWORD PTR [BX].
Assembler guys would hardly recognize "indirect addressing" as data type, but replace "indirect addressing" with "pointer type" and it is.

Still, PDP-11 MACRO made a clean break, and used really different mnemonics for addressing modes.

Quote
No error message is printed if a defined symbol is redefined in a parameter assignment
unless it is a permanent symbol

Proto-variables. Or should i call it preprocessor macro-variables?


...now, let's look at the slash symbol.

Talk about functional overloading (as in chess-like way too much burden, not as subroutine polymorphism).

Quote
COMMENTS
If the character slash / occurs, not immediotely preceded by an element or expression, all
characters between the slosh and the next carriage return are ignored. Illegal characters (see
page 7) are permitted within comments. Parity errors are ignored within comments also.

Examples:

/THIS IS A COMMENT
LAC A  /AS IS THIS
400/ 0 /lAND THIS ALSO!

So what that 400 was and why?  Scroll up to the very very beginning:

Quote
THE LOCATION COUNTER
In general, statements generate 18-bit binary words which are placed into consecutive memory
locations. The location counter is a register used by the PDP-7 Assembler to keep track of the
next memory location available. It is updated after processing each statement.

Note how "register" gets yet another meaning here. And internal "index" or "pointer" varable in the compiler itself. I beleive today it would be seen to avoid using a term in two different meanings within a manual.

Quote
The location counter may be explicitly set by an element or expression followed by a slash. The element or
expression preceding a slash sets the location counter to the value of that element or expression.
Subsequent instructions are assembled into subsequent locations.
Example:
100/ The next instruction is placed in location 100.

So, was it an element or an expression (and should it even make difference here? don't we today think of single constants ase a special, degeneartae case of expressions?)?

Sidenote: actually "element" there meant what we would name a token or an dientifier today. But not quite, not quite...
Quote
Any group of letters, digits, and parentheses which represent binary values less than 2^18 are elements. Values are assigned to elements by the Assembler or the Loader.
Talk about self-recursive declarations. I can not figure otu of this whether values go first or elements do.

Lurk more the slash though...

Quote
LOCATION ASSIGNMENT
The use of a slash V), if immediately preceded by an element or expression, sets the location
counter equal to the value of that element or expression.
Examples:
300/ LAC (56
BEG-240+A/ LAC (56     -  The instruction is stored in location number BEG-240+A.


So, if you would think how ALGOL got the //-comments - this is probably the birthplace  of that bad habbit.
BASIC's use of apostrophe-comments and intel assembler use of semicolon-comments look pristine and perfectly justified attempts at clean break here. But dirty ALGOL prevailed. In modern Pascal too.

Now, commas.

Quote
SYMBOLIC ADDRESS TAG
An element or expression which represents a location in memory may be assigned a value in a
number of ways. The user could utilize the parameter assignment feature thus:
A=. ADD 100
The symbol A is assigned the value equal to the location in which the instruction ADD 100 is
placed by the Assembler. If the symbol already has a definition, it would be redefined. The
user can reference this location later by the symbol A:
JMP A

Redefining goto labels!!! How's THAT to you, Niklaus Wirth? What you consider harmful now, Dijkstra???

Folks, isn't it all sheer delirium? I wish i had a time machine and a big stick (bigger than logrules), to have some softly spoken words with them who designed THIS...

Quote
The simplest way to assign a value to a tag is by use of the comma.
A, ADD 100
The value of A would be the same as in the first case; the only difference would occur if A
had previously been defined, which would result in the diagnostic MDT.

...and strangely we made a full circle and came back to the notion of once-assigned (bound, almosat-immutable) variables, as a syntax construct, saving programmer from accidental typos, but not seeking to prohibit all cases of intentionally unsafe overrides.

Quote
A single undefined symbol or an expression containing only one undefined
symbol preceding the comma has its value set equal to the current location.

Setting value to expressions? My head, my head, please don't leave me yet!..

It is explained later, though.

Quote
An expression preceding the comma which contains more than one undefined symbol causes the
error print TUA. If the expression to the left of the comma contains no undefined symbols but
is equal in value to the current location, it is ignored; otherwise the error print MDT occurs.
This feature is useful for verifying table lengths.

Examples:

A,
B+1,     -  Where A and B are previously undefined symbols.
101,     -  Where the number is the same as the current value of the location counter.
GEORGE+HARRY-4,  -  Where either GEORGE or HARRY are previously undefined symbols.

A nifty trick... But Mel would do without it.

I still left puzzled, if the "LEFT" label in the listing above - and it was a listing for "master tape duplicator" - a CRUCIALLY important utility which errors could brick the super-expensive machine - was buggy and never could be actually "compiled".  Well, today all the books are printed from digital data, so probably some typography boy dropped the comma glyph when pre-mastering.

============

http://www.bitsavers.org/pdf/dec/pdp7/PDP-7_Brochure.pdf

The brochure. What should it have?
Well, obviously, glossy photos with perhydrole maidens, and lots of shallow buzz-talk, aiming to drive you out of your wallet before you started thinking what it specifically was what yujsut bought.

Glossy photos there are, but instead of maidens there is some man with black beard instead. And they say those were years of sexism and ageism, LOL.

The shock is though having found the processors commands explained there, between those advertizing photos! Not in the asm manual, not in instrucitons list, but in the commercial !!!

Page 8 (and a bit on page 7).

1. "Memory referencing instructions" - oh, the classification!
Rememeber what written about "Irish stew" (the Jerome's report edition) and also an eastern's prior art

It, perhaps, made practical sense in the days when core memory was the most limited and slow sectin of the machine, but still, what a stew!

2. Good luck figuring out was "xct Y" is supposed to do

3. rather peculiar isz Y instruction. If i got it right then it was, in Pascal terms, for i := -10 do with eveyr loop ending as the variable reached zero. Sounds simple, right? Exotic, yet simple.

4. The primary operation, add, used now extinct 1-complement negatives. And only the aux, supplementary tad used now pervasive 2-complements.
Which details makes the aforementioned isz ascend to a "fridge horror" estate - so WHAT encoding was supposed to be used there?

5. No conditional jump instructions, but plethora of "skip-if-X" opcodes, today we would've called them conditional prefixes.
So, if you ever wondered where the established Brittish gentleman ARM contracted his dirty habits of conditional execution - you know now. Yankees did it.
Granted, from human perspective this is pretty intuitive and logical, branching and conditioning seems to belong to different boxes of building blocks. The history decided otherwise, though.

6. Exotic "deposit" instead of store/save/write. Yet common "Jump" instead of PDP-11 later "branch". Go figure

7. cal Y - call the subtourint, Y is ignored - "feel joy, Feel Joy, FEEL JOY!!!!" (from a Slient Hill concerto. Or should i rather quote "Rejoice!!!" from Girl Genius?)
Well, i hope this abomination does not exist "in silicium" and is imagnary ghost created by assembler translator. In the years when every bit costed more than it's weight ion gold making a special instruction to have yet ignore the operand!!! OTOH, both Intel 8086 and MACRO-11 assemblers are now to have special distinct mnemonics for specific cases of more general opcodes, so probably thius was not a real command.

8. Now, you may call me an idiot. Mark would certainly have his chance. But i DID spent quite a few minutes trying to find return opcode. What the hell they named it and in which group they sticked it too.Yes, i did.

Caveat: there is NO return instruction. At all.

9. So, how are you supposed to return from a procedure? You are not.
Okay, you are.
You can read JMS instruction descripion. Then again. Then again. Then again.
Until THAT sinks in.
I would not even start to describe HOW wrong and twisted was what it did.

10. Then you go back to page 6 and read that "The PDP-7 Programming System inludes advanced FORTRAN Compiler".  And something starts wrigglign in the darkest corners of your memory. You start to kinda sorta (but not for certain) remembewr that early computers were built to and sold for running Fortran, like the recent computers were sold to run Windowsand newer computers are sold to run Android. You kinda-sorta-maybe remember that the Fortran firstly did not allow for nested functions calls. Or was it recursive? Or reentrant? Googles is of little help, sendign you to som manual and tutorials mentioning no this crucial limitation. Deecades later Fortran 77 "invents" them but demands you to opt-in recursive funcitons with special "compiler directive", giving away that "decent funcitons do not play with themselves". Wikipedia (this time it was the last thing to refer to, call me an idiot again) is blunt that Fortran the program was invented before hardware vendors invented the stack, and recursive calls were not possible and were not part of the language indeed.

Make it sink.

UNIX was coded on a computer that prohibited functions to be called more than once, and that stored the return address in the function body itself.
B/C languages were mostly designed by persons who matured on computers lacking stack and lacking functions reentrancy.

Obscene...

11. There seems to be no INC/DEC opcodes in PDP-7, nor SUBTRACT

12. There seems to be COMPLEMENT opcode, which more traditionally should be code NEGATE, but - it does not specify if it  is 1complement or 2-complement. I suspect it was 1-complement.
If true, this would make implementing out traditional 2-complement subtraction into a real disaster!!!

Code: [Select]
x := x - y

SUB X, Y ; x86

SUB @#Y, @#X ; PDP-11

LAC Y
COM Y
TAD (1)
TAD X
DAC X

eeek....

For people who grew with such instruction sets, the CISC should look an earthly paradise and RISC a conspiracy against mankind
« Last Edit: October 07, 2022, 06:31:08 pm by Arioch »

Bogen85

  • Hero Member
  • *****
  • Posts: 595
Re: Immutable data types
« Reply #92 on: October 07, 2022, 09:00:23 pm »
For those, whom i failed to bore into hibernaiton yet, the supplementary.
....
For people who grew with such instruction sets, the CISC should look an earthly paradise and RISC a conspiracy against mankind

I'm far from bored, even though much of this discussion took a different path from my initial topic.

(but is still relevant to it, albeit sometimes indirectly).

This is a rather intriguing and detailed history lesson and sheds light on a lot of things.

I entered this whole arena a bit late (mid 80s) but all of this very good stuff to know.

And yes, I've always seen CISC as human friendly, and RISC as yeah, maybe very machine friendly, but often not so human friendly...

Though there are some aspects that RISC instruction sets seem to enforce (but not always) is orthogonality and consistent opcode/operand patterning.

But many CISC instruction sets are as well (or seem to try to be), so those obviously are not RISC specific qualities.

But overall I'd agree with that CISC vs RISC sentiment, especially when the latter is taken to extreme with VLIW or juxtaposed instructions that need to follow some complex set of rules or have a lot of NOP insertions if those rules can't be satisfied.




Bogen85

  • Hero Member
  • *****
  • Posts: 595
Re: Immutable data types
« Reply #93 on: October 07, 2022, 09:38:13 pm »
I entered this whole arena a bit late (mid 80s) but all of this very good stuff to know.

Around '83/'84 when I got into programming....
(And a work colleague of my parents gave me some cardboard boxes full of Byte magazines going back several years, so I could "catch up" some)

But I'd already been exposed to PDP11 descendants in VT100 terminal cases at my parents workplaces as far back as 1981. (They were not programmers, just end users).

When I was first exposed to PC clones with my limited knowledge at the time they seemed inferior to me in many ways compared to the PDP11 descendants I'd already used.
(Primarily because MS-DOS seemed very primitive to me compared to what I'd used prior, especially VT2xx terminals or dial-up connected to Unix machines I never saw).

« Last Edit: October 08, 2022, 03:09:00 am by Bogen85 »

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Immutable data types
« Reply #94 on: October 07, 2022, 10:26:26 pm »
I think that I chose my words badly when I suggested that C (or at least ++ etc.) predated the PDP series. I thank Arioch for his scholarship, even though I'm sure that nobody has digested it in its entirety.

When I was first exposed to PC clones with my limited knowledge at the time they seemed inferior to me in many ways compared to the PDP11 descendants I'd already used.
(Primarily because MS-DOS seemed very primitive to me compared to what I'd used prior, especially VT2xx terminals or dial-up connected to Unix machines I never saw).

PCs undoubtedly took a long time to catch up with minis, in the same way that minis took a long time catching up with mainframes. while I think it's fairly safe to say that minis have been obsoleted, the jury's still out on mainframes since there are some things designed in early (e.g. process migration between machines) which their successors never really got.

If I could add one historical observation: CP/M, hence DOS, had low-level system calls to direct I/O to and from an "AUX:" device, which was normally a serial port. IBM VM/370 on mainframes had something comparable for a card reader and punch. Either IBM or the retro community has successfully repurposed that for inter-user communication, so it you want to send something to a different user (or to a background task running in its own VM etc.) you simply use the punch API with a header card.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: Immutable data types
« Reply #95 on: October 08, 2022, 03:40:29 am »
I think the purpouse of immutable data types is to prevent bugs.

If you use threads making a variable read only sounds good.

Rust is immutable by default?

Kotlin suggest me at every variable to set it as immutable if it determines that is not edited later. (Yes Android Studio is the best IDE ever. Not bug free I must say but makes coding so easy.)

Bogen85

  • Hero Member
  • *****
  • Posts: 595
Re: Immutable data types
« Reply #96 on: October 08, 2022, 04:52:36 am »
I think the purpose of immutable data types is to prevent bugs.

To prevent some types of bugs, yes. Runtime mechanisms can be used but in some cases this is added overhead and many require extra debugging to eliminate lock up conditions. (semaphores, mutex, spinlocks) (And these have been discussed in this topic thread)

Hiding data using a read only property (as discussed in this topic thread as well) prevents casual or careless reassignment as no write method was specified, so that is enforced at compile time.
I say casual reassignment, one could still use the instance pointer and calculate how to overwrite the variable in question. But it satisfies many cases where immutability is required for certain types of data, because of the lengths one must go to intentionally modify the data.


If you use threads making a variable read only sounds good.

Yes. Which is why on languages without deep compile time enforcement of immutability I often use forks (fairly cheap, due to copy on write forking, not as cheap as threads) and message pass.
Windows can't fork efficiently and does not provide any fork mechanism by default, so such software can't run on Windows. However, WSL blurs the line about what can run on Windows, so that is not as much an issue any more.
(As it also was on systems that had expensive non copy on write forks).

Immutability when using COW forking is really only preventing a child process from mutating it's parent data that was passed to it.
It does not prevent the child from modifying it's own data, it just prevents the possibility of corrupting parent data through direct memory access.
If the child was not supposed to be running a different copy than the parent, that is not enforced.

However, one could use MMap/MProtect to mark regions read only, so that could be enforced.
Still a runtime check, but low overhead. Since a runtime check, bugs have to be exposed and caught later, and some might slip through the cracks if unit/functional testing is not comprehensive enough, which is why compile time checking is preferable.

But if using MMap/MProtect to mark the regions read only, there is no need to have forked, one could have just spawned another thread.

Rust is immutable by default?

Yes, as is V and most functional languages. (And Nim, if you use let instead of var)

Kotlin suggest me at every variable to set it as immutable if it determines that is not edited later. (Yes Android Studio is the best IDE ever. Not bug free I must say but makes coding so easy.)

I usually take the stance if the language supports immutable variables and that is enforced at compile time, I'll use them everywhere to have the compiler tell me where I messed up and tried to mutate something. (unless I know of course it needs to be mutable).
Then I can make the determination whether or not it needs to be modified, and let it be mutable, or just rewrite that particular code to not need to modify it (within reason, there could be some validity in it being mutable, depends on the overall purpose of what that particular code is supposed to do).

For instance, tracking persistent state of something may be more straight forward with mutable data in memory, rather than resorting to using some data-store external to the program just to wantonly say you had no mutable variables in your program.
Also, but not limited to, long term counter, serial id, etc. There are ways to do those functionally, but that might not always be the most maintainable or desirable way of doing it, or efficient, depending on the particular application.
« Last Edit: October 09, 2022, 01:52:24 am by Bogen85 »

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Immutable data types
« Reply #97 on: October 08, 2022, 08:44:32 am »
To prevent some types of bugs, yes. Runtime mechanisms can be used but in some cases this is added overhead and many require extra debugging to eliminate lock up conditions. (semaphores, mutex, spinlocks) (And these have been discussed in this topic thread)

And I'd point out that having the compiler take steps to avoid problems is very much "the Pascal way".

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: Immutable data types
« Reply #98 on: October 08, 2022, 04:13:29 pm »
A.S. by "the PDP11 descendants" one cam mean 32-bit ST-VAX series. Which originally used to mean "PDP-11 with Virtual Address Extension", but this would be quite a stretch. Like 80386/80486 were "the 8086 descendants" but obviously they were a whole different class.

So, by "PDP11 descendants" then i would assume non-DEC PDP-11 clones.

Around '83/'84 when I got into programming....
(And a work colleague of my parents gave me some cardboard boxes full of Byte magazines going back several years, so I could "catch up" some)

But I'd already been exposed to PDP11 descendants in VT100 terminal cases at my parents workplaces as far back as 1981. (They were not programmers, just end users).

I was exposed to them in late 1980-s and PDP11 was standard setup in Soviet schools (there were also Apple-like Z80 machines, and MSX machines, but the mainstream i believe were two PDP11 based setups).

No, MS-DOS definitely was more advanced than RT11-SJ/CD.
RT11-FB (cooperative two-tasking) could be seen a bit more advanced (*only* in F/B aspect!) than MS-DOS, but not than Concurrent DR-DOS.
RT11-XM could not be actually run on available hardware, just like MS-DOS + EMM could not be run on available second-hand wstern machines without EMM add-on cards.

There was the driver that turned 2/3 of video-memory into RAM DISK (KD.SYS) - but this made videocard badly flicker (probabl the same reason as the infamous CGA "snow" which i never saw personally).
However at it's ideal imaginary condition it would be the same conceptually as MS-DOS + XMS (any 286+ CPU).

More so, even the most el cheapo second-handed  PC286 had 1MB of RAM. If no UMB hardware/ssoftware was available - it would be 640KB main RAM + 64KB High RAM + 320 KB XMS buffer.
RT11-SJ/CD + KD.SYS gave you 64KB RAM + 96KB ex-video buffer (i believe MS-0511 video RAM were 3x48Kb, but my memory may be at fault here).

Among other things that meant MS-DOS had more or less free memory allocation (Memory Arenas AKA MCBs), while RT-11 could not spare scarce RAM on this and only had single pointer of "top user app memory" with all above considered resident core of OS.

MS-DOS has TSR API, compensating for lack of native multitasking.
RT11-SJ had neither (but had loadable device drivers, which could be used as resident programs without any user interface).

And not let me even start about filenames.

If you come from "how much could they cram into 56KB of RAM (the rest was reserved for I/O ports) - then RT11 was a very impressive OS.
But it never provided a share of MS-DOS services. And could not, having such a huge hardware handicap.

Perhaps the only service that RT-11 provided that DOS/Windows/NT did not - was command line templates, which helped to make 3-rd party CLI utilitiees share "look and feel" with standard OS commands. Yet even that was not complete IMHO - the other side of the coin should had been the standard error/warning/request UI, and this RT-11 did not expose (Windows CommonControls does, MS-DOS did not)

PDP-11/RT11 was absolutely impressive when you think against what hardware limits they had to work, "bang forthe buck". But in absolute numbers, the "bang" was veyr much less than any PC+MS-DOS offered.
« Last Edit: October 08, 2022, 04:16:57 pm by Arioch »

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: Immutable data types
« Reply #99 on: October 08, 2022, 04:21:50 pm »
still out on mainframes since there are some things designed in early (e.g. process migration between machines) which their successors never really got.

For waht i heard, lineages like AS/400 are not jsut "big iron" with "fail tolerance" - they are reallt build of different primitives.
Granted, i do not have immediate experience, albeit IBM is said to offer free AS/400 remote access today.

For what i heard, AS/400 is more akin to OOP-OS / Capability-based OS, with their executive environment more resembling what we would expect from JVM/.Net runtimes rather than OS.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Immutable data types
« Reply #100 on: October 08, 2022, 05:03:31 pm »
RT11-FB (cooperative two-tasking) could be seen a bit more advanced (*only* in F/B aspect!) than MS-DOS, but not than Concurrent DR-DOS.

There ain't no such animal. CDOS (formerly CCP/M-86, latterly MDOS) and DR-DOS were completely separate codebases.

For waht i heard, lineages like AS/400 are not jsut "big iron" with "fail tolerance" - they are reallt build of different primitives.
Granted, i do not have immediate experience, albeit IBM is said to offer free AS/400 remote access today.

For what i heard, AS/400 is more akin to OOP-OS / Capability-based OS, with their executive environment more resembling what we would expect from JVM/.Net runtimes rather than OS.

AS/400 is more a supermini than anything else, taking over from unit-record equipment and ultimately tabulating machines. Its execution model is pretty much unlike anything else, and it purports to be based on persistent objects rather than files etc.

However, the AS/400 is a /long/ way removed from actual IBM mainframes.

But all of this is /way/ off-topic.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018