Adding "Simply Scheme" language to DrRacket - scheme

I want to work through this book: http://www.eecs.berkeley.edu/~bh/ss-toc2.html. But I'm having trouble to get the "Simply Scheme" language working. The code won't run.
#lang planet dyoo/simply-scheme:2
(parse ’(4 + 3 * 7 - 5 / (3 + 4) + 6))
I keep getting the following error message: "parse: unbound identifier in module in: parse".

Take a look at this page, it has complete instructions. Simply do this:
#lang racket
(require (planet dyoo/simply-scheme:2:2))
Also be aware that the ’ character is incorrect, for quoting use ', this probably happened because you copy-pasted code with wrong typesetting.
And of course, after the above is done, you have to define the procedures explained in chapter 18, they're not defined in the package you just imported! this will work for sure:
(define (parse expr)
(parse-helper expr '() '()))
(define (parse-helper expr operators operands)
(cond ((null? expr)
(if (null? operators)
(car operands)
(handle-op '() operators operands)))
((number? (car expr))
(parse-helper (cdr expr)
operators
(cons (make-node (car expr) '()) operands)))
((list? (car expr))
(parse-helper (cdr expr)
operators
(cons (parse (car expr)) operands)))
(else (if (or (null? operators)
(> (precedence (car expr))
(precedence (car operators))))
(parse-helper (cdr expr)
(cons (car expr) operators)
operands)
(handle-op expr operators operands)))))
(define (handle-op expr operators operands)
(parse-helper expr
(cdr operators)
(cons (make-node (car operators)
(list (cadr operands) (car operands)))
(cddr operands))))
(define (precedence oper)
(if (member? oper '(+ -)) 1 2))
(define (compute tree)
(if (number? (datum tree))
(datum tree)
((function-named-by (datum tree))
(compute (car (children tree)))
(compute (cadr (children tree))))))
(define (function-named-by oper)
(cond ((equal? oper '+) +)
((equal? oper '-) -)
((equal? oper '*) *)
((equal? oper '/) /)
(else (error "no such operator as" oper))))
(parse '(4 + 3 * 7 - 5 / (3 + 4) + 6))
=> '(+ (- (+ (4) (* (3) (7))) (/ (5) (+ (3) (4)))) (6))
(compute (parse '(4 + 3 * 7 - 5 / (3 + 4) + 6)))
=> 30 2/7

There is also a module allowing you to run "Simply Scheme" here:
https://gist.github.com/alexgian/5b351f367169b40a4ad809f0bb718e1f
You can just run it and then type your code in interactively, no need for an installation like the Planet/dyoo code mentioned above.
Should you wish to, though, you can also install it, so that all you have to do then is to prefix any program with #lang simply-scheme and it will work.
Instructions for how to do so can be seen here:
https://groups.google.com/forum/#!topic/racket-users/jHPtw3Gzqk4
in the message by Matthew Butterick, June 4 2018.
This version takes care of some stuff not done the dyoo code, for instance
> (first 'american)
'a
> (first 'American)
"A"
> (every butfirst '(AmericAn Legacy CODE))
'("mericAn" egacy "ODE")
I.e. incorrect mixing of strings and symbols, instead of
> (first 'american)
a
> (first 'American)
A
> (every butfirst '(AmericAn Legacy CODE))
(mericAn egacy ODE)
as it should be.
The dyoo implementation might be more complete for docs, etc, though
However, as noted in the answer above, you will still have to enter the code for the parse function yourself, as this was the intention of the authors.

I had to revert to DrRacket 5.4.1 in order to get both Simply Scheme and SICP to work.

Related

Scheme function for adding elements in nested list [duplicate]

This question already has an answer here:
scheme recursion
(1 answer)
Closed 5 months ago.
I'm trying to create a scheme program that adds the elements of a given list (both simple and nested).
(define (adder a_list)
(cond
((null? a_list) 0)
((list? (car a_list))(adder (car a_list)))
(else (+ (car a_list) (adder (cdr a_list))))
)
)
(adder '(2 (5 4) 6))```
The problem I'm running into is that when I run this, it only adds (5+4) + 2, and then doesn't add the 6. So my output is 11 rather than 17. I know my null statement at the top is causing this issue, but when I take it out I get this error:
car: contract violation
expected: pair?
given: '()
Any tips would be greatly appreciated.
(define (adder a*)
(if (null? a*)
0
(+ (if (pair? (car a*))
(adder (car a*))
(car a*))
(adder (cdr a*)))))
And, shorter:
(define ++
(lambda (a*)
(fold-left (lambda (a x)
(+ a (if (pair? x) (++ x) x)))
0
a*)))
(written in mit/scheme)

Why might the Scheme `filter` form not process list elements 'in order'?

(filter procedure list) applies procedure to each element of list
and returns a new list containing only the elements for which procedure
returns true.
(R. Kent Dybvig The Scheme Programming Language)
(online)
What may not be apparent from this description is that, while the elements in the returned
list occur in the same order as in list, the order of calls of procedure is not
specified in R6RS. (Racket, however, applies the procedure "to each element from first to last")
A recently active answer
mentions that it requires a filterfunc which works over its argument list
in order. How should one write this function?
An answer with my explanation of the issue is supplied.
What order might a Scheme implementation use, and why? Let's try it (all code run in Chez Scheme REPL):
Display order of applications
> (filter (lambda (x) (display x) (even? x))
'(0 1 2 3 4 5)))
452301(0 2 4)
>
Why this order?
R6RS implementations must check that list is a proper list
ends with the empty list:
> (filter (lambda (x) (display x) (even? x))
'(0 1 2 . 3)))
Exception in filter: (0 1 2 . 3) is not a proper list
>
no circularity:
> (define xs '(0 1 2 3))
> (set-cdr! (cdddr xs) (cdr xs))
> (filter (lambda (x) (display x) (even? x)) xs)
Exception in filter: (0 1 2 3 1 2 ...) is not a proper list
>
the implementation of filter in Chez Scheme which checks these requirements
while filtering, resulting in the "452301" order of predicate applications,
can be seen here
(lines 589-617: a version is included as a spoiler below as an alternative to scrolling through
the source on github)
What?
The Chez Scheme code uses a "tortoise and hare" algorithm
to detect cycles. Without error checks the code could be:
> (let ([filter
(lambda (pred? ls)
(let f ([fast ls])
(if (pair? fast)
(let ([rest (f (cdr fast))])
(if (pred? (car fast))
(cons (car fast) rest)
rest))
'())))])
(filter (lambda (x) (display x) (even? x))
'(0 1 2 3 4 5)))
543210(0 2 4)
>
(the identifier fast is used to match the Chez Scheme code: could be ls otherwise)
How can one change this to call pred? "from first to last"?
replace the rest variable with an accumulator (compare the following with 3 above;
the changes are small, but filtered elements are consed to acc,
so it has to be reversed to give the result):
> (let ([filter
(lambda (pred? ls)
(let f ([fast ls] [acc '()])
(if (pair? fast)
(f (cdr fast)
(if (pred? (car fast))
(cons (car fast) acc)
acc))
(reverse acc))))])
(filter (lambda (x) (display x) (even? x))
'(0 1 2 3 4 5)))
012345(0 2 4)
>
So 4 could be used as the required filterfunc. It would be an interesting exercise
to add error checks like the Chez Scheme implementation, which is effectively:
(define (filter pred? ls)
(unless (procedure? pred?)
(error #f "not a procedure" pred?))
(or (let f ((pred? pred?) (fast ls) (slow ls))
(if (pair? fast)
(let ((fast1 (cdr fast)))
(if (pair? fast1)
(and (not (eq? fast1 slow))
(let ((fast2 (cdr fast1)))
(let ((rest (f pred? fast2 (cdr slow))))
(and rest
(if (pred? (car fast))
(if (pred? (car fast1))
(if (eq? rest fast2)
fast
(list* (car fast)
(car fast1) rest))
(cons (car fast) rest))
(if (pred? (car fast1))
(if (eq? rest fast2)
fast1
(cons (car fast1) rest))
rest))))))
(and (null? fast1)
(if (pred? (car fast))
fast
'()))))
(and (null? fast) '())))
(error #f "circular/improper list" ls)))
It involves you should not use mutation of some external variable inside procedure and it supposes the implementation may apply parallelism, for example map-reduce.

Creating Dr Racket scheme function that takes a list of evaluations in specific order and returns simplified version

I am working towards being able to convert a list in the following way using Dr. Racket Scheme programming:
A function that takes in a list consisting of (9 7 / 8 7 /) would produce the list (7/9 7/8). The operator appears after the operands, with the right value (7 in both of these cases) being the first operand and the left-most value being the second operand. In order to achieve this, I have the following code:
(define (test original)
(let loop ((original original)
(new '()))
(cond ((null? original) new)
((eq? (car original) '/)
(cons (evaluate-expression (grab-last-two-values new) (car original))
(loop (cdr original) (remove-last-two-values new))))
(else
(loop (cdr original) (cons (car original) new))))))
(define (grab-last-two-values ls)
(cond ((null? (cdr (cdr ls))) ls)
(else (grab-last-two-values (cdr ls)))))
(define (remove-last-two-values ls)
(cond ((= (get-count ls) 2) '())
(else (cons (car ls) (remove-last-two-values (cdr ls))))))
(define (evaluate-expression ls operator)
(cond ((eq? operator '/) (/ (car ls) (car (cdr ls))))
((eq? operator '+) (+ (car ls) (car (cdr ls))))
((eq? operator '-) (- (car ls) (car (cdr ls))))
((eq? operator '*) (* (car ls) (car (cdr ls))))
(else #f)))
In the case of the list being ( 9 7 / 8 7 / ), the test function works and returns the list (7/9 7/8). So all good there. However, when the list is ( 9 7 / 8 7 / / ), the function fails, when, ideally, it would return 1 and 1/8th, since 7/8 divided by 7/9 is 1 and 1/8th. I am not able to figure out how exactly to account for this. Any help/hints?
While evaluate expression will ultimately account for addition, subtraction, and multiplication in addition to division, I am only asking the question about division as that answer will apply to the rest.
You are being asked to write a reverse Polish evaluator. Do that rather than implementing a number of special cases. Such a thing has a stream of forms which it is evaluating, a stack, and a table of operators. Each operator knows how many arguments it expects which is a natural number, and has some implementation which is probably a function you can call on the arguments.
At each step it:
checks if the stream is empty: if it is return the current stack;
pick the first form of the stream
if it names an operator, then pop as many arguments as the operator expects off the stack and invoke the operator's implementation on those arguments, pushing its result onto the stack;
if it doesn't name an operator just push it onto the stack;
loop with the rest of the stream, the new stack and the table of operators.
You will also need a function which, given a stack, returns a stream of forms created by popping all the forms off the stack.
First of all, when you are working with lists, add or remove elements from beginning, not from end. Racket has already functions like cddr (removes first two values from list), first and second, so you can delete your grab-last-two-values and remove-last-two-values.
Start with the table of operators:
(define operators
(list (cons '+ +)
(cons '- -)
(cons '* *)
(cons '/ /)))
You will use assoc function for searching in this list:
> (assoc '+ operators)
'(+ . #<procedure:+>)
Then write evaluator function, which takes list of forms as argument. This function calls some helper function (I used letrec here, but it also can be global function), adding empty list as stack argument. Helper function checks every form in args and changes stack accordingly:
(define (evaluate args)
(letrec ((evaluate-help
(lambda (args stack)
(cond ((empty? args) stack)
((number? (car args))
(evaluate-help (cdr args) (cons (car args) stack)))
(else (evaluate-help (cdr args)
(cons ((cdr (assoc (car args) operators)) (first stack) (second stack))
(cddr stack))))))))
(evaluate-help args '())))
If args is empty, stack is returned.
If (car args) is number, is pushed into stack.
Else new value, computed by ((cdr (assoc (car args) operators)) (first stack) (second stack)), is pushed into (cddr stack).
Examples:
> (evaluate '(9 7 / 8 7 /))
'(7/8 7/9)
> (evaluate '(9 7 / 8 7 / /))
'(1 1/8)
A stack for operands and intermediate results is conventional, but given a syntactically correct reverse Polish expression (see other answers), the list can be evaluated "in place":
(define (evaluate rpe)
(cond
[(not (memq '/ rpe)) rpe ]
[(and (number? (car rpe))
(number? (cadr rpe))
(eq? (caddr rpe) '/))
(let ([redex (cons (/ (cadr rpe) (car rpe)) (cdddr rpe))])
(if (and (not (null? (cdr redex))) (number? (cadr redex)))
(evaluate redex)
redex)) ]
[else (evaluate (cons (car rpe) (evaluate (cdr rpe)))) ]))
(check-expect (evaluate '(9 7 / 8 7 /)) '(7/9 7/8))
(check-expect (evaluate '(9 7 / 8 7 / /)) '(9/8))
(check-expect (evaluate '(2 2 9 7 / 8 7 / / / /)) '(9/32))
(works in Racket Intermediate Student Language and Scheme)

scheme- writing a foldl /fold-left like function that works on first 3 items of the given list

I would like to write a function that gets and infix expression and changes it to prefix.
at first let's assume we only deal with + operator, so I want to change the expression 1+1+1 into: (+ (+ 1 1) 1)
I want to do it using foldl or foldl-like matter:
taking the second item in the list (which is always the operand) appending it with the first and the third (in that order) then I would like the expression we've just appended to become the first item in the list so I would do the same on the rest of the list recursively.
Iv'e tried the following:
(lambda (lst)
(fold-left (lambda (pmLst)
`(,((cadr pmLst) ,(car pmLst) (caddr pmLst)) ,(cddr pmLst)))
'()
lst))
but then I realized that the lambda given to the fold-left has to have 2 arguments but I would like to deal with the first 3 items of the list.
I hope I've made myself clear cause it got a bit tricky..
A fold wont do what you want. If you imagine the expression (5 + 3 + 2) then using a fold with proc as the procedure do this:
(proc 2 (proc '+ (proc 3 (proc '+ (proc 5 '())))))
A way would be to make a function that returns the odd and even elements in their own list so that '(+ 2 - 3) becomes (+ -) and (2 3) and then you could do it like this:
(define (infix->prefix expr)
(if (pair? expr)
(let-values ([(ops args) (split (cdr expr))])
(fold (lambda (op arg acc)
(list op acc (infix->prefix arg)))
(car expr)
ops
args))
expr))
However the size of both is much greater than just rolling your own recursion:
(define (infix->prefix expr)
(define (aux lst acc)
(if (pair? lst)
(aux (cddr lst)
(list (car lst)
acc
(infix->prefix (cadr lst))))
acc))
(if (pair? expr)
(aux (cdr expr) (infix->prefix (car expr)))
expr))
(infix->prefix '(1 + 2 - 3))
; ==> (- (+ 1 2) 3)
There is no operator precedence here. Everything is strictly left to right.

Trouble with simple calculator program in Scheme

I need to define a calculator for simple arithmetic expressions in Scheme. For example, when typing (calculator '( 1 + 2)), scheme interpreter will print 3. The calculator will accept expression of any length, and the expression associates to the right. Eg, in (calculator '(1 + 1 - 2 + 3 )) the expression is interpreted as (1 + (1 - (2 + 3))), hence the value is -3. I'm assuming the expression has + and - operators only and there are no brackets in the input. I wrote this program so far:
#lang lazy
(define (calculator exp)
(cond
((null? exp) 0)
(= (length (exp)) 1 exp)
(eq? '+ (cdr (cdr exp)) (+ (car exp) (calculator (cdr (cdr exp)))))
(else (eq? '- (cdr (cdr exp)) (- (car exp) (calculator (cdr (cdr exp)))))))
But when I try something like (calculator '(1 + 1 + 1)), I get this error:
#%module-begin: allowed only around a module body in: (#%module-begin (define
(calculator exp) (cond ((null? exp) 0) (= (length (exp)) 1 exp) (eq? (quote +)
(cdr (cdr exp)) (+ (car exp) (calculator (cdr (cdr exp))))) (else (eq? (quote -)
(cdr (cdr exp)) (- (car exp) (calculator (cdr (cdr exp)))))))) (calculator
(quote (1 + 1 + 1))))
I'm very new to Scheme so any help would be greatly appreciated
The syntax in your code isn't correct. As noted in the comment to your question, you've misplaced some parens. In Scheme you get a large benefit in 'tracking parens' by indenting consistently. Here is a version that gets you mostly there.
(define (calculator exp)
(cond ((null? exp) 0) ; zero terms
((null? (cdr exp)) (car exp)) ; one term only (assumed number)
(else ; assumed three or more terms
(let ((operand1 (car exp))
(operator (cadr exp))
(operands (cddr exp)))
((case operator ; convert operator, a symbol, to its function
((+) +)
((-) -))
operand1
(calculator operands)))))) ; calculate the rest
> (calculator '(1 + 2))
3
> (calculator '(1 - 2 + 3))
-4
In order to convert
1 - 2 + 3
to
(- 1 (+ 2 3))
you need to
cache value 1
apply - to the cached value 1 and the rest of the expression
cache value 2
apply + to the cached value 2 and the rest of the expression
cache value 3
return cached value 3 since your list is empty now
So your have 3 cases:
1) end of list => return cached value
otherwise toggle between
2) cache a value
3) apply the function to the cached value and the rest of the expression
Sample code:
(define (calculator exp)
(define funcs (hasheq '+ + '- -))
(let loop ((exp exp) (toggle #t) (val #f))
(if (empty? exp)
val ; 1) end of list => return cached value
(if toggle
(loop (cdr exp) #f (car exp)) ; 2) cache value
((hash-ref funcs (car exp)) val (loop (cdr exp) #t #f)))))) ; 3) apply the function to the cached value and the rest of the expression

Resources