Barthel's profile picture

Published by

published

Category: Web, HTML, Tech

INTERCAL DAY 2: we did something

Day 2:

So i was thinking, if this has to be a series, than it will have to end, and in order to end i must decide on a objective. Since i like cryptography the objective of all of this, is realizing a working vigenere encryption program in INTERCAL. (i'm already crying at the thought of this)


However we should start from basics:

Hello World!:

Every programmer knows that the first thing you learn everytime you take up a new language is: how to output "Hello Wordl!".

We do this because this should be a simple task, and it should help you understand the basic syntax of the language. So why shouldn't we start with that in INTERCAL  too? (we shouldn't, we should just go away and abandon programming forever).

What did we learn last time:

Last time we learnt that we can assign numbers, and print numbers, and that they will be printed as Ancient roman numbers!

What use we can make of that:

Nothing! I first thought we might use roman numbers as letters to write, but romans only used the following: I,V,X,L,C,M and so we can only use these letters using this "idea".

So i want to see what happends to the output when the number grows, will it be roman numbers up to 65535? so instead of writing 65535 lines of code to see that, we're gonna make a program that does that automatically!!


First checkpoint:

So this program will be a first checkpoint, the first working program we make, a very big milestone in our journey.

What will the program do:

The program will create a variable, set it to 1, print the value, increase the value, print again, until the value reaches 65535.

PLEASE DO NEXT is evil:

{this piece of my life is called: suffer}

In order to do this, we would need a while statement, something like

while(value<65535){

    output(value)

    value = value +1

}

However INTERCAL doesn't have "while", however what it does have is the command "DO NEXT".

Now i will do a little historical digression:

GOTO: a legacy of the past

A lot of years ago, programmers used a command called "GOTO", what this command does is redirecting the program's flow to a specific line. For example

1| print(1)

2| goto 4

3| print(2)

4| end program

In this pseudo-code, line 3 "print(2)" will not be executed, because the program jumps from line 2 to line 4, skipping line 3.

What's the use of this?

The use is you can call subroutines, you can do a while loop or a if statement by using the goto, or take exception and make the program take whatever path you want. Why does this command not exist anymore? (i think it does exist, we just don't use it anymore)

Well...because even though it was practical when writing code for the first time, on the long run, it ruins your code, it makes it a continuos jumping around and you just loose track of the logic of what's happening. When this happends, your code has officially became what is technically called "spaghetti code".

So this GOTO command is not used anymore, however since INTERCAL is old, it does use it, so we will deal with it.

The INTERCAL version of it is DO NEXT, and this is the manual section where the command is explained:


"The NEXT statement is used both for subroutine calls and for unconditional transfers. This statement takes

the form:

        DO (label) NEXT

 where (label) represents any logical line label which appears in the program. The effect of such a

statement is to transfer control to the statement specified, and to store in a push down list (which is initiallyempty) the location from which the transfer takes place."


[Note: regarding the push down list, it is a record of our "entry points", the only thing we have to care about for now is that its max size is 79, so we must clear it with the FORGET command, otherwise our programm will "“DISAPPEAR INTO THE BLACK LAGOON.”]


The "sum" operation:

So this one was pretty simple, but i am an idiot apparently, since i DID read this part of the manual, but for some reason, just skipped 1 line of the explanation and didn't understand nothing.

Now that i have read it again, basically the thing is simple:
There is no "sum" operator, we have two options:

1) Use INTERCAL basic operators to create our own subroutine that does the sum and then use it

2) Use INTERCAL library trough the use of command DO NEXT at the entry point (1000)

The first options scares me at night, when i sleep, i do dream about it and wake up crying, so i decided we are gonna go with standard intercal library for now.

So to do the sum we need 2 variables, .1 and .2, when we then do DO (1000) NEXT intercal will do .1 + .2 and put the result in the variable .3 and we can now take the result from there and use it where we want.

While loop:

So my first idea for this was this: find the "if" statement on the manual, and then use it combined with the DO NEXT command so that we can PLEASE READ OUT as long as .3 is < of a certain number.

However i did not find any "if" statement, what i did find was even WORSE. I'll just copy from the manual and you will understand why i decided that i needed a differen way to do this:


[NOTE: what is written inside [] is my personal comment, to make the text shorter]

"The [logical] operator is inserted between the spot, two-spot, mesh, or whathave-you, and the integer, thus: .&123, #V123." [no operator concatenation allowed]. "These operators perform their respective logical operations on all pairs of adjacent bits, the result from the first and last bits going into the first (most significant) bit of the result. The effect is that of rotating the operand one place to theright and ANDing, ORing, or XORing with its initial value. Thus, #&77 (#77 = binary 1001101) is binary0000000000000100 = 4, #V77 is binary 1000000001101111 = 32879, and #V-77 is binary 1000000001101011 = 32875."

Now...i do understand what the operators do...but i don't really understand how that should be a logic "and" or "or".

Workaround:

As always in programming, you need to find a workaround, and my workaround was to use the INTERCAL standard functions, the ones that by themselves use an "if" statement (somehow) and exploit them to verify my own thing. In particular i wanted to use this subroutine:

"(1009) .3 <- .1 plus .2

       .4 <- #1 if no overflow, else .4 <- #2"


By placing a DO NEXT statement at line 1 and 2, so that from the overflow (or not) of .3 i could end the while. So this was the implementation:


1 | DO (3) NEXT

2 | DO (7) NEXT

3 | DO .1 <- #1

4 | DO .2 <- #1

5 | PLEASE (1009) NEXT

