Open code statement recursion detected during exporting a file - recursion

I try to export a file in SAS but I get "Open code statement recursion detected." error. Since I export more than one files depending on date I define as a macro variable based on the prompt date, I want to name my file to be exported with this variable but it does not work. I would really appreciate if anyone helps me.
rep_date = 30APR2015:00:00:00
Outfile = work.A042015.sas7
%let var = CATS("A",MONTH(DATEPART(&rep_date)),YEAR(DATEPART(&rep_date)));
data WORK.&var(compress=yes); 
set WORK.have;
run; 

Macro variables are just strings. So if you want to execute functions in macro code you need to wrap the function inside of the %SYSFUNC() macro function.
%let rep_date='01JAN2015:01:23'dt ;
%let dsname = A%sysfunc(datepart(&rep_date),monyy6);
data &dsname(compress=yes);
set have;
run;

As a more broad issue, OPEN STATEMENT RECURSION DETECTED refers to cases where you assign a macro variable to itself.
%let &mvar = &mvar;
Of course, this wouldn't normally happen on purpose (one would think). When it does happen, usually it's a sign of one of two classes of mistake.
You're missing a semicolon, end parenthesis, end quote, or something else that causes SAS to not "see" the semicolon at the end of the %let statement. Then your next statement uses the macro variable in a macro context, and SAS sees that as part of the %let statement, which causes this error message.
Something went wrong somewhere else, and you have an issue where that something-else propagates errors further down that don't make any sense. Having an unmatched quotation is a classic example of this, as is a macro that doesn't properly %mend.
1 can happen in cases as simple as this:
%let mvar=mydataset
%put &mvar;
Oops. If it's that simple, then just pop the semicolon on and you're good. It could, however, be caused by something more significant - such as an unmatched parenthesis or quotation - which might require restarting your SAS session. (Sometimes submitting a magic string, which are variations on %*;*;*';*";%*%mend;*);, will fix things, sometimes not. Restarting SAS is a reliable way to fix that).
That's also true with 2 above - if a magic string doesn't fix it, then you may simply need to restart your SAS session. Of course, you still need to find that unmatched quote/parenthesis/etc., but you first need to start SAS over so you can figure it out.

Related

Julia print statement not working in certain cases

I've written a prime-generating function generatePrimes (full code here) that takes input bound::Int64 and returns a Vector{Int64} of all primes up to bound. After the function definition, I have the following code:
println("Generating primes...")
println("Last prime: ", generatePrimes(10^7)[end])
println("Primes generated.")
which prints, unexpectedly,
Generating primes...
9999991
Primes generated.
This output misses the "Last prime: " segment of the second print statement. The output does work as expected for smaller inputs; any input at least up to 10^6, but somehow fails for 10^7. I've tried several workarounds for this (e.g. assigning the returned value or converting it to a string before calling it in a print statement, combining the print statements, et cetera) and discovered some other weird behaviour: if the "Last prime", is removed from the second print statement, for input 10^7, the last prime doesn't print at all and all I get is a blank line between the first and third print statements. These issues are probably related, and I can't seem to find anything online about why some print statements wouldn't work in Julia.
Thanks so much for any clarification!
Edit: Per DNF's suggestion, following are some reductions to this issue:
Removing the first and last print statements doesn't change anything -- a blank line is always printed in the case I outlined and each of the cases below.
println(generatePrimes(10^7)[end]) # output: empty line
Calling the function and storing the last index in a variable before calling println doesn't change anything either; the cases below work exactly the same either way.
lastPrime::Int = generatePrimes(10^7)[end]
println(lastPrime) # output: empty line
If I call the function in whatever form immediately before a println, an empty line is printed regardless of what's inside the println.
lastPrime::Int = generatePrimes(10^7)[end]
println("This doesn't print") # output: empty line
println("This does print") # output: This does print
If I call the function (or print the pre-generated-and-stored function result) inside a println, anything before the function call (that's also inside the println) isn't printed. The 9999991 and anything else there may be after the function call is printed only if there is something else inside the println before the function call.
# Example 1
println(generatePrimes(10^7)[end]) # output: empty line
# Example 2
println("This first part doesn't print", generatePrimes(10^7)[end]) # output: 9999991
# Example 3
println("This first part doesn't print", generatePrimes(10^7)[end], " prints") # output: 9999991 prints
# Example 4
println(generatePrimes(10^7)[end], "prime doesn't print") # output: prime doesn't print
I could probably list twenty different variations of this same thing, but that probably wouldn't make things any clearer. In every single case version of this issue I've seen so far, the issue only manifests if there's that function call somewhere; println prints large integers just fine. That said, please let me know if anyone feels like they need more info. Thanks so much!
Most likely you are running this code from Atom Juno which recently has some issues with buffering standard output (already reported by others and I also sometimes have this problem).
One thing you can try to do is to flush your standard output
flush(stdout)
Like with any unstable bug restarting Atom Juno also seems to help.
I had the same issue. For me, changing the terminal renderer (File -> Settings -> Packages -> julia-client -> Terminal Options) from webgl to canvas (see pic below) seems to solve the issue.
change terminal renderer
I've also encountered this problem many times. (First time, it was triggered after using the debugger. It is probably unrelated but I have been using Julia+Juno for 2 weeks prior to this issue.)
In my case, the code before the println statement needed to have multiple dictionary assignation (with new keys) in order to trigger the behavior.
I also confirmed that the same code ran in Command Prompt (with same Julia interpreter) prints fine. Any hints about how to further investigate this will be appreciated.
I temporarily solve this issue by printing to stderr, thinking that this stream has more stringent flush mechanism: println(stderr, "hello!")

Ada program to detect an end of line

I was assigned this task as my homework. I have a file which contains lines of text of varying lengths. The program is supposed to write the data onto the screen in precisely the same order in which it is written in the file, yet it fails to do so. To achieve the desired result I tried reading only one character per iteration so as to detect new line characters. What am I doing wrong?
WITH Ada.Text_IO;
WITH Ada.Characters.Latin_1;
USE Ada.Text_IO;
PROCEDURE ASCII_artwork IS
File : File_Type;
c : Character;
BEGIN
Open(File, In_File, "Winnie_The_Pooh.txt");
WHILE NOT End_Of_File(File) LOOP
Get(File, C);
IF (C = Ada.Characters.Latin_1.LF) THEN Put_Line(" "); ELSE
Put(C);
END IF;
END LOOP;
Close(File);
END ASCII_Artwork;
For each file, the Ada runtime maintains a fictitious "cursor". This is not the typical file position cursor (index), but one that indicates the position on a page, line, etc. (see also RM A.10 (7)). This is somewhat of an inheritance from the early versions of Ada.
Get stems from this same era and is expected to update the location of this cursor when some particular control characters are being read (e.g. an end-of-line mark). If Get reads such such a control character, it will only use it to update the cursor (internally) and then continue to read a next character (see also RM A.10.7 (3)). You'll therefore never detect an end-of-line mark when using Get.
This behavior, however, has some uncomfortable consequence: if a file ends with a sequence of control characters, then Get will keep reading those characters and hit the end of the file causing an End_Error exception.
You can, of course, catch this exception and handle it, but such a construct is dubious as having a sequence of control characters at the end of a file is actually not such an abnormal case (and hence dubious if worth an exception). As a programmer, however, you cannot change this behavior: it's defined by the language and the language will not be changed because it has been decided to keep Ada (highly) backwards compatible (which in itself is understandable given its field of application).
Hence, in your case, if you want stick to a character-by-character processing approach, I would suggest to move away from Get and instead use (for example) streams to perform I/O as in the example below.
main.adb
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Text_IO.Text_Streams; use Ada.Text_IO.Text_Streams;
procedure ASCII_artwork IS
File : File_Type;
Input : Stream_Access;
Output : Stream_Access;
C : Character;
begin
Open (File, In_File, "Winnie_The_Pooh.txt");
Input := Stream (File);
Output := Stream (Standard_Output);
while not End_Of_File (File) loop
Character'Read (Input, C);
Character'Write (Output, C);
end loop;
Close(File);
end ASCII_Artwork;
Output is as expected (i.e. the content of this the file at ascii-art.de).
NOTE: Check the source code of the GNAT runtime to actually see how Get works internally (focus on the loop at the end).
As explained by DeeDee, text inputs are buffered linewise in Ada. The idea is to be able to read two integers on the same line. For consistency sake (the designers of Ada are picky on that...), Get(File, C) does the same. It is not practical in your case. Fortunately, Ada 95 has introduced Get_Immediate, to solve precisely that issue.
Otherwise, as suggested by Frédéric, you could use the function Get_Line to absorb Winnie_The_Pooh.txt line by line seamlessly. By the way, the Get_Line method will convert the different end-of-line conventions automatically.
Line terminators in Ada.Text_IO are a concept, not a character or sequence of characters in the file. (Although most commonly used file systems implement them as characters or sequences of characters in the file, there exist file systems that do not.) Line terminators must therefore be manipulated using the operations in the package. For reading, End_Of_Line checks to see if the cursor is at a line terminator, Skip_Line skips the next line terminator, and Get_Line may skip a line terminator. For writing, New_Line and Put_Line write line terminators.
For your problem, the canonical solution is to use the Get_Line function to read lines, and Put_Line to output the lines read.

I'm getting the following error: "top-level scope at ./REPL[1]:4" when I run my julia program

So here's the code I was trying to execute in Julia:
i = begin
i = 5
while(i<=10)
println(i)
i+=1
end
end
It's just basically a simple code to print the value of i from 5 to 10 but it's messing with me
Are you in the REPL? What you are probably running into is that begin does not introduce its own scope, so i = 5 declares i as a global variable. Because while does introduce its own scope, if you do println(i), it only looks for i in its local scope where it is not defined, because i exists only as a global variable. You can add a line global i at the beginning of the body of the while loop to tell all code after that to use the global i, but note that global variables come with their own performance caveats. An arguably better solution would be to use let instead of begin, which does introduce a new scope, but note that then you can of course not access i afterwards, because it is now only local to the let block.
This behavior will actually be changed in the upcoming release of Julia 1.5, so your code should then just work.
Your issue is scope. When you enter into a loop, variables created inside the loop are local to the loop and destroyed after it exits. i is not currently defined inside your while loop, so you get the error. The quick fix is to tell Julia you want the loop to have access to the global i variable you defined at the top by adding global i immediately after the while statement. You also don't need the begin block, and naming the block i is immediately overwritten by the next statement defining i.

How to quit/exit from file included in the terminal

What can I do within a file "example.jl" to exit/return from a call to include() in the command line
julia> include("example.jl")
without existing julia itself. quit() will just terminate julia itself.
Edit: For me this would be useful while interactively developing code, for example to include a test file and return from the execution to the julia prompt when a certain condition is met or do only compile the tests I am currently working on without reorganizing the code to much.
I'm not quite sure what you're looking to do, but it sounds like you might be better off writing your code as a function, and use a return to exit. You could even call the function in the include.
Kristoffer will not love it, but
stop(text="Stop.") = throw(StopException(text))
struct StopException{T}
S::T
end
function Base.showerror(io::IO, ex::StopException, bt; backtrace=true)
Base.with_output_color(get(io, :color, false) ? :green : :nothing, io) do io
showerror(io, ex.S)
end
end
will give a nice, less alarming message than just throwing an error.
julia> stop("Stopped. Reason: Converged.")
ERROR: "Stopped. Reason: Converged."
Source: https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/12
You have a latent need for a debugging workflow in Julia. If you use Revise.jl and Rebugger.jl you can do exactly what you are asking for.
You can put in a breakpoint and step into code that is in an included file.
If you include a file from the julia prompt that you want tracked by Revise.jl, you need to use includet(.
The keyboard shortcuts in Rebugger let you iterate and inspect variables and modify code and rerun it from within an included file with real values.
Revise lets you reload functions and modules without needing to restart a julia session to pick up the changes.
https://timholy.github.io/Rebugger.jl/stable/
https://timholy.github.io/Revise.jl/stable/
The combination is very powerful and is described deeply by Tim Holy.
https://www.youtube.com/watch?v=SU0SmQnnGys
https://youtu.be/KuM0AGaN09s?t=515
Note that there are some limitations with Revise, such as it doesn't reset global variables, so if you are using some global count or something, it won't reset it for the next run through or when you go back into it. Also it isn't great with runtests.jl and the Test package. So as you develop with Revise, when you are done, you move it into your runtests.jl.
Also the Juno IDE (Atom + uber-juno package) has good support for code inspection and running line by line and the debugging has gotten some good support lately. I've used Rebugger from the julia prompt more than from the Juno IDE.
Hope that helps.
#DanielArndt is right.
It's just create a dummy function in your include file and put all the code inside (except other functions and variable declaration part that will be place before). So you can use return where you wish. The variables that only are used in the local context can stay inside dummy function. Then it's just call the new function in the end.
Suppose that the previous code is:
function func1(...)
....
end
function func2(...)
....
end
var1 = valor1
var2 = valor2
localVar = valor3
1st code part
# I want exit here!
2nd code part
Your code will look like this:
var1 = valor1
var2 = valor2
function func1(...)
....
end
function func2(...)
....
end
function dummy()
localVar = valor3
1st code part
return # it's the last running line!
2nd code part
end
dummy()
Other possibility is placing the top variables inside a function with a global prefix.
function dummy()
global var1 = valor1
global var2 = valor2
...
end
That global variables can be used inside auxiliary function (static scope) and outside in the REPL
Another variant only declares the variables and its posterior use is free
function dummy()
global var1, var2
...
end

How do I define a macro with the same name as its expansion in m4?

I am attempting to replace if with if( using GNU m4 1.4.14 and I am receiving ERROR: end of file in argument list
when trying:
define(`if', `if(')
define(`then', `){')
define(`fi', `}')
if foo then bar() fi
I have tried escaping the parentheses but that caused m4 to error after a brief period of time saying it's out of memory. Scanning through the manual, I found nothing related to this problem.
Upon changing the name of the macro to 'IF' or something other than 'if', it works as expected, which leads me to believe it's evaluating itself repeatedly.
If so, how can I define a macro that is evaluated only once? Otherwise, what should I look into to fix this?
EDIT I found a way around this issue by processing twice, once to convert if to _IF and the next to convert _IF to if(. I assume there's a better way to do this, so this is only a temporary solution in my eyes.
You need to prevent m4 from attempting to re-expanding the replacements. Do so by double quoting:
define(`if', ``if('')
define(`then', `){')
define(`fi', `}')
if foo then bar() fi

Resources