Andrew's Programming Language
From Esolang
Andrew's Programming Language , or APL, until I come up with a better name (please help!), is the name of an idea for a functional, turing-complete programming language designed by User:Afarnen in 2008. The language, as well as the name, is a work-in-progress.
[edit] Intro
Everything in APL is either a command, keyword, operator, number, variable, or function. Commands start each line of code in an APL program. At this point, "let" is the only command. Now let's create a function:
double(x): 2*x
The parenthesis are where a function's arguments go. In this example, "x" is the only argument. The "*" operator multiplies the values to its immediate left and right by eachother. In this case, these arguments are "2" and "x". So, this function returns two multiplied by its argument, hence the name "double".
Let's now create a variable:
let n = 1 or 2
The "let" command tells us that we're creating a variable. Now, you may think that "or" is an operator that performs on the values "1" and "2". If so, you'd probably expect that it returns the value of "1", since "or" is usually a binary operator. However, when the word "or" is written out in APL, it's actually a keyword. In this example, we're saying that the variable "n" is either equal to 1 or 2, but not both. Now what would happen if we wrote this expression:
double(n)
What would that expression evaluate to? Well, let's go step by step. First, we'd replace "n" with the actual known value of "n":
double(1 or 2)
This is as far as we can evaluate the expression in parenthesis. After all, "or" is a keyword, not an operator. So, since that's as far as we can go, we simply plug what's in parenthesis with "x" in the function declaration. So we evaluate to:
2*(1 or 2)
Now how do we go from here? Simple:
2 or 4
That's how keywords work in APL. They're never evaluated, unlike everything else. Now let's look at some other examples.
let a > 5 let b < -5 let c = a and b
Now, since AFPL is a functional language, it doesn't matter what order we put our function and variable declarations in. The following does the same thing as above:
let c = a and b let b < -5 let a > 5
Now, as you can see, we've introduced three new keywords: ">", "<", and "and". The line "let a > 5" simply means what it says: let the variable "a" be greater than 5. This means that a is equal to all values greater than 5. Similarly, "let b < -5" means let "b" be equal to all numbers less than -5. What would happen if we did this:
double(a)
Well, when we write "double(a)", that evaluates to "double(> 5)". And "2*(> 5)" returns:
> 10
Now, in the last example, we declared "c" as "c = a and b". How does that work?
let c = > 5 and < -5
That's how. Whenever we see "and", we know that it's equal to both the left and the right. So, what that means is that "c" is equal to all numbers greater than 5, and less than -5. If we declared "c" as "let c = a or b", we'd similarly have:
let c = > 5 or < -5
This is read as "c is equal to all values greater than 5 and less than -5".
Other similar keywords:
keyword meaning >= greater than or equal to <= less than or equal to
Now, let's delve a bit more into functions:
[edit] Functions
Suppose we had this function:
multiply(x, y): x*y
In the parenthesis, we have "x" and "y", separated by commas. The comma keyword just separates variable names in function declarations. So if we wrote this:
multiply(2, 3)
That would evaluate to 6, since the function just multiplies its two arguments by eachother. You might as well have written just "2*3", if you wanted to multiply two numbers.
Now, suppose we wanted a function to do different things, depending on the value of the argument(s). Let's make a function that returns "-1" if the argument is negative, "1" if it's positive, and "0" if neutral. How would one go about creating this functions? Well, let me show you:
isposneg(x < 0): -1 isposneg(x = 0): 0 isposneg(x > 0): 1
It's that simple. You could read the "x < 0" in the parenthesis as "if x is less than 0". So, if we gave the function the argument "3", we'd expect it to return "1".
Note: since we never use "x" within the function declarations, we could have just written:
isposneg(< 0): -1 isposneg(= 0): 0 isposneg(> 0): 1
Now, we can also mix that idea of having multiple cases, and the idea of having multiple arguments. How? Let's look at a function called the Ackermann function that I thought provides a good example:
acker(= 0, n): n+1 acker(m > 0, = 0): acker(m-1, 1) acker(m > 0, n > 0): a(m-1, acker(m, n-1))
Now, one thing to keep in mind is that the names of the arguments aren't important. If you notice, we didn't even bother naming some of the arguments in the above example. What's important is the just the order of the arguments (first, second, etc.)

