Что такое "символ" В Юлии?


специально: Я пытаюсь использовать пакет DataFrames Джулии, в частности функцию readtable () с опцией names, но для этого требуется вектор символов.

  • что такое символ?
  • Почему они выбрали бы это по вектору строк?

до сих пор я нашел только несколько ссылок на символ слова в языке Джулии. Кажется, что символы представлены ":var", но мне далеко не ясно, что они собой представляют являются.

в сторону: Я могу бежать

df = readtable( "table.txt", names = [symbol("var1"), symbol("var2")] )

мои два маркированных вопроса все еще стоят.

1 82

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 вместо. Когда это станет возможным, только столбцы, имена которых являются допустимыми идентификаторами, будут доступны с помощью этого удобного синтаксиса.

посмотреть также: