Stlang

Stlang is a stack-based esoteric programming language invented by User:Feuermonster in 2012. The main idea is to create a stack-based esoteric language with a very sophisticated standard library which outshines other major languages' standard libraries. Also, due to possible use in golfing, often-used function names must have a short, symbolic alias. Stlang supports anonymous functions. But most importantly: The spirit of Stlang is to implement lots of features in very weird and esoteric ways no other language or sane person would implement them with.

Builtin functions
Note: Since Stlang is stack based, "return" means "push the result on to the stack". This also applies to things like "removes element from list", etc.

'''unfinished. More documentation is coming, of course.'''

Details
As mentioned: Stlang is stack based. Everything which is not a function call is pushed on to the stack. Functions then take values from the stack, do their stuff, and push the result back on to the stack.

Stlang also supports anonymous functions (lambdas) with the {}-Notation. is an anonymous function which obviously adds 5. What Stlang does with anonymous functions is, it creates a new standalone function with a random name for that anonymous function and replaces the anonymous function inside the code with a call to this randomly named function. There are functions to actually access the name of the created function ( is replaced with the name of the current anonymous function, and   or   is replaced with the name of the parent anonymous function) but these are considered to be especially esoteric ;).

Stlang also performs a little optimization. Let's see an example:

fn myRange []{<> ++ 0 >{1 - ++ -3 ^^ <> : ^-}{$ <-}?}; efn

fn main 10 myRange efn

is converted to

fn 9C36B5A81FG724E0 <> ++ 0 > '94C7BF2518E03DA6 'GB1C6785D3024FA9 ? efn

fn myRange [] '9C36B5A81FG724E0 ; efn

fn main 10 myRange efn

fn GB1C6785D3024FA9 $ <- efn

fn 94C7BF2518E03DA6 1 - ++ -3 ^^ <> : 9C36B5A81FG724E0 efn

These weird function names are the anonymous functions. This is further optimized through inlining to

fn main 10 [] <> ++ 0 > '94C7BF2518E03DA6 'GB1C6785D3024FA9 ? efn

fn GB1C6785D3024FA9 $ <- efn

fn 94C7BF2518E03DA6 1 - ++ -3 ^^ <> : <> ++ 0 > '94C7BF2518E03DA6 'GB1C6785D3024FA9 ? efn

And that's about it ;)

Hello, World!
The following code demonstrates various ways to achieve the goal of greeting the world.

fn main way1 way2 way3 way4 way5 way6 efn

fn way1 'Hello, \s + 'World! + @ efn

fn way2 'Hello, <o \s <o 'World! <o \n <o efn

fn way3 \n 'World! \s 'Hello, <o <o <o <o efn

fn way4 {<o} [] 'Hello, : \s : 'World! : \n : m efn

fn way5 [] 'Hello, : \s : 'World! : _ @ efn

fn way6 [] 'Hello, : \s : 'World! : \n : <- # <o <o <o <o efn

Syntax
A function is declared by  followed by a space and the name of the function. A function declaration is terminated by. Normal functions can not be nested. Anonymous function are declared between  and. Anonymous functions can be nested. A function can be referenced by  followed by the name of the function. When a program is launched, its main method is executed. Function calls and values are usually separated by spaces (if not in golfing mode).

Comments
There are no real comments, but we still can write comments like this:

fn comment {This is a comment, but it's actually just code which is never executed} $ doStuff efn

Strings
There are no real strings, but it is possible to abuse that function references are implemented as strings therefore

fn \o/ 'String <0 efn

will output  to standard out. I think it is obvious that this may have some esoteric side effects if you are careful.

fn \o/ 'String ++ ; <0 efn

fn String 0 $ efn

This will call the function  and then output.

Variables
There are no real variables (you should know this sentence by now ;)), but it is possible to create functions on the fly. The following examples demonstrates this by creating a function  on the fly and call it:

fn main 'test [] ''Hello : '@ : ^F test efn

This can be used for storing values as the following code demonstrates:

