Nonalphabetic Programming Language

Nonalphabetic programming language
called !!AB

Programming language where common and simple operations and expressions (excluding variables) are typed with non-alphabetic symbols. Allows various programming paradigms, including procedural, object oriented, and functional.  Balanced ternary is the base for logic and digit operations. Decimal numbers are preferred for human readability. Array index starts at 1.



PROCEDURE, FLOW
{ } code block
? if (test expr)
: else (not true, can be false or unknown)
:- elseif false (uses last test expr)
:0 elseif unknown (uses last test expr)
:? elseif (test expr)
? expr {block} means if expr is true, execute block
ex. (? x {'true} : {'else not true (can be false or unknown)})
ex. (? x>0 {x=1} :? x<0 {x=-1} : {x=0})
ex. (? x {x=good} :- {x=bad} :0 {x=undefined} )
^ ? loop
^ ? expr {} is while loop
^ ?? expr {} is do-while
^ initialize ? expr ; post-op {} is for loop
^ ? `+ {} will loop forever until break using ^!
^* loop n times (^* (?# 4~) {} means loop up to 4 times (randomly chosen)) (^* #i=n..m {} means loop starting value n up to m) (^* {} will loop forever until break using ^!)
^++ advance loop to next iteration. continue.
^! exit loop or block. break
( ) execute inline operation  (  (x+2)*3 )
( ) function arguments  ( myfunc(myvar) )
^^ return one or more values from function  ( ^^ retval1, retval2 )
; explicitly terminate statement for statements on the same line  (statement 1 ; statement 2)
\ statement continues on next line  (line 1 \ line 2)
::+ include another file or library  (::+ stdio)
::- include another file or library if not already included  (::- stdio)
::: using namespace  (::: std)
^$ evaluate string of code  (^$"x = x + 2") ($code = "x = x + 2"; ^$code)

VARIABLES TYPES AND INITIALIZATION
only alphanumeric characters allowed in variable names. can start with any letter or number. must have at least one letter.
ex. #3n $str0 $camelCase
= () initial assignment, except function, thread  ( $n = 5 is same as $n(5) )
# number  (#n = 5 is integer) (#n = 5. is float)
$ string  ($text = "hi")
@ array, object  (@list = [1, 2, 3, 4]) (@car = Ford())
` boolean  (`flag = `+)
_ file  (_file = _^ "/path/to/file")
^ function  (^print($text) {$< text}) (^(#x) {^^ x*x} anonymous (lambda) function) (^add = ^(#x, #y) {^^ x+y})
~ thread  (~thread{attrs}) (~thread(func, ...))
[] new array  (@list=[1..15])
{} new object  (@json = {"a"="apple"})
:: const, precedes variable definition  (::#NUM = 5)
= object property assignment  ({"a"= "apple"})
= pass function argument by name  (print(text= "hi"))
?=# is variable a number?  ( `bool = ?=# var)
?=$ is variable a string?  ( `bool = ?=$ var)
?=@ is variable a array or object?  ( `bool = ?=@ var)
?=^ is variable a function?  ( `bool = ?=^ var)
?=` is variable a boolean?  ( `bool = ?=` var)
?=~ is variable a thread?  ( `bool = ?=~ var)
?=_ is variable a file?  ( `bool = ?=_ var)

OPERATORS, MATH, LOGIC
numeric constants starting with # are in balanced ternary, using these 3 symbols contiguously: + 0 -
ex. (#+-- == 5) (#-++ == -5)
= assignment, copy  (x = #+-- == y = 5)
>< swap variables  (x >< y) (a >< b >< c means a=b, b=c, c=a)
>< check if number is between interval, [] inclusive, () exclusive  ( `bool = a >< [1, 15] ) (a >< (1, 15) ) (a >< [1, 15) )
+ - * / ** // % math (add, minus, times, divide, power, modulus, percent of )
++ -- increment, decrement
%% make percentage into decimal  (#i = 50 ; i%% results in i = 0.5 or 50%)
+= -= *= /= **= //= compound assignment for math
| max  ( -1 | 1 == 1; 5|1|2 == 5)
& min  ( -1 & 1 == -1; 5&1&2 == 1)
< > < = >= == != compare operators (less, greater, less or equal, greater or equal, equal, not equal)
< < >> || && !! <> !& !| trit (ternary digit) operators (shift left, shift right, or, and, not, xor, nand, nor)
< <= >>= ||= &&= !!= <>= !&= !|= compound assignment for bit operators
. make float (#30.) ($s = "30.00" ; #n = s.)
~ round to nearest integer (#30.15~) ($s = "30.15" ; #n = s~)
.. range of numbers (#+..#++-0+ == 1 .. 100~)
?# @ random float number n times (?# 1 means float between 0 and 1) (?# 100~ @ 20 means array of 20 integers each randomly 0 to 100) (?# 10..20 means float between 10 and 20)

ORDER OF OPERATIONS
TBD

STRINGS
"" string, enclosed ("my string")
`"" fill in values from variables inside string (`"$name has @basket["apple"] apples")
\ escape for regexp, special characters, Unicode, hexadecimal ("\n" is newline) ("©" == "\u00A9" == "\xA9")
$ to string. Default delimiter is space (number$) (array$",")
$< output ($< "hello", " world")
$> input ($> $first, $second)
+ concatenate string ($hw = "hello" + " world")
* repeat string n times ($fill = "-" * 8)
$%() string format  ( $%( "%$ has %# apples", name, @basket["apple"]) )
%$ format takes a string
%# format takes a number

FILE
_^ open file or I/O device  (_file = _^ "/path/to/file")  (_prn = _^ "/dev/prn0")
! close file  (file!)
>$ read characters from file  ( $string = file >$ 9 .. 12)
>_ read lines from file  ($line = file >_ lineNum)
_! end of file  (? ((file >$ index) == _!) )
< write to file  (file < string)
<< append to file  (file << string)

ARRAYS & OBJECTS
, separate arguments, elements (@list = [1, 2, 3, 4]) (^function($arg1, $arg2))
^@ for each (^@array key,value {}) (^@array[1..n] i,v {} subset of array) ($s = "word" ; ^@s ,l {} operates on each letter of the word) (^@array ,v myfunc is like map) (^@array ,v,acc myfunc is like reduce)
/ unpack array (^sum(...) {} ; @a = [1, 3, 2, 4] ; sum(/a))
>< swap elements  (array[1 >< 2]) (array[x >< y >< z])
@& set intersection (@c = a @& b)
@| set union (@c = a @| b)
@< check if is subset. convert 1st parameter to array if necessary  (`bool = a @< b)

REFERENCE
. lvalue (LongName = . + 5 is same as LongName = LongName + 5)
@ this object (@.property) (@["key"])
[ ] get element from array, object, string (array[i]) (object["a"]) (string[0])
.. subset of array (arr[2..5] means 2nd to 5th elements)
. element of object (object.property)
... any number of function arguments (^print(...) { @args = {...} })
:: namespace  (std::cout)
# size (size = array#) (length = string#) (size = object#)
?@ check if array has value. Return array of positions or `0 (@match = string ?@ 'pattern') (#firstMatch = (array ?@ 'apple')[1] )
?: check if array has key. Return logic value `-, `0, `+ (object ?: "a") (REDUNDANT?  ? object["a"] evals to value or `0)

COMMENTS
' comment rest of line
'[ '] '( ') comment block start & end. nestable '[ outside '( inside ')  ']

DEBUG, ERROR HANDLING
'{ }' debug block start & end. runs only if in debug mode.
::{} enable debug mode
?< try
?> catch
?^ finally
(?< { x = x/y } ?> @err { $< err.2 '[ divide by zero error ]' } ?^ { $< "Completed." } )
error object has 3 properties: {"0": "error code"; "1": "error name"; "2": "message"; }

LOGIC (BALANCED TERNARY)
`+ true
`0 unknown, empty, null
`- false
`+$ "TRUE" the string
`0$ "UNKNOWN" the string
`-$ "FALSE" the string
`+~ 1 the integer
`0~ 0 the integer
`-~ -1 the integer
! negate, opposite, self-assignment, after variable (victory! means victory = !.)
lazy matching:
`- | `0 | 0 | "" | empty-array are all false
`+ | non-0 number | non-""-string | non-empty-array are all true
early exit for "or" "and":
| "or" returns first true argument, else last argument
& "and" returns first false argument, else last argument
a | b & c ; implies ? a {a} :? b & !c {c} :? !b & c {b} : c
a & b | c ; implies ? a & b {b} : c
TRUTH tables
sum, anything, consense (iff), carry, imply, tand

THREADS
~ current thread
{} thread attributes  (thread{joinable= `+, func= myfunc }}
. [] thread attribute  (thread.joinable) (thread["joinable"])
() execute thread  (thread(func, ...))
! stop thread  (thread!) (~!)
< join thread  (parent < child) (~ < thread) (~ < array)
> detach thread  (thread>)



EXAMPLES


'[ "for" loop ']
^ #i = 1 ? i < = 10 : i++ {
	$< i
}



'[ for each item in array
' print the array's keys and values
']
@array = ["Apple", "Banana", "Chocolate"]
^@array i, fruit {
	' output
	$< i, "th item:\n"
	$< "\t", fruit, " has ", fruit#, " letters\n" ' length of string

	' alternative output 1
	' string format
	$< $%("%$th item:\n\t%$ has %# letters\n", i, fruit, fruit#)
}



'[ deck shuffling
' Fisher-Yates-Durstenfield
']

' iterate array
@deck = [1..52]
^@deck[1..(deck#-1)] i {
	#j = ?# i..(deck#)~
	deck[i >< j]
}

' alternative with 'for' loop
@deck = [1..52]
^ #i=1 ? i<=deck#-1 ; i++ {
	#j = ?# i..(deck#)~
	deck[i >< j]
}




'[ Reverse a string ']
^reverse($str) {
	^@str[1..str#/2] i {
		str[i] >< str[str#-i]
	}
	^^ str
}
$< reverse("Hello World!")



'[ Guessing game
' user has 5 tries to guess random number from 0 to 100
']

`victory, #solution, #guess
^* {
	victory = `-
	solution = ?# 100~
	^* 5 {
		$< "Guess a number between 1 and 100."
		$> guess
		? guess == solution {
			victory = `+
			^!
		}
		:? guess > solution {
			$< "Too high."
		}
		: {
			$< "Too low."
		}
	}
	? victory {
		$< "Correct!"
	}
	: {
		$< "Sorry, loser."
	}
	$< "The answer is ", solution
	$< "Do you want to play again? y/n"
	$> $replay
	? replay == "n" | replay == "N" {
		^!
	}
}




'[ Functional programming ']

' Higher-order functions take functions as argument into another function

' execute function twice
^twice(^f, ...) {
	^^ f(f(...))
}
$< twice( ^(#x) { ^^ x+3}, 7)  ' should be 13 = ((7+3)+3)

' factorial with tail recursion
^fact(#x) {
	? x <= 1 {^^ 1} : {^^ x * fact(x-1)}
}

' closure
^increment = ^() {
	#counter(0)
	^^ ^(){^^ ++counter}
}()
^* 3 increment()  ' counter should be 3

' map function
^@array ,v ^() { $< reverse(v) }

' reduce function
^@array ,v,#sum=0 ^() {sum += v}


Liked it? Take a second to support amuseum on Patreon!

Leave a Reply

Your email address will not be published. Required fields are marked *

*