Reducing the start-up time of Racket (compared to Chez Scheme) - performance

Racket is currently using Chez Scheme implementation; see e.g. Thoughts on Racket & Chez Scheme.
The start-up time of Racket interpreter is yet much longer than that of Chez Scheme.
For instance, a simple Hello-World script which only includes
(display "Hello World!")
takes, at least, ca. 2x longer using Racket vs. Chez Scheme interpreter;
e.g., on a Linux laptop, with chezscheme 9.5.4 and Racket 8.3 [CS]:
time chezscheme --script helloworld.scm # => real 0m0.064s
time racket -f helloworld.scm # => real 0m0.337s
time racket -l racket/base -f helloworld.scm # => real 0m0.114s
Note that the difference is observed despite loading only the racket/base library.
What is the reason for this difference, despite Racket itself using Chez Scheme?
How to achieve the performance of Chez Scheme with Racket?

Related

How to analyze unknown Common Lisp code with sbcl and slime

How to analyze unknown common lisp source code, in order to understand it?
Given, I have Common Lisp source code of a function. That imaginary function operates on arbitrary and complex data. Now I'd like to analyze such a function.
So, I'm interestend in working methods to analyze some given common lisp source code. I.e. by stepping through source code, like it can be done with elisp source code in Emacs by using edebug-defun.
My tools are slime, sbcl and Emacs.
End of actual question, things below are written only to give a better overview, what this question is about.
Notes about questions background:
I'm not interested in what the above given function does, since
I already know basic common lisp like if, dolist, defun and basics. Also I also know how to query CLHS.
I could probably go through code and data with pen and paper, but why? When I'm sitting in front of a computer.
I already read CL Cookbook - Debugging and Malispers debugging tutorial
Here is an example of such a function, the answer does not need to refer to this function:
(defun wins (grid color)
(declare (optimize (speed 0)
(debug 3)))
(dolist (phase *phase*)
(dolist (start (car phase))
(if (= (* 4 color)
(reduce #'+ (cadr phase)
:key
(lambda (offset)
(aref grid (+ start offset)))))
(return-from wins t)))))
Given above code, for me, it is a mystery when which parts of the arbitrary data is processed and how. It would probably be useful to see it in action.
With that special example, I tried to use (step (wins ...)), but this only stops at (* 4 color), (reduce ... and (* start offset), which is not enough (for me) to understand the function.
Also (trace wins) did not help much.
I took this function from an common lisp teaching book, which already explains it. So there is no need to explain this function.

Sort with R5RS scheme in DrRacket

I'm learning scheme using DrRacket version 7.0.
I have copied, and modified, the following procedure from this SO answer.
#lang racket
(define sort-asc-by-second
(lambda (lst)
(sort lst
(lambda (x y) (< (cdr x) (cdr y))))))
And it works perfectly.
Now I have change the #lang racket instruction with this one #lang r5rs.
And DrRacket complains with the following error:
sort: unbound identifier in: sort
Do I forget to add something to DrRacket (libraries, modules, etc.)? Or maybe sort is not available in R5RS.
According to the R5RS report there is no such thing as sort. You may fetch the reference implementation for sort from SRFI-95 Sorting and merging. It's not 100% compatible with the #lang racket one. R5RS doesn't have libraries so the portable way would be to load it or inline it.
R6RS has superseded R5RS and it has list-sort in its standard library.
R7RS-Large, which is not yet fully ratified, uses SRFI-132 as it sorting library (scheme sort) which also has list-stable-sort which is the same as the R6RS list-sort.
In Racket you can mix and match libraries from all the languages it supports, but it does not work for lists that are implemented differently and it is a lock in. Being dependent on a different languages library means you cannot run the code with other implementations, like Ikarus and Chez.

How do I load my file at DrRacket

I am a undergraduate who wants to go through "The Scheme programming language" as a self-study.
Here is a simple program and I named it as "reciprocal.ss"
(define reciprocal
(lambda (n)
(if(= n 0)
"oops!"
(/ 1 n))))
Then I wanted to load my procedure:
(load "reciprocal.ss")
It produces this error:
reciprocal.ss:1:0: #%top-interaction: unbound identifier;
also, no #%app syntax transformer is bound in: #%top-interaction
I did each parts as what the book says. Perhaps I am just making a rookie mistake. Any insight would be appreciated.
Since load uses eval, using it outside of a REPL generally will not work — for reasons described in Namespaces
Using racket/load can work for you here however:
loader.ss
#lang racket/load
(load "reciprocal.ss")
(display (reciprocal 10))
reciprocal.ss
(define reciprocal
(lambda (n)
(if (= n 0) "oops!"
(/ 1 n))))
In Racket (and Scheme at large) has a more complex story than the average language regarding running external code. In general, you should use import when you want to directly 'include' a file, you should use provide/require when you want to establish module boundaries and you should use load when you are sophisticated enough to be stretching the limits of either.
The simplest approach is not to use load at all.
In "reciprocal.ss" make the first lines:
#lang racket
(provide (all-defined-out))
(define reciprocal
(lambda (n)
(if (= n 0)
"oops!"
(/ 1 n))))
Then use (require "reciprocal.ss") in the file where you need to use the function reciprocal.
The load mechanism was used back in the good old days before module systems had arrived. Writing (load "foo.ss") basically works as if you manually pasted the contents of foo.ss into the repl and excecuted it. This means that the result of your program is dependent of the order of loading files (if you are using side effects). Module systems handle this (and other things too) much better.

Little Schemer "S-expression" predicate

Is it true that this is an S-expression?
xyz
asks The Little Schemer. but how to test?
syntactically, i get how to test other statements like
> (atom? 'turkey)
and
> (list? '(atom))
not entirely sure how to test this...
> (list? '(atom turkey) or)
as it just returns...
or: bad syntax in: or
but anyway, knowing how to test for S-expressions is foxing me
so, as per usual, any illumination much appreciated
An "S-expression" is built of atoms via several (possibly zero) cons applications:
(define (sexp? expr)
(or
; several cases:
(atom? expr)
; or
(and (pair? expr) ; a pair is built by a cons
(sexp? (car expr)) ; from a "car"
(sexp? .........)) ; and a "cdr"
)))
This is practically in English. Nothing more to say about it (in code, I mean). Except, after defining the missing
(define (atom? x)
(not (pair? x)))
we see that (sexp? ...) can only return #t. This is the whole point to it: in Lisp, everything is an S-expression – either an atom, or a pair of S-expressions.
The previous answer is correct -- Scheme (and Lisp) are languages that are based on S-expressions. And the provided code is a great start.
But it's not quite correct that everything is an S-expression in those languages. In this case you have an expression that isn't syntactically correct, so the language chokes when it tries to read it in. In other words, it's not an S-expression.
I know it's frustrating, and honestly, not that great of an answer, but this is a great lesson in one of the Golden Rules of Computer Programming: Garbage In, Garbage Out. The fat is that you are going to get these kinds of errors simply because it isn't really feasible, when starting out programming, to test for every possible way that something isn't an S-expression without using the language itself.

MIT-Scheme: Different Behavior on Infinite Loop Depending on Numbers

I was working on the solution of the exercise 1.6 of the SICP book when I saw two different behaviors when I run the code depending on the numbers that I used.
If I use natural numbers when I call the sqrt-iter procedure the interpreter just never stop but when I force the decimal division using float-point numbers the interpreter responds: Aborting!: maximum recursion depth exceeded.
Does anyone know the reason for the different behavior?
I made a gist with my answer to help anyone that wants to run the code, just copy & paste: http://bit.ly/Qv1wru. The mit-scheme version is 9.1.1.
Your good-enough? procedure seems wrong, try with this one:
(define (good-enough? guess x)
(< (abs (- (sqr guess) x)) 0.001))

Resources