FunctionsFTW

From Esolang
Jump to navigation Jump to search
FunctionsFTW
Paradigm(s) procedural, imperative
Designed by User:NutronStar45
Appeared in 2022
Type system strict
Memory system variable-based
Computational class Unknown
Reference implementation Unimplemented
File extension(s) .fftw

FunctionsFTW (FFTW for short) is an esoteric programming language created by User:NutronStar45 where you should use functions for everything.

FFTW programs automatically terminate when the end of the program in reached.

Every statement should end with a semicolon (;).

There are no "reserved words" due to the string-based variable name system.

Syntax

Types

There's 5 types of value in FFTW: num, str, bool, func and obj.

Numbers

Numbers are integers, floats or NaN described in

  • one or more decimal digits
  • none or one dot (.)
  • or just NaN

Strings

Strings are text enclosed with a pair of single (') or double (") quotes.

The quotes enclosing a string must be consistent. For example

'single quotes'

and

"double quotes"

are both allowed, but

'inconsistent quotes"

are not allowed and will raise a SyntaxError if there isn't a closing quote.

To access the length of a string, use len(strToObj(string)), for example

len(strToObj("Hello, world!"))

returns 13.

Booleans

Booleans are either true (T) or false (F).

Functions

Functions are some codes condensed into one line.

Enclose parameters with a pair of parentheses (()), enclose some codes with a pair of braces ({}) and combine them together to define an anonymous function, or define a custom function by assigning an anonymous function to a variable.

To return a number, use the returnNum(num val) function.

To return a string, use the returnStr(str val) function.

To return a boolean, use the returnBool(bool val) function.

To return a function, use the returnFunc(func val) function.

To return an object, use the returnObj(obj val) function.

For example

(bool "b1", bool "b2") {
  returnBool(and(or(b1, b2), not(and(b1, b2))));
}

defines an XOR function.

Note that the value is returned to the current function, so the following function

(bool "input") {
  if(input, () {
    returnNum(10);
  }, () {});
}

won't return anything because the returnNum(10); is returning to the function inside the if. Do this instead:

(bool "input") {
  if(input, () {
    setNum("ret", 10);
  }, () {
    setNum("ret", NaN);
  });
  returnNum(getNum("ret"));
}

The function will always return a number even if input was F due to "technical limitations".

Objects

Objects are made of keys and values, each value is assigned to its key, similar to objects in JavaScript or dictionaries in Python.

All keys should be strings, even if the key is 0.

To define an object, enclose pairs of key and value with a pair of brackets ([]), for example

[
  "firstName" "John"
  "lastName" "Doe"
  "age" 26
  "isAdult" T
  "children" [
    "0" [
      "firstName" "Jane"
      "lastName" "Doe"
      "age" 6
      "isAdult" F
      "children" []
    ]
  ]
]

Objects can also be used for arrays, just use the indices as the keys.

To access a number in an object, use the numInObj(obj object, str key) => num function.

To access a string in an object, use the strInObj(obj object, str key) => str function.

To access a boolean in an object, use the boolInObj(obj object, str key) => bool function.

To access a function in an object, use the funcInObj(obj object, str key) => func function.

To access an object in an object, use the objInObj(obj object, str key) => obj function.

To access a list of keys in an object, use the keys(obj object) => obj function, for example

keys([ "name" "John Doe" "age" 26 ])

returns [ "0" "name" "1" "age" ].

To access the number of keys in an object, use the len(obj object) => num function, for example

len([ "name" "John Doe" "age" 26 ])

returns 2.

Type conversions

Conversion Table
Original \ Target num str bool func obj
num numToStr() numToBool()
str strToNum() strToBool() strToObj()
bool boolToNum()
func
obj

Type conversions are very important in an FFTW program as all the function parameters are type-strict, including type conversions.

To convert a number to a string, use the numToStr(num val) => str function, for example

numToStr(12.34)

returns "12.34".

To convert a number to a boolean, use the numToBool(num val) => bool function. 0 will be converted to F or otherwise T. For example

numToBool(123)

returns T, and

numToBool(0)

returns F.

To convert a string to a number, use the strToNum(str val) => num function, for example

strToNum("12.34")

returns 12.34.

To convert a string to a boolean, use the strToBool(str val) => bool function. Empty strings will be converted to F or otherwise T. For example

strToBool("Hello, world!")

returns T, and

strToBool("")

returns F.

To convert a string to an object (parse the characters to an array), use the strToObj(str val) => obj function, for example

strToObj("Hello, world!")

returns

[
   "0" "H"
   "1" "e"
   "2" "l"
   "3" "l"
   "4" "o"
   "5" ","
   "6" " "
   "7" "w"
   "8" "o"
   "9" "r"
  "10" "l"
  "11" "d"
  "12" "!"
]

To convert a boolean to a number, use the boolToNum(bool val) => num function. F will be converted to 0 and T will be converted to 1. For example

boolToNum(T)

returns 1, and

boolToNum(F)

returns 0.

Print

To print something to the console (without newline), use the print(str content) function, for example

print("Hello, world!");

prints Hello, world! to the console.

Note that the print() function can only accept strings, so you need to manually convert the input to string, for example

print(str(100));

prints 100 to the console.

Input

To get one line of text from the input stream, use the input() => str function, for example

num(input())

Will get one line of text from the input stream, convert it to a number and return it.

Negation

Negative

To get the negative of a number, use the neg(num number) => num function, for example

neg(5)

returns -5

Reciprocal

To get the reciprocal of a number, use the recip(num number) => num function, for example

recip(20)

returns 0.05.

Calculation

Addition

To add two numbers together, use the add(num n1, num n2) => num function, for example

add(123, 456)

returns 579.

Subtraction

To subtract a number from another, use add(n1, neg(n2)), for example

add(50, neg(30))

returns 20.

Multiplication

To multiply two numbers together, use the mult(num n1, num n2) => num function, for example

mult(4, 8)

returns 32.

Division

To divide a number by another, use mult(n1, recip(n2)), for example

mult(35, recip(7))

returns 5.

Remainder

To get the remainder of dividing a number by another, use rem(num n1, num n2) => num, for example

rem(10, 3)

returns 1.

Exponentiation

To raise a number to the power of another, use the pow(num base, num exponent) => num function, for example

pow(5, 4)

returns 625.

Root

To get the root of a number, use pow(radicand, recip(degree)), for example

pow(256, recip(4))

returns 4.

Logarithm

To get the logarithm of a number, use the log(num antiLog, num base) => num function, for example

log(128, 2)

returns 7.

Comparisons

Equality

To check if two numbers are the same, use the eqNum(num n1, num n2) => bool function, for example

eqNum(add(0.1, 0.2), 0.3)

returns F. ('cause binary inconsistency LOL why not)

To check if two strings are the same, use the eqStr(str s1, str s2) => bool function, for example

eqStr("Hello, world!", "Bye, world!")

returns F.

Greater than

To check if a number is greater than another, use the gt(num n1, num n2) => bool function, for example

gt(123, 234)

returns F.

Less than

To check if a number is less than another, use gt(n2, n1), for example

gt(234, 123)

returns T.

Greater than or equal to

To check if a number is greater than or equal to another, use not(gt(n2, n1)).

Less than or equal to

To check if a number is less than or equal to another, use not(gt(n1, n2)).

Inequality

To check if two numbers are not the same, use not(eqNum(n1, n2)).

Boolean algebra

And

b1 \ b2 T F
T T F
F F F

To perform an AND function, use the and(bool b1, bool b2) => bool function, for example

and(T, F)

returns F.

Or

b1 \ b2 T F
T T T
F T F

To perform an OR function, use the or(bool b1, bool b2) => bool function, for example

or(T, F)

returns T.

Not

val not(val)
T F
F T

To perform a NOT function, use the not(bool val) => bool function, for example

not(T)

returns F.

Xor

b1 \ b2 T F
T F T
F T F

To perform an XOR function, use and(or(b1, b2), not(and(b1, b2))), for example

and(or(T, F), not(and(T, F)))

returns T.

Concatenation

Strings

To concatenate two strings together, use the concatStr(str s1, str s2) => str function, for example

concatStr(concatStr("Hello, ", "world"), "!")

returns "Hello, world!".

Objects

To concatenate two objects together, use the concatObj(obj o1, obj o2) => obj function, for example

concatObj([ "name" "John Doe" "age" 20 ], [ "age" 26 ])

returns [ "name" "John Doe" "age" 26 ].

Note that the latter object overwrites the former one.

Conditions

if

To execute a function if a value is T, use the if(bool condition, func ifT, func ifF), for example

if(gt(2, 1), () {
  print("2 is greater than 1");
}, () {});

checks if 2 is greater than 1 (which always evaluates to T), print 2 is greater than 1 to the console.

if ... else

To execute a function if a value is T, or execute another function otherwise, use the if() function, for example

if(gt(1, 2), () {
  print("1 is greater than 2");
}, () {
  print("1 isn't greater than 2");
});

checks if 1 is greater than 2 (which always evaluates to F), print 1 is greater than 2 to the console, or print 1 isn't greater than 2 to the console otherwise.

if ... else if ... else

To execute a function if a value is T, or execute another function if the value is F and another value is T, or execute another function if both values are F, use nested if, for example

setNum("secret", 20);
setNum("guess", num(input()));
if(gt(getNum("secret"), setNum("guess")), () {
  print("Too small");
}, () {
if(gt(getNum("guess"), getNum("secret")), () {
  print("Too big");
}, () {
  print("Correct");
}); });

does the following:

Set secret to 20
Take a number from the input stream and store it to guess
If secret is bigger than guess:
  Print Too small to the console
Else:
  If guess is bigger than secret:
    Print Too big to the console
  Else:
    Print Corrent to the console

Labels & gotos

To create a label, use the label(str labelName) function.

To goto a label, use the goto(str labelName) function.

For example

setNum("i", 0);
label("l1");
if(gt(10, i), () {
  print(numToStr(getNum("i")));
  setNum("i", add(getNum("i"), 1));
  goto("l1");
}, () {});

prints 0123456789 to the console.

Note that you can overwrite labels by using the same string as the labelName.

Variables

A variable stores some values and can be accessed anytime if the variable is available.

All variables are global.

There can be spaces and symbols in a variable name (which is illegal in most modern languages) due to variable name being a string, but I'm not gonna use these because I don't like them.

Assignment

To assign a number to a variable (declared on first assignment), use the setNum(str varName, num value) function, for example

setNum("myNumber", 123);

declares and sets myNumber to 123.

To assign a string to a variable (declared on first assignment), use the setStr(str varName, str value) function, for example

setStr("myString", "Hello, world!");

declares and sets myString to "Hello, world!".

To assign a boolean to a variable (declared on first assignment), use the setBool(str varName, bool value) function, for example

setBool("myBoolean", T);

declares and sets myBoolean to T.

To assign an object to a variable (declared on first assignment), use the setObj(str varName, obj value) function, for example

setObj("myObject", [
  "name" "John Doe"
  "age" 26
]);

declares and sets myObject to [ "name" "John Doe" "age" 26 ].

Access

To access a numeral variable, use the getNum(str varName) => num function, for example

getNum("myNumber");

returns the value of myNumber.

To access a string variable, use the getStr(str varName) => str function, for example

getStr("myString");

returns the value of myString.

To access a boolean variable, use the getBool(str varName) => bool function, for example

getBool("myBoolean");

returns the value of myBoolean.

To access an object variable, use the getObj(str varName) => obj function, for example

getObj("myObject");

returns the value of myObject.

Type

To get the type of a variable, use the type(str varName) => str function, for example

setNum("myNumber", 123);
print(type("myNumber"));

prints num to the console,

setStr("myString", "Hello, world!");
print(type("myString"));

prints str to the console,

setBool("myBoolean", T);
print(type("myBoolean"));

prints bool to the console,

def("myFunction", {
  print("Hello, world!");
});
print(type("myFunction"));

prints func to the console, and

setObj("myObject", [
  "name" "John Doe"
  "age" 26
]);
print(type("myObject"));

prints obj to the console.

Availability

To check if a variable exists, use the ex(str varName) => bool function.

Comments

To write a comment, use a statement containing only a string, for example

"This is a comment";

For multi-line comments:

"This
 is a
 multi-line
 comment";

Note that comments are also statements, so the following code wouldn't work:

setNum("i",       "Some comment";
10);

Custom functions

Definition

To define a custom function, use the def(str funcName, func val) function, for example

def("myFunction", (str "name") {
  print(concatStr(concatStr("Hello, ", getStr("name")), "!"));
});

Defines a function that accepts a name argument and prints Hello, {name}! to the console.

Call

To call a custom function with no returning value, use the call(str funcName, obj params) function, for example

def("myFunction", (str "name") {
  print(concatStr(concatStr("Hello, ", getStr("name")), "!"));
});
call("myFunction", [ "name" "Mr. John" ]);

prints Hello, Mr. John! to the console.

To call a custom function that returns a number, use the callNum(str funcName, obj params) => num function.

To call a custom function that returns a string, use the callStr(str funcName, obj params) => str function.

To call a custom function that returns a boolean, use the callBool(str funcName, obj params) => bool function.

To call a custom function that returns a function, use the callFunc(str funcName, obj params) => func function.

To call a custom function that returns an object, use the callObj(str funcName, obj params) => obj function.

If the function don't accept any parameters, use an empty object ([]) for params.

Exceptions

SyntaxError

There's an error in the syntax.

TypeError

Caused by feeding an argument with a wrong type to a function.

Examples

Hello world

print("Hello, world!");

Cat

Back to FunctionsFTW
print(input());

Truth-machine

setStr("input", input());               "Get input";
if(eqStr(getStr("input"), "0")), () {   "If input is 0";
  print("0");                             "Print 0";
}, () {
  if(eqStr(getStr("input"), "1"), () {  "If input is 1";
    label("l");
    print("1\n");                         "Print 1";
    goto("l");                            "Repeat";
  }, () {});
});

Minimized (140 bytes)

setStr("i",input());if(eqStr(getStr("i"),"0")),(){print("0");},(){if(eqStr(getStr("i"),"1"),(){label("l");print("1\n");goto("l");},(){});});

