LINUX.ORG.RU

Самый лучший язык для скриптов: Tcl?

 , , , ,


7

5

Кратко: Я немного сравнивал разные языки и выбрал Tcl, при дальнейшем изучении не разочаровался.

А какие языки вы используете для задач средней сложности — тех что не требуют эпохальных тяжеловесных программ, но и не решаются тривиально пайпом из трёх-пяти команд в баше? Средняя сложность — это что-то порядка от 3-5 до 3-5 тысяч строк кода (смотря какой язык). Такие где разбиение программы на отдельные модули, хранимые в разных файлах ещё не требуется.

Длинно. Почему я выбрал Tcl.

Долгое время я писал на bash. Это неплохой язык, к тому же он достаточно выразительный, чтоб делать что угодно без вызова внешних программ и в таком случае производительность получается вполне на уровне.

Но у bash есть проблемы. Основная из которых — многие выражения (в частности пайпы) выполняются в субшелле, а из субшелла почти невозможно передать информацию в материнский иначе через stdout. Ещё одной проблемой является постоянная сериализация-десериализация объектов. Это уже не настолько важно, но всё-таки хотелось бы от этого по возможности избавиться.

То же самое касается других стандартных языков UNIX: dc, bc, sed, m4, awk, ... На последнем, впрочем, наверное, можно писать и нормальные программы, но синтаксис у него не очень красивый и возможностей не так уж много. Это хорошие языки, очень хорошие в своей области, но имеют ограниченную область применения.

Я уже знаю C и несколько других императивных языков, но если нужно что-то быстро посчитать или сделать, эти языки малопригодны — в том же C даже сравнить строки просто так нельзя, нужна специальная функция, кроме того нужно вручную рулить памятью. Pascal крайне беден в экспрессивном плане, а begin / end — это уродливо, так что лучше уж C. Basic уже мёртвый, да к тому же ещё более убог чем паскаль. C++ крайне сложен для изучения, а профита по сравнению с C почти никакого.

Таким образом, стало ясно, что мне нужно изучить какой-то другой язык. Так как язык требуется для того, чтоб быстро решить какую-то задачу, а не писать оптимизированное решение на века, стало ясно, что нужен один из динамических языков общего назначения: Perl, Python, PHP, Ruby, Tcl, Lua или какой-то другой.

Я выбрал Tcl.

1. PHP не подходит сразу, на нём только веб-странички хорошо писать, а всё остальное лучше в Perl (да и про страницы можно поспорить, если нужно чёткое разделение контента, стилей и логики).

1. На Perl, Python и Ruby множество сложных синтаксических конструкций, которые без поллитра не разберёшь, например (python):

_='_=%r;print _%%_';print _%_

2. Lua: простой язык, код на нём быстрый, изучить тоже можно довольно быстро. Но однако на каждый чих нужна либа. Даже работы с юникодом изкоробки нет (в смысле строку можно прочитать и вывести, но нельзя посчитать кол-во символ или заменить подстроку и тд).

3. Tcl: крайне простой синтаксис: 12 правил и man-ы по всем используемым командам достаточно для для понимания любого кода. При этом богатая стандартная библиотека, хорошая интеграция с Tk и кроссплатформенность.

То есть на Tcl можно решить любую задачу почти так же просто как на баше (да в крайнем случае даже пайпы есть), но при этом синтаксис гораздо более предсказуем.

Плюс на Tcl можно писать графические приложения так же легко как и консольные, например вот такой код в 10 строк — это уже целая работающая игра! Правда автор явно экономил строки, и читаемость кода из-за этого несколько страдает. Кроме того, Tcl поддерживает (особенно с 8.6) функциональное программирование и длинные числа изкоробки. Так что переход с bc, который только их и использует будет проще. Ещё мне очень нравится, что ключевых слов в этом языке нет. Вообще. Те же for / if и другие — это просто такие команды, которые берут условие и фрагмент и его исполняют. Можно запросто объявить процедуру for, которая будет использовать другой синтаксис итератора и далее использовать её, если так удобней. Язык динамически типизированный, как и другие скриптовые, но проблем из за этого не возникает. Если переменная используется внутри expr, то она интерпретируется как число. Если в команде string ... на месте строки — строка и тд. Никаких сомнительных x=«10»+10 Работа с переменными похожа на такую в bash, что тоже плюс: при присваивании переменной знак $ не ставится, а при извлечении из неё значения ставится:

set i 10 # i:=10
puts $i ;# будет выведено 10
incr i ;# i теперь 11
puts [expr [set i]+3] ;# set можно использовать вместо $i или ${i}\
так как при отсутствии третьего аргумента он просто возвращает значение.\
Ещё это один из немногих способов двойной подстановки.

4. Что-то другое. А что собственно? Пока только идёт в голову что-то лиспоподобное (например: clisp (scheme (или racket guile))), APL-подобное: J, K (есть свободная Kona), APL и тд или конкатенативное (dc-подобное): forth, factor...

Из 2, 3, 4 выбрал всё-таки Tcl, потому что синтаксис у него хоть и не стандартный для императивных языков, но похож на привычный шелловский и он есть в GNU/Linux изкоробки или в репозитории, так что не придётся заморачиваться ручной сборкой.

Уже начал изучать, почти всё нравится, кроме необходимости писать всё время expr и set, всё-таки такие частые операции можно было бы и сделать частью синтаксиса, хоть и немного в ущерб единообразию.

Быстродействие вначале разочаровала, но потом я почитал про некоторые советы и мои программы стали работать быстрее чем у знакомого, изучающего питон уже больше года.

Учить его действительно легко, так как базовый синтаксис простой, а команды можно изучать по мере надобности, к тому же man к командам Tcl снабжен сносками на команды с похожим назначением, так что поняв, что команда — это не то, что надо, можно посмотреть все остальные и найти наиболее подходящую.

Таким образом, язык сочетает достоинства лиспа — гибкость, функциональщину и простоту базового синтаксиса и достоинства других скриптовых языков — более привычную инфиксную нотацию для арифметики и читаемый код.

★★★★★

Последнее исправление: Xenius (всего исправлений: 5)
Ответ на: комментарий от Xenius

Оберни в функцию и юзай, в чём проблема? А лучше нагугли уже готовую обертку.

cPunk ★★
()
Ответ на: комментарий от harm

Я имею ввиду, что для сложной логики, которая, кроме прочего, сильно подвержена изменениям во времени, нельзя повсеместно использовать невыразительные или костыльные конструкции. В случае перла это текст процессинг, в случае луа это возможность на метатаблицах строить нужные «объектные» модели, чтобы код был прямолинейнее некуда. Шелл рулит тем, что в нем прозрачный бесплатный IPC. Make рулит тем, что он функциональная надстройка над шеллом. Когда предметная область плохо покрыта, возникает куча паразитного кода, который рассыпается и сильно мешает при попытках изменений или рефакторинга.

Я уверен, приведенный пример с инкрами не специфичен для тикля, наверняка есть sum или HOF'ы, но в данном случае выразительность стремится к нулю.

arturpub ★★
()
Ответ на: комментарий от Xenius

У «ё-моё» длина иногда 5, иногда 7. Есть языки, где длина строки в буквах/графемах вообще не имеет смысла, а есть где имеет лишь частично. Язык «поддерживает» уникод, только если в него встроен icu, для кодирования используется UTF-x, а для работы — регулярки. Посимвольные операции больше ничего не значат. На кодировку файловой системы даже стандарта нет. Читай прикрепленную тему про wchar_t.

lua+icu

arturpub ★★
()
Ответ на: Ах ты тостячок от silver-bullet-bfg

А так - Си. В качестве скриптового языка. Чистый Си. Голый Си...В качестве скриптового.

А я что сказал? Я как раз в точности это и сказал: язык C в качестве скриптового не подходит. И где ты бред нашел в этой фразе?

А пацаны то не знают...Передам, поржем.

Покажи хоть одну серьёзную свободную программу, написанную на бейсике. Которой кто-то реально пользуется, у которой есть свои конференции. На Tcl вот сразу в голову приходят Eggdrop и Tkabber, к примеру — самый популярный IRC бот и один из самых популярных IM-клиентов.

set a 118; set b -399; set c 467
set d -128; set e -229 set f 260
set g -111; set h 18
# установить значения переменных a b c d e f g h
set q [scan "жопажопа" %c%c%c%c%c%c%c%c] ;# то же самое что set q [split "жопажопа" {}], только вместо букв в переменную попадут числовые значения символов
set r {}
foreach x $q {
	append r [
	format %c [
	incr x [
	incr a [
	incr b [
	incr c [
	incr d [
	incr e [
	incr f [
	incr g $h]]]]]]]]]
}
# Ну (справа налево) x+=a+=b+=c+=d+=e+=f+=g+=h, после чего вывод x в виде юникодного символа и запихивание всего этого в r.
puts $r
# Если заменить append на lappend и убрать format, получаются числа: 1074 1077 1095 1085 1086 1089 1090 1100