6 | DO READ OUT .3

7 | DO (.4) NEXT

8 | DO NOT GIVE UP YET

9 | PLASE NOT NOT WORK

10| PLEASE GIVE UP


and today's output is:


ICL129I PROGRAM HAS GOTTEN LOST

ON THE WAY TO WHO KNOWS WHERE

        CORRECT SOURCE AND RESUBNIT

Now...After this, i was confused and very much tired, and many things i understand now (4 hours later) i didn't understand back then. So the error message "PROGRAM HAS GOTTEN LOST ON THE WAY TO WHO KNOWS WHERE" hunted me down for the past 4 hours, i did change a lot, even changed strategy but i didn't know that it was the syntax to be wrong, not the logic (also some of the logic).

Let's move on...

After that failed, my first analysis let me to think that the error was rising because i was calling PLEASE NEXT but without FORGETting the NEXTing list elements, and if you remember, we said above that they can only be 79, otherwise our program will get lost into the black lagoon.

So i did add the forget command, like this:


1 | DO (3) NEXT

2 | DO (8) NEXT

3 | DO .1 <- #1

4 | DO .2 <- #1

5 | PLEASE (1009) NEXT

6 | DO READ OUT .3

7 | PLEASE FORGET #80

8 | DO (.4) NEXT

9 | DO NOT GIVE UP YET

10| PLASE NOT NOT WORK

11| PLEASE GIVE UP


But the output...was still the same.

Change of strategy:

So after this big fail, i thought that maybe my logic was a bit to complicated, and i decided to dump the "if" check all together, and i embraced the much joyful and wild spirit of INTERCAL.

In fact what i did remember is that in The Manual at page 6 The Manual says:


"[...] The identifier is then

followed by either, neither, or both of the following optional parameters(qualifiers):

[...]

2. a number between 0 and 100, preceded by a double-oh-seven (%), which causes the statement to have only the specified percent chance of being executed each time it is encountered in the course of execution."

What it means is we can embrace the madness and instead of checking the condition, re-calling the DO NEXT randomly, without any control on it (we have never had control on it).

So the code now is this:

1 | DO .2 <- #1

2 | DO .1 <- #1

3 | DO (1000) NEXT

4 | PLEASE READ OUT .3

5 | DO FORGET #10

6 | DO %10 ABSTAIN FROM (7)

7 | DO (3) NEXT

8 | PLEASE GIVE UP


the output was 


  ICL139I I WASN'T PLANNING TO GO THERE ANYWAY

ON THE WAY TO 6

        CORRECT SOURCE AND RESUBNIT


Desperation and salvation:

Now this last output really made me feel defeated. Even madness didn't work against INTERCAL, now i truly understand why every code has to end with "PLEASE GIVE UP" , because that maybe is the only hope you have: to humbly plead to the compiler.

However, we're on a journey, so, i kept goint trough the manual, until i realized...there was one thing i was ignoring, one thing i read, i did'n KNOW but pretended like i'm the smartest human in the universe, and so my understanding was, obviously, correct...but maybe, was it not?

Well turns out no it was not, and i should have read much better the following line:

"...where (label) represents any logical line label which appears in the program...."

it is the LOGICAL label, not the actual number. And reading trough the section talking about labels it says:

"A statement may begin with a logical line label enclosed in wax-wane pairs (())."

And now everything was clear. what was wrong all along was the syntax of the command DO NEXT,

in fact i had to actually assign the labels before using them (it sounds like i'm stupid now that i say it clearly) like this:


1 | DO .2 <- #1

2 | DO .1 <- #1

3 | (3) DO (1000) NEXT

4 | PLEASE FORGET #1

5 | DO READ OUT .3

6 | DO .1 <- .3

7 | DO %30 ABSTAIN FROM (8)

8 | (8) DO (3) NEXT

9 | PLEASE GIVE UP


Now this program works!! Finally


the output varies a lot actually, i'll put three outputs of execution:


output 1:

II

III

IV


output 2:

II


output 3:

II

III

IV

V

VI

VII

VIII

IX

X

XI


Conclusion:

The day ended on a positive note, since we learnt a lot of things and we made a working program, but also, it was all useless work, because the answer to my question "is it just roman numbers or does it interpret ti differently at some point?" was answered already inside the manual...and no, it doesn't change, it's all just roman numbers.

Tomorrow i will try to figure out how to make INTERCAL output letters instead of (roman) numbers.


Goodnight, hope you enjoy reading about my sufference


2 Kudos

Comments

Displaying 1 of 1 comments ( View all | Add Comment )

deathletterz.c0m

deathletterz.c0m's profile picture

that manual part came in clutch for real intercal looks like pure madness but its also really interesting (i cant quite describe it but its...one of a kind i guess?) i cant even imagine how hard would it be to type anything in it


Report Comment



You could say it's one of a kind, in the sense that it is the first of the esoteric languages, also probably if you compare it to programming languages of the same age it would seem less weird. A lot of the difficulties seems to not come from the complexity of the language itself, but from old languages in general. Also it's frustrating for sure, but if you think i was able to make a working program in two days (of not so intense work), putting that in perspective, it's mostly a weird language more than a difficult language. I think other languages, "normal" ones, might be much more difficult, for example Assembly is very difficult, even though it's not an esoteric one. As the manual says, one should not start programming with INTERCAL, but if someone already grasps enough firmly the basics of programming, learning INTERCAL feels more like a game, a difficult game, but still just a game (wich probably was the primary intention of the creators). Thank you for reading btw

by Barthel; ; Report