Often when running exprimental code to empirically investigate an algorithm, you tweak a parameter, then rerun the code, and generate a bunch of saved models for various parameters.To make sure I don't loose what the parameters were set to I defined a macro that saves there values.module Utilusing JLDexport @param_save #...function names_candidates(blk::Expr)    names_in_block = Vector{Symbol}()    for a in blk.args        typeof(a) <: Expr || continue        if a.head == :(=)            push!(names_in_block, a.args[1])        else #Recurse, so we captured things in blocks or behind `const`            append!(names_in_block, names_candidates(a))        end    end    names_in_blockendmacro param_save(filename, blk::Expr)    names_in_block =  names_candidates(blk)    quote        $(esc(blk))        names_defined = Set($(names_in_block))  Set(names(current_module()))        names_and_vals =[(string(name), eval(name)) for name in names_defined]        println(Paramaters -- saving to $($filename))        println(----------)        println(join(($n = $v for (n,v) in names_and_vals),\n))        JLD.save($filename, Base.flatten(names_and_vals)...)        println(----------)    endend#...end #moduleUsage:using Utilbase_name = paper_v1param_save_fn =  ../models/adagram/$(base_name).params.jldoutput_fn = ../models/adagram/$(base_name).adagram_model#file to save the model (in Julia format)@assert !isfile(output_fn)@param_save param_save_fn begin        nprocessors = nprocs()        train_fn  =  ../data/corpora/WikiCorp/tokenised_lowercase_WestburyLab.wikicorp.201004.txt #training text data        output_fn = output_fn #file to save the model (in Julia format)        dict_fn = ../data/corpora/WikiCorp/tokenised_lowercase_WestburyLab.wikicorp.201004.1gram #dictionary file with word frequencies        window = 10 #(max) window size C in the paper        min_freq  = 20 #min. frequency of the word        remove_top_k = 0 #remove top K most frequent words        dim  = 300 #dimensionality of representations        prototypes = 5 #number of word prototypes T in the paper        alpha = 0.15 #prior probability of allocating a new prototype        d  = 0.0 #parameter of Pitman-Yor process D in paper        subsample = 1e-5 #subsampling treshold. useful value is 1e-5        context_cut  = true #randomly reduce size of the context        epochs = 1 #number of epochs to train        initcount = 1. #initial weight (count) on first sense for each word        stopwords = Set{AbstractString}() #list of stop words        sense_treshold = 1e-10 #minimal probability of a meaning to contribute into gradients        save_treshold = 0.0 #minimal probability of a meaning to save after trainingendOutput:Paramaters -- saving to ../models/adagram/paper_v1btempexample.params.jld----------train_fn = ../data/corpora/WikiCorp/tokenised_lowercase_WestburyLab.wikicorp.201004.txtalpha = 0.15subsample = 1.0e-5sense_treshold = 1.0e-10initcount = 1.0nprocessors = 1epochs = 1window = 10output_fn = ../models/adagram/paper_v1btempexample.adagram_modelmin_freq = 20prototypes = 5context_cut = truestopwords = Set{AbstractString}()remove_top_k = 0save_treshold = 0.0dict_fn = ../data/corpora/WikiCorp/tokenised_lowercase_WestburyLab.wikicorp.201004.1gramdim = 300d = 0.0----------Writing code with macros is hard.It took me a few shots to get the escaping all right.Is this reasonable code?AFAICT julia doesn't have a method like pythons locals() that lists all variables in a given scope. So I have to work around that by finding possible variables in the AST then cross referencing that against all variables in the module.
Saving the values of all variabled declared in a block
macros;julia