One More Program and I'm Out!

Given a positive integer nesting level n and string s of printable ascii characters( to ~, output a program which, when run in the same language, outputs a program which outputs a program . . . which outputs the string s.

A total of n programs should be generated, all of which should be run in the same language as your answer.

Note: you may output programs or functions -- anything you are allowed by default as a submission.

You may input s with escaped characters, how a program or function in your language would usually input a string.

Example

For example, given n=1 and s="recursion", a Python 2 program might output:

print "recursion"


Running this would output:

recursion


Given n=2 and s="PPCG", a Python 2 program might output:

print "print \"PPCG\" "


Running this outputs:

print "PPCG"


Running this outputs:

PPCG


Related (+title inspiration): One more LUL and I'm out

Also Related (in sandbox - now deleted, but can still be viewed with enough reputation): Source Code Recursion

Test Cases

Make sure that your code works for the following test cases (one per line):

n s
2 PPCG
4 Robert'); DROP TABLE Students;--
17 Deep
2 Spaces In Here
3 "Don't forget quotes!"
5 'Backtcks might be a htch'
6 5%s
8 [Brackets]<Are>(Great){Usually}

f=->n,s{"$><<%p"%(n>1?f[n-1,s]:s)}  Try it online! R, 62 bytes f=function(n,s){"if"(n,{formals(f)$n=n-1;formals(f)$s=s;f},s)}  Try it online! Call it like so: f(n,s) followed by n copies of () A named function; returns an anonymous function. All it does is modify the default values of the formals of f, allowing the resulting function to be called (and then the result of that called, n times). when n reaches 0, it returns s. R is actually not too bad at escaping! It uses C-style escaping, so you just have to take the input, replace " with \" and \ with \\, and then wrap the whole thing in " ". Underload, 11 bytes (a(S)*)~^^S  Try it online! Input needs to start on the stack, with the number on top in the form of a church numeral. I don't know if this is a valid input method, but the specification has no input, and placing input to the top of the stack seems like a stranded method used in such languages. APL (Dyalog), 24 23 bytes -1 thanks to ngn. This is a full program which prompts for s and then for n and prints to STDOUT. ''''{⍺,⍨⍺,⍵/⍨1+⍵=⍺}⍣⎕⊢⍞  Try it online! (the 17 Deep case is omitted as it exceeds TIO's output limit – works offline) ⍞ prompt for s ⊢ yield that (to separate ⎕ and ⍞) ''''{}⍣⎕ prompt for n and apply this lambda with a single quote as left argument that many times. ⍺ stands for the left argument (the quote) and ⍵ is stands for the right argument (the input text): ⍵=⍺ Boolean where the text is equal to a quote 1+ add one ⍵/⍨ replicate each character of the argument the corresponding number of times ⍺, prepend a quote ⍺,⍨ append a quote This works because strings in APL are ' delimited and single-quotes in strings are doubled, while no other characters need escaping. Dyalog APL also ships with a utility (⎕SE.Dyalog.Utils.repObj) that generates an APL expression which evaluates to its argument (similar to Jelly's uneval). The following program is therefore equivalent to the above, but works for all arrays: ⎕SE.Dyalog.Utils.repObj⍣⎕⊢⎕  Try it online! • I think APLX allows "doubly-" as well as 'singly-quoted' strings. If the rest works there, you can save a byte :) ngn/apl used to but I removed "" recently – ngn Sep 30 '17 at 10:10 • Consider passing the quote as ⍺.- that saves (at least) a byte. – ngn Sep 30 '17 at 10:16 • @ngn Thanks, but APLX doesn't have dfns. NARS2000 has both double-quotes and and dfns, but characters cost two bytes each. – Adám Oct 2 '17 at 7:30 QuadR, 8 bytes Simple translation of ngn's answer. Takes n as argument and s as Input. ^|'|$
'&


Try it online!

PCRE Replace all instances of

^|'|$ Beginning of line OR Quote OR End of line '& with a Quote and the entire match The Argument specifies how many times to repeat the transformation. • ah, now I know what that language is for :) – ngn Oct 2 '17 at 17:47 APL (Dyalog Classic), 19 bytes '^|''|$'⎕r'''&'⍣⎕⊢⍞


