On Sun, Sep 4, 2022, at 10:00 AM, Reuben Thomas wrote:
> On Sun, 4 Sept 2022 at 10:31, Reuben Thomas <r...@sc3d.org> wrote:
>> On Sun, 4 Sept 2022 at 04:13, Philip McGrath <phi...@philipmcgrath.com> 
>> wrote:
>>> 
>>> However, in some cases you might really want a program other than `racket` 
>>> as the entry point for your language: for instance, maybe you want to have 
>>> flags for controlling where the output goes. One example of such a program 
>>> is the `scribble` executable included in the main Racket distribution. The 
>>> implementation is in 
>>> <https://github.com/racket/scribble/blob/master/scribble-lib/scribble/run.rkt>,
>>>  and the associated "info.rkt" file 
>>> (<https://github.com/racket/scribble/blob/master/scribble-lib/scribble/info.rkt>)
>>>  arranges for `raco setup` to create a `scribble` to run it. (This example 
>>> uses the old mzscheme-launcher-names/mzscheme-launcher-libraries instead of 
>>> the newer racket-launcher-names/racket-launcher-libraries: see 
>>> documentation at 
>>> <https://docs.racket-lang.org/raco/setup-info.html#%28idx._%28gentag._18._%28lib._scribblings%2Fraco%2Fraco..scrbl%29%29%29>.)
>> 
>> Thanks for the pointer.
>>  
>>> It is possible to use Racket to implement languages that don't use #lang, 
>>> but you would loose many advantages like IDE support and well-defined 
>>> separate compilation, and you would need to use some fairly low-level 
>>> mechanisms. Unless there is a hard requirement, I'd recommend that you just 
>>> use #lang in your programs.
>> 
>> I'm trying to write a standalone assembler (nothing to do with Racket), so 
>> I'm happy to lose this advantage!

You may indeed want a tool that supports files without #lang if you are working 
with an existing language and there isn't a way to make the #lang line 
acceptable to its existing grammar. That's about the only situation I can think 
of. Almost always, things will work better in the long run if you can make 
#lang work somehow, even for languages that have "nothing to do with Racket". 
For example:
 * Zuo programs start with #lang, even though the primary implementation of 
`#lang zuo/kernel` is written in C and runs without Racket. (IIUC Sam 
Tobin-Hochstadt has an almost-complete implementation of zuo/kernel in Racket, 
but the C implementation is needed to build Racket itself.) See 
<https://docs.racket-lang.org/zuo/>.
 * The `jsonic` and BASIC languages from Beautiful Racket have fairly little to 
do with Racket, but #lang is the basis for the syntax coloring and indentation 
mechanisms introduced in 
<https://beautifulracket.com/jsonic-2/drracket-integration.html>. Despite the 
title of the chapter, this isn't limited to DrRacket: you also get editor 
support for your language in Emacs' racket-mode, VSCode, and other clients of 
the Language Server Protocol.
(Small caveat: I have not actually read Beautiful Racket, just looked at it 
admiringly, recommended it to others, and wished MB had written it a year 
earlier than he did.)

> OK, I've had another look, and I still can't see how to do this, so I would 
> appreciate a hint. I have updated my repo to add a launcher script, but again 
> this only works with files that have a #lang line. As I said before, I have 
> worked out how to parse a file without a #lang line (just pass it to my 
> language's read-syntax), but I can't work out how to turn that into a module 
> and execute it. I guess I need something like dynamic-require that takes a 
> syntax-object and an expander module or #%begin-module macro as arguments?

For running a file without a #lang, you will need to use `eval`. Probably the 
right example to follow is the implementation of the plt-r6rs command-line tool 
(part of the main Racket distribution; source at 
<https://github.com/racket/r6rs/blob/master/r6rs-lib/r6rs/run.rkt>), which uses 
`get-module-code` from 
<https://docs.racket-lang.org/syntax/module-helpers.html#%28def._%28%28lib._syntax%2Fmodcode..rkt%29._get-module-code%29%29>
 and similar functions to control low-level evaluation and compilation. See 
more details about plt-r6rs at 
<https://docs.racket-lang.org/r6rs/Running_Top-Level_Programs.html> and in its 
--help output.

A different way to use eval would be to use `define-namespace-anchor` in the 
module that provides your hackasm language, explicitly read-syntax the given 
file, and evaluate the expressions with current-namespace parameterized to a 
namespace created using namespace-anchor->namespace.

Yet another option would be to split your files in two: have files in your 
language without #lang and separate files in a wrapper #lang that uses 
include-at/relative-to/reader 
<https://docs.racket-lang.org/reference/include.html> to get the contents of 
the non-#lang files. A simple approach would have a wrapper file for every 
#lang-less file, and it could automatically include a file of the same name but 
a different extension. More elaborate wrapper languages would also be possible: 
it could work like a sort of linker specification. I mention this because it 
can be a useful technique sometimes, though I don't think it's what you want. 
For an example of how this sort of thing can be useful, see `#lang s-exp 
srfi/provider`, which simplifies making SRFI libraries available under several 
different names, for compatibility: it's implemented in 
<https://github.com/racket/srfi/blob/master/srfi-lite-lib/srfi/provider.rkt> 
and used e.g. in 
<https://github.com/racket/srfi/blob/master/srfi-lite-lib/srfi/1.rkt> and 
<https://github.com/racket/srfi/blob/master/srfi-lib/srfi/%253a63/arrays.rkt>.

Hope this helps!

-Philip

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/c97601c4-22ae-44d6-a464-30a032fd36fc%40www.fastmail.com.

Reply via email to