Is it possible to use `provide` in Racket's Student Language? [duplicate] - racket

I'm having an issue with BSL. I want to divide my code into separate auxiliary files and use
(require "auxiliary-function.rkt")
at the beginning to import the separated code into the definitions area. However it doesn't work as supposed. Though no explicit error given, it seems like that that DrRacket simply doesn't see the code in the separate file and all I see is the error
<auxiliary-function-name>: this function is not defined
Apparently,
(provide x)
is not included in BSL. I've read the manual and this answer but it’s still not clear how to make this work. Is this even possible in BSL?
Thanks!

Note that if you're doing this for a course this strategy might not be accepted for a submission.
What I have done for some of my own projects is a pattern like this:
Have one file written in plain Racket, called "provide.rkt", like this:
; provide.rkt
#lang racket
(provide provide all-defined-out)
Then you can use this to either provide specific functions or provide all definitions from a file.
For providing specific functions
In your "library" BSL file, you can require provide into it like this, and use that to provide the specific function(s) you want:
; <auxiliary-library>.rkt
; written in BSL
(require "provide.rkt")
(provide <auxiliary-function-name>)
(define (<auxiliary-function-name> ....) ....)
And finally, in your "main" BSL file, you can require the library like this:
; written in BSL
(require "<auxiliary-library>.rkt")
(<auxiliary-function-name> ....)
For providing all definitions from a file
In your "library" BSL file, you can require provide into it and use that to provide everything:
; <auxiliary-library>.rkt
; written in BSL
(require "provide.rkt")
(provide (all-defined-out))
(define (<auxiliary-function-name-1> ....) ....)
(define (<auxiliary-function-name-2> ....) ....)
...
Then in your "main" BSL file, you can require the library and get all of the definitions:
; written in BSL
(require "<auxiliary-library>.rkt")
(<auxiliary-function-name-1> ....)
(<auxiliary-function-name-2> ....)
...

BSL is not for you. If you know how to manage modules, I recommend you use full-fledged Racket.
If you wish to create auxiliary libraries, I recommend you develop them in full Racket, provide the identifiers you need, use htdp/error to formulate error messages, and 'require' will then work.

Related

How to figure out the minimal set of provides from a racket expander module

