Pull to refresh

Comments 19

Насчет токенов. Вы считаете неправильно и нечестно, многие языки имеют совершенно разное лексическое строение. Например:
  • вы не учли знак подчеркивания в именах
  • вы не учли строки
  • многие си-подобные языки позволяют использовать знак доллара в идентификаторах
  • в перле у идентификаторов используются префиксы из спецсимволов, в старых бейсиках — суффиксы
  • в типичной программе на APL, J или K буквы встречаются не часто :)
  • кстати, сколько токенов ваш парсер насчитает в brainfuck'е?
  • в форте и ему подобных в словах используются любые печатаемые непробельные символы, и это только в простом случае, т.к. в форте программа может сама парсить свой текст в общем случае чтобы разбить его на токены его понадобиться выполнить
  • наконец на Rosetta Code часто можно встретить хорошо комментированный код, это немного портит и правильность подсчета строк и симолов
То о чем вы говорите имеет отношение только к близости языков.

Так-то токеном считается при подсчете любая конструкция, по сути, разделенная пробелом (или другим white-space знаком).

Да, стоит учесть, хотя каких-либо критических изменений не будет.

Спасибо за четкие указания, сделаю UPD позже. Я, безусловно, на 600 языках не программирую, поэтому знать особенности каждого не могу.
Тут и кроме пробелов остается довольно много символов:
tokens[str_String]:=DeleteCases[StringSplit[str, Complement[Characters@FromCharacterCode[Range[1, 127]], CharacterRange["a", "z"], CharacterRange["A", "Z"], CharacterRange["0", "9"], {"."}]], ""];


Подсчет токенов работает неправильно даже в вашем языке. Например здесь:
tokenCount[str_String]:=Length[tokens[str]];

ваш «токенизатор» насчитал 6 токенов. Это не токенизатор, он работает только как счетчик идентификаторов в Mathematica, и к другим языкам не применим.

P.S. Еще как оказалось во многих решениях на APL и J представлен не только код, а копия команд из REPL'а и их результат. Так, например, транспонирование матрицы на J плюс вывод созданной матрицы размером 5 строк, плюс результат транспонирования размером 4 строки, превращается в 11 строк, при том что реального кода здесь 2 строки.
Вы видимо пот токеном понимаете что-то «особое» (или обязательно рабочий фрагмент кода). То, что в приведенном вами примере выдается 6 токенов — вполне разумно, их там именно столько.

В моей статье (по аналогии со статьей Джона) был принят подход с токенами для того, чтобы компенсировать длину названий функций и переменных, что явно верно учитывается в количестве символов кода (а то, в одном языке что-то вызывается как sin, а в другом как mathematicalsin, условно говоря, хотя по сути это одна единица).

Этот подход себя оправдывает, потому что две другие функции (количество символов и строк) дают те же результаты.

Можно также говорить о том, что в Wolfram Language есть полная форма выражения, тогда оно будет выглядеть как

CompoundExpression[SetDelayed[tokenCount[Pattern[str, Blank[String]]], Length[tokens[str]]], Null]


и в нем будет 11 токенов.

Можно говорить о том, что еще более «глубоко», верным будет выражение в боксах:

RowBox[{RowBox[{RowBox[{"tokenCount", "[", "str_String", "]"}], ":=", 
    RowBox[{"Length", "[", RowBox[{"tokens", "[", "str", "]"}], 
      "]"}]}], ";"}]


которое опять же выдаст 11 токенов.

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

Вы всегда можете предложить свое решение или предложить правильную версию токенизатора, учитывающую все особенности всех языков — это в целом не плохой вариант был бы вашей дебютной статьи на Хабре.
Обновил функцию. Теперь есть вариант, в котором отсутствует хоть какая-то очистка. Отрадно, что как я и думал, результат изменился несущественно.
Можно добавить в список: лексический анализатор Питона выдает два специальных токена INDENT и DEDENT, которые обозначают увеличение и уменьшение уровня отступа, соответсвенно. Было бы логично их тоже считать за токены.
Мне кажется или в упорядоченных графиках MatLab пропал?
Он не самый популярный на RosettaCode, он примерно на месте так 65-м выходил, насколько помню. Многие графики построены для первых 30 языков, часть для 50-ти. Только несколько для 80-ти.
А, точно, не заметил изменения масштаба при переходе от 80 к 50… Думал это та же самая, но упорядоченная картинка.
Здорово)

Логотип у него — огонь)

image
Из статьи стало понятно, что Дельфи и Паскаль ни на что не похожи и, конечно, гораздо меньше распространенны, чем Ада, лисп, фортран, бейсик и т.п.
Там просто было 50 языков, а на неотфильтрованной — 80.

Это, безусловно, путает. Поэтому исправил, теперь на этих диаграммах с усами везде по 80 языков.
Спасибо! Получается, что oforth один из самых выразительных языков.
Да, получается так. Его синтаксис действительно интересен весьма:

: fact ( n -- n1 )
   | i | 1 n loop: i [ i * ] ;
Wolfram Language было приятно узнать, что он получается самым «компактным» языком, с одной стороны, с другой стороны его объективная «непохожесть» на другие языки, очевидно, делает вхождение в него несколько сложнее.
Мне кажется, тут проблема скорее не в сложности, а в «чистоте стиля», чтобы код, написанный одним человеком, легко читался другим. В вашем коде используются то подстановки, то функции, то чистые, то «грязные», и сложно сходу понять, является ли выбор конкретной семантики оптимальным или же у вас просто стиль такой.

Я, например, довольно активно использую постфиксную запись — пишу не
ListPlot[Log[Abs[Fourier[data]]]],
а
ListPlot[data//Fourier//Abs//Log],
чтобы минимизировать количество вложенных скобок и выделить первичное над вторичным.
Тут много вариантов, может и префиксный быть:

ListPlot@Log@Abs@Fourier@data

Правые и левые композиции

ListPlot@*Log@*Abs@*Fourier@*data
Fourier/*Abs/*Log/*ListPlot@data

Wolfram Language просто позволяет очень свободно писать код, это правда, отсюда и свой стиль, хотя часто определенные конструкции быстрее работают, что уже с опытом приходит. А другие конструкции проще реализовать.
Sign up to leave a comment.