If languages like Smalltalk, APL and Lisp aren't counted, then sure, Java was big productivity boost in the history of programming.
Einstein got the Nobel for the photoelectric effect, which we take advantage of continuously every day. I'd say that was influential.
I'm also a big FORTRAN fan, especially the VAX-FORTRAN variant DEC introduced in the 1980s. It was great for numerical analysis but also included library calls to access the operating system, much like C. Some of us were late to the Unix party, so this was a huge step forward.
You can do that in assembly too
struct foo {
int count;
char name[16]; /* not null terminated! */
};
REPL: define an alias name foo for the type with typedef: 1> (typedef foo (struct foo (count int) (name (array 16 char))))
#<ffi-type (struct foo (count int) (name (array 16 char)))>
Now put an instance of the Lisp struct into a binary buffer using this FFI type: 2> (ffi-put #S(foo count 42 name "ABCDABCDABCDABCD") (ffi foo))
#b'2a00000041424344 4142434441424344 41424344'
Now, recover a new Lisp struct instance from this binary struct: 3> (ffi-get *2 (ffi foo))
#S(foo count 42 name "ABCDABCDABCDABCD")
No problem; the FFI type system knows that an "array of char" is different from a null terminated string, and can make it correspond to a Lisp string in both directions.Now, for fun, let's poke a zero byte into that buffer:
4> (set [*2 8] 0)
0
5> *2
#b'2a00000041424344 0042434441424344 41424344'
There it is. Now decode: 6> (ffi-get *2 (ffi foo))
#S(foo count 42 name "ABCD\xDC00;BCDABCDABCD")
What's that? My UTF-8 decoder treats the 00 as an invalid byte, and maps it into the surrogate pair range U+DCXX.
The otherwise optional semicolon was output because the next character in the string is a hex digit.If that U+DC00 is encoded back, it will reproduce the null byte:
7> (ffi-put *6 (ffi foo))
#b'2a00000041424344 0042434441424344 41424344'Two variables holding common license plate formats might look like this:
01 LIC-PLATE1 PIC 9A(3)9(3) VALUE '1ABC234'.
01 LIC-PLATE2 PIC 9(3)A(3). VALUE '123ABC'.
[edit: added a newline to separate my examples]
("9" specifies a numerical digit, "A" specifies an alphabetic character, and there are other types that deal with sign, explicit and implicit decimal points, etc).
Assembly deals with memory layouts, but doesn't enforce any kind of higher-level data type, and especially not a human-oriented data specification.
COBOL is still pretty efficient for tasks like scanning data on magnetic tapes--not that most of us do that any more. In fact it was pretty good for any problem that involved reading from or writing to storage devices because you could control the data layouts very precisely. It was great on reports for the same reason. I even wrote a simple doc markdown processor in COBOL because the place I worked didn't have usable word processors and we needed something to do pagination and formatting of docs.
I don't miss the verbosity or the lack of modularity but on the other hand COBOL was an effective tool that you could use to solve problems more quickly than other tools available at the time.