scope of julia variables: re-assigning within a loop in open expression - scope

I am struggling with re-assigning a variable in a loop in Julia. I have a following example:
infile = "test.txt"
feature = "----"
for ln in 1:3
println(feature)
feature = "+"
end
open(infile) do f
#if true
# println(feature)
# feature = "----"
println(feature)
for ln in 1:5 #eachline(f)
println("feature")
#fails here
println(feature)
# because of this line:
feature = "+"
end
end
It fails if I do reassignment within the loop. I see that the issue with the variable scope, and because nested scopes are involved. The reference says that the loops introduce 'soft' scope. I cannot find out from the manual what scope open expression belongs to, but seemingly it screws things up, as if I replace open with if true, things run smoothly.
Do I understand correctly that open introduces 'hard' scope and that it is the reason why re-assignment retroactively makes the variable undefined?

You should think of
open("file") do f
...
end
as
open(function (f)
...
end, "file")
that is, do introduces the same kind of hard scope as a function or -> would.
So to be able to write to feature from the function, you need to do
open(infile) do f
global feature # this means: use the global `feature`
println(feature)
for ln in 1:5
println("feature")
println(feature)
feature = "+"
end
end
Note that this is only the case in top-level (module) scope; once inside a function, there are no hard scopes.
(The for loop in this case is a red herring; regardless of the soft scope of the loop, the access to feature will be limited by the hard scope of the anonymous function introduced by do.)

Related

Matlab: Exporting variables from ODE45

