Tcl
Tcl за 14 минут: весь язык на одной странице через закомментированный код. Команды, переменные, строки, списки, expr, циклы, proc, массивы, regexp.
Tcl (Tool Command Language) — минималистичный скриптовый язык, где всё является командой, а всё значение — строка. Синтаксис умещается в горстку правил подстановки. Ниже — почти весь язык на одной странице: читай комментарии в коде.
Вывод и комментарии
Программа на Tcl — это последовательность команд. Команда — это первое слово строки, остальное — её аргументы.
# Это комментарий. Он работает ТОЛЬКО там, где Tcl ждёт начало команды.
# puts — команда вывода. Слова после неё — аргументы.
puts "Привет, мир!"
# Каждая строка — отдельная команда. "Всё команда":
# даже if, for, set, proc — это обычные команды, а не ключевые слова.
puts {Фигурные скобки тоже задают строку, но без подстановок}
# Точка с запятой разделяет команды в одной строке
puts "один"; puts "два"
# Комментарий в конце строки требует ; перед #
puts "hi" ;# вот теперь это комментарий
Переменные
Команда set создаёт и изменяет переменные. Знак $ подставляет значение переменной.
# set ИМЯ ЗНАЧЕНИЕ — присваивание
set name "Аня"
set age 25
# $ВАР — подстановка значения переменной
puts "Имя: $name, возраст: $age"
# set с одним аргументом ЧИТАЕТ значение
puts [set name] ;# то же, что $name
# Подстановка $ внутри двойных кавычек работает,
# внутри фигурных скобок — НЕТ (буквальный текст)
puts "value: $age" ;# value: 25
puts {value: $age} ;# value: $age
# unset удаляет переменную
unset age
# ${имя} — явные границы имени переменной
set x 5
puts "${x}0" ;# 50
Строки
В Tcl всё — строка. Число, список, имя — всё это текст. Семейство команд string работает со строками.
set s "Hello, Tcl"
# Длина, индексация, срез
puts [string length $s] ;# 10
puts [string index $s 0] ;# H
puts [string range $s 0 4] ;# Hello
# Регистр
puts [string toupper $s] ;# HELLO, TCL
puts [string tolower $s] ;# hello, tcl
# Поиск и замена подстроки
puts [string first "Tcl" $s] ;# 7 (индекс вхождения)
puts [string map {Tcl Мир} $s] ;# Hello, Мир
# Проверки
puts [string match "Hel*" $s] ;# 1 (glob-шаблон)
puts [string equal $s "Hello"] ;# 0
# Конкатенация и format
set full "$s!!!"
puts [format "%-10s|%05d" abc 42] ;# abc |00042
# {} vs "": кавычки делают подстановку, скобки — нет
set n 3
puts "n=$n" ;# n=3
puts {n=$n} ;# n=$n
Числа и выражения
Сами по себе числа — это строки. Арифметику считает команда expr.
# expr вычисляет математическое выражение
puts [expr {2 + 3 * 4}] ;# 14
puts [expr {10 / 3}] ;# 3 (целочисленное)
puts [expr {10.0 / 3}] ;# 3.333...
puts [expr {10 % 3}] ;# 1 (остаток)
puts [expr {2 ** 10}] ;# 1024 (степень)
# Скобки {} вокруг выражения — хороший тон:
# они откладывают подстановку, expr сам разбирает $переменные
set a 5
set b 2
puts [expr {$a > $b}] ;# 1 (истина)
puts [expr {$a == 5 && $b < 3}] ;# 1
# Математические функции
puts [expr {sqrt(16)}] ;# 4.0
puts [expr {max(3, 7, 2)}] ;# 7
puts [expr {int(3.9)}] ;# 3
# Результат можно сохранить
set sum [expr {$a + $b}]
puts $sum ;# 7
Списки
Список — это строка из слов, разделённых пробелами. Команды list, lindex, lappend и др. работают с ними безопасно.
# Создание списка
set fruits [list apple banana cherry]
set nums {1 2 3 4 5} ;# фигурные скобки — тоже список
# Длина и доступ по индексу (с нуля)
puts [llength $fruits] ;# 3
puts [lindex $fruits 0] ;# apple
puts [lindex $fruits end] ;# cherry
# Добавление элемента (меняет переменную)
lappend fruits date
puts $fruits ;# apple banana cherry date
# Срез, поиск, вставка
puts [lrange $nums 1 3] ;# 2 3 4
puts [lsearch $fruits banana] ;# 1 (индекс)
puts [linsert $nums 0 0] ;# 0 1 2 3 4
# Сортировка и объединение
puts [lsort $fruits] ;# apple banana cherry date
puts [lsort -integer {3 1 2}] ;# 1 2 3
puts [join $nums "+"] ;# 1+2+3+4+5
puts [split "a,b,c" ","] ;# a b c
# Перебор списка
foreach f $fruits {
puts "фрукт: $f"
}
# foreach сразу по двум переменным
foreach {k v} {имя Аня город Москва} {
puts "$k = $v"
}
Условия
if, elseif, else — это команды. Условие лучше брать в фигурные скобки (его вычислит expr).
set score 75
# Классический if/elseif/else
if {$score >= 90} {
puts "отлично"
} elseif {$score >= 60} {
puts "хорошо"
} else {
puts "плохо"
}
# Слово then необязательно. Скобки { } обязательны для тел.
if {$score > 0} {
puts "положительно"
}
# switch — выбор по значению
set cmd "start"
switch $cmd {
start { puts "запуск" }
stop { puts "остановка" }
default { puts "неизвестно" }
}
# switch с шаблонами glob и -- (конец опций)
switch -glob -- "file.txt" {
*.txt { puts "текст" }
*.jpg { puts "картинка" }
}
Циклы
Три основных цикла: for, foreach и while. Тело и условие — в фигурных скобках.
# for {инициализация} {условие} {шаг} {тело}
for {set i 0} {$i < 5} {incr i} {
puts "i = $i"
}
# incr увеличивает переменную (по умолчанию на 1)
set c 10
incr c ;# 11
incr c 5 ;# 16
incr c -1 ;# 15
# while {условие} {тело}
set n 3
while {$n > 0} {
puts "осталось $n"
incr n -1
}
# foreach — самый частый цикл по коллекции
foreach color {красный зелёный синий} {
puts $color
}
# break и continue работают как обычно
for {set i 0} {$i < 10} {incr i} {
if {$i == 3} continue
if {$i == 6} break
puts $i
}
Процедуры
Команда proc создаёт новую команду. Аргументы могут иметь значения по умолчанию и собираться в args.
# proc ИМЯ {аргументы} {тело}
proc greet {name} {
return "Привет, $name!"
}
puts [greet "Аня"] ;# Привет, Аня!
# Значение аргумента по умолчанию
proc power {base {exp 2}} {
return [expr {$base ** $exp}]
}
puts [power 5] ;# 25
puts [power 2 10] ;# 1024
# args собирает переменное число аргументов в список
proc sum {args} {
set total 0
foreach n $args {
set total [expr {$total + $n}]
}
return $total
}
puts [sum 1 2 3 4 5] ;# 15
# Без return процедура возвращает результат последней команды
proc double {x} { expr {$x * 2} }
puts [double 21] ;# 42
# Переменные внутри proc локальны.
# global даёт доступ к глобальной переменной.
set counter 0
proc tick {} {
global counter
incr counter
}
tick; tick
puts $counter ;# 2
Массивы
Массивы в Tcl — это ассоциативные (хеш-таблицы) с ключами-строками. Доступ — через имя(ключ).
# Запись по ключу
set person(name) "Аня"
set person(age) 25
set person(city) "Москва"
# Чтение
puts $person(name) ;# Аня
puts "$person(name), $person(age) лет"
# array — команды для работы с массивом целиком
puts [array size person] ;# 3
puts [array names person] ;# city name age (порядок любой)
puts [array exists person] ;# 1
# Перебор массива
foreach key [array names person] {
puts "$key => $person($key)"
}
# Массив из списка пар ключ-значение
array set colors {red FF0000 green 00FF00 blue 0000FF}
puts $colors(green) ;# 00FF00
# array get превращает массив обратно в список пар
puts [array get colors]
# Удаление элемента
unset person(city)
Подстановка команд
Квадратные скобки [...] выполняют команду и подставляют её результат на это место — ядро композиции в Tcl.
# [команда] выполняется, результат вставляется вместо скобок
set now [clock seconds]
puts "timestamp: $now"
# Вложенность любой глубины
puts [string length [lindex {aa bbb cccc} 2]] ;# 4
# Результат команды — аргумент другой команды
set x [expr {[llength {1 2 3}] * 10}]
puts $x ;# 30
# Внутри " " подстановка [ ] тоже работает
set name "мир"
puts "Длина слова: [string length $name]" ;# Длина слова: 3
# Внутри { } — НЕ работает (буквальный текст)
puts {Тут [команда] не выполнится}
Регулярные выражения
regexp ищет совпадение, regsub заменяет. Шаблон удобно брать в фигурные скобки.
# regexp ШАБЛОН СТРОКА — вернёт 1, если совпадение есть
puts [regexp {[0-9]+} "abc123"] ;# 1
puts [regexp {^\d+$} "abc"] ;# 0
# Захват подвыражений в переменные
set date "2026-06-16"
if {[regexp {(\d+)-(\d+)-(\d+)} $date -> y m d]} {
puts "год=$y месяц=$m день=$d"
}
# -all -inline вернёт список всех совпадений
puts [regexp -all -inline {\d+} "a1 b22 c333"] ;# 1 22 333
# regsub ШАБЛОН СТРОКА ЗАМЕНА — замена
puts [regsub {\s+} "a b" "_"] ;# a_b (первое вхождение)
puts [regsub -all {\d} "a1b2c3" "#"] ;# a#b#c#
# Обратные ссылки \1 в замене
puts [regsub {(\w+)@(\w+)} "user@host" {\2.\1}] ;# host.user
Особенности языка
Главные идеи, которые отличают Tcl от привычных языков.
# 1. ВСЁ — СТРОКА. Число 42, список {1 2 3}, имя — это текст.
set n 42
puts [string length $n] ;# 2 — да, у числа есть "длина"
# 2. ВСЁ — КОМАНДА. if, for, proc, set — обычные команды.
# Поэтому скобки { } у тел обязательны: это аргументы команды.
# 3. ФИГУРНЫЕ СКОБКИ ОТКЛАДЫВАЮТ ПОДСТАНОВКУ.
# " " — подстановка $ и [ ] происходит сразу.
# { } — текст передаётся буквально, без подстановки.
set x 10
puts "сейчас: $x" ;# сейчас: 10
puts {потом: $x} ;# потом: $x
# Именно поэтому условия пишут в { }: чтобы expr/if сами
# решили, КОГДА подставлять переменные.
if {$x > 5} { puts "да" } ;# правильно
# if "$x > 5" ... — подставит сразу, медленнее и опаснее
# 4. Подстановка \ для спецсимволов
puts "строка1\nстрока2\tтаб"
# 5. Команды можно переименовывать и создавать на лету
rename puts say
say "puts теперь зовётся say"