Второй код — функция <, которая преобразует строку примерно таким же образом — каждый символ уменьшает на единицу.

proc transform {step string {l ""}}  {
	foreach sym [split $string {}] {
		append l [format %c [incr [scan $sym %c] $step]]
	}
	return $l
}
puts [transform -1 {зпрб}]

Правда почему-то после того как я его преобразовал он уже не работает...

Код привел выше. Объясняй.

Слишком просто. Мог бы вот этот предложить: http://psg.com/~joem/tcl/iotcc.html Хотя там тоже довольно простенько, обфускация слабовата.

Напиши мне дрова на баше и тикле для видеокарты. (задача же любая)

Сначала напиши их мне на ассемблере (fasm в идеале).

А так -какой к чертовой матери предсказуемый синтаксис в языке, где любое слово можно перегрузить и балом правят макры?!

Синтаксис перегрузить нельзя, зато

Использовать вместо скриптового языка ... factor

А почему нет?

Но почему не тот же Io?

Ну хотя бы потому что там функции вызываются не через function args

Xenius ★★★★★
() автор топика
Последнее исправление: Xenius (всего исправлений: 1)
Ответ на: комментарий от anonymous

А в чём собственно проблема? Пример на практике корректно работает на utf-8 строках с латинскими(1 байт), русскими(2 байта) и японскими(4 байта) символами одновременно.

cPunk ★★
()
Ответ на: комментарий от Xenius

Ну хотя бы потому что там функции вызываются не через function args

*крутит пальцем у виска*

anonymous
()

Никаких скриптовых языков не существует. Bash не для программистов, а для админов, они неучи — им нужно просто и чтобы привычными средствами.

Для любой задачи сложнее mv $1 $2, если есть возможность использовать что-то кроме Bash, лучше сразу закладываться на нормальный язык: Java/Scala/SBCL/D/... Все эти ваши Python, TCL, PHP и Lua все равно дадут о себе знать через 1000 строк и будете все переписывать или колоться и плакать.

metadeu5
()
Ответ на: Ах ты тостячок от silver-bullet-bfg

В tcl нет ни одного слова, которое нельзя было бы перегрузить. Все операторы - функции, которые можно перегрузить.

Я испытал культур^Wбескультурный шок, когда понял в PHP нельзя переопределить ранее определенную функцию. Упираюсь в это, как в каменную стену иногда...

Suntechnic ★★★★★
()
Последнее исправление: Suntechnic (всего исправлений: 1)
Ответ на: комментарий от Xenius

Не прикидывайся. Ты прекрасно понимаешь что скрипт нужно выполнить не в интерактивном интерпретаторе. И надо переключаться на UTF-16 - это тоже не будет считаться.

Suntechnic ★★★★★
()
Ответ на: комментарий от Suntechnic

Убейсо

$ cat 1.tcl 
puts [string toupper "строка на русском"]
$ tclsh 1.tcl 
СТРОКА НА РУССКОМ
$ 
anonymous
()
Ответ на: комментарий от metadeu5

Никаких скриптовых языков не существует. Bash не для программистов, а для админов, они неучи — им нужно просто и чтобы привычными средствами. Для любой задачи сложнее mv $1 $2, если есть возможность использовать что-то кроме Bash, лучше сразу закладываться на нормальный язык: Java/Scala/SBCL/D/... Все эти ваши Python, TCL, PHP и Lua все равно дадут о себе знать через 1000 строк и будете все переписывать или колоться и плакать.

Эталонный БУГУРТ программиста-борщевика.

anonymous
()

А какие языки вы используете для задач средней сложности — тех что не требуют эпохальных тяжеловесных программ, но и не решаются тривиально пайпом из трёх-пяти команд в баше?

Perl. ИМХО, лучший язык программирования.

anonymous
()
Ответ на: комментарий от Xenius

Ну уж ни Python, хотя бы. Хотя, конечно, Scala получше будет, только судя по метаниям вам все равно статическую типизацию не осилить.

