-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Malang is an esoteric programming language that gets compiled down to, get ready for this, a single mathematical operation. No machine code, no assembly, no byte code, no nothing. Just a single mathematical operation.
That is; any program that you write in the language, becomes a mathematical operation that, when computed / evaluated, gives the expected result of the program.
Wild stuff, huh?
Furthermore, that operation will only be composed of / contain basic algebraic operations*, which are: +
addition, -
subtraction, *
multiplication, /
division, ^
exponentiation, and //
euclidean division, a.k.a. integer division.
*
Technically, integer division,//
, is not part of the basic algebraic operations. But never the less, it's a basic operation.
What is that suppose to mean? Or how does that even work? Let's see some examples to actually understand. I will be showing you how a concept would be implemented using Python, and its equivalent compiled Malang code, which would be an operation (I will not show any actual Malang code, yet, just the operation that the code would get compiled to):
1. Adding two numbers:
In Python, you can do that like so:
def add(a, b):
return a + b
And its equivalent, as a mathematical operation, would be the same thing:
Whatever result the add
function would return, the operation a + b
would return. Because it's the same thing, duh. Nothing special / interesting so far..
2. Logical operator and:
In Python:
def logical_and(bool_1, bool_2):
return bool_1 and bool_2
Very simple.
Now, since there is no logical values in math, we will instead use their numerical representations, 1
being True
and 0
being False
.
An equivalent of the logical operator and
is:
This simple multiplication operation behaves the same way the logical operator and
does. Because if either boolean values is 0
(which is False
), then the result would be 0
(False
). And the only time the result would be 1
(True
), is if both boolean values are also equal to 1
.
bool_1 | bool_2 | bool_1 * bool_2 | bool_1 and bool_2 | result |
---|---|---|---|---|
0 / False | 0 / False | 0 * 0 | False and False | 0 / False |
0 / False | 1 / True | 0 * 1 | False and True | 0 / False |
1 / True | 0 / False | 1 * 0 | True and False | 0 / False |
1 / True | 1 / True | 1 * 1 | True and True | 1 / True |
3. Logical operator not:
Again, in Python it's pretty straight forward:
def logical_not(bool):
return not bool
As mentioned previously, we will be using the numerical representation of the logical values, and so, an equivalent of the logical operator not
as a mathematical operation would be:
Once again, this operation (which is composed of two operations; -
subtraction, and /
devision) when evaluated with any logical value would give the same result that the logical operator not
would.
If bool
is True
, then
simply equals 0
, which is False
, it negated it.
If bool
is False
, then
equals 1
, which is True
, it also negated it.
Logical not
using math, Ladies and Gentlemen.
Okay, but how far can you push it?
Quite far.. Kinda..
4. Checking if a number is zero:
Now, IMHO, it gets a bit more interesting..
In Python:
def equal_zero(x):
return x == 0
And an operation that would preform the same thing is:
This operation, believe it or not, would evaluate to 0
(False
) for any value of x
that is different than zero. And at zero it is equal to 1
(True
).
But what is actually happening in that operation? Let's decompose it. First of all, we have this part:
All what it does is, it squares the value of x
, and then takes its square root, a.k.a the absolute value of x
. So let's replace it with |x|
so that it's clearer.
Then we have this part:
This is the main part of the whole operation. It is simply a fraction, where the numerator is the absolute value of x
, and the denominator is the absolute value of x
plus one. So, it's a fraction that is always less than 1
, because the numerator is always less than the denominator. More over it is only equal to zero when x
is zero.
Now, if we were to subtract that fraction from 1
, like so:
it would basically flip it over the y
axis, and shift it up by 1
. So, now it is always greater than zero, and it is only equal to one when x
is zero.
We are half way there to our goal. We only need a floor
function or something similar to "flatten" the parts where it's between 1
and 0
down to zero. That floor
function is the integer division, // 1
, part at the end of the operation.
And that's that! That simple function, more or less, allows us to check if a number is equal to zero. Here is a desmos link if you want to visualize the operation / function.
Now since we have a way to check if a number is equal to zero, we can use that function to build another function that check if any two numbers are equal to each other. I'll let you figure out how that could be done, it's pretty simple.
5. If statements:
Last example! If statements, or at least a less powerful version..
In Python, one could write:
if condition:
return a
else:
return b
In Malang, the operation that would preform that is:
A very simple operation. If condition
is 1
(True
), then the operation would be:
which is equal to a
.
Otherwise, if condition
is 0
(False
), then the operation would be:
which is equal to b
.
A key thing however, is that in Malang, there is no actual code branching. There is no "execute this section of code if the condition is true, otherwise execute this other section of code". Instead, only a single value is "returned", and both "branches" of the code are always "executed". Because it's an operation that is getting evaluated, not a program that is getting executed.
So far, we haven't seen any actual code, just whatever the code would get compiled to. So, how does the code actually look like? And how does it get compiled? Let's see!
Note
I write compiled as such (in italic), because it's not really compiled, it's more of a transpilation / interpretation / evaluation, but I will be using the word compiled for simplicity.# Let's start simple, and simply create a variable and then return it
foo = 4 + 5
ret foo
The syntax, as you will see as we see more examples, is quite simple and is a bit similar to Python's syntax.
If we compile that bit of code, the operation that we would get, which would then be evaluated, is:
Pretty straight forward.. You are returning the variable foo
, and foo
is equal to what ever the result of 4 + 5
is.
Let's see another example:
# Let's create a variable
foo = 42
# Let's multiply it by 2
foo = foo * 2
# Let's create another variable
bar = foo + 3
# And let's return their difference
ret bar - foo
If you were to compile the above code, it would turn into this:
The way it works, is that, the state of each variable, either its value or whatever combination of operations that constitutes it, is kept track of. And whenever an operation is preformed on two variables, what actually happens is, is that that operation gets preformed on whatever the current state of those two variables is. In the above code for example, we return bar - foo
and in the compiled operation you can see that the top level operation
is just that, -
subtraction. And what is getting subtracted is foo
from bar
, and indeed on the right hand side of the operation we have (42 * 2)
, which is the state of foo
at that line. And on the left hand side of the operation we have ((42 * 2) + 3)
, which is the state of bar
at that line too. And you can see that bar
is made up from foo
, that is because we assigned to bar
the value foo + 3
.
And that's how the language works, the state of whatever is returned at the end is the single mathematical operation that encompasses within it the whole program.
And since the "machine code" of Malang only consists of mathematical operations, here is the file that contains the mathematical operations as op_codes if you want to check it out, the language alone is very basic and simple, and doesn't provide much on its own. It is the libraries that come with it, which are, of course, also written in Malang, that make it more interesting. These libraries contain functions like the ones we saw (logical operators, checking if a number is zero, and many others..) that the user can include in their code to be able to actually do something interesting .
PS: there is even a string library.
The malang.py file takes care of everything.
You can do:
$ python3 malang.py -h
to see all the possible features, and so I will not go into details here, but to run a file you could do:
$ python3 malang.py name_of_file_to_run
Some examples are available here, and you can run them like so:
$ python3 malang.py -i examples/fizzBuzz 15
If you want to know how the above code works, you can read more about it in the section about the string library.
Goto
next page.