True — язык программирования, где программа есть цикл, а код программы — лента кубитов (строк).
Simple — кроссплатформенный интерпретатор на Python 3 + Tkinter. Простой, без зависимостей.
Статус: Проект экспериментальный, на стадии MVP. В общем и целом, True — полноценный язык с собственной концепцией, и может развиваться как самостоятельный язык.
Идея
В True программа является и источником данных(одним из) и набором инструкций для исполнителя (агента).
Программа здесь лента строк (я называю их кубитами).
Агент-наблюдатель — часть программы (первая строка .cycle). Он идёт по ленте сверху вниз, на каждом шаге меняет строку с нижестоящей и выполняет прочитанное.
Программа одновременно и источник данных, и инструкции для выполнения. Нет отдельного кода и данных — есть кубиты, которые агент читает и переставляет.
Агент — не внешний интерпретатор, а часть файла .cycle. Он исполнитель и данные одновременно: строка Mr.Green, ... — такая же строка программы, как и все остальные, но именно она читает остальные.
Одна и та же логика на четырёх языках
True (main.cycle):
Mr.Green, #5fb85f | Data as <condition> | Aim: 1Поднимайся на лифте Mr.Green :)6 = max1 = floor1 = dir= liftdir > 0 ? floor =>| lift:y(, ):floordir < 0 ? lift:y(, ):last -> ::nothingfloor == max ? -1 => dirfloor == 1 ? 1 => dirfloor + dir => ::math => floor
(Здесь => — копирование, -> — перемещение, ? — условие)
Python:
max_floor = 6floor = 1dir = 1lift = []while True: if dir > 0: lift.append(floor) if dir < 0 and lift: lift.pop() if floor == max_floor: dir = -1 if floor == 1: dir = 1 floor = floor + dir print(f"floor={floor} dir={dir} lift={lift}")
Lisp (Scheme):
(define max-floor 6)(define floor 1)(define dir 1)(define lift '())(define (step) (when (> dir 0) (set! lift (append lift (list floor)))) (when (and (< dir 0) (not (null? lift))) (set! lift (reverse (cdr (reverse lift))))) (when (= floor max-floor) (set! dir -1)) (when (= floor 1) (set! dir 1)) (set! floor (+ floor dir)) (display (list floor dir lift)) (newline))(let loop () (step) (loop))
Rust:
fn main() { let max_floor = 6; let mut floor = 1; let mut dir: i32 = 1; let mut lift: Vec<i32> = Vec::new(); loop { if dir > 0 { lift.push(floor); } if dir < 0 { lift.pop(); } if floor == max_floor { dir = -1; } if floor == 1 { dir = 1; } floor += dir; println!("floor={} dir={} lift={:?}", floor, dir, lift); }}
Python, Lisp и Rust здесь реализуют ту же логику, но не читают и не меняют свой исходный код. True делает это на каждом шаге — программа самомодифицируется: агент меняет строки, memory отражается в тексте, <type> обновляется. Это отличие True от императивных языков: программа = данные + инструкции в одном.
Ключевые идеи
1. Кубит = строка
Строка — кубит. Её значение зависит от наблюдателя (агент).
На каждом шаге агент:
-
читает строку
target(тип, значение), -
выполняет действие (если
action/condition), -
меняет
lines(flush памяти), -
меняет строку агента (
Data as <type>).
2. Наблюдатель = агент = часть программы
Агент — первая строка .cycle:
Mr.Green, #5fb85f | Data as <condition> | Aim: 1
-
Mr.Green— имя, -
#5fb85f— цвет, -
Data as <...>— тип, который агент распознал (обновляется каждый шаг), -
Aim: 1— цель, условие при котором цель считается достигнутой (в ROADMAP)
3. Цепочки кубитов
Пустая строка ("") — граница блока. Когда агент определяет тип первого кубита в цепочке, вся цепочка до separator срабатывает вместе как один блок этого типа.
Фрагмент реальной программы (main.cycle):
Mr.Green, #5fb85f | Data as <condition> | Aim: 1dir > 0 ? floor =>| lift:y(, ):floordir < 0 ? lift:y(, ):last -> ::nothingfloor + dir => ::math => floor
-
dir > 0 ? ...иdir < 0 ? ...— один блокcondition(пустая строка — граница). -
floor + dir => ...— отдельный блокaction(послеseparator).
Это позволяет группировать логику без скобок и определять тип всей цепочки определив только один кубит.
4. Оси данных
Контейнер может быть осью — списком:
|
Синтаксис |
sep по умолчанию |
Что |
|---|---|---|
|
|
|
горизонталь |
|
|
|
вертикаль |
Разделитель оси можно переопределять.
Пример:
1, 2, 3 = liftlift:y(, ):last -> ::nothing
→ lift = "1, 2" (удалён последний элемент).
Оси — это способ интерпретации данных\кубита.
5. Расширения (вида ::name)
-
::math— арифметика (+ - * / % ^ == != && ||), -
::nothing— удаление (->удаляет,=>— no-op).
Где посмотреть
-
github.com/e39din/True— репозиторий с доками и кодом -
Демка:
Видео Title
Философия
-
Кубит = строка — данные в чистом виде, тип данных и как с ними работать определяет агент.
-
Наблюдатель = агент = часть программы — исполнитель и данные одновременно.
-
Программа читает и меняет саму себя — отличие от императивных языков.
-
Цепочки кубитов — группировка без скобок.
-
Оси данных — работа с данными как с геометрической фигурой.
-
Программа как цикл — программа циклична (можно остановить инструкцией).
-
::name— функции расширения, встроенные или скомпилированные модули. -
Наглядность процесса исполнения — живая обратная связь.
True v0.9.6. Simple v0.16.3.
Буду рад вашей обратной связи, добро пожаловать к обсуждению 🙂
ссылка на оригинал статьи https://habr.com/ru/articles/1103660/