On Linux and Racket v5.3, next program runs as expected,
#lang racket
(let loop ([i 0])
(printf "~a\n" i)
(sleep 0.01)
(loop (add1 i)))
But this hangs after printing up to around 200,
#lang racket
(require racket/gui)
(let loop ([i 0])
(printf "~a\n" i)
(sleep 0.01)
(loop (add1 i)))
This problem does not arise when running inside DrRacket.
Is this a bug or am I missing something? If a bug, is there a workaround?
It looks like a bug -- do you mind filing a bug report using the web page, or preferably using DrRacket?
This has now been fixed in the latest development version, see this commit.
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" ...)) ...)
Working through Little Schemer,
We're required to define a few of our own functions.
I've defined them, only add1 and sub1 appear in the repl after it loads. I'm using Racket v7.0.
#lang racket
(provide atom? add1 sub1)
(define atom?
(lambda (x)
(and (not (pair? x)) (not (null? x)))))
(define add1
(lambda (x)
(+ x 1)))
(define sub1
(lambda (x)
(- x 1)))
I cannot figure out why (atom?) does not load. When I copy paste the s-expression into repl it works. Any ideas?
Since you are unsing #lang racket and provide the correct way to use the file is with require.
$ ls
toys.rkt
$ racket
Welcome to Racket v6.8.
> (require "toys.rkt")
> (atom? '())
#f
So imagine you make a program like this:
#lang racket
(require "toys.rkt")
(if (atom? 'test)
'atom
'no-atom)
You save it and run it:
$ racket program.rkt
'atom
Also note that you can use R6RS and make toys a library. You then need to use plt-r6rs --install toys.rkt and then use (import (rnrs base) (toys)).
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
the module: test-define.rkt
#lang racket
(provide test)
(provide (contract-out [add-test! (-> void)]))
(define test 0)
(define (add-test!)
(set! test (add1 test)))
the main program:act.rkt
#lang racket
(require "test-define.rkt")
(printf "~a~%" test)
(add-test!)
(printf "~a~%" test)
run the act.rkt, I get:
0
1
this is what I want.
But if I change the contract in test-define.rkt:
(provide test)
change to
(provide (contract-out [test integer?]))
then I run the act.rkt again, I get:
0
0
Why? I can't change the test value.
If I provide a get func, it turns normal again.
(provide (contract-out [get-test (-> integer?)]))
(define (get-test)
test)
If test's type change to hash map, it's always normal.
What I missed?
I notice that in test-define.rkt you have this line
(set! test3 (add1 test))
Should test3 be test ?
This might explain why you saw that two zeros (test never changed).
EDIT 2
For convenience I put your two modules in the same file
and changed the contract of test:
#lang racket
(module test-define racket
(provide test)
; (provide (contract-out [test integer?]))
(provide get-test)
(provide (contract-out [add-test! (-> void)]))
(define test 0)
(define (add-test!)
(set! test (add1 test)))
(define (get-test)
test))
(module ack racket
(require (submod ".." test-define))
(printf "~a~%" test)
(add-test!)
(printf "~a~%" test))
(require (submod "." ack))
Now I see the 0 1 vs 0 0 output as you do.
Hmmm. Why?
Well. If we change the provide forms to use no contracts
at all, the output is 0 1.
Adding a contract shouldn't change this behaviour (I think).
Maybe a bug?
http://pre.racket-lang.org/docs/html/guide/contracts-gotchas.html?q=contract&q=ignore
Says:
The contract library assumes that variables exported via contract-out
are not assigned to, but does not enforce it. Accordingly, if you try
to set! those variables, you may be surprised. ...snip... Moral: This
is a bug that we will address in a future release.
I'm trying understand how to interpret the output of, and use, the Lisp debugger.
I've got a pretty simple Backtrace for the evaluation of my function, but I cann't seem to work out how to use it to find out in which Lisp 'form' in my function the exception occurred.
I'd appreciate any clues as to what I should be doing, to find where in my code the error originated.
Also - why does the second frame display as "no debug information available for frame"?
I've attached a screen shot with the debugger, and repl (I've also included my function below - I know it's very wrong - but I'm just interested in learning to use the debugger properly). In addition, I hit 'v' on the first frame to go to the source, but this resulted in the error below the repl. (EDIT - the missing source code issue is fixed by downloading & copying it to the correct path)
(horrible function - no comments please!)
(defun myquicksort2 (lst)
(if (eql 1 (length lst))
lst
(let ((mid (middle lst)))
(do ((i 0 (+ i 1)))
((>= i mid) (append (myquicksort2 (subseq lst 0 mid))
(myquicksort2 (subseq lst mid (length lst)))))
(if (> (ltval i lst) (nth 100 lst))
(let ((tmp (ltval i lst)))
(setf (nth i lst) (gtval i lst))
(setf (nth (- (- (length lst) i) 1) lst) tmp)))))))
(defun ltval (i lst)
(nth i lst))
(defun gtval (i lst)
(nth (- (- (length lst) i) 1) lst))
(defun middle (lst)
(round (/ (length lst) 2)))
The error is with > and you have only one > in your source, so that's where the problem is.
edit Built-in CL functions are highly prone to optimization in SBCL, so although the function call in your code is to CL:<, the code that's actually called (and which shows up in the debugger) is from an optimized, specific, SBCL-internal routine. This is less of an issue for user-defined functions, where you will be much more likely to get a useful frame.