I'm trying to learn Racket by using DrRacket and when run this code:
(define f2!
(let ([n 0])
(lambda()
(set! n (add1 n))
n)))
I get an exception: let: this function is not defined.
What am I doing wrong?
Thank you
I've found a solution, I had to pick racket as the main language and also add:
#lang racket
at the top of the file.
Just so you know, the #lang at the top of your file determines what set of actions you are permitted to and also the computation algorithm (Applicative/normal evaluator).
I basically add #lang racket as a basic to all files.
Related
I know Racket doesn't have "docstrings" in the same way that many other languages do, but given how convenient documenting things at the source is, I'd like to approximate something like it in Racket.
When I first learned about Scribble and #langs, I thought it would be possible to do something like:
#lang racket
#lang scribble
... and then write code in Racket with docstrings in Scribble. But this doesn't work, probably because "languages don't compose."
#lang racket
(require scribble/manual)
#racket['hi]
which results in:
my-source.rkt:4:0: #racket: unbound identifier
I came across scribble/srcdoc which seems compelling because it sounds like it allows you to piggyback docs on top of contracts which already serve as a kind of minimal (typically module-level) documentation, in addition to providing runtime checks of course. I haven't been able to get it to work so far, but instead of thrashing around for another several hours I thought it would be more useful to ask about it here. For what it's worth, here's what I'm seeing at the moment:
#lang racket
(require scribble/srcdoc
(for-doc scribble/base scribble/manual))
(provide
(proc-doc/names fib
(-> integer? integer?)
(n)
#{Computes the #racket[n]th Fibonacci number}))
(define (fib n)
(if (< n 2)
n
(+ (fib (- n 1))
(fib (- n 2)))))
which results in:
my-source.rkt:6:1: proc-doc/names: bad syntax
in: (proc-doc/names fib (-> integer? integer?) (n) # (Computes the #racket (n) th Fibonacci number))
Since reference docs like these are better at explaining how things work than how to use it, I'm looking for an answer that is more of a how-to on writing "docstrings" in Racket. It needn't be long, just sufficient to help the reader employ this "contract + docstring" pattern in their code (and, possibly, describing other alternatives).
You want the at-exp 'meta-language'. This lets you program in another language (in this case racket, with the modification of using at-expressions.
So taking your example above, you get:
#lang at-exp racket
(require scribble/srcdoc
(for-doc scribble/base scribble/manual))
(provide
(proc-doc/names fib
(-> integer? integer?)
(n)
#{Computes the #racket[n]th Fibonacci number}))
(define (fib n)
(if (< n 2)
n
(+ (fib (- n 1))
(fib (- n 2)))))
Note the at-exp in the first line.
You can also do:
#lang at-exp racket
(require scribble/manual)
#racket['hi]
and get:
(sized-element #f (list (cached-element #0=(style "RktVal" (list 'tt-chars (css-addition '(collects #"scribble" #"racket.css")) (tex-addition '(collects #"scribble" #"racket.tex")))) "'" ...) (cached-element #0# "hi" ...)) ...)
As just one of many possible examples, break-example.rkt would be a perfectly valid Java program, except for the #lang mini-java header that Racket requires.
So e.g. if I've written a Java interpreter/compiler in Racket as a Racket module language, how can I say, "require this file Main.java which is written in module language mini-java but doesn't have any Racket-specific header"?
(Note that I have almost non-zero practical experience with Racket. I'm evaluating this for a specific use case I have for Racket + DrRacket, which has nothing to do with Java by the way. I searched the documentation but couldn't find any way to achieve this.)
I can’t run or test this right now, but maybe you can start from here and experiment with it. The main thing it uses is include/reader:
#lang racket
(require racket/include
syntax/parse/define
(for-syntax racket/syntax
racket/port
syntax/modread))
(define-simple-macro (require/mini-java path)
#:with modname (generate-temporary #'path)
(begin
(include/reader path (mini-java-reader 'modname))
(require 'modname)))
(begin-for-syntax
;; Symbol -> [Any InputPort -> Syntax]
(define ((mini-java-reader modname) src input)
(cond
[(port-closed? input) eof]
[else
(define stx
(with-module-reading-parameterization
(lambda ()
(read-syntax src
(input-port-append #t
(open-input-string "#lang mini-java\n")
input)))))
(close-input-port input)
(syntax-parse stx
[(module _ l . b)
#`(module #,modname l . b)])])))
I have a file with the name “functions.rkt”, where I have some functions.
And I am working in another file, let’s name it “working.rkt”
I have tried the following (one by one) at “working.rkt” to use the function defined at “functions.rkt”:
(require “functions.rkt”)
(include “functions.rkt”)
(provide “functions.rkt”)
And anyone of them hasn’t worked, any help?
They are in the same path.
In the file "functions.rkt:
#lang racket
(provide my-function)
(define (my-function x) (* 2 x))
In the file "working.rkt":
#lang racket
(require "functions.rkt")
(my-function 21)
I need to read a Racket source file and run it through macro expansion. I have a simple test file that Racket itself happily accepts:
C:\ayane>type factorial.rkt
#lang racket
(provide factorial)
(define (factorial n)
(if (<= n 1)
1
(* n (factorial (sub1 n)))))
Now I try from the REPL:
C:\ayane>racket
Welcome to Racket v6.5.
> (read-accept-reader #t)
> (expand (with-input-from-file "factorial.rkt" (lambda () (read-syntax "factorial.rkt"))))
#<syntax::1 (module factorial racket (#%m...>
So far so good. Now the same thing from a test program:
C:\ayane>type test.rkt
#lang racket
(read-accept-reader #t)
(expand (with-input-from-file "factorial.rkt"
(lambda ()
(read-syntax "factorial.rkt"))))
C:\ayane>racket test.rkt
factorial.rkt::1: module: unbound identifier;
also, no #%app syntax transformer is bound
at: module
in: (module factorial racket (#%module-begin (provide factorial) (define (factorial n) (if (<= n 1) 1 (* n (factorial (sub1 n)))))))
context...:
C:\ayane\test.rkt: [running body]
So it looks like the same code works interactively but not in a program. What am I missing?
You need to specify which namespace expand should use to lookup top-level variables (i.e. variables not bound in the program).
For example:
(parameterize ([current-namespace (make-base-namespace)])
(expand ...))
For more information see the comments in the file below in which I attempt to explain the relationship between namespaces and expand:
https://github.com/soegaard/meta/blob/master/runtime/racket-eval.rkt#L122
The answer from #soegaard addresses the immediate issue, but if you want a comprehensive program that reimplements expansion from primitives, you can look at
https://github.com/samth/pycket/blob/master/pycket/pycket-lang/expand.rkt
I have a file, configuration.rkt:
(define file-path "path/to/file.rkt")
Then I have the 'main' file program.rkt, in which I would like to include the file specified by file-path. I tried this way, but it does not work:
(include "configuration.rkt")
(include file-path)
What can I do?
Use require instead of include.
http://docs.racket-lang.org/guide/module-require.html
As #soegaard said, you want to use Racket's module system via require, instead of textually including source files. It will save you a ton of grief.
I noticed that you seem to want the choice of source file to be determined at runtime?
If so, two options:
You could use units and signatures.
You could use dynamic-require. For example:
config.rkt:
#lang racket
(provide to-be-required)
(define to-be-required "foo.rkt")
foo.rkt:
#lang racket
(provide foo-value
foo-proc)
(define foo-value "I am from foo.rkt and I was dynamic-required!")
(define (foo-proc)
"I am foo-proc.")
main.rkt
#lang racket
(require "config.rkt")
(printf "Let's dynamic-require ~a, as config.rkt said.\n" to-be-required)
(define foo-value (dynamic-require to-be-required 'foo-value))
(define foo-proc (dynamic-require to-be-required 'foo-proc))
foo-value
(foo-proc)
Output:
Let's dynamic-require foo.rkt, as config.rkt said.
"I am from foo.rkt and I was dynamic-required!"
"I am foo-proc."