@lattice_states
generic macro¶Based on Cory Simon's Nested loops via recursion article.
VERSION
v"0.5.0-dev+2446"
"""
`@lattice_states(lattice::Expr, loop_level::Int)`
Prints all possible `lattice_state` vectors`of a given `lattice` up to `loop_level` nesting.
## Parameters
* `lattice`: A `Vector{Int}` literal expression, ie: `[1, -1]`.
* `loop_level`: An `Int`, ie: `4`.
## Usage
```
julia> @lattice_states [-1, 1] 4
[-1,-1,-1,-1]
[-1,-1,-1,1]
[-1,-1,1,-1]
[-1,-1,1,1]
[-1,1,-1,-1]
[-1,1,-1,1]
[-1,1,1,-1]
[-1,1,1,1]
[1,-1,-1,-1]
[1,-1,-1,1]
[1,-1,1,-1]
[1,-1,1,1]
[1,1,-1,-1]
[1,1,-1,1]
[1,1,1,-1]
[1,1,1,1]
```
## Macro expansion
```
julia> macroexpand(:(@lattice_states [-1, 1] 4))
:(for #3#state = [-1,1] # none, line 71:
([0,0,0,0])[1] = #3#state # none, line 72:
for #3#state = [-1,1] # none, line 71:
([0,0,0,0])[2] = #3#state # none, line 72:
for #3#state = [-1,1] # none, line 71:
([0,0,0,0])[3] = #3#state # none, line 72:
for #3#state = [-1,1] # none, line 71:
([0,0,0,0])[4] = #3#state # none, line 72:
println([0,0,0,0])
end
end
end
end)
```
## Misusage
```
julia> @lattice_states [-1.0, 1.0] 4
ERROR: AssertionError: `lattice` must be a Vector{Int} literal expression, ie [1, -1], got: [-1.0,1.0].
julia> @lattice_states [-1, 1] 4.0
ERROR: MethodError: `@lattice_states` has no method matching @lattice_states(::Expr, ::Float64)
julia> @lattice_states [-1, 1] -4
ERROR: AssertionError: loop_level must be an Int greater than 0, got: -1.
```
"""
macro lattice_states(lattice::Expr, loop_level::Int)
@assert(
lattice.head == :vect && all(x -> issubtype(typeof(x), Int), lattice.args),
"`lattice` must be a Vector{Int} literal expression, ie [1, -1], got: $lattice."
)
@assert loop_level > 0 "loop_level must be an Int greater than 0, got: $loop_level."
lattice_state = zeros(Int, loop_level)
inner = :(println($lattice_state))
outer = inner
for i = reverse(1:loop_level)
outer = :(
for state in $lattice
$lattice_state[$i] = state
$outer
end
)
end
return outer
end
@lattice_states (macro with 1 method)
@lattice_states [-1, 1] 2
[-1,-1] [-1,1] [1,-1] [1,1]
@lattice_states [-1, 1] 4
[-1,-1,-1,-1] [-1,-1,-1,1] [-1,-1,1,-1] [-1,-1,1,1] [-1,1,-1,-1] [-1,1,-1,1] [-1,1,1,-1] [-1,1,1,1] [1,-1,-1,-1] [1,-1,-1,1] [1,-1,1,-1] [1,-1,1,1] [1,1,-1,-1] [1,1,-1,1] [1,1,1,-1] [1,1,1,1]
macroexpand(:(@lattice_states [-1, 1] 2))
:(for #26#state = [-1,1] # In[2], line 71: ([0,0])[1] = #26#state # In[2], line 72: for #26#state = [-1,1] # In[2], line 71: ([0,0])[2] = #26#state # In[2], line 72: println([0,0]) end end)
macroexpand(:(@lattice_states [-1, 1] 4))
:(for #31#state = [-1,1] # In[2], line 71: ([0,0,0,0])[1] = #31#state # In[2], line 72: for #31#state = [-1,1] # In[2], line 71: ([0,0,0,0])[2] = #31#state # In[2], line 72: for #31#state = [-1,1] # In[2], line 71: ([0,0,0,0])[3] = #31#state # In[2], line 72: for #31#state = [-1,1] # In[2], line 71: ([0,0,0,0])[4] = #31#state # In[2], line 72: println([0,0,0,0]) end end end end)
macroexpand(:(@lattice_states [-1, 1] 8))
:(for #42#state = [-1,1] # In[2], line 71: ([0,0,0,0,0,0,0,0])[1] = #42#state # In[2], line 72: for #42#state = [-1,1] # In[2], line 71: ([0,0,0,0,0,0,0,0])[2] = #42#state # In[2], line 72: for #42#state = [-1,1] # In[2], line 71: ([0,0,0,0,0,0,0,0])[3] = #42#state # In[2], line 72: for #42#state = [-1,1] # In[2], line 71: ([0,0,0,0,0,0,0,0])[4] = #42#state # In[2], line 72: for #42#state = [-1,1] # In[2], line 71: ([0,0,0,0,0,0,0,0])[5] = #42#state # In[2], line 72: for #42#state = [-1,1] # In[2], line 71: ([0,0,0,0,0,0,0,0])[6] = #42#state # In[2], line 72: for #42#state = [-1,1] # In[2], line 71: ([0,0,0,0,0,0,0,0])[7] = #42#state # In[2], line 72: for #42#state = [-1,1] # In[2], line 71: ([0,0,0,0,0,0,0,0])[8] = #42#state # In[2], line 72: println([0,0,0,0,0,0,0,0]) end end end end end end end end)
@lattice_states [-1.0, 1.0] 2
LoadError: AssertionError: `lattice` must be a Vector{Int} literal expression, ie [1, -1], got: [-1.0,1.0]. while loading In[9], in expression starting on line 1 [inlined code] from ./essentials.jl:80 in include_string(Base.#include_string, ASCIIString, ASCIIString) at ./loading.jl:371
@lattice_states [-1, 1] 2.0
LoadError: MethodError: `@lattice_states` has no method matching @lattice_states(::Expr, ::Float64) Closest candidates are: @lattice_states(::Expr, !Matched::Int64) while loading In[10], in expression starting on line 1 [inlined code] from ./essentials.jl:80 in include_string(Base.#include_string, ASCIIString, ASCIIString) at ./loading.jl:371
@lattice_states [-1, 1] -1
LoadError: AssertionError: loop_level must be an Int greater than 0, got: -1. while loading In[11], in expression starting on line 1 [inlined code] from ./essentials.jl:80 in include_string(Base.#include_string, ASCIIString, ASCIIString) at ./loading.jl:371