Парадигма | Мультипарадигмальный : событийно-ориентированный , функциональный , императивный , объектно-ориентированный |
---|---|
Разработано | Джон Оустерхаут |
Разработчик | Основная команда Tcl [1] |
Впервые появился | 1988 ( 1988 ) |
Стабильный релиз | 9.0.0 [2] / 26 сентября 2024 г. ( 26 сентября 2024 ) |
Дисциплина набора текста | Динамическая типизация , все является строкой |
Лицензия | BSD -стиль [3] |
Расширения имени файла | .tcl, .tbc [4] |
Веб-сайт | www.tcl-lang.org www.tcl.tk |
Основные внедрения | |
ActiveTcl Андройш | |
Диалекты | |
Джим, Игл | |
Под влиянием | |
AWK , Лисп | |
Под влиянием | |
PHP , [5] PowerShell , [6] Чай , TH1 [7] |
Tcl (произносится как « тикл » или как аббревиатура [8] ) — это высокоуровневый , универсальный , интерпретируемый , динамический язык программирования . Он был разработан с целью быть очень простым, но мощным. [9] Tcl отливает все в форму команды , даже такие программные конструкции, как назначение переменных и определение процедур. [10] Tcl поддерживает несколько парадигм программирования , включая объектно-ориентированный , императивный , функциональный и процедурный стили.
Он обычно используется встроенным в приложения C , [11] для быстрого прототипирования , скриптовых приложений, графических интерфейсов и тестирования. [12] Интерпретаторы Tcl доступны для многих операционных систем , что позволяет запускать код Tcl на самых разных системах. Поскольку Tcl является очень компактным языком, он используется на платформах встроенных систем , как в своей полной форме, так и в нескольких других малогабаритных версиях. [13]
Популярное сочетание Tcl с расширением Tk называется Tcl/Tk (произносится как «тикл тик» или как аббревиатура ) и позволяет создавать графический пользовательский интерфейс (GUI) нативно на Tcl. Tcl/Tk включен в стандартную установку Python в виде Tkinter .
Язык программирования Tcl был создан весной 1988 года Джоном Оустерхаутом , когда он работал в Калифорнийском университете в Беркли . [14] [15] Первоначально он «родился из разочарования», [11] по словам автора, программистами, разрабатывающими свои собственные языки для расширения программного обеспечения автоматизации электронного проектирования (EDA) и, в частности, инструмента проектирования СБИС Magic , который был профессиональным направлением Джона в то время. [16] Позже Tcl получил признание сам по себе. Оустерхаут был награжден премией ACM Software System Award в 1997 году за Tcl/Tk. [17]
Первоначально название произошло от слова Tool Command Language , но традиционно пишется Tcl, а не TCL . [18]
Дата | Событие |
---|---|
Январь 1990 г. | Tcl анонсирован за пределами Беркли (зимний USENIX ). |
Июнь 1990 г. | Ожидается анонс (летний USENIX). |
Январь 1991 г. | Первое объявление о Tk (Winter USENIX). |
Июнь 1993 г. | Первая конференция Tcl/Tk (Беркли). На ней анонсированы менеджер геометрии [table] (предшественник [grid]), [incr Tcl] , TclDP и Groupkit. |
Август 1997 г. | В Tcl 8.0 появился компилятор байт-кода. [19] |
Апрель 1999 г. | Tcl 8.1 представляет полную поддержку Unicode [20] и расширенные регулярные выражения . [21] |
Август 1999 г. | Tcl 8.2 представляет архитектуру расширения Tcl (TEA) [22] |
Август 2000 г. | Сформирована основная команда Tcl, что позволило перевести Tcl на модель разработки, более ориентированную на сообщество. [1] |
Сентябрь 2002 г. | Девятая конференция Tcl/Tk (Ванкувер). Анонс системы упаковки starkit. Выпущен Tcl 8.4.0. [23] |
Декабрь 2007 г. | В Tcl 8.5 добавлены новые типы данных, новый репозиторий расширений, bignums , [24] лямбда-выражения . [25] [26] |
Декабрь 2012 г. | В Tcl 8.6 добавлена встроенная динамическая объектная система, TclOO и оценка без стека. [27] |
Сентябрь 2024 г. | В Tcl 9.0 добавлены 64-битные возможности, поддержка всего диапазона кодовых точек Unicode, используются epoll и kqueue [28] |
Конференции и семинары Tcl проводятся как в Соединенных Штатах, так и в Европе. [29] Несколько корпораций, включая FlightAware [30], используют Tcl как часть своих продуктов.
Возможности Tcl включают в себя:
uplevel
, но позволяет upvar
процедурам взаимодействовать с областями действия включающих функций.Safe-Tcl — это подмножество Tcl, которое имеет ограниченные функции, так что скрипты Tcl не могут нанести вред их хост-машине или приложению. [33] Доступ к файловой системе ограничен, и выполнение произвольных системных команд запрещено. Он использует модель двойного интерпретатора с ненадежным интерпретатором, выполняющим код в ненадежном скрипте. Он был разработан Натаниэлем Боренштейном и Маршаллом Роузом для включения активных сообщений в электронную почту. Safe-Tcl может быть включен в электронную почту, когда поддерживаются application/safe-tcl и multipart/enabled-mail . Функциональность Safe-Tcl с тех пор была включена как часть стандартных выпусков Tcl/Tk. [34] [35]
Синтаксис и семантика Tcl описываются двенадцатью правилами [36], известными как Додекалог. [37]
Скрипт Tcl состоит из серии вызовов команд. Вызов команды — это список слов, разделенных пробелом и завершающихся новой строкой или точкой с запятой. Первое слово — это имя команды, которая может быть встроена в язык, найдена в доступной библиотеке или определена в самом скрипте. Последующие слова служат аргументами команды:
имя_команды аргумент1 аргумент2 ... аргументN
В следующем примере команда puts (сокращение от «put string») используется для отображения строки текста на консоли хоста:
ставит "Привет, мир!"
Это отправит строку «Hello, World!» на стандартное устройство вывода вместе с добавленным символом новой строки.
Переменные и результаты других команд можно подставлять в строки, как в этом примере, где команды set и expr используются для сохранения результата вычисления в переменной (обратите внимание, что Tcl не использует =
в качестве оператора присваивания), а затем используется puts для вывода результата вместе с некоторым пояснительным текстом:
# expr вычисляет текстовую строку как набор выражений sum [expr 1 + 2 + 3 + 4 + 5 ] puts "Сумма чисел 1..5 равна $sum."
Персонаж #
вводит комментарий . Комментарии могут появляться в любом месте, где интерпретатор ожидает имя команды.
# с фигурными скобками подстановка переменных выполняется с помощью expr set x 1 set sum [expr { $x + 2 + 3 + 4 + 5 }]; # $x не подставляется перед передачей параметра в expr; # expr заменяет 1 вместо $x при вычислении выражения puts "Сумма чисел 1..5 равна $sum." ; # сумма равна 15
# без фигурных скобок подстановка переменных происходит в месте определения (лексическая область видимости) set x 2 set op * set y 3 set res [expr $x$op$y ]; # $x, $op и $y подставляются, и выражение вычисляется как 6 puts "$x $op $y is $res." ; # $x, $op, $y и $res подставляются и вычисляются как строки
Как видно из этих примеров, в языке есть одна базовая конструкция: команда. Механизмы цитирования и правила подстановки определяют, как обрабатываются аргументы каждой команды.
Одна специальная подстановка происходит перед разбором любых команд или аргументов. Если последний символ в строке (т. е. непосредственно перед новой строкой) является обратной косой чертой, то комбинация обратной косой черты и новой строки (и любые пробелы или табуляции, следующие сразу за новой строкой) заменяются одним пробелом. Это обеспечивает механизм продолжения строки , посредством которого длинные строки в исходном коде могут быть перенесены на следующую строку для удобства читателей.
Продолжая обычную обработку аргументов, слово, начинающееся с символа двойной кавычки ( "
), расширяется до следующего символа двойной кавычки. Таким образом, такое слово может содержать пробелы и точки с запятой, и эти символы не будут интерпретироваться как имеющие какое-либо особое значение (т. е. они будут рассматриваться как обычные текстовые символы). Слово, начинающееся с открывающей фигурной скобки ( {
), расширяется до следующей закрывающей фигурной скобки ( }
). Внутри фигурных скобок все формы подстановки подавляются, за исключением ранее упомянутого исключения обратной косой черты и новой строки. Слова, не заключенные ни в одну из конструкций, называются голыми словами.
В простых и заключенных в двойные кавычки словах могут иметь место три типа замены:
[expr 1+2+3]
заменяется на результат оценки содержащегося выражения (в данном случае 6).$foo
заменяется содержимым переменной с именем "foo". Имя переменной может быть заключено в фигурные скобки, чтобы отделить его от последующего текста в случаях, когда это может быть неоднозначно (например, ${foo}ing
).\n
заменяется на новую строку.Замена выполняется слева направо за один проход по каждому слову. Любой замененный текст не будет повторно сканироваться на предмет возможных дальнейших замен. Однако в одном слове может быть любое количество замен.
Начиная с версии Tcl 8.5, к любому слову может добавляться префикс {*}
, который приводит к разделению слова на составляющие его подслова для целей построения вызова команды (аналогично последовательности ,@
функции квазицитирования Lisp ).
Вследствие этих правил результат любой команды может быть использован в качестве аргумента любой другой команды. Обратите внимание, что в отличие от командных оболочек Unix , Tcl не перерабатывает никакие строки, если это явно не указано, что делает интерактивное использование более громоздким, но скриптовое использование более предсказуемым (например, наличие пробелов в именах файлов не вызывает трудностей).
Одинарный знак равенства ( =
) не играет никакой особой роли в языке. Двойной знак равенства ( ==
) — это проверка на равенство, которая используется в таких контекстах выражений, как expr
команда и в первом аргументе if
. (Обе команды являются частью стандартной библиотеки; они не занимают особого места в библиотеке и могут быть заменены при желании.)
Большинство команд Tcl, особенно в стандартной библиотеке, являются вариативными , а proc
(конструктор для процедур скриптовых команд) позволяет определять значения по умолчанию для неуказанных аргументов и универсальный аргумент, позволяющий коду обрабатывать произвольное количество аргументов.
Tcl не является статически типизированным: каждая переменная может содержать целые числа, числа с плавающей точкой, строки, списки, имена команд, словари или любые другие значения; значения переинтерпретируются (с учетом синтаксических ограничений) как другие типы по требованию. Однако значения неизменяемы , и операции, которые, как кажется, изменяют их, на самом деле просто возвращают новое значение.
Наиболее важными командами, относящимися к выполнению программ и операциям с данными, являются:
set
записывает новое значение в переменную (создает переменную, если она не существует). Если используется только с одним аргументом, возвращает значение указанной переменной (в этом случае она должна существовать).proc
определяет новую команду, выполнение которой приводит к выполнению заданного скрипта Tcl, записанного в виде набора команд. return
может использоваться для немедленного возврата управления вызывающей стороне.Обычные команды управления выполнением:
if
выполняет заданное тело скрипта (второй аргумент), если условие (первый аргумент) выполнено. За ним могут следовать дополнительные аргументы, начиная с elseif
альтернативного условия и тела, или else
с дополнительного блока.while
повторяет выполнение указанного тела скрипта до тех пор, пока условие (первый аргумент) остается выполненнымforeach
выполняет заданное тело, где управляющей переменной присваиваются элементы списка один за другим.for
сокращение для инициализации управляющей переменной, условия (как в while
) и дополнительного оператора «следующая итерация» (команда, выполняемая после выполнения тела)Вышеуказанные команды циклов могут дополнительно контролироваться следующими командами:
break
прерывает выполнение тела и возвращается из команды циклаcontinue
прерывает выполнение тела, но управление все равно возвращается к команде цикла. Для while
это означает повторный цикл, для for
и foreach
, подхватывает следующую итерацию.return
прерывает выполнение текущего тела независимо от глубины процедуры, пока не будет достигнута граница процедуры, и возвращает указанное значение вызывающему.expr
передает аргумент в отдельный интерпретатор выражений и возвращает оцененное значение. Обратите внимание, что тот же интерпретатор используется также для "условных" выражений for if
и циклических команд.list
создает список, содержащий все аргументы, или пустую строку, если аргумент не указан. lindex
Команда может быть использована для результата, чтобы повторно извлечь исходные аргументы.array
манипулирует переменными массива .dict
манипулирует словарем (начиная с версии 8.5), представляющим собой списки с четным числом элементов, где каждые два элемента интерпретируются как пара ключ/значение.regexp
сопоставляет регулярное выражение со строкой.regsub
Выполняет замены на основе сопоставления шаблонов регулярных выражений.uplevel
— это команда , которая позволяет выполнить командный скрипт в области, отличной от текущей самой внутренней области в стеке.upvar
создает ссылку на переменную в другом стековом фрейме.namespace
позволяет создавать, получать доступ и уничтожать отдельные контексты для команд и переменных.apply
применяет анонимную функцию (начиная с версии 8.5).coroutine
, yield
, а также yieldto
создавать и выдавать значения из сопрограмм (начиная с версии 8.6).try
позволяет перехватывать и обрабатывать ошибки и исключения.catch
позволяет вам получать исключительную прибыль.zlib
обеспечивает доступ к возможностям сжатия и контрольного суммирования библиотеки Zlib (начиная с версии 8.6).uplevel
позволяет командному скрипту выполняться в области, отличной от текущей внутренней области в стеке. Поскольку командный скрипт может сам вызывать процедуры, использующие команду uplevel , это имеет чистый эффект преобразования стека вызовов в дерево вызовов. [38]
Первоначально он был реализован, чтобы позволить процедурам Tcl повторно реализовывать встроенные команды (например, for , if или while ) и при этом иметь возможность манипулировать локальными переменными . Например, следующий скрипт Tcl является повторной реализацией команды for (без обработки исключений ):
proc для { initCmd testExpr advanceCmd bodyScript } { uplevel 1 $initCmd set testCmd [ list expr $testExpr ] while {[uplevel 1 $testCmd ]} { uplevel 1 $bodyScript uplevel 1 $advanceCmd } }
upvar
организует для одной или нескольких локальных переменных в текущей процедуре ссылку на переменные в охватывающем вызове процедуры или на глобальные переменные . Команда upvar упрощает реализацию вызова процедур по имени, а также упрощает построение новых конструкций управления в качестве процедур Tcl. [39]
Команда decr, которая работает так же, как встроенная incr
команда, за исключением того, что она вычитает значение из переменной, а не прибавляет его:
proc decr { varName { decrement 1 }} { upvar 1 $varName var incr var [expr { -$decrement }] }
В Tcl 8.6 в 2012 году была добавлена встроенная динамическая объектная система TclOO. [31] Она включает в себя такие функции, как:
oo :: class create fruit { method eat {} { puts "yummy!" } } oo :: class create banana { superclass fruit constructor {} { my variable peeled set peeled 0 } method peel {} { my variable peeled set peeled 1 puts "skin now off" } method edible ? {} { my variable peeled return $peeled } method eat {} { if { ! [ my edible ? ]} { my peel } next } } set b [ banana new ] $b eat → prints "skin now off" and "yummy!" fruit destroy $b eat → error "unknown command"
Tcl не имел объектно-ориентированного (OO) синтаксиса до 2012 года, [31] поэтому появились различные пакеты расширений для включения объектно-ориентированного программирования. Они широко распространены в существующем исходном коде Tcl. Популярные расширения включают в себя:
TclOO был добавлен не только для построения сильной объектно-ориентированной системы, но и для того, чтобы позволить пакетам расширения строить объектно-ориентированные абстракции, используя его в качестве основы. После выпуска TclOO, incr Tcl был обновлен для использования TclOO в качестве своей основы. [27]
Tcl Web Server — это реализация HTTP-сервера на чистом Tcl. Он работает как скрипт поверх ванильного интерпретатора Tcl.
Apache Rivet — это система программирования с открытым исходным кодом для Apache HTTP Server , которая позволяет разработчикам использовать Tcl в качестве языка сценариев для создания динамических веб-приложений. Rivet похож на PHP , ASP и JSP . Rivet был изначально разработан Дэймоном Кортни, Дэвидом Уэлтоном, Массимо Манги, Харальдом Ольманном и Карлом Лехенбауэром . Rivet может использовать любой из тысяч общедоступных пакетов Tcl, которые предлагают бесчисленные функции, такие как взаимодействие с базами данных (Oracle, PostgreSQL, MySQL, SQLite и т. д.) или интерфейсы для популярных приложений, таких как библиотека GD Graphics .
Tcl изначально взаимодействует с языком C. [40] Это связано с тем, что изначально он был написан как фреймворк для предоставления синтаксического интерфейса для команд, написанных на C, и все команды в языке (включая то, что в противном случае могло бы быть ключевыми словами , такими как if
или while
) реализованы таким образом. Каждой функции реализации команды передается массив значений, которые описывают (уже подставленные) аргументы команды, и она может интерпретировать эти значения по своему усмотрению.
Цифровые логические симуляторы часто включают в себя интерфейс сценариев Tcl для моделирования аппаратных языков Verilog , VHDL и SystemVerilog .
Существуют инструменты (например, SWIG , Ffidl) для автоматической генерации необходимого кода для соединения произвольных функций C и среды выполнения Tcl, а Critcl делает обратное, позволяя встраивать произвольный код C в скрипт Tcl и компилировать его во время выполнения в DLL .
Язык Tcl всегда допускал пакеты расширений, которые предоставляют дополнительные функции, такие как графический интерфейс, автоматизация приложений на базе терминала, доступ к базе данных и т. д. Обычно используемые расширения включают: