• Bittle Tobby Lables (unregistered)
    const FRIST = 0;
    
  • Michael (unregistered)

    const SECOND = FRIST;

  • Tim Ward (unregistered)

    Which stories always remind me of the IBM 360 assembler code bug that took a lot of finding. Conventionally, registers were given names, so

    .... R3 EQU 3 R4 EQU 4 R5 EQU 5 ....

    So when you saw some code like

    MOV R4,...
    

    you'd expect that instruction to move something into register 4, yes?

    Not if what was actually buried somewhere in the hundreds of preceding lines was

    R4 EQU 3

    though.

  • RLB (unregistered)

    We don't even need the comments, if the variables are sensibly named. If...

  • Chris (unregistered)

    I feel like maybe this was some form of malicious compliance to some inane code standards that were in place at the time, trying to prove how stupid they were.

  • (nodebb)

    What's worse: if the snipper is really form a model JS/TS, the second snipped can be done without any numbers at all:

    const [customerId, customerName] = custRec;

    Addendum 2022-08-23 07:36: typo fix: s/snippe[rd]/snippet/g

  • Daniele (unregistered)

    Now I want the compilers to have a feature that translate automatically letter-written numbers into numerical, so everytime I write SIXTYFIVETHOUSANDFIVEHUNDREDANDTHIRTYFIVE it becames automagically 65535. It shall also work with ZEROICSEFEFEFEF

  • (nodebb)

    Reminds me of INTERCAL's rule that you must have enough statements marked PLEASE but not too many.

  • scott2718281828 (unregistered) in reply to Tim Ward

    Back in the stone age, doing assembly on a DEC PDP-8 with 12-bit words, saw a physics phD going bonkers looking at a code printout. There was a label on an instruction, but he couldn't find a jump instruction anywhere that went there. And it was in the middle of a routine, it made no sense to jump to that location.

    I found the reference for him. Instead of defining a constant and wasting a word of memory to store it, the author found an instruction that would assemble as the desired value, put a label on it, and where needed referenced the label in a register load operation.

  • Conradus (unregistered) in reply to scott2718281828

    Well, when you have only 4k words of memory, you can start to regard such tricks as reasonable.

  • HG (unregistered)

    Hah, that's nothing! I once had to work on some code where a single header file defined roughly 27 "numeric word" constants to be the corresponding numeric values. They were all correct, but they ran from ZERO and ONE up to something like THIRTY_FIVE (so, not all values covered) and were not declared in numeric order (but ... nearly), and had some completely unrelated "#define"s in between.

  • Argle (unregistered)

    I think I've mentioned this before, but I did encounter a legit, well-reviewed use for this back when I started programming. I worked on a fuel saving's system for the 727 for Lear Siegler back in the late 70s. The CPU was the TMS9900 (same one in the TI 99/4A, the only 16-bit "home computer" the time). Memory was tight back then. I don't recall the size, but it was probably 16K of RAM. Programming was done in ForTran IV. Parameters to functions were ALWAYS by reference. Thus, if you did "FOO(1)" then space was set aside for an unnamed integer containing the value 1 and a reference to that was passed. If you do this in enough locations, you wind up with a lot of unnamed variables with the value 1 in them. This eventually had an impact. Create a global value called ONE (and ZERO, TWO, etc.) and use it everywhere you would use 1 and you get back an appreciable amount of memory in a memory tight system.

    Today this is unnecessary and stupid. But there was a day... sigh I'm feeling old today.

  • Yet Another Old Programmer (unregistered)

    A story I heard in school, about a project on a CDC 7600:

    The initial design called for all-caps data, so they stored 10 6-bit characters in each 60-bit memory word. Things were going well until the requirements changed, and they decided they needed lower case and special characters, so they switched to a 12-bit character set.

    ... and the program started doing all its math in base 5.

    Some frugal programmer had re-used CHARACTERSPERWORD as the base for math conversions.

  • a cow (not a robot) (unregistered)

    Still today, the ANSYS APDL "programming language" (actually: macros) doesn't allow a constant condition for a *DOWHILE cycle. So, very sadly, the "best" way I found is:

    ONE=1 *DOWHILE,ONE [...] *ENDDO

    (of course there is a conditional exit from the cycle in the instructions inside)

  • a cow (not a robot) (unregistered)

    Sorry... the "code" was messed up (it's still understandable, I believe). How do you guys write code in those comments? Are there some instructions anywhere?

  • (nodebb) in reply to Argle

    IBM's mainframe Fortran compiler was notorious for doing constant folding in those cases, and would also fold in actual constants used in expressions, so all those literal 1s were, in fact, the same literal 1. And it was writable. Hilarity ensued.

  • (nodebb) in reply to a cow (not a robot)

    Sorry... the "code" was messed up (it's still understandable, I believe). How do you guys write code in those comments? Are there some instructions anywhere?

    Use backticks.

    So, if @ represents a backtick in the "howto" examples: @bool@ produces bool

    @@@ if ( x == 7 ) printf("x is seven\n"); @@@ produces

        if ( x == 7 )
            printf("x is seven\n");
    

    Addendum 2022-08-23 12:34: And of course the autoformatting (it's a bastardised Markdown) broke the "howto" guide for the second.

    @@@

    if ( x == 7 )
    
        printf("x is seven\n");
    

    @@@

    produces

    Just remove the extra blank lines

  • a cow (not a robot) (unregistered)

    Just trying... (I don't see any "preview" option)

    
    _ONE_=1
    *DOWHILE,_ONE_
    [...]
    *ENDDO
    
    
  • a cow (not a robot) (unregistered) in reply to Steve_The_Cynic

    Thank you very much!

    (Sorry for the late "tank you", but I have to click 256 traffic lights, 512 buses and 4096 whatever before being allowed to post another message...)

  • (nodebb) in reply to a cow (not a robot)

    Cool, no problem, glad to help.

  • Yikes (unregistered)

    This could be conveniently written code, if people often reassigned the names of numbers while reusing exactly the same names. So, I guess that means it's not very convenient.

  • Argle (unregistered) in reply to Steve_The_Cynic

    Of course!

    J = 2
    CALL EVIL(J)
    K = J + J
    

    What do you mean 2 + 2 = 6?

  • (nodebb)

    I was part of the eval team for REXX. One of the early ideas and releases allowed for tokens (variables) to be numeric. Hence a variable declaration "1=2" was valid and operable. That generated a LOT of discussion and the feature was quickly killed.

  • Yikes (unregistered) in reply to sdh

    My first thought is: there are only negatives. As soon as you use a number for a variable, you've now lost it as a number/index/...

    I've seen a lot of features/enhancements/customality that people decide to add in after naively considering only the positives, but that's definitely a top example.

  • (nodebb)

    A MVI (Move Instruction) opcode has the value X'40' on the IBM/360 and RCA Spectra. This is the value for a blank. In the code for the RCA Fortran compiler you might see something like *+123 where that was the location of an MVI. It was used to get a blank to fill a buffer. If code was added so that *+123 was no longer a blank one could get strange errors. That resulted in bug which was a challenge to find. The good old days of limited memory.

  • Erwin (unregistered) in reply to Argle
    Comment held for moderation.
  • FTB (unregistered)

    The comments on that code snippet also deserve a special mention:

    const customerId = custRec[ZERO]; //CUSTOMER_ID const customerName = custRec[ONE]; //CUSTOMER_NAME

    One comment per line, right?

  • Bittle Tobby Lables (unregistered) in reply to a cow (not a robot)

    Sounds like a specification for a starting grid of Conway's Life ...

  • Prophet (unregistered) in reply to Argle

    Happy memories of the ZX81 BASIC. Numbers were held as a (4?) byte float as well as the text of the number. Pi was a token of 1 byte. It was more memory efficient to code Pi/Pi than 1, Pi-Pi for 0.

  • (nodebb)

    Nah, it wasn't true art. True art would have been definitions like:

    ONE = 1 ZERO = (1-1) TWO = (1+1) THREE=(TWO+1)

  • Rob (unregistered) in reply to Tim Ward

    I don't remember a MOV in S/360 BAL, to load a register from a fullword you would use the L instruction, optionally referring to the register through an EQU symbol.

    More interesting was the MVC instruction, to move characters between storage locations. A novice might have tried, though, MVC R3,TEXT, which moved data into storage location 3 and not into the register. And let's not even cringe at the offset and length values that had to be specified in parentheses...

    EQU might have improved readability, but did not provide typing.

  • T. E. (unregistered) in reply to Argle

    @argle: sigh I'm feeling old today

    Me too. But I would put it, "Yes, my beard is a fine shade of white. Thankyouverymuch."

  • (nodebb) in reply to BatConley

    ITYM

    ONE = 1 ZERO = (ONE - ONE) TWO = (ONE + ONE) THREE = (TWO + ONE)

  • (nodebb) in reply to jkshapiro

    You're right.

  • Officer Johnny Holzkopf (unregistered) in reply to Daniele

    For the expected internationalization, it should also work for German, dreihundertelftausendsiebenhundertsechsundneunzig Komma fünf.

  • (nodebb)

    Wish I could say I've never seen this WTF in my career, but I have.

Leave a comment on “Constantly Magic”

Log In or post as a guest

Replying to comment #:

« Return to Article