FizzBuzz

setNum("i", 1);                             "Initialize i";
label("l");
if(not(gt(getNum("i"), 100)), () {          "If i isn't greater than 100";
  if(eqNum(rem(getNum("i"), 15), 0), () {     "If i is divisable by 15";
    print("FizzBuzz");                          "Print FizzBuzz";
  }, () {
  if(eqNum(rem(getNum("i"), 3), 0), () {      "Else if i is divisable by 3";
    print("Fizz");                              "Print Fizz";
  }, () {
  if(eqNum(rem(getNum("i"), 5), 0), () {      "Else if i is divisable by 5";
    print("Buzz");                              "Print Buzz";
  }, () {                                     "If all checks above failed";
    print(numToStr(getNum("i")));               "Print i";
  }); }); });
  print("\n");                                "Return";
  setNum("i", add(getNum("i"), 1));           "Increment i by 1";
  goto("l");                                  "Repeat";
}, () {});

Minimized (319 bytes)

setNum("i",1);label("l");if(not(gt(getNum("i"),100)),(){if(eqNum(rem(getNum("i"),15),0),(){print("FizzBuzz");},(){if(eqNum(rem(getNum("i"),3),0),(){print("Fizz");},(){if(eqNum(rem(getNum("i"),5),0),(){print("Buzz");},(){print(numToStr(getNum("i")));});});});print("\n");setNum("i",add(getNum("i"),1));goto("l");},(){});

