[plt-scheme] Apply a procedure in a module
On Oct 12, Synx wrote:
> I'd like to know how to invoke mzscheme or mred or the like, so that
> I can run a specific procedure inside a specific module. What I have
> is a situation where I make a do-something.ss file/module and it
> contains something useful to import for do-something-else.ss, so I
> end up having to remove the toplevel procedure application from
> do-something.ss and instead make do-do-something.ss which contains a
> pretty carbon copy form of this:
> ---
> #lang scheme/base
> (require "do-something.ss")
> (main)
> ---
>
> Two things about that strike me as not a good idea. First off having
> toplevel procedure application at all is ugly,
It's perfectly fine to do that.
> and the only reason I do is because I can't specify a procedure to
> apply on the command line.
You can use `--main' to have the `main' function applied on the list
of command-line arguments. For example, try this:
#!/bin/sh
#|
exec mzscheme -um "$0" "$@"
|#
#lang scheme
(provide main)
(define (main . args)
(printf "Arguments: ~s\n" args))
But it's better to do that using scheme/cmdline, for example:
#!/bin/env mzscheme
#lang scheme
(let ([a "A"] [b "B"])
(command-line
#:once-each
[("-a" "--hay") a-val "blah blah" (set! a a-val)]
[("-b" "--bee") b-val "blah blah" (set! b b-val)]
#:args stuff
(printf "A: ~s\nB: ~s\nArguments: ~s\n" a b stuff)))
> Secondly it means I have a bunch of redundant nearly identical files
> that do nothing besides import a module and apply its procedure. I'd
> like to have something instead the likes of:
>
> $ mzscheme -n -t do-something.ss -e '(main)'
>
> ...and not need to bother manually writing out a do-do-something.ss file
> at all.
You can use the above and use an argument to dispatch to some function
to run -- using scheme/cmdline will make it easy to do this reliably
(for example, using `#:once-any' to choose exactly one mode).
> Another advantage to doing that is it would enable me to be more
> flexible with regard to program entry points. This is very convenient
> especially for testing, and in my opinion is more expressive.
>
> Trouble is, I don't know how to do it. :(
>
> $ mred -n -t prompt.ss -e '(watch-forever "/var/tmp/bink")'
> #f::0: compile: bad syntax; function application is not allowed, because
> no #%app syntax transformer is bound in: (watch-forever "/var/tmp/bink")
If you really insist on doing this, you will need to have the bindings
from `scheme' available. Here's one way to do this:
#lang scheme
(provide (all-from-out scheme))
(provide foo)
(define (foo x)
(printf "foo: ~s\n" x))
and you can now run it with
mzscheme -t that-file.ss -e '(foo 123)'
But it's better to avoid the module providing the scheme bindings, and
instead require them yourself -- drop that first `provide', and run
with:
mzscheme -l scheme -t $f -e '(foo 123)'
or
mzscheme -lte scheme $f '(foo 123)'
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!