metadeu5
()
Ответ на: комментарий от anonymous

Анон упрлс? Java делает из любого борщевика энтырпрайз разработчика больших хайлоуд n-tier scalable софтов с зорплатой в 300 тыщ.

metadeu5
()
Ответ на: комментарий от metadeu5

Ха ха, голый Tcl весит от 300 кб до 1 метра
и позволяет создавать приложения работающие годами и всегда на любых платформах ...

bedcasus
()
Ответ на: комментарий от metadeu5

вам все равно статическую типизацию не осилить.

Почему не осилить? И что, по-твоему джава хорошо подходит для задач средней сложности (пример: решето Эратосфена)?

Вот сколько времени джава будет считать решето до миллиарда? И получится ли код на ней проще чем на C?

Xenius ★★★★★
() автор топика
Ответ на: комментарий от d_a

В тред торжественно приглашается stevejobs как ыксперд по борщу. Гы-гы.

anonymous
()
Ответ на: комментарий от metadeu5

Просто признай, что ты жаву для красного словца приплёл. А сам компилишь ночами под одеялом хелловорлды на Дэ.

anonymous
()
Ответ на: комментарий от anonymous

Зачем? Любой кто может писать хеллофорлды на Дэ может с легкостью днями компилить public static final String за многие тыщи.

metadeu5
()
Ответ на: комментарий от metadeu5

Считать его Джава будет на порядок меньше, чем TCL.

А пруф? Если писать на Tcl нормально, он намного быстрее питона например.

Xenius ★★★★★
() автор топика
Ответ на: комментарий от Xenius

Если писать на Tcl нормально, он намного быстрее питона например.

На одних и тех же достаточно больших задачах? Сомневаюсь. Да и скорость — явно не главное качество в сабжевом контексте (а у питона, минуточку, ещё и pypy есть).

x3al ★★★★★
()
Ответ на: комментарий от x3al

На одних и тех же достаточно больших задачах?

Что именно ты понимаешь под «достаточно больших»?

Впрочем, хочешь померяться — можно попробовать

а у питона, минуточку, ещё и pypy есть

Tcl иногда выигрывает и у него. Вот Cython оказался несколько побыстрее.

Xenius ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

Математика в Tcl не быстрая.

А это как считать. Нет, она конечно не особенно быстрая, но из скриптовых его, похоже обгоняет только Lua, и то не во всём.

Хотя конечно нужны нормальные тесты. Обычно авторы на одном языке пишут код хуже чем на другом и не поймешь, где они правы, а где просто не умеют пользоваться языком.

Вот на Tcl например функции компилятся в байткод, а основной скрипт нет, кроме того, списки работают значительно быстрее массивов, если ими правильно пользоваться. И даже если просто поставить фигурные скобки вокруг выражений expr, это само по себе позволяет код сделать быстрее в несколько раз.

Xenius ★★★★★
() автор топика
Последнее исправление: Xenius (всего исправлений: 1)
Ответ на: комментарий от Xenius

А ну-ка выложил алгоритм для тестов)

anonymous
()
Ответ на: комментарий от Xenius

очевидно же, что никто в здравом уме так не пишет и это целенаправленно сделанная магия.

потратил сейчас 2 минуты, расшифровать до конца в уме не сумел. хочешь, я приведу нипанятную магию на tcl?

val-amart ★★★★★
()
Ответ на: комментарий от val-amart

очевидно же, что никто в здравом уме так не пишет и это целенаправленно сделанная магия. потратил сейчас 2 минуты, расшифровать до конца в уме не сумел

Гы, почему мне этот код понятен без знания петона?

anonymous
()
Ответ на: комментарий от val-amart

хочешь, я приведу нипанятную магию на tcl?

уже пытались

Только вот на Tcl непонятную магию надо специально делать. Может быть только сложный алгоритм и обфусцированные имена переменных. А в питоне часто «непонятная магия» — это самый простой способ что-то сделать. В данном случае это квайн.

Код в Tcl можно обфусцировать и усложнять специально, как и на любом другом языке, но это никак не отменяет того, что сам язык простой и легкопонятный.

В питонах/перлах/руби много разных синтаксических конструкций. Там «непонятная магия» делается не только семантически, но и синтаксически, вот в чём разница.