Fibonacci

Back to FunctionsFTW
setNum("stl", 1);                                        "Set stl(second to last) to 1";
setNum("last", 0);                                       "Set last to 0";

label("l");
print(numToStr(add(getNum("stl"), getNum("last"))));     "Print stl + last";
setNum("last", add(getNum("stl"), getNum("last")));      "last = stl + last";
setNum("stl", add(getNum("last"), neg(getNum("stl"))));  "stl = (stl + last) - stl = last";
goto("l");                                               "Repeat";

Minimized (182 bytes)

setNum("s",1);setNum("l",0);label("L");print(numToStr(add(getNum("s"),getNum("l"))));setNum("l",add(getNum("s"),getNum("l")));setNum("s",add(getNum("l"),neg(getNum("s"))));goto("L");

Fibonacci (Recursive)

def("fib", (num "index") {
  if(eqNum(getNum("index"), 0), () {
    "F(0)";
    returnNum(0);
  }, () {
  if(eqNum(getNum("index"), 0), () {
    "F(1)";
    returnNum(1);
  }, () {
    "F(i-2) + F(i-1)";
    returnNum(add(callNum("fib", [ "index" add(getNum("index"), neg(2)) ]), callNum("fib", [ "index" add(getNum("index"), neg(1)) ])));
  }); });
});