I have an ODE that uses many functions. I wish to export these "helper" functions so that I may graph them vs the independent variable of the ODE.
function dFfuncvecdW = ODE(W,Ffuncvec);
X = Ffuncvec(1);
y = Ffuncvec(2);
#lots of code
R = ... #R is a function of X,W and y.
#and a few other functions that are a function of X,W and y.
dXdW = ... #some formula
dydW = ... #some formula
dFfuncvecdW = [dXdW; dydW];
end
I call this function with:
Wspan = [0 8000.]
X0 = [0; 1.]
[W,X] = ode45(#ODE, Wspan, X0);
I can easily output X or W to an excel file:
xlswrite(filename,X,'Conversion','A1');
But I what I need is to save "R" and many other functions' values to an Excel file.
How do I do that?
I am still extremely new to Matlab. I usually use Polymath, but for this system of ODE's, Polymath cannot compute the answer within a reasonable amount of time.
EDIT1: The code I use was generated by Polymath. I used a basic version of my problem so that Polymath may excecute the program as it only gives the Matlab code once the Polymath code has succefully run. After the export, the complete set of equations were entered.
The easiest, and possibly fastest, way to handle this is to re-evaluate your functions after ode45 returns W and X. If the functions are vectorized it will be easy. Otherwise, just use a simple for loop that iterates from 1 to length(W).
Alternatively, you can use an output function to save your values on each iteration to a file, or a global, or, most efficiently, a sub-function (a.k.a. nested function) variable that shares scope with an outer function (see here, for example). See this answer of mine for an example of how to use an output function.
I found a rather quick and painless solution to my answer.
I merely appended a text file with code inside the ode function.
EDIT: I am unable to comment because I do have enough rep on this branch of SE.
My solution was add the following code:
fid = fopen('abc1.txt', 'at');
fprintf(fid, '%f\n', T);
fclose(fid);
right above
dYfuncvecdW = [dFAdW; dFBdW; dFCdW; dFDdW; dydW];
at the end of the ode function. This proved to be a temporary solution. I have opened another question about the output I recieved.

Julia automatically generate functions and export them

I want to automatically generate some functions and export them automatically. To have some concrete example, lets say I want to build a module, which provides functions that take a signal and apply a moving average/maximum/minimum/median... to it.
The code generation already works:
for fun in (:maximum, :minimum, :median, :mean)
fname = symbol("$(fun)filter")
#eval ($fname)(signal, windowsize) = windowfilter(signal, $fun, windowsize)
end
Giving me functions
maximumfilter
minimumfilter
...
But how do I export them automatically? e.g. I would like to add some code to the above loop like
export $(fname)
and have each function exported after creation.
You could consider using a macro:
module filtersExample
macro addfilters(funs::Symbol...)
e = quote end # start out with a blank quoted expression
for fun in funs
fname = symbol("$(fun)filter") # create your function name
# this next part creates another quoted expression, which are just the 2 statements
# we want to add for this function... the export call and the function definition
# note: wrap the variable in "esc" when you want to use a value from macro scope.
# If you forget the esc, it will look for a variable named "maximumfilter" in the
# calling scope, which will probably give an error (or worse, will be totally wrong
# and reference the wrong thing)
blk = quote
export $(esc(fname))
$(esc(fname))(signal, windowsize) = windowfilter(signal, $(esc(fun)), windowsize)
end
# an "Expr" object is just a tree... do "dump(e)" or "dump(blk)" to see it
# the "args" of the blk expression are the export and method definition... we can
# just append the vector to the end of the "e" args
append!(e.args, blk.args)
end
# macros return expression objects that get evaluated in the caller's scope
e
end
windowfilter(signal, fun, windowsize) = println("called from $fun: $signal $windowsize")
# now when I write this:
#addfilters maximum minimum
# it is equivalent to writing:
# export maximumfilter
# maximumfilter(signal, windowsize) = windowfilter(signal, maximum, windowsize)
# export minimumfilter
# minimumfilter(signal, windowsize) = windowfilter(signal, minimum, windowsize)
end
when you load it, you'll see the functions are automatically exported:
julia> using filtersExample
julia> maximumfilter(1,2)
called from maximum: 1 2
julia> minimumfilter(1,2)
called from minimum: 1 2
See the manual for more info.

Is there a way to pass a parameter into a NATURAL subroutine?

I am new to the NATURAL programming language. I am trying to find a way that I can pass one parameter to a subroutine just like in C++ or Java. Right now I have to move everything to another variable and call the method. Thus is cumbersome and is a lot more code to write.
Question: Can a Natural Program Sub-Routine have a parameter list like in C++ or Java?
D = passVariable1
PERFORM FLIP-DATE
A = D
END-SUBROUTINE
newVariable = A
Code:
DEFINE SUBROUTINE FLIP-DATE
#A = #D
#B = #E
#C = #F
RESET #NMM #NDD #NCCYY
END-SUBROUTINE
What I would like to do.
Code:
DEFINE SUBROUTINE FLIP-DATE(A,B,C,D,E,F) <-- is this possible somehow?
#A = #D
#B = #E
#C = #F
RESET #NMM #NDD #NCCYY
END-SUBROUTINE
The parameter data area (PDA) is a special verision of the local data area (LDA), that is used in function, external subroutine, or helproutine objects. You can either define parameters inline like
DEFINE DATA
PARAMETER
1 #A(N2)
1 #B(N2)
1 #C(N2)
1 #D(N2)
1 #E(N2)
1 #F(N2)
LOCAL
your local variables
END-DEFINE
…
Alternatively you can also create a separate source object, similar to an external LDA.
DEFINE DATA
PARAMETER USING pda
LOCAL
your local variables
END-DEFINE
…
Note that you cannot use parameters with an internal subroutine.
I suggest you start reading the Natural documentation on Software AG's web site, especially the "First Steps" manual, if you've never worked with this powerful language before.
parameter-data-area can be used to pass the data to sub programs and routines.

Velocity: Is it possible to nest macros that use ## and $bodyContent?

I have a macro that looks essentially like this:
#macro( surround $x )
surround:$x
$bodyContent
/surround:$x
#end
Invocation ##surround("A")bunch o' stuff#end produces "surround:A bunch o' stuff /surround:A" as
expected. Invocation ##surround("A")##surround("B")more stuff#end#end produces
surround:A surround:B more stuff /surround:B /surround:A which is exactly what I want.
But now I want to build upwards with another macro
#macro( annotated-surround $x $y )
##surround( $x )
annotate:$y
$bodyContent
#end
#end
The intended expansion of #annotated-surround( "C" "note" ) stuff #end is
surround:C annotate:note stuff /surround:C
...but this doesn't work; I get the dreaded semi-infinite expansion of the annotated-surround body
content.
I have read the answer at Closure in Velocity template macros and still don't quite know whether what I want to do is possible.
I'm willing to do arbitrarily tricky things within the definitions of #surround and
#annotated-surround, but I don't want the users of those macros to see any complexity. The
whole idea is to simplify their lives.
As long as I have your ear: Setting macro.provide.scope.control=true is supposed to "a local namespace in macros". What does this mean? Is the provided namespace independent of the default context, but with a single such space shared among all invocations of all macros? Or is a separate context provided for each macro invocation, even recursively? It has to be the latter because of $macro.parent, right?
And yet another question. Consider the following macro:
#macro( recursive $x )
#if($x == 0)
zero
#else
$x before . . .
#set($xMinusOne = $x - 1)
#recursive($xMinusOne)
. . . $x after
#end
#end
#recursive( 4 ) yields:
4 before . . .
3 before . . .
2 before . . .
1 before . . .
zero . . .
0 after . . .
0 after . . .
0 after . . .
4 after
Now I understand all those occurrences of "0": there's only one global $x, so assigning to it on
the recursive calls smashes it and it doesn't get restored. But where on earth does that final "4"
come from? For that matter, how is it that my first "surround" macro works to arbitrary depth;
how come its final $x doesn't get smashed in inner calls?
Sorry to be so prolix, but I have been unable to find clear documentation in this matter.
The problem is the combination of global variables, a name collision, and lazy rendering.
Let's walk through the rendering process for ##annotated-surround( "x" "y" )content#end:
Rendering enters the annotated-surround macro. The context map contains:
$x = String x
$y = String y
$bodyContent = Renderable content - note that the String output of this has not yet been evaluated.
Rendering of the first line enters the surround macro. This updates the context map to:
new $x = old $x = String x
$y = String y
$bodyContent = Renderable annotate:$y\n$bodyContent - note that the String output of this still has not yet been evaluated, it's still template code.
Rendering outputs the first line of surround, producing the String surround:x.
Rendering begins evaluating the second line of surround, which references $bodyContent.
Rendering the first line of $bodyContent produces the String annotate:y.
Rendering begins evaluating the second line of $bodyContent, which references $bodyContent.
Rendering the first line of $bodyContent produces the String annotate:y.
Rendering begins evaluating the second line of $bodyContent, which references $bodyContent.
etc.
The solution is to remove part of the problem's combination. Global variables and lazy rendering are fundamental parts of how Velocity works, so you can't touch those. That leaves the name collision. What you need is for each macro's $bodyContent to be referred to with a different name. This is easily achieved by assigning it to new variables with unique names in each macro before invoking any other macros, and using the new variable in any invoked macro's body, like this:
#macro( surround $x )
surround:$x
$bodyContent
/surround:$x
#end
#macro( annotated-surround $x $y )
#set( $annotated-surround-content = $bodyContent )
##surround( $x )
annotate:$y
$annotated-surround-content
#end
#end
Rendering of this version goes like this:
Rendering enters the annotated-surround macro. The context map contains:
$x = String x
$y = String y
$bodyContent = Renderable content - note that the String output of this has not yet been evaluated.
Rendering of the first line executes the #set directive, adding a variable to the context map: $annotated-surround-content = current $bodyContent = Renderable content.
Rendering of the second line enters the surround macro. This updates the context map to:
new $x = old $x = String x
$y = String y
$annotated-surround-content = old $bodyContent = Renderable content
$bodyContent = Renderable annotate:$y\n$annotated-surround-content
Rendering outputs the first line of surround, producing the String surround:x.
Rendering begins evaluating the second line of surround, which references $bodyContent.
Rendering the first line of $bodyContent produces the String annotate:y.
Rendering begins evaluating the second line of $bodyContent, which references $annotated-surround-content.
Rendering $annotated-surround-content produces the String content.
Rendering outputs the third line of surround, producing the String /surround:x.
The final rendered output is surround:x annotate:y content /surround:x. This approach can be generalized by applying such substitutions to all occurrences of $bodyContent that are inside the content of another macro call, each time using a variable name derived from the macro's name to ensure uniqueness. It won't work for recursive macros without something extra to distinguish each nested invocation, however.
Regarding the scope setting, all that does is add a $macro object to the context, which is unique to each macro invocation and can be used as a map. If you set $macro.myVar to something different in each of two nested macro calls, the outer macro's value for it will be unchanged when the inner one finishes. This does not help with the $bodyContent issue, however, because any reference to $macro inside a macro's $bodyContent will be resolved to the innermost macro when it's rendered.
Regarding the final 4 from #recursive( 4 ), that comes from a combination of macro arguments having local scope and being passed by name. For all but the outermost invocation of #recursive, the argument $x is a reference to the global context variable $xMinusOne - when they render the after line, the use of $x is actually resolved to looking up the current value of $xMinusOne in the global context. For the outermost invocation it is instead the constant value 4, and the arguments of the inner invocations go out of scope when they finish, so when the outermost one gets to the final line it's back to being 4.
Starting with the easiest, macro.provide.scope.control=true will definitely create a separate $macro scope object for every macro invocation. Otherwise, as you note, the $macro.parent would be nonsense. The whole point of the "scope controls" is to provide an explicit namespace for the type of VTL block in question. You can even do surround.provide.scope.control=true to automatically create a $surround scope inside of ##surround bodyContent.
On your first question, i'm a little confused as to what's happening. Both the call to ##annotate-surround and the nested call to ##surround will make $bodyContent references available. Am i right that's what happening is that the "wrong" $bodyContent is being used? The $bodyContent reference should belong to the nearest block macro call. To reference the outer macro's $bodyContent within the inner macro, you'll probably need to #set( $macro.bodyContent = $bodyContent ) and then, within the inner, use it via $macro.parent.bodyContent
As for #recursive weirdness, i don't know offhand and have to get on to other work now. It also doesn't help that i don't have Velocity checked out on my present machine, so i can't quickly try things out.

How can I create function pointers from a string input in MATLAB?

If I use the inline function in MATLAB I can create a single function name that could respond differently depending on previous choices:
if (someCondition)
p = inline('a - b','a','b');
else
p = inline('a + b','a','b');
end
c = p(1,2);
d = p(3,4);
But the inline functions I'm creating are becoming quite epic, so I'd like to change them to other types of functions (i.e. m-files, subfunctions, or nested functions).
Let's say I have m-files like Mercator.m, KavrayskiyVII.m, etc. (all taking a value for phi and lambda), and I'd like to assign the chosen function to p in the same way as I have above so that I can call it many times (with variable sized matrices and things that make using eval either impossible or a total mess).
I have a variable, type, that will be one of the names of the functions required (e.g. 'Mercator', 'KavrayskiyVII', etc.). I figure I need to make p into a pointer to the function named inside the type variable. Any ideas how I can do this?
Option #1:
Use the str2func function (assumes the string in type is the same as the name of the function):
p = str2func(type); % Create function handle using function name
c = p(phi, lambda); % Invoke function handle
NOTE: The documentation mentions these limitations:
Function handles created using str2func do not have access to variables outside of their local workspace or to nested functions. If your function handle contains these variables or functions, MATLAB® throws an error when you invoke the handle.
Option #2:
Use a SWITCH statement and function handles:
switch type
case 'Mercator'
p = #Mercator;
case 'KavrayskiyVII'
p = #KavrayskiyVII;
... % Add other cases as needed
end
c = p(phi, lambda); % Invoke function handle
Option #3:
Use EVAL and function handles (suggested by Andrew Janke):
p = eval(['#' type]); % Concatenate string name with '#' and evaluate
c = p(phi, lambda); % Invoke function handle
As Andrew points out, this avoids the limitations of str2func and the extra maintenance associated with a switch statement.

Resources