Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^4: The error says the value is uninitialized, but it works anyway

by afoken (Chancellor)
on Aug 18, 2019 at 08:22 UTC ( [id://11104645]=note: print w/replies, xml ) Need Help??


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". ;-)

Replies are listed 'Best First'.
Re^5: The error says the value is uninitialized, but it works anyway
by choroba (Cardinal) on Aug 18, 2019 at 19:58 UTC
    Note that each in scalar context returns the next key.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      Note that each in scalar context returns the next key.

      One of the things I rarely use.

      each iterates over the keys of a hash, returning different values when called repeatedly.

      >perl -E '%h=map{ $_ => 1 } qw( a b c d e f ); while ($k=each %h) { sa +y $k }' a c d b f e >

      But the MUMPS $ORDER() function is different. Keys in MUMPS are always sorted, unlike Perl's hash keys. And keys must not be empty. $ORDER() returns the next key for the key you pass into. It does not iterate. Passing -1 as a second argument to $ORDER() returns the previous key instead of the next one. If there is no previous / next key, an empty string is returned.

      KILL ^H SET ^H("D")=1 SET ^H("E")=1,^H("F")=1 S ^H("A")=1,^H("B")=1,^H("C")=1 ; ^-- ^H now contains the keys "A", "B", "C", "D", "E", "F" ; WRITE $ORDER(^H("")),! ; ^-- writes "A", the first key (in order) of ^H ; W $O(^H("C")),! ; ^-- writes "D", the next key after "C" in ^H ; W $O(^H("F")),! ; ^-- writes "", because "F" is the last key in ^H ; W $O(^H("D"),-1),! ; ^-- writes "C", the key before "D" in ^H ; W $O(^H("A"),-1),! ; ^-- writes "", because "A" is the first key in ^H ; SET K="" FOR SET K=$ORDER(^H(K)) QUIT:K="" DO .WRITE K WRITE ! ; ^-- writes "ABCDEF", all keys of ^H in order ; S K="" F S K=$O(^H(K,-1)) Q:K="" D .W K W ! ; ^-- writes "FEDCBA", all keys of ^H in reverse order (-1 passed as + second argument to $ORDER) ; S K="B" F S K=$O(^H(K)) Q:K="" Q:K="E" D .W K W ! ; ^-- writes "CD", all keys of ^H following "B" and stopping at the +end of keys or at "E", in order ; S K="B" F S K=$O(^H(K)) Q:K="" Q:K]]"E" D .W K W ! ; ^-- writes "CDE", all keys of ^H following "B" and stopping at the + end of keys or at the first key sorting after "E", in order

      Actually, $ORDER() is a "new" (*cough*) function, it can handle negative and non-numeric keys. The original function used to iterate over keys was $NEXT(), and it was intended to be used only with positive integers, i.e. plain arrays or sparse arrays. It returns -1 if no more keys can be found. Unfortunately, -1 is a legal key. So if $NEXT() returns -1, you can not know if you found the last key or you just happen to have -1 as a key. $ORDER() fixes that problem, and $NEXT() is provided for legacy code from the dark ages.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re^5: The error says the value is uninitialized, but it works anyway
by holli (Abbot) on Aug 18, 2019 at 10:46 UTC
    Wow, MUMPS is a real thing???!! I always thought TheDailyWTF made that up. Are you next going to tell me Initech is a real company?


    holli

    You can lead your users to water, but alas, you cannot drown them.
      Wow, MUMPS is a real thing???!! I always thought TheDailyWTF made that up.

      Yes, it's old, it's real, and it is still in use. Most implementations are gone, unmaintained or unsupported, but MUMPS is hidden in InterSystems Caché, and you can still write software in MUMPS in a Caché system. Another surviving implementation is GT.M. See also "Current users of MUMPS applications" in MUMPS.

      From the 1980s to 2015, a MUMPS implementation was used as the main database for producing and distributing blood products for two federal states (about 5 million people) in Germany. During the 1990s, the system was cloned to support another two federal states for a short time. Duing its last five years, working with that system paid my bills.

      That MUMPS system was replaced by a custom application written around a commercial SQL database, originally written in and for a completely different country. Not for performance reasons, but because blood services merged, and a political decision was made to use the larger system. As far as I know, the MUMPS system is still running, disconnected from all other systems, to be able to access the original records that have been ported into the new system.

      Update note: A few minutes after posting, I have removed some details that should not have been exposed.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        MUMPS is hidden in InterSystems Caché

        Wow - I had no idea this was still going. It has been a good 15 years since I heard anyone discussing Caché as a viable application. Good hear it is still alive and kicking.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11104645]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-03-19 09:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found