Creating variables programmatically

1,492 views
Skip to first unread message

cormu...@mac.com

unread,
Nov 3, 2015, 8:40:34 AM11/3/15
to julia-users
I can't work out the syntax for creating symbols and assigning values to the variables in a loop. Here's a simple example:

Starting with this basic idea:

    julia> for n in 1:10
                 println("x_$(n)")
              end

I'd like to do this:

    julia> for n in 1:10
                symbol("x_$(n)") = n
              end
       ERROR: syntax: "(string #<julia: "x_"> n)" is not a valid function argument name

to create variables called x_1, x_2, and assign numeric values to them...  (Numbers in this example, but will be image data eventually.)

Also, for better formatting for variable names:

    julia> "x_$(@sprintf "%03d" 2)"
    "x_002"

but this gives a similar error when used with symbol():

    julia> for n in 1:10
                 symbol("x_$(@sprintf "%03d" 2)") = n
            end

    ERROR: syntax: "(string #<julia: "x_"> (let (block (= #21#out (call (. #0=#<julia: Base.Printf> (inert IOBuffer)))) (= #22###x#6979 2) (local #27#neg #26#pt #25#len #20#exp #23#do_out #24#args) (if (call (. #0# (inert isfinite)) #22###x#6979) (block (= (tuple
   #23#do_out #24#args) (call (. #0# (inert decode_dec)) #21#out #22###x#6979 #<julia: "0"> 2 -1 #<julia: Char(0x00000064)>)) (if #23#do_out (block (= (tuple #25#len #26#pt #27#neg) #24#args) (&& #27#neg (call (. #0# (inert write)) #21#out #<julia:
   Char(0x0000002d)>)) (&& (comparison (call (. #0# (inert -)) (call (. #0# (inert -)) 2 #27#neg) #26#pt) (. #0# (inert >)) 0) (call (. #0# (inert write)) #21#out #<julia: Char(0x00000030)>)) (call (. #0# (inert write)) #21#out (call (. #0# (inert pointer)) (. #0# (inert DIGITS)))
   #26#pt)))) (call (. #0# (inert write)) #21#out (block (line 145 printf.jl) (if (call (. #0# (inert isnan)) #22###x#6979) #<julia: "NaN"> (if (comparison #22###x#6979 (. #0# (inert <)) 0) #<julia: "-Inf"> #<julia: "Inf">))))) (. #0# (inert nothing)) (call (. #0# (inert takebuf_string))
  #21#out))))" is not a valid function argument name

Perhaps `symbol` isn't what I want here?

Patrick Kofod Mogensen

unread,
Nov 3, 2015, 9:05:45 AM11/3/15
to julia-users
I know this does _not_ answer your question, but are you really sure you want to do this? Can't you just push your variables to an array, and access them as x[1], x[2], ... ?

Yichao Yu

unread,
Nov 3, 2015, 9:10:09 AM11/3/15
to Julia Users
On Tue, Nov 3, 2015 at 8:40 AM, <cormu...@mac.com> wrote:
> I can't work out the syntax for creating symbols and assigning values to the
> variables in a loop. Here's a simple example:

You can only do this in global scope and you need to do this with
`eval`. (Since you are basically creating an expression at runtime to
execute).

This works.
```
julia> for n in 1:10
@eval $(symbol("x_$n")) = $n
end

julia> x_1
1

julia> x_10
10
```

If you want to do this in local scope, you can either use macro or
other metaprogramming techinques to construct the entire function
body.

e.g. a twisted way to return a tuple from 1 to 10 is
```
julia> @eval function f()
$([:($(symbol("x_$i")) = $i) for i in 1:10]...)
($([symbol("x_$i") for i in 1:10]...),)
end
f (generic function with 1 method)

julia> f()
(1,2,3,4,5,6,7,8,9,10)
```

Alternatively, you can check out the `@nexpr` and related macro[1].

[1] http://julia.readthedocs.org/en/latest/devdocs/cartesian/

cormu...@mac.com

unread,
Nov 3, 2015, 10:27:19 AM11/3/15
to julia-users
Hi Patrick. I'm never sure about things like this, but it seemed like a good approach to investigate. I want to load 20 or so images from disk and access them using predictable names.

cormu...@mac.com

unread,
Nov 3, 2015, 10:28:23 AM11/3/15
to julia-users
Thanks! Looks like a solution.

Dawid Crivelli

unread,
Nov 3, 2015, 11:27:27 AM11/3/15
to julia-users
How about using a dictionary instead of variables, to do something like the following:

images = Dict{AbstractString, Image}()     # dictionary associating an Image object to a string
image
["flower"] = imread("flower.png") # made up function name

Accessing the dictionary won't significantly slow the access to the image data stored in memory, and you can access the images by their reference string, which can depend on input data (e.g. a list of files).

David P. Sanders

unread,
Nov 3, 2015, 12:36:46 PM11/3/15
to julia-users
Using a dictionary is a nice solution, but usually you want the types used for the keys and values to be concrete types, not abstract:

images = Dict{UTF8String, Image}()
Reply all
Reply to author
Forward
0 new messages