Хотя в Tcl тоже можно, но это далеко не так просто, ибо именно синтаксических правил всего 12. Ты просто не можешь использовать синтаксис, которого нет в этих правилах, только семантику — команды.

Xenius ★★★★★
() автор топика
Последнее исправление: Xenius (всего исправлений: 1)
Ответ на: комментарий от Xenius

В питонах/перлах/руби много разных синтаксических конструкций. Там «непонятная магия» делается не только семантически, но и синтаксически, вот в чём разница.

Бедный, как же ты русский язык-то осилил. Рубя с пистоном у него непонятные...

anonymous
()
Ответ на: комментарий от Xenius

В питонах/перлах/руби много разных синтаксических конструкций. Там «непонятная магия» делается не только алгоритмически, но и синтаксически, вот в чём разница.

человек, который поставил в один ряд перл, питон и руби рассуждая о синтаксической сложности очевидно поленился пролистать хотя бы туториалы по этим языкам.

В данном случае это квайн.

это я догадался, но не смог ментально представить все этапы. фоматирование строк — единственная известная мне синтаксическая магия в питоне, да и то она deprecated в py3k. ну, разве что есть еще *list и **dict.

val-amart ★★★★★
()
Ответ на: комментарий от metadeu5

То, что получается в результате использования Питонов и Тисиэлев я
бы приложениями называть постеснялся.

Это только характеризует лично Вас, и то, что написать вам явную глупость совсем не стеснительно тут.

bedcasus
()

все знают, что самый лучший язык для скриптов: perl

chg ★★★★★
()
Ответ на: комментарий от Xenius

такое можно на любом языке нахреначить. даже на русском :)
просто не далай так

chg ★★★★★
()
Ответ на: комментарий от val-amart

человек, который поставил в один ряд перл, питон и руби рассуждая о синтаксической сложности очевидно поленился пролистать хотя бы туториалы по этим языкам.

Люто, бешено удваиваю.

anonymous
()
Ответ на: комментарий от val-amart

За там вроде нет «синтаксической магии». Обычные форматные строки, к которым применяется обычный оператор %.

anonymous
()
Ответ на: комментарий от bedcasus

у tcl есть critcl

Чёрт, я о таком 10 лет мечтал!

Вопрос для расширения кругозора: а для других скриптовых ЯП что-нибудь такое есть?

anonymous
()

но если нужно что-то быстро посчитать или сделать, эти языки малопригодны — в том же C даже сравнить строки просто так нельзя, нужна специальная функция, кроме того нужно вручную рулить памятью. Pascal крайне беден в экспрессивном плане, а begin / end — это уродливо, так что лучше уж C. Basic уже мёртвый, да к тому же ещё более убог чем паскаль. C++ крайне сложен для изучения, а профита по сравнению с C почти никакого.

PHP не подходит сразу, на нём только веб-странички хорошо писать, а всё остальное лучше в Perl (да и про страницы можно поспорить, если нужно чёткое разделение контента, стилей и логики).

а почему «нет»?

emulek
()
Ответ на: комментарий от anonymous

хз, что-то должно быть
но у tcl потрошки больно уж стабильные и выписаны хорошо под Си.
есть еще строенный фортран в tcl и перл ))

bedcasus
()
Ответ на: комментарий от x3al


так как и jvm не java, да ?)
все это не проблемы в случае использования tcl
но проблемы других ЯП и подходов.)

bedcasus
()
Ответ на: комментарий от val-amart

поставил в один ряд перл, питон и руби рассуждая о синтаксической сложности

Ну вот скажи, чем питон, перл и руби друг от друга отличаются кроме ключевых слов, некоторых операторов и синтаксиса?

Xenius ★★★★★
() автор топика
Ответ на: комментарий от Xenius

разной корявостью реализации ООП и разной нестабильностью и степени глюкавости )

bedcasus
()
Ответ на: комментарий от x3al

у tcl есть critcl

Это не tcl.

а Odyce считается? http://www.evolane.com/software/odyce/index.html

«Odyce is a dynamic compiler, which allow to embed C code into Tcl scripts. Those C portions will be automatically compiled and translated into native machine code. This is similar to critcl extension, but doesn't require any compiler or headers to be installed on target machine.

Odyce is an experimantal project. It's currently available for Win32 (x86), MacOSX (x86), linux (x86 and arm) and Windows Mobile (arm).»

(как часть проекта eTcl http://www.evolane.com/software/etcl/ )

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.