xk0der logo Hey there, Welcome! :)

AFL - A Functional Language

Introduction

As the name implies AFL is a functional language. The goal of creating AFL was to create an easy to parse functional language and help me refurbish my PHP knowledge. :)

Use the table of contents below to find out what's available, how to use things, what can be done and what can't.

You may also want to try out AFL code snippets available from a drop down at this page AFL - A Functional Language

Inbuilt functions

AFL provides inbuilt functions to perform following operations:
  • Arithmetic operations

    Result of all arithmetic operations is either float or integer depending on the context.

  • Boolean operations

    In AFL boolean TRUE is represented by 1
    and boolean FALSE is represented by 0.
    All boolean functions return either TRUE or FALSE i.e 1 or 0.

  • Bitwise operations

    Bitwise functions allow you to manipulate individual bits in integer number.

Math Functions

+ VAR VAR

Sum of two numbers.

- VAR VAR

Subtraction of two numbers.

/ VAR VAR

Division of two number - result is float.

\ VAR VAR

Integer Division.

% VAR VAR

Modulus of two numbers.

* VAR VAR

Product of two numbers.

Examples:
/ 24 2
* 7 9
- 2 10
% 4 3
\ 10 3
Output:
12
63
-8
1
3

Boolean Functions

&& VAR VAR

Boolean AND

|| VAR VAR

Boolean OR.

^ VAR VAR

Exclusive OR.

! VAR

Boolean NOT.

Examples:
&& 1 0
|| 1 0
^ 1 1
! 0
Output:
0
1
0
1

Bitwise Functions

& VAR VAR

Bitwise AND.

| VAR VAR

Bitwise OR.

~ VAR

Complement.

<< VAR VAR

Left shift

>> VAR VAR
Right shift

Examples:
& 4 3
| 4 3
~ 4
<< 4 1
>> 4 1
Output:
0
7
-5
8
2

Comparison Functions

< VAR VAR

Less than.

> VAR VAR

Greater than.

<= VAR VAR

Less than OR equal to.

>= VAR VAR

Greater than OR equal to.

== VAR VAR

Equal to.

!= VAR VAR

Not equal to.

Examples:
< 4 9
> 4 9
<= 4 9
>= 4 9
== 4 9
!= 4 9
Output:
1
0
1
0
0
1

User defined functions

Defining/creating functions
You can define functions by using the following syntax.

f argument(s) = expression

Where 'f' is the name of the function followed by space separated list of arguments the function accepts. A function may accept ZERO or more arguments.

Types of arguments : There are three type of arguments in AFL

  • Variables: Variables are values that my change. Specified using a name.
  • Literals:Numbers i.e. numeric literals can be used as argument place holder. Look at simulating IF condition below for an example.
  • Lists:To specify that a particular variable argument is a list prefix it with '@' symbol

Passing functions as arguments : You may even pass functions as arguments. (Think of it like passing a function pointer in C, or a function referance in other languages.) See the 'map' function below for an example how it is done.

Examples:
i = 10
f n = + n 1
sum a b = + a b
map i f @list = f i @list
pi = / 22 7
g a b c = + (* a c) (* b c)
        

Calling/using functions
To call a function type it's name followed by values for the arguments. Another definite way to call a function is by enclosing the function name and arguments within parentheses '( )'.

Examples:
i
f 10
sum 2 3
map 5 sum [1,2,3]
(pi)
g (i) 7 8
        

In the above examples parentheses around 'pi' are optional. But while calling function 'g' with 'i' as one of the argument, you need to enclose 'i' with parentheses. This is required so that function 'i' gets called and its value is used as the first argument of function 'g'.

Simulating IF conditions for a function
Suppose you have a math function defined as follows

     F n = 2n 
         | 1 IF n = 0 
     

To define such a function in AFL you write the following code

f n = * 2 n
f 0 = 1
        

So to simulate IF conditions for a function, you provide as many definitions for the function as needed to meet the given criteria. Appropriate function will be called based on the argument being passed, when the function is invoked.

Lists

[ 1, 2, 3 ]

List with three values

[]

Empty List

List Expansion

.. END_VALUE

Create list with values 0 to END_VALUE

.. START_VALUE END_VALUE

Create list with values START_VALUE to END_VALUE

.. START_VALUE END_VALUE STEP

Create list with values between START_VALUE and END_VALUE with difference of STEP from start to end.

