• (cs)

    This "language" looks worse than JCL, COBOL, LISP, APL, VB combined! Looks like something using the worst features from any of these languages. (And no, I am not dissing on all of these languages. Except VB, which should have never existed.)

    To all y'all MUMPS defenders: 'Tis a general security rule not to allow data to be executed as code. Ah, I can only begin to see the world of exploits based on XECUTE...

    (Then again, the would-be hacker would die of brain explosion while trying to write the exploit...)

    I actually like COBOL after reading this thing ... it may have been fast and efficient 40 years ago, but so is assembly code. And I'm not about to write an ERP system out of assembly...

    Addendum (2007-02-13 17:34): Oh yes I know about why it was used back in its own days. But trying to defend it against current languages is just insane. Maybe 40 years ago I would've wanted to have code and data side by side, but now I don't.

  • RH (unregistered) in reply to Ebs2002
    Ebs2002:
    ...

    Wow.

    I'm not surprised this is happening, but...wow. I feel bad for Bryan, not just because he had to work here, but because he can't find something else because he stayed for 2 years.

    captcha:muhahaha, what I'm sure the management is thinking to themselves when someone tries to quit: "muhahaha, you'll be back, there's nowhere else for you to work!"

    That brings about a new twist in "job security"... I've always thought of it being the coders making horrible code in order to keep their job since they only know how to maintain it. I never heard of employers having their employees use a horrible language in order for them to never quit. ;)

  • (cs)

    This is why when developers say to me "I don't care what language I code in" I laugh. Yes, yes you do. The programming language world is larger than java, perl, ruby, and C#.... ;)

    As far as the WTFness of MUMPS.... that's pretty weak, MUMPS is simply old and does what a lot of languages did in it's time. Abbreviate commands with a single letter? Brilliant when every byte counts. Xecute code stored in a variable? Uh, even early BASIC could do this. Today it's called a function pointer or a delegate....

    Would I want to code in it today? Hell no, but recognize the past for what it is. Features and oddities we laugh at today the next generation will be laughing at ours.

    -Me

  • (cs)

    Well what would you expect of a language that was born in an Animal lab by a (presumably) evil doctor?

    MUMPS was developed by Neil Pappalardo and colleagues in Dr Octo Barnett's animal lab at Massachusetts General Hospital (MGH) in Boston during 1966 and 1967. The original MUMPS system was, like Unix a few years later, built on a spare DEC PDP-7.
    Source:wikipedia
  • dkf (unregistered) in reply to Rev. Johnny Healey
    Rev. Johnny Healey:
    As far as production-use obfuscated languages go, nothing really compares to BANCSTAR. MUMPS looks like a walk in the park by comparison.
    Ugh. Looks just like it is working directly with machine code (not assembler, real raw machine code). I've done that, and it sucks.

    Indeed, it was hard enough that I used another machine I had to develop my own toolchain (in the only higher-level language I had at the time, BASIC) and built my own communications hardware and bootstrap loader so that I could develop in greater comfort. I wouldn't do it that way now, but it was tremendously instructive.

    Curiously, that mess ended up (indirectly) getting me my first real job. :-)

    Come to think of it, I've also done machine code in situations where the only input mechanism I had was DOS's 'COPY CON:' and that was even suckier. But that's a story for another time...

  • bspiral (unregistered) in reply to the-moss
    the-moss:
    This company wouldn't be based in Madison, Wi would they?

    I think I also worked for them straight out of college.. I only lasted a year though.

    ?smetsys cipe

    Yeah, burnout in 2 years tops for most fresh meat. If they're using MUMPS - then I see why.

    Ironically enough, my captcha for posting this is: sanitarium

  • (cs)
    You see, because MUMPS has a rather small routine limit, developers had to spread code across several routines (GBLVCM1, GBLVCM2, etc) and “chain” them together with a GOTO at the end.

    To edit the code stored in the “database” (if you’re charitable enough to call it that), developers needed to use the internally-created text editor. It actually made vi look user-friendly. The editor made extensive use of DEC VT 220 keys as shortcuts; these keys, naturally, did not exist on any modern keyboard. Things that we take for granted (the Enter key, for example) required a bizarre set of escape commands to be entered.

    Both of these put me much in the mind of Forth: code stored in 1 kbyte disk blocks with continuation operator to chain to the next block; an integrated and irritating editor that made extensive use of the VT 100 PF keys and number pad.

    I'm glad to have left it behind many years ago.

  • (cs)

    At this point I would like to point out a previous sidebar article: http://forums.thedailywtf.com/forums/thread/73428.aspx

  • dkf (unregistered) in reply to Zygo
    Zygo:
    There is also no GOTO in Tcl, or at least it doesn't come with one (anything's possible if you start mucking with the language at runtime).
    I advise regarding GOTO as impossible in Tcl. The amount of work required to make even a simple C-like GOTO is quite enormous; it's far easier to handle exceptions, build state machines or drive automated resource deallocation by other means.
  • (cs) in reply to Sgt. Zim
    Sgt. Zim:
    asuffield:
    DATA TYPES: one universal datatype, interpreted/converted to string, integer, or floating-point number as context requires.

    Not a WTF.

    In theory. When it works. But when it doesn't ... Get the bandages, because your eyes will start bleeding.
    The googles, they do nothing!
  • Sizer (unregistered) in reply to gwenhwyfaer
    gwenhwyfaer:
    I'm afraid the only real reason for operator precedence is "Fortran did it".

    That's not completely true - it comes from how you'd normally evaluate written equations. 3x+4y should be read as (3x)+(4y), not ((3*x)+4)*y. And that holds true even if you do 3(dot)x+4(dot)y.

  • Mitch (unregistered) in reply to Flo

    I've worked as a programmer for 22 years in a multitude of environments, technologies and languages. And that code is by far the most awful, unmaintainable bollox I've ever seen!!! But then again, maybe I've just been lucky...

    Certainly wouldn't want to be dreaming in that code.

  • Hank Miller (unregistered) in reply to Saladin
    Saladin:
    me:
    VI is user friendly.

    [...]

    Do the tutorial and in a matter of hours you will be faster than notepad

    Does not compute.

    A tutorial and "hours" to learn how to use a TEXT EDITOR? That's the antithesis of "user-friendly" to me.

    Let me guess, you see no reason why peoples' grandmas shouldn't be forced to use a command prompt, right?

    You are wrong. There are several different classes of user friendly. One is friendly to "grandma" (meaning those who rarely use a computer and are afraid of it). Another is friendly to those who are trying to get something done fast.

    Phone directory operators for instance work the same job for years. If the phone company can save 1/10th of a second on each directory assistance call they save millions each year. Thus in the context of phone operators a system that requires 1 month of intense training to use is user friendly - you can afford to make sure only those who have the training use it.

    Vi is like that. Hard to learn, but once you learn it very friendly. The only question is if it is worth learning. There are editors that use technology vi doesn't, and thus have a lot of power without being as hard to learn.

  • Prozak (unregistered)

    How can I state that this is by far the worse horror story of the industry. And I was only complaining that my last company, that went bust in London 2 months ago, where not using hibernate and Spring. I brought Java 5 in there. Building yesterdays technology with today's tools, was the hidden motto.

    I was part of the hot team, the one building the next flagship product that never got delivered. And that made customers go bust. Would not mention any names, but my next job is in the same sector, and God did we leave a stench.

    So for the story of this fellow, it nearly brought a tear to my eye. That language has all the worse that the industry can make. Please get him a job at Google for life. He deserves that more than any one.

    May the many years of industry hell ahead of him help him heal from such a deep trauma.

    After that the rest, its peanuts, you have seen hell, please do enjoy life.

  • Derek Johnston (unregistered) in reply to Anonymous Coward
    Anonymous Coward:
    This MUMPS monstrosity puts RPG in perspective for sure.

    RPG as in Rocket Propelled Grenade...?

    Captcha: paint (mmmmmm.... smells good)

  • Mr. Mike (unregistered)

    Our hospital's main patient database uses MUMPS. They've been working on a replacement for at least two years. (Users enter patient info into the replacement system, which feeds into the MUMPS system, where users can then correct the data, if they need to enter something the new system doesn't implement yet, which is a fair amount.) Anyway, to get data out, we have a DTS script which launches a telnet session, which runs reports, and then runs kermit to download the reports. They are fed to a perl script which cleans up the data, which is then piped to MS SQL Server. We then get the data from SQL Server. It has about a 50% chance of completing successfully.

  • Mr. Mike (unregistered)

    Our hospital's main patient database uses MUMPS. They've been working on a replacement for at least two years. (Users enter patient info into the replacement system, which feeds into the MUMPS system, where users can then correct the data, if they need to enter something the new system doesn't implement yet, which is a fair amount.) Anyway, to get data out, we have a DTS script which launches a telnet session, which runs reports, and then runs kermit to download the reports. They are fed to a perl script which cleans up the data, which is then piped to MS SQL Server. We then get the data from SQL Server. It has about a 50% chance of completing successfully.

  • Stas (unregistered)

    I worked on the VA .NET project and I can say they still use MUMPS a lot. They tried to get rid of it, but it seems like it's impossible to kill the thing. The execution environment migrates from platform to platform (VAX/VMS, Cache) but their entire software package remains virtually the same.

    One of my first tasks (after working for several months) was to create an interface between a .NET application and MUMPS system. When I started looking at M code, I was horrified at first, just like many folks here. I was totally disgusted. Then I learned that the stuff was nearing 30 years in production and it changed my perspective a bit.

    Yes, it is ancient. Yes, it's a mindfuck to do anything in it. However, it is fairly powerful and works well with hierarchical data.

    In the end, I didn't have to learn much M since I was working together with M programmer and we practically didn't touch the M part of it (there already was some server side code developed for interaction with Delphi and Java clients). I wrote my .NET client (XML over TCP, simple stuff) and it proved itself well.

    I agree, it's about time for MUMPS to retire. However, looking at pro users working with our new GUI .NET app and the legacy MUMPS text-based app, I still think it was a step back.

  • Stas (unregistered)

    I think Mr. Mike and I worked on the same project :) This all sounds very familiar :)

  • (cs)

    Given that (IIRC) it was the second language to get ANSI approval, MUMPS was exceedingly high-tech for its time. Many of the modern MUMPS interpreters are quite fast.

    One of the reasons the code referenced in the article may be slow is that it sounds like it's using interpreted strings (rather than stored routines) for EVERYTHING. Rather than having the possibility of tokenization or pre-compilation using a saved routine, it's having to re-interpret everything at runtime because it's all stored as strings.

    MUMPS might be considered the Perl of the 1960s. It had associative arrays and was very easy to write obfuscated code in. It was even better at this last than Perl, given each command could be specified as the shortest, unambiguous abbreviation. The ability to access a hierarchy of lockable, multi-process global variables alongside your local-process global variables was kinda cool.

    I almost got sucked into that after graduating from college with a background in C/C++. I almost didn't get out, and was lucky I did. It's very much a dead end, but there are still well-paying jobs there because there's lots of legacy code big business wants to keep running.

  • Zygo (unregistered) in reply to Anonymous Coward
    Anonymous Coward:

    Yes, but the bad habits learnt in those years can be deadly and worse than nothing. It's not just the language; the general quality and culture of a place can strongly affect how a programmer thinks.

    Amen to that. I often find myself struggling with a thorny C++ problem and thinking, "what would I do if I were programming this in Perl?" If this trick works, my problem is solved and I write some simple and obvious algorithm in Perl code, translated into C++. If it doesn't work, I see that what I'm trying to do will result in C++ code that looks like the innards of the Perl interpreter, in which case I give up on the whole approach and try something else. Often the "other" language isn't Perl--it might be Tcl or Matlab.

    Strangely enough I never find myself wondering "what would I do if I were programming this in C++?" while programming in Perl...or any other language except C...funny, that.

    Perl, Ruby, Smalltalk, Tcl, Fortran, Lisp, Forth, SQL, even Java and Javascript provide inspiration for different approaches and techniques. I generally consider anyone who hasn't mastered at least two languages, where one language idiomatically treats variable values as potential code and the other doesn't, as at best a junior developer. It doesn't matter to me if the person has 20 years of industry experience in COBOL, Fortran, Java, VB, C and C++--as a developer, they're little better than a recent graduate until they learn from working in a larger variety of languages.

  • Matt (unregistered) in reply to Mitch

    This article and the numerous and highly charged responses made me laugh. The examples quoted are almost all classic examples of stuff you'd fire a mumps programmer for writing, since they are patently obscure, opaque and barely maintainable. No wonder you all think it's bollocks. However, I'm sure I could dig up equally awful examples of the abuse of pretty much any other language. It's quite straightforward to write totally clear and maintainable mumps code.

    It's also the intensity of the cries of horror that everyone comes out with that amuses me too. A bit like someone who shoots a rattlesnake because he's led to believe it's nasty, rather than take the time to discover some background to the animal. Calm down guys, it's only a programming language with a syntax which, to guys who've swallowed the Java, C++ and .Net koolaid, looks freaky. So what? Chinese looks pretty scary to me, but it seems to do a good job in the hands of a proficient Chinese person.

    As a great example of a prejudicial article intended to show something in its worst possible light, it sure did a great job. It leaves me wondering what was its objective and motivation?

  • Zygo (unregistered) in reply to anonymous guy
    Saladin:
    me:
    VI is user friendly.

    [...]

    Do the tutorial and in a matter of hours you will be faster than notepad

    Does not compute.

    A tutorial and "hours" to learn how to use a TEXT EDITOR? That's the antithesis of "user-friendly" to me.

    Let me guess, you see no reason why peoples' grandmas shouldn't be forced to use a command prompt, right?

    All computer programs communicate with their users through a command language. For vi, the command language is a number of simple letter and symbol commands. For notepad, the command language is a mixture of ape-like gesturing and finger-snapping, or a very limited set of keyboard commands.

    Now, gesturing like an ape and snapping your fingers will get you through the working day in some parts of the world. The experience will be frustrating and slow for both you and the people who have to work with you, but since a text editor knows nothing of frustration, in theory it's only the user who will be inconvenienced by a weak text editor (although in practice it's the user's co-workers who get the most frustrated). Maybe the user will spend 15 minutes of her life editing text, so the loss is acceptable.

    In other parts of the world, wandering around where you don't know the native language will get you in a dark alley somewhere with a knife wound in your chest while your worldly possessions and/or your children are stolen and sold in the nearest market. Arming yourself with a knowledge of enough language to express what you need and to negotiate as an equal with the people (or in this case machine) who can get it for you gives you real power over your environment. If the environment looks like a bunch of text files then you really want to spend a few hours to learn how to use a text editor, just like you'd want to spend a few hours learning self-defense before wandering in dark alleys in unfriendly neighborhoods...

  • Kenneth Spicer (unregistered)

    I've been programming in M for about 25 years. Everything in this article is true. Sparse arrays, data and programs are interchangable. Oh, and you forgot post-conditionals (all commands can become their own IF statements). But I can't say the options (Oracle?) is any better. I've done Oracle DBA. PL/1, Assembler, JAVA etc. etc. etc. When I started oh so many years ago I was the first "trainee" who'd actually been trained to program in MUMPS design. All of the previous traineees were lab techs.

  • (cs) in reply to Anonymous Coward
    Anonymous Coward:
    Paul Graham has a rather harsher opinion on this than I do. Check out http://www.paulgraham.com/avg.html
    Wow, you completely misread his point there! He wasn't saying anything about people who merely use weak languages, and especially not about those who use them but are aware of stronger alternatives. His criticism in that article was aimed at those who refuse to believe that any language offers constructs more powerful and/or expressive those provided by the (weaker) language they're used to; and I agree with him wholeheartedly on that. That's not the situation described here, where Bryan is fully aware of the weaknesses of M(UMPS) (although apparently less aware of some of the things it got right, and unsympathetic to its historical context).

    I am in no way prepared to accept that two years spent learning to read and work with incomprehensible code in an industry riven with NIH syndrome is useless. Let alone worse than useless, as you seem to be contending. I can't imagine Paul Graham would be delighted to find himself quoted in support of such a position either.

    (And welcome to the redditors, I guess.)

  • Kenneth Spicer (unregistered)

    Oh, and before I forget (old age, you understand). I do work for the VA now. I don't know if it's in spite, or because of MUMPS, but they are now 100% electronic medical records. And over 150 Medical centers working together. What other Medical system can say that? Their primary concern at this point is that many of us Mumpsters are getting old. And they are trying to fill the void with youngsters fresh out of college.

  • (cs) in reply to RogerC
    RogerC:
    Both of these put me much in the mind of Forth: code stored in 1 kbyte disk blocks with continuation operator to chain to the next block
    In fairness, I think that was a FIGforth thing; Chuck Moore is on record as believing it's a very bad idea, exactly because you can't tell the thing to load one block in isolation.
    an integrated and irritating editor that made extensive use of the VT 100 PF keys and number pad.
    Was that also FIGforth?

    The problem with Forth is that it's not a difficult language to implement. In fact, it's far easier to implement than to use - kind of like Lisp without the standardisation (!) - so hundreds of little "toy" implementations appeared and got distributed for free, but without decent support or a sane environment. And people picked them up, thought "This is Forth? Eurgh!" and rejected the whole concept, despite the rather nicer products available commercially (again, not entirely unlike Lisp). For a couple of examples of modern Forths, there's Forth, Inc's SwiftForth, MPE Ltd's VFX, or Bernd Paysan's bigForth.

  • foobar (unregistered)

    OMG, poor guy! I actually checked the date for 2007-04-01

  • (cs)

    I don't know that I'd hide the job. He should be honest and up front about the experience and that it was a bad one. No one will hold it against him. Either that, or he's going to look like he's been in jail for a couple of years.

  • (cs) in reply to Sizer
    Sizer:
    That's not completely true - it comes from how you'd normally evaluate written equations. 3x+4y should be read as (3*x)+(4*y), not ((3*x)+4)*y.
    Firstly, the earliest Fortrans limited the complexity of expressions in arbitrary ways (particularly inside things like array subscripts). In fact, Fortran-I was a total hack. The only reason it caught on was that IBM were pushing it, and that at the time there wasn't anything else (except dressed-up assembler).

    Secondly, in the comment you're replying to I've already pointed out one way in which algebraic convention was completely ignored. The use of multicharacter variable names and the asterisk to denote multiplication was another. So all you're doing is reiterating a suggestion I already gave reason for rejecting.

    Thirdly, APL is much more mathematically sound than Fortran; yet it eschews operator precedence entirely. Indeed, its successor, J, dispensed with the need to program non-functionally (and with the funny character set) - but did not reintroduce it. Thus, one can conclude that operator precedence is not exactly a deal-breaker for the mathematically inclined.

    ...Now if you'd countered with the argument that Algol-60 did a lot more to cement operator precedences than Fortran, you might have had an argument. But then the question becomes, if Fortran-I had enforced a strict left-to-right discipline on expressions, would Algol-60 have gone with precedences? But in view of all the other discrepancies between Fortran and expression/algebraic notation, would we have missed operator precedences if they had been thrown out too?

  • Henry Troup (unregistered) in reply to Sgt. Zim

    The problem with one datatype is the inevitable unexpected interpretation. A former employer used department numbers of the form nAnn - n A digit, A an alpha. Periodically, someone in 2E02 or the like would find that their department was now rendering as "200" or more likely, 7E13 would see "****" for overflow - because something had interpreted the E as exponential notation. Excel will do this

  • Tim (unregistered) in reply to mkb
    PHP arrays can contain both hash keys and integral indices at any given time. If you use a Boost variant as the key into a C++ STL map you might be able to do something weird as well.

    Does this mean that you need to use a language extension to make C++ as baroque and convoluted as MUMPS? Talk about scoring a point for the other team. :-)

  • (cs) in reply to Anonymous Coward

    Also, because it bears saying:

    Anonymous Coward:
    it's like human languages. If you know 24 different words for snow, then you naturally pay more attention to snow because you have more ways to classify and decipher it
    Beware of referencing things you think you know without checking them first. Not to mention that not only have you inferred causation from correlation where not even correlation exists, you've done so backwards.
  • Zygo (unregistered) in reply to craaazy
    craaazy:
    Top Cod3r:
    First of all, for all you newbies out there, you want to store your code in a global array for performance optimization purposes. You see global arrays get optimized by the compiler making them as much as twice as fast as normal arrays.

    The only WTF about this is why you guys all think this is a WTF. Maybe you just dont understand MUMPS.

    You're joking right? I mean, why on earth doesn't the compiler optimize anything well but the stuff in a global array? These days, it's the compiler's job to figure out which pieces of code get called most often, and to try harder to optimize those pieces of code. Surely the MUMPS compilers could be upgraded to handle this better?

    Your entire rant is predicated on one huge assumption--that most MUMPS code is compiled, and most MUMPS code maintenance involves writing new code in some other language.

    To the second point, there are very few successes among those who try to rewrite an existing system with a new language that compiles to the old one. Even fewer that involve interoperation between a dozen vendors. There would have to be massive external pressures against development on the old system while at the same time massive value in maintaining the old system intact. That set of circumstances is rare.

    To the first point, everything I've read so far suggests that MUMPS is normally not compiled, not even to the extent that Perl code is compiled to bytecode immediately before execution. Some implementations don't even do that. It seems that MUMPS has some level of bytecode compilation but only under certain circumstances where the cost of compilation is expected to be recovered by savings during execution.

    So there's no precompilation step, and no way to avoid having to directly understand machine-generated 1970's MUMPS code if you are maintaining this crap.

    CAPTCHA: craaazy

  • Tim (unregistered)

    I have to say that while reading this post was a little depressing, reading the comments cheered me considerably.

    The MUMPS description in the original post did not strike me as particularly WTFable, and in fact reminded me a lot of Level II BASIC -- which, while not an enterprise programming language by any means, was also not WTF-class.

    Much of the shock and horror on this issue seems like terror at things that are different. I got news for you, guys -- not every language is procedural and not every database is relational. Alex, I recommend getting some screeners who are older than 22. :-)

  • Zygo (unregistered) in reply to earl
    earl:
    I also worked there. Call it Ep*c Syst**s.

    So, yeah. All storage are in a giant automatically sparse global arrayo. So what you do is you have ^data[ attribute one, , , attribute four] = x

    where you aren't specifying attributes 2-3. The whole scheme works like this, so it's very hard to convert to SQL. That would be, for example, a way of storing data about someone if attribute one were SSN, etc.

    What? That's trivial to convert to SQL:

      update data set val = x where a1 = one and a4 = four
                              and a2 is null and a3 is null;
    

    or

      insert into data (val, a1, a4) values (x, one, four);
    

    depending on the result of

      select val from data where a1 = one and a4 = four
                           and a2 is null and a3 is null;
    

    Most SQL implementations provide a way to merge the update and insert into a single operation.

    Leave out the "and a2 is null and a3 is null" if not specifying an attribute means some datum is found with arbitrary values for those attributes.

    To get the semantics right you'd probably have to automatically create tables or add columns to existing tables (e.g. what happens when someone assigns to ^data[one, two, three, four, five]?). Or use a schema that we've seen many times on tdwtf:

        update global_vars set val = x where array_name = 'data'
                       and a1 = one and a4 = four;
    

    where all data is stored in the "global_vars" table which has as many columns named a0..aN as the implementation allows.

    The SQL would never make any sense to human eyes (all tables would have a text column named var, and N text columns named a1, a2, a3...aN, no constraints, probably a lot of application code for handling transaction semantics since the RDBMS's transaction logic is not used, etc) and performance would utterly suck; however, translation seems to me to be not only possible but simple.

  • (cs) in reply to EvanED
    Some of those language features sound like REXX, one of my favorite work experiences and one of the most readable languages. It's inspired by PL1, ANSI standard, still on all IBM OSs and most others, small but loyal user base.

    I've only used REXX a little bit (on IBM's CMS), but the PARSE keyword is damn sweet. Only other thing that I've seen with similar uses are regexs with backreferences, but PARSE doesn't require you to learn a new language to use.

    REXX on CMS is heaven! The most hacker-friendly OS I ever used. I tried to duplicate parse in Java ... the parsing pattern was in an array of strings. It didn't come out that well. Maybe I should try again with VarArgs. The EASEL language (now ESL corp) has "skip" and "take" commands that are almost as good as parse.

  • Watson (unregistered) in reply to asuffield
    asuffield:
    Much of this stuff is not new (sadly). And I say that in the full knowledge that MUMPS is from the 1970s.

    I was just thinking how all those features made it sound like the illegitimate offspring of PHP and PickBASIC.

    I almost ended up in a PickBASIC shop. But if I was lucky down the road I might have got some of the Visual Basic jobs, too. Mmmm....

  • Foobar (unregistered) in reply to gwenhwyfaer
    gwenhwyfaer:
    Beware of referencing things you think you know without checking them first. Not to mention that not only have you inferred causation from correlation where not even correlation exists, you've done so backwards.

    Beware of tedious nerds who apparently spend the entire day reading the comments to this WTF and angrily responding with great brilliance and /delicious/ witicism. Are you sure you're not Larry Groznic?

  • (cs) in reply to Flo
    Flo:
    Appendix 7: An example of "traditional" M coding style
    

    %DTC %DTC ; SF/XAK - DATE/TIME OPERATIONS ;1/16/92 11:36 AM ;;19.0;VA FileMan;;Jul 14, 1992 D I 'X1!'X2 S X="" Q S X=X1 D H S X1=%H,X=X2,X2=%Y+1 D H S X=X1-%H,%Y=%Y+1&X2 K %H,X1,X2 Q ; C S X=X1 Q:'X D H S %H=%H+X2 D YMD S:$P(X1,".",2) X=X_"."$P(X1,".",2) K X1,X2 Q S S %=%#60/100+(%#3600\60)/100+(%\3600)/100 Q ; H I X<1410000 S %H=0,%Y=-1 Q S %Y=$E(X,1,3),%M=$E(X,4,5),%D=$E(X,6,7) S %T=$E(X_0,9,10)*60+$E(X"000",11,12)60+$E(X_"00000",13,14) TOH S %H=%M>2&'(%Y#4)+$P("^31^59^90^120^151^181^212^243^273^304^334","^",%M)+%D S %='%M!'%D,%Y=%Y-141,%H=%H+(%Y365)+(%Y\4)-(%Y>59)+%,%Y=$S(%:- 1,1:%H+4#7) K %M,%D,% Q ;

    [...]

    Can i have the private key, so i can decrypt this chunk to see the real message. Thanks.

  • Zygo (unregistered) in reply to its me
    its me:
    Xecute code stored in a variable? Uh, even early BASIC could do this. Today it's called a function pointer or a delegate....

    Ummm, I don't think you (and quite a few other people today) understand. Function pointers look like this:

      // A function
      void foo() { printf("Hello, World!\n"); }
    
      // A function pointer variable
      void (*fooP)();
    
      // Assigning the function to the function pointer
      fooP = &foo;     // your syntax may vary
    
      // Invoke a function through the pointer
      (*fooP)();         // prints "Hello, World!"
    

    Xecute isn't about function pointers. Function pointers require you to have a compiled function somewhere to point to. Xecute is about function bodies:

      // Compile this string as C source code inside 
      // an anonymous function body, then execute it.
      xecute("printf(\"Hello, World!\\n\");");
    

    and in languages which have this kind of capability it tends to be used like this sooner or later:

      // Here's a string:
      char buf[1024];
    
      // Cut+Paste user input directly into some C code
      // as strings:
      sprintf(buf, "var[%s] = %s + %s;", argv[1], argv[2], argv[3]);
    
      // Compile and execute
      xecute(buf);
    

    Now if the user typed in "0", "2", and "3", then this compiles and executes:

    var[0] = 2 + 3;

    but if the user typed in

    0] = 1; system("c:/malware.exe"); var[0
    

    as the first variable then the results are a lot more interesting:

    var[0] = 1; system("c:/malware.exe"); var[0] = 2 + 3;

  • opie (unregistered)

    It's ironic that someone mentioned the VA system...

    Check this out: http://www.tgdaily.com/2007/02/13/va_laptop_lost_18million/

    Yet ANOTHER one. There's no way these are all accidental.

  • (cs) in reply to Remco G
    Remco G:
    See its Wikipedia page: http://en.wikipedia.org/wiki/MUMPS.

    Looks like the article wasn't exaggerated one bit. That Wikipedia article is full of wondrous WTFs by itself.

    Here's a good reason for keeping your money under your mattress: "MUMPS also gained an early following in the financial sector, and MUMPS applications are still in use at many banks and credit unions."

  • kavyboy (unregistered)

    MUMPS is an abomination. I work with it daily, and there is possibly no worse computer language that has even been developed. Unmaintainable isn't even the word for it. My god, it's just... my god! I can post some real samples if anyone is interested. I seriously hurts to look at it, though. Goto branches named "4", and the like.

    Beyond syntax you get into the fun stuff: S X="10D2"+1 S Y="10E3"+1 S Z="10F4"+1 This sets X and Z to 11, but Y to 1001. Obviously.

    Or how about the fact that there is NO standardization for input/output? The common solution is to put implementation-specific code into variables (agreed upon by convention only) then execute the variables to perform simple I/O. Yes, execute the variables.

    Oh, you can only have one I/O device open at a time. You have to switch between them with the "U" command. The current device in use is specified by the $IO variable, of course.

    And on and on it goes.

  • Watson (unregistered)

    Meh, the offspring of an illegitimate orgy. The only language I haven't seen it compared to yet is FoxPro.

    I've realised something that's been bothering me:

    Because their MUMPS system was so ridiculously slow, it would often take minutes for a simple operation to complete. Reports would take hours.
    If using MUMPS was feasible forty years ago, what has happened to computing power since? Doesn't Moore's Law apply to it for some reason?

    CAPTCHA: tastey. "Like maybe what I think MUMPS coding's like was really coding like chicken."

  • TheQuux (unregistered) in reply to Anonymous Coward
    Anonymous Coward:
    I always felt sorry for the AS/400 (sorry I meant iseries, no wait I meant system i....) folks that only knew RPG. How useful is RPG in an era of Unix/Linux/Windows?

    This MUMPS monstrosity puts RPG in perspective for sure.

    Last time I checked (last weekend), it was the "I series". Of course, that same IBM sales(err)person tried to sell me a Z series. (note: I'm a poor, starving college student...)

  • Dave Ross (unregistered)
    I was just thinking how all those features made it sound like the illegitimate offspring of PHP and PickBASIC.

    I was thinking the same thing...shiver

    I have a similar story to the OP, having gotten my first programming job before I even finished my Associate's Degree. It was on Unidata, a Pick derivative. Then, from there, a Pick D3 shop. From there...well, until I got my Java certification nobody would talk to me about anything but Pick.

  • bucky (unregistered)

    I'm a former Epic employee of around four years and this article is definitely about Epic. My role was not a true developer... more of a programmer / analyst where the coding needs were smaller projects in MUMPS (Technical Services).

    Personally, I didn't mind working in MUMPS or with the custom functions written to maintain Epic's data structure, think Epic treats its employees well, and disagree with some of the article's comments, but don't feel like going into that.

    What I do agree with is that the knowledge learned in such a role at Epic is a very specific skill set making Epic's customers or consulting firms likely employers of Epic folks (if they want to stay in health care after Epic). Epic makes it very difficult for employees to leave since employment agreements now typically state that the employee cannot work for customers until a year or so has passed since they left Epic. For employees that started before such a clause was added, customers also sign an agreement saying they will not hire ex-Epic folks for a certain amount of time.

    That may be off topic a bit, but felt it was an important "warning" despite what one may feel about MUMPS itself.

  • Zygo (unregistered) in reply to dkf
    dkf:
    Zygo:
    There is also no GOTO in Tcl, or at least it doesn't come with one (anything's possible if you start mucking with the language at runtime).
    I advise regarding GOTO as impossible in Tcl. The amount of work required to make even a simple C-like GOTO is quite enormous; it's far easier to handle exceptions, build state machines or drive automated resource deallocation by other means.

    Don't say things like that, someone might hear you and implement GOTO in Tcl...

    I wouldn't say GOTO is impossible in Tcl at all. Consider:

    
    # A label to go to
    begin_program:
    
    while {1} {
      # go up two blocks and forward
      if {[foo]} { goto block_exit }
    
      # go up two blocks and backward
      if {[bar]} { goto begin_program }
    
      # A label we can't actually get to from outside here
      forbidden_label:
      puts "in the while loop"
    }
    
    # We can't get here either
    puts "normal exit from while, should never happen"
    
    # Forward jump in this block
    goto end_program
    
    # A label we jump to from within while
    block_exit:
    
    puts "block_exit label, only if foo"
    exit 0
    
    # The forward jump ends here
    end_program:
    puts "end of the program"
    
    # Go backwards within this block
    goto begin_program
    
    

    It would be possible to jump out of while loops, procedures, etc. (e.g. block_exit) by implementing a new return code (like continue or break, but this one says "goto" and provides the label name in interp->result). A similar effect can be achieved by replacing the error, return, and catch commands with procedures. Once the call stack unwinds to a block (which is really just a text string) where that label is defined, the Tcl interpreter then starts executing from immediately after the label.

    It would be possible to jump around within a single block (e.g. begin_program, end_program) by modifying Tcl_Eval to understand the syntax (or replacing it with one that does). Since our goto command would be a procedure with a special return value (just like the break and continue Tcl commands are), this case is actually identical to the previous one (special return value with a label name).

    To do this within Tcl (i.e. without modifying Tcl) you'd have to replace just about every procedure that takes Tcl code as an argument (ironically including the proc procedure, which defines procedures) as well as uplevel, upvar, trace, etc. A pure Tcl implementation unfortunately won't handle cases like:

    set x [
      foo;
      bar: quux;
      if {[qux]} {goto bar} else {return 3}
    ]
    

    Fortunately within Tcl you can dynamically link in libraries to replace the built-in C functions.

    It would not be possible to jump into a block (e.g. jump to forbidden_label from outside the while loop) since the block's execution context doesn't exist and can't be created without first executing all the code leading up to the block containing the label...and even then this assumes you can predict which blocks are code and which are just data. Often you can't do this in C or C++ either (IIRC C++ explicitly forbids it, sometimes you can do it in C with a permissive compiler but the results are undefined) so even though this doesn't work it's still C-like.

  • Zygo (unregistered) in reply to dkf
    dkf:
    Zygo:
    There is also no GOTO in Tcl, or at least it doesn't come with one (anything's possible if you start mucking with the language at runtime).
    I advise regarding GOTO as impossible in Tcl. The amount of work required to make even a simple C-like GOTO is quite enormous; it's far easier to handle exceptions, build state machines or drive automated resource deallocation by other means.

    Don't say things like that, someone might hear you and implement GOTO in Tcl...

    I wouldn't say GOTO is impossible in Tcl at all. Consider:

    
    # A label to go to
    begin_program:
    
    while {1} {
      # go up two blocks and forward
      if {[foo]} { goto block_exit }
    
      # go up two blocks and backward
      if {[bar]} { goto begin_program }
    
      # A label we can't actually get to from outside here
      forbidden_label:
      puts "in the while loop"
    }
    
    # We can't get here either
    puts "normal exit from while, should never happen"
    
    # Forward jump in this block
    goto end_program
    
    # A label we jump to from within while
    block_exit:
    
    puts "block_exit label, only if foo"
    exit 0
    
    # The forward jump ends here
    end_program:
    puts "end of the program"
    
    # Go backwards within this block
    goto begin_program
    
    

    It would be possible to jump out of while loops, procedures, etc. (e.g. block_exit) by implementing a new return code (like continue or break, but this one says "goto" and provides the label name in interp->result). A similar effect can be achieved by replacing the error, return, and catch commands with procedures. Once the call stack unwinds to a block (which is really just a text string) where that label is defined, the Tcl interpreter then starts executing from immediately after the label.

    It would be possible to jump around within a single block (e.g. begin_program, end_program) by modifying Tcl_Eval to understand the syntax (or replacing it with one that does). Since our goto command would be a procedure with a special return value (just like the break and continue Tcl commands are), this case is actually identical to the previous one (special return value with a label name).

    To do this within Tcl (i.e. without modifying Tcl) you'd have to replace just about every procedure that takes Tcl code as an argument (ironically including the proc procedure, which defines procedures) as well as uplevel, upvar, trace, etc. A pure Tcl implementation unfortunately won't handle cases like:

    set x [
      foo;
      bar: quux;
      if {[qux]} {goto bar} else {return 3}
    ]
    

    Fortunately within Tcl you can dynamically link in libraries to replace the built-in C functions.

    It would not be possible to jump into a block (e.g. jump to forbidden_label from outside the while loop) since the block's execution context doesn't exist and can't be created without first executing all the code leading up to the block containing the label...and even then this assumes you can predict which blocks are code and which are just data. Often you can't do this in C or C++ either (IIRC C++ explicitly forbids it if there are local variables in the block, sometimes you can do it in C with a permissive compiler but the results are undefined) so even though this doesn't work it's still C-like.

Leave a comment on “A Case of the MUMPS”

Log In or post as a guest

Replying to comment #:

« Return to Article