http://www.perlmonks.org?node_id=11104645


in reply to Re^3: The error says the value is uninitialized, but it works anyway
in thread The error says the value is uninitialized, but it works anyway

Another point. Computer languages are not just words and some funny interpuction. There are phrases, and you are rarely told explicitly that they exist. Phrases just appear in the documentation, and everyone uses them.

I learned several computer languages until I really understood that. I was learning MUMPS at that time, a language older than C, originally running on the bare metal of 1960s hardware, now running in its own integrated environment on top of common operating systems. MUMPS is a small, but very powerful language. To me, it feels very much like 1960s version of Perl, restricted only by the limited resources of the old hardware.

Because MUMPS is such a small language, many things you do don't just require one command, but a combination of commands. For example, writing a file:

OPEN 51:("FOOBAR":"W") ELSE GOTO FAILED USE 51:("FOOBAR":"W") WRITE "HELLO WORLD" USE 0 CLOSE 51

Or shorter:

O 51:("FOOBAR":"W") E G FAILED U 51:("FOOBAR":"W") W "HELLO WORLD" U 0 C 51

Yes, white space is significant. Opening files differes wildly between various implementations. And you don't write out commands at all. You use their one-letter equivalent, because you don't have memory for all of those redundant letters. You put as much code into a single line as possible, because the code is read and interpreted line by line. Using as few lines as possible makes your code run faster on ancient machines.

The equivalent perl code looks like this:

open HANDLE,'>','FOOBAR' or die; select HANDLE; print "HELLO WORLD"; select STDOUT; close HANDLE;

The great thing about MUMPS is that it has associative arrays, and you can use them as in Perl.

for my $key (sort keys %hash) { print $key,"\n"; }

In MUMPS:

SET KEY="" FOR SET KEY=$ORDER(^HASH(KEY)) QUIT:KEY="" D .WRITE ^HASH(KEY),!

Short form:

S KEY="" F S KEY=$O(^HASH(KEY)) Q:KEY="" D .W ^HASH(KEY),!

The equivalent perl code requires an imaginary nextkey function:

my $key=''; while (($key=nextkey(\%hash,$key)) ne '') { print $hash{$key},"\n"; }

My point here is the phrase: There is only this way to enumerate all keys of a hash. You set the current key to the empty string. Then you run an infinite loop, in which you call the $ORDER() function to get the next key of a hash (or the first key, when called with the empty string). When the $ORDER() function returns an empty string, you are done and must quit the infinite loop. Only after that, you can work with the current key. And yes, the $ORDER() function is special. It should really be called with a reference to the hash and a key. Actually, it is, but it looks like it is called with the hash value of the key.

Once you have written a sufficient amount of MUMPS code, you think "iterate over ^HASH" and automatically type S K="" F  S K=$O(^HASH(K) Q:K=""  D. You no longer think about the for loop and its abort condition. You just type that line noise from muscle memory.

And this is true for all languages. In Perl, you think "iterate over %hash and write for my $key (sort keys %hash) { or while (my ($k,$v)=each %hash) {.

(There may be some minor errors in the MUMPS code, as I haven't used MUMPS for a few years.)

Update: fixed some MUMPS errors around OPEN and USE.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)