Try it online!

• That's very clever. I tried this approach, but didn't think of prepending. – Adám Oct 2 '17 at 7:09
• Sell also this. – Adám Oct 2 '17 at 7:17

As of when I write this, this is the shortest answer for a non-golfing-specific language.

It is a function which takes s and n in that order, and returns the result or the source code of an expression which, when evaluated, returns the next source code.

(!!).iterate show


Argument for why this counts:

1. Solutions are allowed to be functions.
2. Their outputs are allowed to be functions.
3. Those functions have no parameters.
4. In Haskell, since it is lazy and everything-is-curried, the most natural — for practical programming purposes — definition of a 0-parameter function is the same as its result; the closest alternative, a 1-parameter function which ignores the parameter, is silly.

If f is given PPCG and 2 as its parameters, the result is the text "\"PPCG\"" (first generated function), which when evaluated returns the text "PPCG" (second generated funtion), and when that is evaluated it returns PPCG.

Thanks to nimi for suggesting a shortening.

• There is a relevant Meta question on the issue of functions with no arguments in Haskell, though it hasn't received that much attention yet and still has open questions: codegolf.meta.stackexchange.com/q/12924/56433 – Laikoni Sep 29 '17 at 6:48

JavaScript (ES6), 47 44 bytes

Saved 3 bytes thanks to @HermanLauenstein

Takes input in currying syntax (n)(s).

n=>g=s=>alert(atob("${btoa(--n?g(s):s)}"))  Example f(2)('PPCG')  Will output: 'alert(atob("YWxlcnQoYXRvYigiVUZCRFJ3PT0iKSk="))'  Which will print: 'alert(atob("UFBDRw=="))'  Which will print: 'PPCG'  Demo A more complex example where alert() has been overridden so that intermediate results are printed to the console and automatically executed. let f = n=>g=s=>alert(atob("${btoa(--n?g(s):s)}"))

alert = s => { console.log(s); try { eval(s); } catch(e) {} }

alert(f(5)("'Backtcks might be a htch'"));

Alternate version, 40 bytes

Suggested by @Shaggy

This one returns an anonymous function instead of a full program.

n=>g=s=>_=>atob("${btoa(--n?g(s):s)}")  • Could you return an anonymous function, instead of using the alert? 41 bytes – Shaggy Sep 28 '17 at 9:00 • @Shaggy I don't really know. I've asked the OP. – Arnauld Sep 28 '17 at 9:08 • If not, maybe you could get away with an IIFE instead for 45 bytes. – Shaggy Sep 28 '17 at 9:09 • -3 bytes using currying: n=>g=s=>BTalert(atob("${btoa(--n?g(s):s)}"))BT (replace BT with backticks) – Herman L Sep 28 '17 at 17:41
• @HermanLauenstein Thanks! :) – Arnauld Sep 28 '17 at 17:55

Java 8, 95 93 bytes

String c(String s,int n){return"v->\""+(n-->1?c(s,n).replaceAll("[\\\\\"]","\\\$0"):s)+'"';}  -2 bytes thanks to @Lynn. Escaping special characters is so annoying in Java.. Explanation: String c(String s,int n){ // Method with String and int parameters and String return-type return"v->\""+ // Return literal "v->" + a leading double-quote + (n-->1? // If n is larger than 1: c(s,n) // Recursive-call, .replaceAll("[\\\\\"]","\\\$0")
//    with all double-quotes ('"') and slashes ('\') escaped
:                      //   Else:
s)                    //    The input String
+'"';                   //   + a trailing double quote
}                          // End of method


Additional explanation for the regex replacement:

Jelly, 2 bytes

Ṿ¡


Try it online!

Ṿ¡  Main link; left argument (text) is x, right argument (repetitions) is y
¡  Repeat y times:
Ṿ   Uneval x; produce code that outputs x


hehe builtins

• This is broken, "hi" produces hi, not "hi" – Tahg Sep 28 '17 at 0:41
• @Tahg Jelly input is automatically evaluated as Python code if it doesn't throw an error. If it does, then it's just a string. You'd have to do '"hi"' to see the expected outcome – HyperNeutrino Sep 28 '17 at 0:42