setNum("x", 1);
label("l");
print(callNum("fib", [ "index" getNum("x") ]));
setNum("x", add(getNum("x"), 1));
goto("l");

Minimized (323 bytes)

def("f",(num "i"){if(eqNum(getNum("i"),0),(){returnNum(0);},(){if(eqNum(getNum("i"),0),(){returnNum(1);},(){returnNum(add(callNum("f",["i" add(getNum("i"),neg(2))]),callNum("f",["i" add(getNum("i"),neg(1))])));});});});setNum("x",1);label("l");print(callNum("f",["i" getNum("x")]));setNum("x",add(getNum("x"),1));goto("l");

Factorial

setNum("input", strtoNum(input()));                           "Get number";
setNum("result", 1);                                          "The result";

label("l");
if(gt(getNum("input"), 1), () {                               "If input > 1";
  setNum("result", mult(getNum("result"), getNum("input")));    "result = result * input";
  setNum("input", add(getNum("input"), neg(1)));                "input--";
  goto("l");                                                    "Repeat";
}, () {});

print(numToStr(getNumber("result")));                         "Print result";

Minimized (207 bytes)

setNum("i",strtoNum(input()));setNum("r",1);label("l");if(gt(getNum("i"),1),(){setNum("r",mult(getNum("r"),getNum("i")));setNum("i",add(getNum("i"),neg(1)));goto("l");},(){});print(numToStr(getNumber("r")));

