HQ9+: Functional Edition

From Esolang
Jump to navigation Jump to search

HQ9+: Functional Edition is an esolang by User:BoundedBeans. It is very clearly a derivative of HQ9+ (although none of the features of HQ9+ are very prominent in this language), but not a joke and part of the functional paradigm.

Functions

Functions are the only datatype. In fact, the accumulator doesn't even really need to be added to an implementation since, to the user, it's practically just a no-op. Functions can pass functions in as a parameter, and they can also return functions. It doesn't necessarily need to do either of these things, so subroutines are totally possible.

You can declare a function with:

[name];

You can assign a function with:

name = expression;

(Names can be made out of letters, underscores, and digits. Since there are no numerical datatypes, a name can start with a digit.)

Expressions are either function literals:

f(parameter-names){inner-code}

Or function calls:

name/comma-separated-list-of-expressions\

You can also just write a function call as a command (remember to add a semicolon). Functions can have local variables, but can also access global variables.

Another command is:

run "HQ9+-code";

Note that Q quines the whole code, not just the function.

And you can return a function with:

ret expression;

A function can recurse by calling this/\. This accepts the same number of arguments as the function calling it, and does the same thing.

Built-ins

Here are the built-in functions.

  • after/a, b\; Creates a new function consisting of the contents concatenated together. By putting these over and over again, you can make "for loops".
  • if/a, b, c, d\; If a and b are exactly equal, returns c, otherwise d. You can use this with recursion and Church numerals to make while loops.
  • church/\; Creates the church numeral for 1
  • cadd/a, b\; Adds two church numerals
  • csub/a, b\; a - b
  • cmul/a, b\; a * b
  • cdiv/a, b\; a / b
  • mthread/a, b\; Creates a function that multithreads a and b
  • print/a\; Given a church numeral, creates a function that prints the corresponding Unicode character.
  • input/\; Takes a character of input and returns its Unicode value as a church numeral.
  • choice/\; Creates a function, that, when called, will return the program back to the state it was in when it called this, along with setting backtrack_times to a church numeral of the number of times it has backtracked before, and backtrack_line to a church numeral of the line it previously was at.
  • pair/a, b\; Returns a function that accepts one argument. When called, if the argument is the church numeral zero, it will return a, otherwise b.

Examples

Hello world

run "H"

Quine

run "Q"

99 bottles of beer

run "9"

Truth-machine

[truth]; truth = input/\;
[0]; 0 = csub/church/\, church/\\;
[48]; 48 = cmul/cadd/church/\, cadd/church/\, cadd/church/\, cadd/church/\, 
cadd/church/\, church/\\\\\\\, cadd/church/\, cadd/church/\, cadd/church/\,
cadd/church/\, cadd/church/\, cadd/church/\, cadd/church/\, church/\\\\\;
[finalfunc]; finalfunc = if/0, truth, f(){
p = print/48\; p/\;
}, 
f(){
p = print/cadd/48, church/\\\; p/\; this/\;}\;

Computational class

This language is likely annoying to prove, but not hard. It can recurse and do conditional branches, and can hold an infinite amount of data through pairs and church numerals. I dare you to make a Brainfuck interpreter in this (since it does have full I/O).