Ans

From Esolang
Jump to navigation Jump to search

Ans is an esoteric programming language invented on Saturday, April 19, 2008 by revcompgeek. Ans is a flexible language related to lisp, and is functional. Ans stands for Almost No Syntax.

Calling Functions

In Ans, all function names are either a single non-alphabetic character, or an upper-case letter optionally followed by any number of lower-case letters (e.g. Fibonacci). Non-alphabetic characters are not allowed in the names of user defined functions. No parentheses are needed as every function knows how many arguments it takes.

Variables

All variables in Ans start with an underscore(_), followed by any number of lower-case letters. Variables can either hold integers, lists or code blocks. Strings are represented as lists. In user defined functions, the _ variable is used as the return value and _a through _i are the parameters passed to the function. Command line arguments are also stored in _a through _i.

Numbers

Single digit numbers are the largest numbers that can be written into the language. You must use the math functions to produce higher numbers. For example, if you wanted to produce 42 in Ans you would have to add something like +*4*252 which is equivalent to (4*(2*5))+2 or simply *67.

Lists

Lists are simply arrays of values, which could be numbers, code blocks, or more lists. Lists are specified inside parenthesis (). Any code inside is executed and the results are placed into the list, unless the list is prefixed with a `, in which case it becomes a list of code blocks. Also, any strings in the program in the form "..." are converted into lists.

Built in functions

Name Arguments Description
Math Functions
+ number,number add
- number,number subtract
* number,number multiply
/ number,number divide
^ number,number power function
% number,number modulus or remainder
~ number bitwise NOT
& number,number bitwise AND
| number,number bitwise OR
Comparison Functions
! anything logical NOT
Or or O anything,anything logical OR
And or A anything,anything logical AND
< number,number less than
> number,number greater than
= anything,anything equal to
I/O Functions
$ list or number string print (ascii values)
# list or number integer print
N print newline
' string input
? integer input
List Functions
. list,index List Get
, list,index,value List Set
Slice or Sl list,begin,end List Slice
Listappend or La list,list Append #2 to the end of #1
Listconcat or Lc list,list Concat #2 to the end of #1
List or L Create empty list
Listsize or Ls list Size of list
String Functions
Format or Ft list(string) Format string: replace `var` with the value of var, `` with `
Escape or Es list(string) replace ~ with ~~ and " with ~"
Replace or Rp list(string),list(string),list(string) replace all occurances of #2 with #3 in #1
Variable Functions
Set or S variable,value Sets the variable to the value
Exists or E variable Does the variable exist?
Islist or Il variable Is the variable a list?
Isnum or In variable Is the variable a number?
Isblock or Ib variable Is the variable a block?
Flow Control Functions
If or I value,code execute code if value evaluates to true
Ifelse or Ie value,code,code execute code if value evaluates to true else execute second code
While or W code,code while code #1 evaluates to true, execute code #2
Do or D code,code execute #1, while code #2 evaluates to true, execute code #1
For or F variable,number,code move value of variable towards number by 1, executing code each time
\ break out of loop
@ terminate program or function
Misc Functions
` code or variable if variable, run the code inside, otherwise capture the code into a block
B anything,anything evaluates both params in order
Func or Fc function name,number,code defines a function that takes number params
Load or L list(string) Loads a module into memory

Explanations

While and Do loops

While and Do loops both need a code block passed as their first parameter because the expression will need to be evaluated multiple times. If and Ifelse do not need a block as their first parameter because it is evaluated once every time. See Code passing for more information.

For loop

The first parameter to a for loop must be a variable. This variable will be incremented or decremented after each run through the loop. The variable should already be initialized to the value that the loop should start with. The next parameter is the value that the for loop should loop to. This can be above or below the variable's value because the loop will adjust. The last parameter is the code that should be run. Example:

Set _num 0
For _num 10
  `# _num

Code passing

Closures are used in many languages to pass a section of code to be used later. To do this in Ans you must prefix the block of code with a back quote(`). The code will be followed until all parameters are accounted for and then returned as a value. When that value is prefixed with a back quote, whether inside of a variable or not, the code will be executed. Note that the tree will be evaluated every time that it is used with a back quote and that it executes in the same scope that it was used in, so it can use the same variables. See 'Func' function for an example

'B' function

When creating functions, you may want to have multiple commands run at the top level. The solution is the 'B' function. There are only two parameters that are evaluated in order. Example:

If = _ 1 `B
   $"_ is 1"
   @

'Func' function

Using the 'Func' function is the way to define new functions. The first parameter is the capitalized function name. The second parameter is the number of parameters that the function takes. The last parameter is the code that is to be run when it is called. Example:

Func Fac 1 `BB
    If Or =_a 1  =_a 0 `B
       Set _ _a
       @
    Set _ + 1 Fac - _a 1 
    @

See Examples section for an obfuscated version

'Listappend' and 'Listconcat'

'Listappend' and 'Listconcat' both do operations on the list in the first argument, but the difference is that 'La' can take a list or an integer as the second argument while 'Lc' takes only a list as the second argument. If both arguments are lists, then 'La' will put the second list inside the first as a nested list while 'Lc' will simply tack the second list to the end. Example:

 _la is (1, 2, 3), _lb is (4, 5)
La _la _lb  returns (1, 2, 3, (4, 5))
Lc _la _lb  returns (1, 2, 3, 4, 5)

Examples

Hello World

$"Hello, World!"

Cat

(assuming -1 is EOF)

S_v0S_eof-01While`!=_v_eof`BS_v'$_v

or a more obfuscated:

D`!=_-01`BS_'$_

Factorial

FuncFac1`BBIO=_a1=_a0`BS__a@S_+1Fac-_a1@

Called like this:

Fac 5

Quine

S_"S_q*2+98$`_q`S_`_q`$_q$_$_q$Ft_"S_q*2+98$"S_"$_q$_$_q$Ft_

Can anyone come up with a smaller one?

Bottles of Beer

S_b" bottles of beer"
S_w_b
S_wLc_w" on the wall."
S_bLc_b"."
S_t"Take one down, pass it around,"
S_*9+56S_n_
F_1 `BBB
  BB#_$_wN
  BB#_$_bN
  B$_tN
  BBB#-_1$_wNN
$"No"$_wN
$"No"$_bN
$"Go to the store, buy some more,"N
#_n$_wN

A smaller version based on this one:

FcU0`B$"on the wall"NFcZ1`BBB#_a$" bottle"I!=_a1`$"s"$" of beer "FcV1`BBBBBBBZ_aUZ_aN$"Take one down, pass it around"NZ-_a1US_*9+56F_1`V_

Interpreter

The interpreter is written in D, and uses the Tango library. It is likely very buggy but it has been tested with every example program listed on this page. See http://github.com/revcompgeek/ans/ (dead link) for the source and bug tracker. Please post issues on this website if you find anything wrong. NOTE: The interpreter does not currently have the list syntax implemented. I am currently working on a new implementation in Python that I'm hoping will be a little bit more powerful.