99 bottles of beer

setNum("bottles", 99);                                   "Set X (bottles) to 99";
setStr("form", " bottles");                              "Plural";

label("l");
if(gt(getNum("bottles"), 0), () {                        "If X > 0";
  print(numToStr(getNum("bottles")));                      "X bottle(s) of beer on the wall,";
  print(getStr("form"));
  print(" of beer on the wall,\n");

  print(numToStr(getNum("bottles")));                      "X bottle(s) of beer.";
  print(getStr("form"));                                   "Take one down, pass it around,";
  print(" of beer.\nTake one down, pass it around,\n");

  setNum("bottles", add(getNum("bottles"), neg(1)));       "X--";
  if(eqNum(getNum("bottles"), 1), () {                     "If X = 1";
    setStr("form", " bottle");                               "Singular";
  }, () {                                                  "Else";
    setStr("form", " bottles");                              "Plural";
  });

  if(gt(getNum("bottles"), 0), () {                        "If X > 0";
    print(numToStr(getNum("bottles")));                      "Use X";
  }, () {                                                  "Else";
    print("No");                                             "Use No";
  });
  print(getStr("form"));                                   "X/No bottle(s) of beer on the wall.";
  print(" of beer on the wall.\n\n");
  goto("l");                                               "Repeat";
}, () {});

Minimized (522 bytes)

setNum("b",99);setStr("f"," bottles");label("l");if(gt(getNum("b"),0),(){print(numToStr(getNum("b")));print(getStr("f"));print(" of beer on the wall,\n");print(numToStr(getNum("b")));print(getStr("f"));print(" of beer.\nTake one down, pass it around,\n");setNum("bottles",add(getNum("b"),neg(1)));if(eqNum(getNum("b"),1),(){setStr("f"," bottle");},(){setStr("f"," bottles");});if(gt(getNum("b"),0),(){print(numToStr(getNum("b")));},(){print("No");});print(getStr("f"));print(" of beer on the wall.\n\n");goto("l");},(){});

List of functions

Back to FunctionsFTW

This list is alphanumerically sorted.

add(num n1, num n2) => num
and(bool b1, bool b2) => bool
boolInObj(obj object, str key) => bool
boolToNum(bool val) => num
call(str funcName, obj params)
callBool(str funcName, obj params) => bool
callFunc(str funcName, obj params) => func
callNum(str funcName, obj params) => num
callObj(str funcName, obj params) => obj
callStr(str funcName, obj params) => str
concatObj(obj o1, obj o2) => obj
concatStr(str s1, str s2) => str
def(str funcName, func val)
eqNum(num n1, num n2) => bool
eqStr(str s1, str s2) => bool
ex(str varName) => bool
funcInObj(obj object, str key) => func
getBool(str varName) => bool
getNum(str varName) => num
getObj(str varName) => obj
getStr(str varName) => str
goto(str labelName)
gt(num n1, num n2) => bool
if(bool condition, func ifT func ifF)
input() => str
keys(obj object) => obj
label(str labelName)
len(obj object) => num
log(num antiLog, num base) => num
mult(num n1, num n2) => num
neg(num number) => num
not(bool val) => bool
numInObj(obj object, str key) => num
numToBool(num val) => bool
numToStr(num val) => str
objInObj(obj object, str key) => obj
or(bool b1, bool b2) => bool
pow(num base, num exponent) => num
print(str content)
recip(num number) => num
rem(num n1, num n2) => num
returnBool(bool val)
returnFunc(func val)
returnNum(num val)
returnObj(obj val)
returnStr(str val)
setBool(str varName, bool value)
setNum(str varName, num value)
setObj(str varName, obj value)
setStr(str varName, str value)
strInObj(obj object, str key) => str
strToBool(str val) => bool
strToNum(str val) => num
strToObj(str val) => obj
type(str varName) => str

Implementation

Unimplemented, please someone writes an interpreter here