I am working through the exercises in Matthew Flatt's Creating Languages in Racket. I am currently at step 3, where #lang s-exp "txtadv.rkt top line for a language "client" (world.rkt) is used. In this case, I am assuming that the reader is the s-exp racket reader and that the expander is "txtadv.rkt". Per the text:
"The exports of txtadv.rkt completely determine the bindings that are available in world.rkt—not
only the functions, but also syntactic forms such as require or lambda. For example, txtadv.rkt could
supply a lambda binding to world.rkt that implements a different kind of function than the usual
lambda, such as functions with lazy evaluation."
I see then that txtadv.rkt has this:
(except-out (all-from-out racket) #%module-begin)
I understand by this: re-export (provide) all the imports I got from racket, except for #%module-begin.
What I want: I would like to figure out a proccess to further trim-down this provide list as I do not want to export all of racket.
Things I have tried so far:
I changed at the top of txtadv.rkt to require racket/base and then put this:
(except-out (all-from-out racket/base) #%module-begin)
That worked, but it's still too coarse and fails at the next step with no clue other than revert to require racket.
I started trying to figure out (guess) what s-exps were in "world.rkt" the client, that would require extra syntax:
I commented out the (except-out (all-from-out racket)..)
started "guessing" exports:
that were missing, i.e. define-one-verb
racket functions/forms that are used in macros like symbol->string, list
For all I have tried, the expander txtadv.rkt passes Ctrl-R / syntax-chek, but in the client world.rkt I keep getting:
txtadv.rkt:84:4: define-one-verb: bad syntax in: (define-one-verb north (= n) "go north")

Is it possible to use rackunit in DrRacket with language set to sicp, and if so, how?

I'm starting to work through SICP using DrRacket. I installed the sicp package, and declared #lang sicp at the top of the unit test file and then (require rackunit "xxx.scm"), but I get an unbound identifier error. Is there a mistake, or is it not possible to use rackunit with the sicp package in this way?
You need to use #%require.
#%require is actually a primitive type in the lowest level of racket and it is slightly different than require:
#lang sicp
(#%require rackunit "xxx.scm")
The file you want to test becomes a module so you can use it from other code by providing the identifiers you want to expose:
(#%provide procedure-name)
You can also just require a few needed forms. eg. error and time from racket/base:
(#%require (only racket/base error time))
A hint on finding out where they are is to search the online manuals or from Help > Racket documentation in DrRacket. Eg. here is an example of searching error where you have many choices, but the racket prefixed ones are the ones you're looking for.
NB: Not all forms are compatible across languages. Eg. R5RS has different pair implementation than #lang racket

BSL (How to Design Programs): how to import code from a separate file into definitions area?

I'm having an issue with BSL. I want to divide my code into separate auxiliary files and use
(require "auxiliary-function.rkt")
at the beginning to import the separated code into the definitions area. However it doesn't work as supposed. Though no explicit error given, it seems like that that DrRacket simply doesn't see the code in the separate file and all I see is the error
<auxiliary-function-name>: this function is not defined
Apparently,
(provide x)
is not included in BSL. I've read the manual and this answer but it’s still not clear how to make this work. Is this even possible in BSL?
Thanks!
Note that if you're doing this for a course this strategy might not be accepted for a submission.
What I have done for some of my own projects is a pattern like this:
Have one file written in plain Racket, called "provide.rkt", like this:
; provide.rkt
#lang racket
(provide provide all-defined-out)
Then you can use this to either provide specific functions or provide all definitions from a file.
For providing specific functions
In your "library" BSL file, you can require provide into it like this, and use that to provide the specific function(s) you want:
; <auxiliary-library>.rkt
; written in BSL
(require "provide.rkt")
(provide <auxiliary-function-name>)
(define (<auxiliary-function-name> ....) ....)
And finally, in your "main" BSL file, you can require the library like this:
; written in BSL
(require "<auxiliary-library>.rkt")
(<auxiliary-function-name> ....)
For providing all definitions from a file
In your "library" BSL file, you can require provide into it and use that to provide everything:
; <auxiliary-library>.rkt
; written in BSL
(require "provide.rkt")
(provide (all-defined-out))
(define (<auxiliary-function-name-1> ....) ....)
(define (<auxiliary-function-name-2> ....) ....)
...
Then in your "main" BSL file, you can require the library and get all of the definitions:
; written in BSL
(require "<auxiliary-library>.rkt")
(<auxiliary-function-name-1> ....)
(<auxiliary-function-name-2> ....)
...
BSL is not for you. If you know how to manage modules, I recommend you use full-fledged Racket.
If you wish to create auxiliary libraries, I recommend you develop them in full Racket, provide the identifiers you need, use htdp/error to formulate error messages, and 'require' will then work.

how can I create a new language in racket?

I would like to create a new language that has the same syntax as typed racket, but when executed will do two things:
run the given program as typed racket
if type checks, then translates the input into another language (say python). I am planning to write a translator from typed racket forms to python syntax.
Any suggestions on how to start or pointers to some skeleton code? I have read this tutorial but it mostly talks about creating new syntax which I don't need in my case.
I understand how I can write racket code to translate from one language to another, what I don't get is how I can do both of the above, i.e., first run it as another language, and then do something else with the same input.
It sounds like you want to make a language with a new #%module-begin form. This form is either inserted by the reader (when you do a #lang .... line at the top of your file, or by the language if you wrote the module out by hand. Either way, its generally associated with your language definition. This macro has full access to the entire module's unexpanded syntax. So for example, a macro like this:
(provide (rename-out [-module-begin #%module-begin]))
(define-simple-macro (-module-begin body ...)
(#%module-begin
(writeln '(body ...))
body ...))
Would create a language that does two things:
Print out the body of the code (as an s-expression), and
Run the body with the #%module-begin that the language definition was written in.
You can see how you can use this technique to grab the body of your program twice, and do two different things with it. So let's try running this example. First, lets take the sample from above, and put it in a file "mylang.rkt":
#lang racket
(provide (rename-out [-module-begin #%module-begin])
(except-out (all-from-out racket) #%module-begin))
(require syntax/parse/define)
(define-simple-macro (-module-begin body ...)
(#%module-begin
(writeln '(body ...))
body ...))
And now we can write a program in mylang like this:
#lang s-exp "mylang.rkt"
(+ 1 2)
And when you run it, you'll get something like this:
((+ 1 2))
3
First its printing out the program text, then running it.
You can read more about this process in a paper I wrote discussing this aspect of the Video language. You might also find the book Beautiful Racket to have some examples you might find useful.

Racket reader where newline is end of statement

I'm trying to create a new language in Racket where statements are on separate lines. A newline defines the end of a statement and the start of a new one.
I read through the Create Languages chapter of the guide which was very useful but the examples were focused on extending s-exp-like languages. The only option I see is manually writing my own parser for read and read-syntax.
I was hoping to use readtables but I don't know if I can. I tried:
(make-readtable #f #f 'non-terminating-macro my-read-line-fn)
but I don't know if this is much help. I guess I could create a sub-readtable that does things like read-word, read-string which I dispatch to based on what character my-read-line-fn gets.
Is that the best strategy or is there a predefined way of reading until the end of line?
I don't think you need to do anything with the readtable. Your lang/reader.rkt can provide your own read-syntax that can read/parse however it wants, and presumably stop when it encounters EOL.
One interesting example is Brainfudge. Its concept of a "statement" is a single character, but IIUC also [ brackets ].
See its lang/reader.rkt and parser.rkt for the low-level bits, and then try to understand how that is ultimately evaluated as Racket expressions.
You do indeed need to write version of read and read-syntax that parse your language. The readtable is only meant to modify the builtin read, so I suggest that you take a look at Parser Tools (http://docs.racket-lang.org/parser-tools/index.html), which is tool for writing parsers in the lex/yacc style.
An alternative is to use ragg:
http://www.hashcollision.org/ragg/
Install Ragg using the package manager in DrRacket. Search for ragg in the list of available packages.
Make your own reader.rkt:
#lang s-exp syntax/module-reader
(test test)
#:read-syntax my-read-syntax
#:read my-read
;; override default read (won't be used but is required)
(define (my-read in) (read-line in))
;; override read-syntax by reading in one string at a time and
;; pass it to statement-string->code to get code as dara and
;; make it syntax with datum->syntax
(define (my-read-syntax in)
(datum->syntax #f (statement-string->code (read-line in))))
;; This is actually how you want your code
;; to become s-expressions. I imagine that my
;; module has a primitive called code that
;; interprets the string as is
(define (statement-string->code str)
(list 'code str))
Racket doesn't have "statements", so the concept of newlines ending "statements" is nonsensical.
If your motivation is to reduce or do away with parentheses, I encourage you to use a "standard alternative" reader like sweet-expressions, rather than making something home-grown.