Examples:
.. 10
.. 1 10
.. 1 10 2
Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 3, 5, 7, 9]

List Builder

@@ INITIAL_LIST : NEXT_VALUE : CONDITION

Build a list starting with inital value, next value

@@ INITIAL_LIST : NEXT_LIST_ITEM : NEXT_VALUE : CONDITION

Build a list starting with inital value, next value

By default list builder token appends the next list item to the list. You can prepend the next list item by using '@^' to build a list. '@$' is a synonym for '@@' which mean append to list.

NEXT_VALUE

This is the expression or a function which will calculate the next value for building the list and for the CONDITION part.
The expression needs to have exactly one argument prefixed with the '#' symbol, for example:

 - #10 1
The value prefixed with '#' will be used as the starting value for the list builder.

CONDITION

This result of the CONDITION determines whether list building continues or stops. If the CONDITION expression results in a False value, list building is stopped. If the CONDITION expression results in a True value, list building continues.
The CONDITION expression needs to have at least ONE argument as the symbol '#'. This will be replaced with whatever NEXT_VALUE evaluates to. Example of a CONDITION expression:

 > # 0 

NEXT_LIST_ITEM

This section, if present, calculates the next value that will be put into the list being built. Like the CONDITION expression, NEXT_LIST_ITEM expression too needs to have at least ONE argument as the symbol '#', which will be replaced with the results of evaluation of NEXT_VALUE expression. Example:

 * # 2 


Example of 3-TUPLE List Builder

 @@ [] : - #10 1 : > # 0

The above code will output:

[ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ]

Example of 4-TUPLE List Builder

 @$ [] : * # 2 : - #10 1 : > # 0

The above code will output:

[ 20, 18, 16, 14, 12, 10, 8, 6, 4, 2 ]

Note that we can use '@$' in place of '@@'. They both mean append new items at the end of list.


Example of 4-TUPLE Prepend List Builder

 @^ [100, 200] : + # 2 : - #10 2 : > # 0

The above code will output:

[ 4, 6, 8, 10, 12, 100, 200 ]

Apart from the prepend list builder, the examples also shows the use of non-empty list as initial value.

List operators

@& LIST

List length : This operator computes the length of the list.

@# VAR LIST

List Item: Use this operator to extract a list item out of a list.
VAR is the index of the item in the list. Indexes start with ZERO (0).

Examples:
@& [1,2,3,4]
@# 2 [1,2,3,4]
Output:
4
3

Comments

You may insert comments into AFL code by starting a line with a semi-colon ';'.
Comments need to be on a line of their own.

Example:
; This is a comment
f a b = + a b ; Comments like these won't work, they need to be on a line of their own.
            

Complex expressions

You may use output of one function as input of another function to create complex expressions.

Example:
f a = + a 1
g b = + a 2
f (g 7)
            

Notice how we used parentheses around 'g 7' to tell AFL that this is a function call, evaluate it first. Had we not used parentheses, AFL would have complained about not being able to found a matching signature for 'f g 7', i.e. a function named f accepting two arguments.
So the rule of the thumb is to always enclose functions in parentheses when passing their result to another function. See another example below.

Example:
i = 10
f a = * a 2
f (i)
f 3
            

As you can see 'i' is a function which takes no arguments and always returns 10. To pass its result to 'f' we need to enclose it inside parentheses as shown. Literal values can be passed without parentheses.

You may use as many deeply nested functions using parentheses, as the need may be.

Example:
+ 1 (+ 2 (+ 3 4))
            

Limitations and special notes

There are some intentional limitations to the AFL language to keep it simple. Most of them are quite obvious from the documentation above. The things that are not obvious are listed here.

  • PHP Script timeout: Scripts being run through the web interface may timeout. You may try the command-line interpreter to execute time intensive scripts.
  • No lazy evaluation: AFL does not support lazy evaluation like some popular functional languages (eg: Haskell)
  • Lack of optimization: As of now, the interpreter has not been optimized at all. The current code's main motive is to execute the code properly and ina reliable manner only. Speed of execution is not looked into, as of now.

  • The snippets
    Even though there are certain limitaions to AFL, still there are some cool and nifty things that can be done. You may have a look at snippets on the Demo page to see few examples. Use the drop down to select an example and click on the execute button to try it out. And do experiment with the snippet, trying out different values and/or editing some code to see how things are working!

(c) 2010, Amit Singh (xk0der), All Rights Reserved.

http://xkoder.com | blog.xkoder.com