I would like to include all the functions defined in a given racket file so that I get the same effect as if they were copied. Is it possible to do that?
To export the functions out of a module, you use provide, consider a file "foo.rkt":
#lang racket
(define fortytwo 42)
(define (det a b c)
(- (* b b) (* 4 a c)))
(provide (fortytwo det))
The file "bar.rkt" now can import definitions from "foo.rkt":
#lang racket
(require "foo.rkt")
(define (baz a b c)
(+ (det a b c) (- c 4)))
The other way you could allow other files to have access to everything that’s defined in the file, is using (all-defined-out):
#lang racket
(define fortytwo 42)
(define (det a b c)
(- (* b b) (* 4 a c)))
(provide (all-defined-out))
Hope that helps.
You can use include as follows:
Create a file called "foo.rkt" that looks like this:
(define x 1)
(define y 2)
Then in another file:
#lang racket
(require racket/include)
(include "foo.rkt")
(+ x y)
You should see the result 3.
You can see the documentation for include as well.
You could use load
(load "assert.scm")
Related
I followed the directions on the Rosette website to download rosette (https://docs.racket-lang.org/rosette-guide/ch_getting-started.html). It seems that I can run this program and get an output error free.
#lang rosette/safe
; Compute the absolute value of `x`.
(define (absv x)
(if (< x 0) (- x) x))
; Define a symbolic variable called y of type integer.
(define-symbolic y integer?)
; Solve a constraint saying |y| = 5.
(solve
(assert (= (absv y) 5)))
However, when I try running this or any similar program using more than the basic racket keywords I get unclear (to me) errors.
#lang rosette
(struct plus (left right) #:transparent)
(struct mul (left right) #:transparent)
(struct square (arg) #:transparent)
(define prog (plus (square 7) 3))
(define (interpret p)
(destruct p
[(plus a b) (+ (interpret a) (interpret b))]
[(mul a b) (* (interpret a) (interpret b))]
[(square a) (expt (interpret a) 2)]
[_ p]))
(interpret prog)
This gives me an error destruct: unbound identifier in: destruct. What is going on? This code is not my own and is copy pasted from a tutorial so it should work I think. I have also tried example code copy pasted from the Rosette website and that gives similar errors. I've followed all the installation instructions and updated the environment path etc. Any help?
destruct is not provided by #lang rosette by default. You need to require it by writing:
(require rosette/lib/destruct)
after #lang rosette
Where did you find this code, by the way?
I'm using Chez Scheme and I'd like to introduce some top-level bindings based on the contents of a directory. The usage of this hypothetical macro might look like this:
(bind-files f "~/my-dir/")
;; Expanding to:
(begin (define f0 "~/my-dir/a.wav")
(define f1 "~/my-dir/b.wav"))
I'm getting comfortable with syntax-case, datum->syntax and with-syntax as described in the Scheme book's examples. But I can't imagine how one could create identifiers based on the result of something 'runtime-y' like (directory-list "~/") - is it even possible?
(By the way, this is for a live-coding musical application, so there's no need to comment that this is a bad idea for reliable software - it's for a very specific interactive context.)
You can use something like this macro:
#!r6rs
(import (rnrs) (chezscheme))
(define-syntax bind-file
(lambda (x)
(define (name&file k dir)
(define (->fn i)
(string->symbol (string-append "f" (number->string i))))
(let ((files (directory-list (syntax->datum dir))))
(datum->syntax k (do ((i 0 (+ i 1)) (files files (cdr files))
(r '() (cons (list (->fn i) (car files)) r)))
((null? files) r)))))
(syntax-case x ()
((k dir)
(string? (syntax->datum #'dir))
(with-syntax ((((name file) ...) (name&file #'k #'dir)))
#'(begin (define name file) ...))))))
(bind-file ".")
#|
;; depending on the number of files
f0 ... fn variables are defined.
|#
I would like to alias some racket 2htdp functions/macros, so that I can translate them in another language for my children.
Things which are functions I can simply alias with define. I'm having trouble with the big-bang structure; If I try to alias on-tick for instance, everytime I get big-bang: [new-name] clauses are not allowed within big-bang.
I tried various variants of define-syntax but I could not make it work so far (that said, I'm a complete racket newbie).
Something like this works (well, ladja is not defined):
#lang racket
(require 2htdp/universe 2htdp/image)
(big-bang 0
(on-tick (lambda (x) (+ x 1)))
(to-draw (lambda (x) (place-image ladja 150 x (prazni-prostor 300 300))))
(stop-when (lambda (x) (= x 300))))
But this doesn't (triggers the error):
#lang racket
(require 2htdp/universe 2htdp/image)
(define new-name on-tick)
(big-bang 0
(new-name (lambda (x) (+ x 1)))
(to-draw (lambda (x) (place-image ladja 150 x (prazni-prostor 300 300))))
(stop-when (lambda (x) (= x 300))))
I see that big-bang is a macro, so that explains the issue: I guess I would have to be able to force my macro to be evaluated first, somehow?
If you're writing a module that you would require into your program, then you can use provide with rename-out to provide an alias:
In big-bang-with-new-name.rkt:
#lang racket
(require 2htdp/universe 2htdp/image)
(provide big-bang
to-draw
stop-when
empty-scene
(rename-out [on-tick new-name]))
Using it in another file:
#lang racket
(require "big-bang-with-new-name.rkt")
(big-bang 0
[new-name (lambda (x) (+ x 1))]
[to-draw (lambda (x) (empty-scene 200 200))]
[stop-when (lambda (x) (= x 300))])
Many macros use free-identifier=? to recognize keywords like this. Rename transformers cooperate with free-identifier=? to create exact aliases. This means you can also define new-name as a rename transformer in the main file like this:
#lang racket
(require 2htdp/universe 2htdp/image)
(define-syntax new-name (make-rename-transformer #'on-tick))
(big-bang 0
[new-name (lambda (x) (+ x 1))]
[to-draw (lambda (x) (empty-scene 200 200))]
[stop-when (lambda (x) (= x 300))])
Let's say I have the following two files:
;; demo.scm
(define-module (demo)
#:export (f))
(define (g x) 1)
(define (f x) (g x))
... and in the same directory:
;; use-demo.scm
(add-to-load-path ".")
(use-modules (demo))
(define (g x) (+ x 1))
(display (f 5))
(newline)
Running use-demo.scm in Guile (2), I get the output 1. So it looks like the function f has 'closed over' the function g that's defined in module demo. Is there any way to get around this? I really want to use the version of g that I've redefined in use-demo.scm.
OK, just for the record, I did some research and am posting the solution to this specific problem in case it helps someone.
The trick is to not redefine g locally, but rather to 'inject' the new function into the demo module's mapping of names to values.
(add-to-load-path ".")
(use-modules (demo))
(module-define! (resolve-module '(demo)) 'g
(lambda (x) (+ x 1)))
(display (f 5))
(newline)
If you have specific functions that you'd like to be able to override, you could make them configurable using parameters. This has some advantages:
You don't need to call reload-module to put the module back in its original configuration.
The changes only apply for the scope of the code which needs the modified behaviour.
It works properly when using multiple threads.
Obviously, the main disadvantage is that you need to add some boilerplate for each function that you want to allow to be overridden (although that's what hygienic macros are for, hehe).
The following code may work. I haven't run it.
;; demo.scm
(define-module (demo)
#:export (f))
(define (default-g x) 1)
(define p (make-parameter default-g))
(define (f x) ((p) x))
;; use-demo.scm
(add-to-load-path ".")
(use-modules (demo))
(define (my-g x) (+ x 1))
(parameterize ((## (demo) p) my-g)
(display (f 5))
(newline))
Obviously, if you can provide some additional information about what the application for this capability is, I might be able to suggest alternative approaches (there are a few others).
I am trying to convert a C program to Scheme for an assignment I'm working on. The program is supposed to compute the area of a circle given the formal parameter (diameter, in this case). I think I have it figured out but I don't know how to print the actual value to verify it. I've tried just putting in the number into the print call. The way it is now is the method my book used. When I run the program with Dr. Racket I get:
print: undefined;
cannot reference undefined identifier
(define pi 3.14159265)
(define test 5)
(define (areac d)
(lambda (d)
(* pi (/ d 2) (/ d 2)
)))
(print (areac test))
Edit: Language is set to R5RS
If you use "define", you don't have to use "lambda", because "define" is just convenient way to give the name to the lambda-procedure. Your code must look like this:
(define pi 3.14159265)
(define test 5)
(define (areac d)
(* pi (/ d 2) (/ d 2)
))
(display (areac test))
Command for printing data in scgeme is "display". So, just write
(display (areac test))