Что такое "символ" В Юлии?
специально: Я пытаюсь использовать пакет DataFrames Джулии, в частности функцию readtable () с опцией names, но для этого требуется вектор символов.
- что такое символ?
- Почему они выбрали бы это по вектору строк?
до сих пор я нашел только несколько ссылок на символ слова в языке Джулии. Кажется, что символы представлены ":var", но мне далеко не ясно, что они собой представляют являются.
в сторону: Я могу бежать
df = readtable( "table.txt", names = [symbol("var1"), symbol("var2")] )
мои два маркированных вопроса все еще стоят.
1 ответ:
символы в Julia такие же, как в Lisp, Scheme или Ruby. Однако,ответы на эти вопросы не очень удовлетворительным, по-моему. Если Вы читаете эти ответы, кажется, что причина, по которой символ отличается от строки, заключается в том, что строки изменчивы, а символы неизменны, а символы также "интернированы" – что бы это ни значило. Строки действительно бывают изменчивыми в Ruby и Lisp, но они не в Julia, и эта разница на самом деле отвлекающий маневр. Тот факт, что символы интернируются, т. е. хэшируются языковой реализацией для быстрого сравнения равенства, также является неуместной деталью реализации. У вас может быть реализация, которая не интернирует символы, и язык будет точно таким же.
так что же такое символ, на самом деле? Ответ заключается в том, что Джулия и Lisp имеют общее – способность представлять код языка как структуру данных в самом языке. Некоторые люди называют это "гомоиконичность" (Википедия), но другие, похоже, не думают, что одного этого достаточно для того, чтобы язык был гомоиконическим. Но терминология не имеет значения. Дело в том, что когда язык может представлять свой собственный код, ему нужен способ представления таких вещей, как назначения, вызовы функций, вещи, которые могут быть записаны как литеральные значения и т. д. Он также нуждается в способе представления своих собственных переменных. То есть, вам нужен способ представить-как данные -
foo
на левой стороне этого:foo == "foo"
теперь мы подходим к сути дела: разница между символом и строкой-это разница между
foo
на левой стороне этого сравнения и"foo"
С правой стороны. Слева,foo
является идентификатором и вычисляет значение, привязанное к переменнойfoo
в текущей области. Справа,"foo"
является строковым литералом и вычисляет строковое значение "foo". Символ в обоих случаях Lisp и Julia-это то, как вы представляете переменную как данные. Строка просто представляет себя. Вы можете увидеть разницу, применивeval
них:julia> eval(:foo) ERROR: foo not defined julia> foo = "hello" "hello" julia> eval(:foo) "hello" julia> eval("foo") "foo"
что символ
:foo
вычисляется в зависимости от того, что – если что-то-переменнаяfoo
обязательно, тогда как"foo"
всегда просто оценивает "foo". Если вы хотите построить выражения в Julia, которые используют переменные, то вы используете символы (знаете ли вы это или нет). Для пример:julia> ex = :(foo = "bar") :(foo = "bar") julia> dump(ex) Expr head: Symbol = args: Array{Any}((2,)) 1: Symbol foo 2: String "bar" typ: Any
то, что этот выброшенный материал показывает, среди прочего, что есть
:foo
объект символа внутри объекта выражения, который вы получаете, цитируя кодfoo = "bar"
. Вот еще один пример, построение выражения с символом:foo
хранится в переменнойsym
:julia> sym = :foo :foo julia> eval(sym) "hello" julia> ex = :($sym = "bar"; 1 + 2) :(begin foo = "bar" 1 + 2 end) julia> eval(ex) 3 julia> foo "bar"
если вы попытаетесь сделать это, когда
sym
привязан к строке"foo"
, это не сработает:julia> sym = "foo" "foo" julia> ex = :($sym = "bar"; 1 + 2) :(begin "foo" = "bar" 1 + 2 end) julia> eval(ex) ERROR: syntax: invalid assignment location ""foo""
это довольно ясно, чтобы понять, почему это не работа – если вы пытались назначить
"foo" = "bar"
вручную, он также не будет работать.это суть символа: символ используется для представления переменной в метапрограммировании. Если у вас есть символы в качестве типа данных, конечно, становится заманчиво использовать их для других вещей, таких как хэш-ключи. Но это случайное, оппортунистическое использование типа данных, которое имеет другую основную цель.
обратите внимание, что я перестал говорить о Руби некоторое время назад. Это потому что Руби нет homoiconic: Ruby не представляет свои выражения как объекты Ruby. Таким образом, тип символа Ruby – это своего рода рудиментарный орган-оставшаяся адаптация, унаследованная от Lisp, но больше не используемая для своей первоначальной цели. Символы Ruby были кооптированы для других целей - как хэш-ключи, чтобы вытащить методы из таблиц методов-но символы в Ruby не используются для представления переменных.
что касается того, почему символы используются в кадрах данных, а не в строках, это потому, что это общий шаблон в Фреймы данных для привязки значений столбцов к переменным внутри пользовательских выражений. Поэтому естественно, что имена столбцов являются символами, поскольку символы-это именно то, что вы используете для представления переменных в качестве данных. В настоящее время, вы должны написать
df[:foo]
кfoo
столбец, но в будущем вы можете получить к нему доступ какdf.foo
вместо. Когда это станет возможным, только столбцы, имена которых являются допустимыми идентификаторами, будут доступны с помощью этого удобного синтаксиса.посмотреть также: