title: loading a common racket header into current toplevel
body: <p>There's a simple code section I'd like to share among a few racket scripts I wrote. I don't want to (require ..) it, but want to run it at top level (the common code includes calls to (current-command-line-arguments), etc. that a required module doesn't understand (at least I don't know if that's possible).</p>
  
  <p>I try (load)'ing it, but it doesn't work as it was part of the current top-level context - I get an unbound identifier error in the loading context for a definition that's defined in the common header.</p>
  
  <p>It seems I still don't understand some sections of the chapter 14 of the racket reference - I tried some examples of 14.1 (namespaces), 14.3 (racket/load) but couldn't get it working.</p>
  
  <p>What am I missing? How can we make such a seemingly simple case work? </p>
  
  <p>Edit: Here is an example from my case:</p>
  
  <p>this is header.rkt:</p>
  
  <pre><code>#lang racket/load
  
  (define-for-syntax args (current-command-line-arguments))
  (define-for-syntax PROTOTYPING (or
                              (= (vector-length args) 0)
                              (equal? (vector-ref args 0) "local")))
  
  (define-syntax (if-prototyping stx)
    (syntax-case stx ()
      ((_ debug-expr non-debug-expr)
       (if PROTOTYPING
           #'debug-expr
           #'non-debug-expr))))
  
  (if-prototyping
   (require (prefix-in "ci:" (file "/debugenvpath/utils.rkt")))
   (require (prefix-in "ci:" (file "/releaseenvpath/utils.rkt"))))
  
  ; arrange arguments
  (define args (current-command-line-arguments))
  (if-prototyping
   (set! args (if (= (vector-length args) 0)
                  (vector "arg1")
                  (vector (vector-ref args 1))))
   #t)
  </code></pre>
  
  <p>and this is a file that uses it (let's call this test.bat):</p>
  
  <pre><code>; @echo off
  ; "C:\Program Files\Racket\racket.exe" "%~f0" %*
  ; exit /b
  #lang racket
  
  (require "header.rkt")
  
  "hello, args are: "
  args
  </code></pre>
  
  <p>and running test.bat gives error below for the last line of the file:</p>
  
  <pre><code>args: unbound identifier in module in: args
  </code></pre>
  
  <h3>Update2</h3>
  
  <p>OK, here is an update with phase1 (so-called macro-time) &amp; phase0 (so-called runtime) expansion of my approach:</p>
  
  <p>I can run (current-command-line-arguments) in phase1 (macro) when everything is in one file:</p>
  
  <pre><code>#lang racket
  
  (define-for-syntax args (current-command-line-arguments))
  (define-for-syntax PROTOTYPING (or
                                  (begin
                                    (printf "phase1 expansion, args are: ~a\n" args)
                                    (= (vector-length args) 0))
                                  (equal? (vector-ref args 0) "local")))
  (begin-for-syntax 
    (printf "phase1, val for PROTOTYPING is: ~a\n" PROTOTYPING))
  
  (define-syntax (if-prototyping stx)
    (syntax-case stx ()
      ((_ debug-expr non-debug-expr)
       (if PROTOTYPING
           #'debug-expr
           #'non-debug-expr))))
  
  (if-prototyping
   (require (prefix-in "ci:" (file "./debug-env/util.rkt")))
   (require (prefix-in "ci:" (file "./release-env/util.rkt"))))
  
  ; arrange arguments
  (define args (current-command-line-arguments))
  (printf "phase0 expansion, args are: ~a\n" args)
  (if-prototyping
   (set! args (if (= (vector-length args) 0)
                  (vector "my-testing-arg-to-use-from-drracket")
                  (vector (vector-ref args 1))))
   #t)
  
  "util func call: "
  (ci:f)
  </code></pre>
  
  <p>have util.rkt files for double checking:
  debug-env/util.rkt:</p>
  
  <pre><code>#lang racket
  (provide f)
  (define (f) (display "f from debug"))
  </code></pre>
  
  <p>release-env/util.rkt:</p>
  
  <pre><code>#lang racket
  (provide f)
  (define (f) (display "f from release"))
  </code></pre>
  
  <p>and this is the output of the test run:</p>
  
  <pre><code>&gt;test-commonheader.bat local arg1 arg2
  phase1 expansion, args are: #(local arg1 arg2)
  phase1, val for PROTOTYPING is: #t
  phase0 expansion, args are: #(local arg1 arg2)
  "util func call: "
  f from debug
  
  &gt;test-commonheader.bat arg1 arg2
  phase1 expansion, args are: #(arg1 arg2)
  phase1, val for PROTOTYPING is: #f
  phase0 expansion, args are: #(arg1 arg2)
  #t
  "util func call: "
  f from release
  </code></pre>
  
  <p>it works as I expected. Now, the problem standing is, I can't put this whole logic in a common-header.rkt file to reuse. I'm just doing some more reading on Racket Reference 3.2 (Importing and Exporting), and there's a lot more that I should understand on require'ing for-syntax or directly to a phase level and provide'ing to phase-levels. I progressed a bit more with (for-syntax) in require and provide, but not there yet :/</p>
  
  <h3>update 3</h3>
  
  <p>It seems I was too busy trying to understand the phase-level extensions I missed the basics again. A simple (provide if-prototyping) from the header and (require "header.rkt") is actually working - but not perfectly :( . Alex was somehow correct in suggesting require should work. I was trying to (provide (for-syntax if-prototyping)) but that doesn't work because the if-prototyping is used at phase0 in the importing module.</p>
  
  <p>Here's the latest header:</p>
  
  <pre><code>#lang racket
  
  (provide if-prototyping)
  
  (define-for-syntax args (current-command-line-arguments))
  (define-for-syntax PROTOTYPING (or
                                  (begin
                                    (printf "phase1 expansion, args are: ~a\n" args)
                                    (= (vector-length args) 0))
                                  (equal? (vector-ref args 0) "local")))
  (begin-for-syntax
    (printf "phase1, val for PROTOTYPING is: ~a\n" PROTOTYPING))
  
  (define-syntax (if-prototyping stx)
    (syntax-case stx ()
      ((_ debug-expr non-debug-expr)
       (if PROTOTYPING
           #'debug-expr
           #'non-debug-expr))))
  
  (if-prototyping
   (begin
     (require "debug-env/util.rkt")
     (provide (all-from-out "debug-env/util.rkt")))
   (begin
     (require "release-env/util.rkt")
     (provide (all-from-out "release-env/util.rkt"))))
  </code></pre>
  
  <p>and in the test-commonheader.bat I require the header:</p>
  
  <pre><code>(require "header.rkt")
  </code></pre>
  
  <p>now, a new problem is, header.rkt phase1 definitions run twice (which may be alright for this case - that's why I'll accept Alex's answer on using require):</p>
  
  <pre><code>&gt;test-commonheader.bat arg1 arg2
  phase1 expansion, args are: #(arg1 arg2)
  phase1, val for PROTOTYPING is: #f
  phase1 expansion, args are: #(arg1 arg2)
  phase1, val for PROTOTYPING is: #f
  phase0 expansion, args are: #(arg1 arg2)
  #t
  "util func call: "
  f from release
  </code></pre>