fn main {Initialize myGlobalVar with the value 1336. Remember: Code is string -> We have to store 1336 as string. We use (i to convert the float to int, as per default all numbers are floats. } $  'myGlobalVar [] '1336 : '(i : ^F myGlobalVar @ {This will print 1336}$ doSomething myGlobalVar @ {Somehow myGlobalVar was magically incremented ;)}$ efn

fn doSomething {Load myGlobalVar add 1 to it and store it back again} $ myGlobalVar .1+(s[]<>: '(i : 'myGlobalVar <> ^F efn

Pattern matching
Stlang also supports something like pattern matching. Functions can match against the top-most element of the stack. The pattern to match is followed by the name of the function and a. Here is an example:

fn main 0 isZero @ efn

fn isZero ?0 efn

fn isZero:0 ?1 efn

fn isZero:0.0 ?1 efn

Another example:

fn main 'John checkName 'Lisa checkName 'Dylan checkName efn

fn checkName 'I \s + 'don't + \s + 'know + \s + <> + @ efn

fn checkName:John 'I \s + 'like + \s + <> + @ efn

fn checkName:Dylan 'I \s + 'hate + \s + <> + @ efn

which produces the following output:

I like John I don't know Lisa I hate Dylan

Golfing
There is a special golfing mode for a sequence of function calls. This mode is entered with a dot and left with a space. This 11 characters long program reads lines in an infinite loop from the console and reverses them.

M ./r<-` \

Without the golfing mode this program has to be written as:

M /r <- ` \

In clear code the same program is:

fn main readln rev show main efn

OOP
Stlang also supports some sort of object oriented programming. Classes can be defined as well as some sort of inheritance. Classes can inherit from multiple classes and from each other.

Classes
class Animal fn makeSound &sound show efn

prop sound 'Miau eclass

fn main 'Animal new makeSound 'sound 'Woof modprop makeSound efn

In this example a class named Animal is defined and an object of that class is created in main by the new function. modprop is a function to modify properties. Properties can be accessed through  followed by the name of the property.

Casts and Inheritance
class Person fn greet 'Hello, out space out &Name show efn

prop Name 'Peter eclass

class Manager fn greet 'Greetings, out space out &Name show efn eclass

inherit Manager Person

fn main 'Person new greet pop 'Manager new greet pop

'Manager new 'Name 'John modprop greet 'Person castTo greet pop efn

Objects of classes can be casted to other classes with the  function. Any class can be casted to any other class!

class Foo fn do   'Foo show efn eclass

class Bar fn do   'Bar show efn eclass

class Baz fn foobar 'Baz show efn eclass

class Buz eclass

inherit Buz Baz inherit Buz Bar

class A fn a    'A show efn eclass

class B fn b    'B show efn eclass

inherit A B inherit B A

fn main 'Foo new 'Bar castTo do pop 'Buz new foobar do 'Foo castTo do pop 'A new a b pop 'B new a b pop efn

Classes can inherit from multiple classes and even a class A can inherit from B and B can inherit from A.

class Tester fn addTest pop add efn

fn saySomething 'something show efn eclass

fn main 'Tester new saySomething 5 6 that addTest swp show saySomething efn

The that function can be used to get the latest object back on top of the stack (no matter where on the stack it is). This is sometimes necessary if you want to pass parameters to a member function.

Constructors/Destructors
Classes can implement the functions "con" (constructor) and "decon" (deconstructor) which are called automatically on object construction or deconstruction.

Internals
An object is somehow an instance of a class. A class holds function definitions and properties with their default value. The new function creates an object based on its class definition and pushes that object on to the stack. If a function is called which is neither a builtin function nor a function defined in the global scope Stlang checks if the topmost value on the stack is an object and if it is, it calls the function of the corresponding class. After a call to a member function the topmost value of the stack is always the object. Property accessing works analog to this. To access a property of an object that object must be on top.

Clear-text version
fn main readln toint 1 eq { { pop false } { 1 toint show } 0 until } {    0 toint show } cif efn

Golfed version
M ./r(i1=={{.$?0}{.1(i@}.0U}{.0(i@}? \

OOP version
class 0 fn con 0 toint show efn eclass

class 1 fn con { pop false } { 1 toint show } 0 until efn eclass

fn main readln new efn

Golfed OOP version
Cc 0 fn con .0(i@ \ cC Cc 1 fn con{.$?0}{.1(i@}.0U \ cC M ./rN \

99 bottles of beer
fn main 99 (i) strophe efn

fn strophe <+ '_bottles_of_beer_on_the_wall, '_ .\s/R<>}{2 *}2 -> @ efn

Read comma seperated values from the console and print the sum of all numbers (infinite loop):

fn \o/{+}{(i)}/r ', ;; m r @ \o/ efn

Print the 11th fibonacci number:

M 11 fib @ \ fn fib .<+1-"<>2-"+ \ fn fib:0.0 \ fn fib:1.0 \

Print the 11th fibonacci number in clear, commented, well formated code:

fn main 11 fib show efn

fn fib {fib n = (fib (n-1)) + (fib (n-2))} pop dup 1 sub fib swp 2 sub fib add efn

fn fib:0.0 {fib 0 = 0} pop efn

fn fib:1.0 {fib 1 = 1} pop efn

Implementation
Not available anymore.

Problems

 * Ugly code (of course)
 * evalFn is recursive so the max recursion depth is reached very fast (in that case, python does not terminate but yield the weirdest results ;))