symbols, modules and expressions

165 views
Skip to first unread message

Tamas Papp

unread,
Apr 19, 2015, 9:15:39 AM4/19/15
to juli...@googlegroups.com
Hi,

Working on some macros I realize that I have quite a few misconceptions
about Julia's symbols and modules. Most of this is probably the result
of trying to think of Julia as a kind of Common Lisp, which apparently
it isn't. If someone has a few moments then explanations (or pointers to
documentation) would help me greatly. Sorry if the questions are silly,
I think I am stuck in a wrong mental model.

1. Are symbols tied to modules? I thought they were, but apparently they
aren't:

module Foo
givesymbol() = :Quux
end
module Bar
givesymbol() = :Quux
end
Foo.givesymbol() === Bar.givesymbol() # => true

2. Would it be useful to think of Julia symbols as living in the same
single namespace that is unrelated to modules? Ie a symbol is the same
no matter where it was used (interned) first.

3. Does it matter whether a symbol has been interned or not (does the
question even make sense in Julia?)

4. So :(Foo.givesymbol) is not a symbol, but then how should I think of
it?

julia> dump(:(Foo.givesymbol))
Expr
head: Symbol .
args: Array(Any,(2,))
1: Symbol Foo
2: QuoteNode
value: Symbol givesymbol
typ: Any

What is a QuoteNode? I am especially confused because

julia> dump(:(Foo.meaningless.chain))
Expr
head: Symbol .
args: Array(Any,(2,))
1: Expr
head: Symbol .
args: Array(Any,(2,))
1: Symbol Foo
2: QuoteNode
value: Symbol meaningless
typ: Any
2: QuoteNode
value: Symbol chain
typ: Any

Best,

Tamas

Toivo Henningsson

unread,
Apr 19, 2015, 12:39:54 PM4/19/15
to juli...@googlegroups.com
As it seems you might be starting to suspect, a Symbol is just a kind of immutable string, which is used by the Julia parser to represent both identifiers and the types of nodes (the head of an Expr) in the AST. I guess it's fair to say that all symbols are interned.

:(Foo.bar) is just an Expr of type
., eg the dot operator, equivalent to a call to getfield/setfield depending on connect. A QuoteNode quotes its contents; right now :(Foo.(bar)) does not quote bar and so looks up the symbol that is the value of bar instead.

Toivo Henningsson

unread,
Apr 19, 2015, 2:07:04 PM4/19/15
to juli...@googlegroups.com
Also, https://github.com/JuliaLang/julia/pull/6910 will change how symbols are handled quite fundamentally if/when it is merged (which I hope).

Tamas Papp

unread,
Apr 23, 2015, 5:02:39 AM4/23/15
to juli...@googlegroups.com
Thanks. What would be the idomatic way of defining an unique object that
1. can be dispatched on and
2. is in the namespace of a module?

Use case: I have functions with the signature

repack(schema, object, outputtype)

which does something like convert, but behavior can depend on
schema. For the latter, currently I am using Val{:Symbol}, which
satisfies (1) but not (2). Empty types

immutable Schema1 end

can do 1&2, but that seems like an abuse of types and leads to a
proliferation of types (I have 6-7 schemas in my module). Parametric
empty types also work and solve the namespace clutter problem. Are there
better alternatives?

Best,

Tamas

Toivo Henningsson

unread,
Apr 23, 2015, 6:46:09 AM4/23/15
to juli...@googlegroups.com
Not that I can think of. The question to ask yourself is if you really want the JIT to specialize methods on those types. If you do, go ahead and use empty types, parametric or otherwise.

Matt Bauman

unread,
Apr 23, 2015, 7:48:52 AM4/23/15
to juli...@googlegroups.com
If you're on 0.4, you can try enums. I've not played with them yet, but I think they can be dispatched on.
Reply all
Reply to author
Forward
0 new messages