# Comun

{ UPDATE: I am currently thinking about reworking comun a bit, maybe drop the whole bytecode and build it more with the incremental style of Forth. I will probably need a lot more time to think it through, please be patient :-) ~drummyfish }

Comun is a [beautiful](beauty.md), experimental [minimalist](minimalism.md) [programming language](programming_language.md) made by [drummyfish](drummyfish.md) in 2022, based on his ideals of good, [selfless](selflessness.md) [technology](technology.md) known as *[less retarded software](lrs.md)* (LRS) -- it is still a very much work in progress and may potentially change a lot. It was planned that in the [future](future.md) it should gradually replace [C](c.md) as the preferred LRS language, however it's very soon for this still. The language has been inspired mainly by [Forth](forth.md) but also [C](c.md), [brainfuck](brainfuck.md) and other ones. Though already usable, it is still in development; currently there is a [suckless](suckless.md) implementation of comun in [C](c.md) as well as a basic [self hosted](self_hosting.md) one which can [bootstrap](bootstrap.md) itself and should gradually replace the C version. There is also a number of supplemental materials such as a specification, tutorial and some example programs. The project repository is currently at https://codeberg.org/drummyfish/comun. The aim now is to make a [self hosted](self_hosting.md) implementation, i.e. write comun in comun.

**How minimal is comun?** The specification fits on one sheet of A4 paper (using both sides) and the minimal self hosted compiler without preprocessor and fancy features has some 2400 [lines of code](loc.md), a lot of which are documenting comments (the whole self hosted codebase that also includes a more "feature rich" compiler, optimizer, interpreter etc. still has fewer than 5000 lines).

{ NOTE: I found a language on esolang wiki called *Minim* that looks a bit similar to comun, however it looks a bit sucky. Anyway it should be researched more. ~drummyfish }

The language is intended to be the foundation of a completely new, non-[capitalist](capitalism.md) computer technology built from the ground up, which should culminate in the creation of the LRS much desired [public domain computer](public_domain_computer.md). This technology is derived from the model of an [ideal society](less_retarded_society.md) and as such will aim for completely different goals (such as helping all living beings as much as possible without enslaving them) and values; this makes comun astronomically different in philosophy and design of the shitty, toxic capitalist joke languages such as [C++](cpp.md) and [Rust](rust.md) which pursue fascism, enslavement of humans to the [productivity cult](productivity_cult.md) etc.

Comun is planned to closely interact with [comun shell](comun_shell.md), though the two parts will be completely independent.

**A quick sum up** is following: comun is **[minimalist](minimalism.md)**, **[low level](low_level.md)** with minimum [abstraction](abstraction.md), **[portable](portability.md)**, **[imperative](imperative.md)** and **[stack](stack.md)-based**, using **reverse Polish notation**. It can be **both [compiled](compiler.md) and [interpreted](interpreter.md)**. There are **only primitive integer [data types](data_type.md)** (native integer size by default with possibility to specify exact width where necessary, signed/unsigned interpretation is left to the programmer) and **optional [pointers](pointer.md)** that can be used as variables, for managing multiple stacks, creating [arrays](array.md) etc. Its **specification can fit on a sheet of paper** and is **completely [public domain](public_domain.md)** under [CC0](cc0.md) (as is its current implementation). It has **no [standard library](stdlib.md)**. There are **no [English](english.md) keywords**; commands are rather very short (mostly 1 to three symbols) math-like symbols. Source code only allows [ASCII](ascii.md) symbols (no [unicode](unicode.md)). There is an **optional [preprocessor](preprocessor.md) that uses comun itself** (i.e. it doesn't use any extra language). **[Functions](function.md) and [recursion](recursion.md)** are supported. Many features of the language are optional and never burden the programmer if he doesn't use them. Simplified versions of the language (minicomun and microcomun) are also specified. The only I/O in pure comun is standard input and standard output, i.e. there is no input/output from/to files, screen, network etc., the language merely processes input values into output values -- handling more complex I/O is left for libraries and/or comun's wrapping environment, such as [comun shell](comun_shell.md).

TODO: compare to Forth

## Examples

Here is a very short showcase of comun code, demonstrating some common functions:

```
max: <' ? >< . ^ .      # takes maximum of two values

max3: max max .         # takes maximum of three values

# recursive factorial
factR:
  ?'
    $0 -- factR *
  ;
    ^ 1
  .
.

# iterative factorial
factI:
  $0 --

  @'
    >< $1 * ><
    --
  .
  ^
.
```

The following is a [quine](quine.md) in comun:

```
0 46 32 34 S 34 32 58 83 S --> S: "0 46 32 34 S 34 32 58 83 S --> " .
```

The following code translates [brainfuck](brainfuck.md) to comun (proving comun really is [Turing complete](turing_complete.md)):

```
0 "$>0 " -->

@@
  <? ?
    <- 

    $0 "+" = $1 "-" = | ?
      $0 -> $0 -> " " ->
    .

    $0 "<" = $1 ">" = | ?
      "$" -> $0 -> "0" -> " " ->
    .

    $0 "." = ?
      0 "->' " -->
    .

    $0 "," = ?
      0 "$<0 <- " -->
    .

    $0 91 = ? # left bracket
      0 "@' " -->
    .

    $0 93 = ? # right bracker
      0 ". " -->
    .

    ^
  ;
    !@
  .
.
```

The following is our standardized **[divisor tree](divisor_tree.md)** program written in comun:

```
# pops a number (< 1000) and prints it
numPrint999:
  $0 99 > ? $0 100 / "0" + -> .
  $0 9 > ?  $0 10 / 10 % "0" + -> .
  10 % "0" + ->
.

# converts single digit to number (or -1 if invalid)
digitToNum:
  $0

  $0 "0" >= >< "9" <= & ?
    "0" -
  ;
    ^ -1
  .
.

# takes x, pops it and recursively prints its divisor tree
printDivisorTree:
  -1 -1                 # divisors: a, b

  $2 2 / @@             # for i = x / 2
                        # stack now: x a b i
    $0 1 <= ?
      !@
    .

    $3 $1 % 0 = ?       # i divides x?
      $0 $:3            # a = i
      $3 $1 / $:2       # b = x / i

      $2 $2 <= ?        # a <= b?
        !@
      .
    .

    --                  # decrement i
  .
  ^                     # pop i

  "(" ->

  $0 -1 != ?
    printDivisorTree
    " " ->
    >< numPrint999      # print x
    " " ->
    printDivisorTree
  ;
    ^ ^                 # pop a, b
    numPrint999
  .

  ")" ->
.

@@                      # read numbers from the user
  0 10 "enter a number:" -->

  0                     # x
  @@                    # read x
    <-
    $0 10 = ? ^ !@ .    # newline?
    digitToNum
    $0 -1 = ? !. .      # wrong digit? then end
    >< 10 * +
  .

  $0 1000 < ?           # x < 1000?
    printDivisorTree
    10 ->               # newline
  ;
    !@
  .
.
```

## See Also

- [comun shell](comun_shell.md)
- [MIX](mix.md)
- [uxn](uxn.md)
- [minim](minim.md)
- [Oberon](oberon.md)
- [C](c.md)
- [conum](conum.md)