I'm trying to figure out why I got #!unspecific on output.
I checked other post forum about it but still couldn't figure out what is causing it.
TEST 12: ----- process-square side=3.16228
Side = 3.16228
Perimeter = 12.64911
Area = 10.
#!unspecific
This is my code
;Calculate Distance
(define (get-dist-sq x1 y1 x2 y2)
(+ (expt (- x2 x1) 2)
(expt (- y2 y1) 2))
)
;Calculates the distance between two points
(define (dist-square p1 p2)
(get-dist-sq (get-x p1) (get-y p1) (get-x p2) (get-y p2))
)
;Check if it is a square
(define (is-square p1 p2 p3 p4)
(let ((d2 (dist-square p1 p2)) (d3 (dist-square p1 p3)) (d4 (dist-square p1 p4)))
(cond
((or (equal? d2 0) (equal? d3 0) (equal? d4 0)) #f)
((and (equal? d2 d3) (equal? (* 2 d2) d4) (equal? (* 2 (dist-square p2 p4)) (dist-square p2 p3))) #t)
((and (equal? d3 d4) (equal? (* 2 d3) d2) (equal? (* 2 (dist-square p3 p2)) (dist-square p3 p4))) #t)
((and (equal? d2 d4) (equal? (* 2 d2) d3) (equal? (* 2 (dist-square p2 p3)) (dist-square p2 p4))) #t)
(else #f))
)
)
;Calculate square side length
(define (sq-side-length p1 p2)
(distance p1 p2)
)
;Calculate square area, A= side^2
(define (square-area p1 p2 p3 p4)
(expt (sq-side-length p1 p2) 2)
)
;Calculate square perimeter, P= side * 4
(define (square-perimeter p1 p2 p3 p4)
(* (sq-side-length p1 p2) 4)
)
;Display square calculations
(define (display-square p1 p2 p3 p4)
(display "Side = ")
(display (round-five-decimal (sq-side-length p1 p2)))
(newline)
(display "Perimeter = ")
(display (round-five-decimal (square-perimeter p1 p2 p3 p4)))
(newline)
(display "Area = ")
(display (round (square-area p1 p2 p3 p4)))
(newline)
)
;Process square and display it
(define (process-square p1 p2 p3 p4)
(if (equal? #t (is-square p1 p2 p3 p4))
(display-square p1 p2 p3 p4)
(display "Error: The 4 points does not form a square"))
)
This is the test
(display "TEST 12: ----- process-square side=3.16228")
(newline)
(display (process-square (make-point 3 1) (make-point 2 4) (make-point 5 5) (make-point 6 2)))
(newline)
Your code prints something and returns a value.
The returned value is the same as the returned value of newline (at the end of the test), which is undefined by definition. For this undefined value your scheme implementation uses the symbol #!unspecific
Call your scheme interpreter with some --silent option to get rid of the returned value.
I cannot reproduce your code as I do not know what metaobject protocol are you using -- but this is not an important detail for your question.
Related
I'm working on an assignment from one of my CS courses and got kinda stuck.
The assignment is to create a message-oriented implementation of associative arrays. These arrays should understand (among others) the following messages:
cdr: returns an associative array that contains the current array without the first pair, or an empty array if the array is empty
cons: expects a pair (key value) as an argument and generates a new associative array by prepending the given key-value-pair to the current array
Basically, the associative array is a list of pairs like ((a 1) (b 7) (c 4) (a 6) (c 5) (d 4) (b 2)) where the characters are the keys and the integers are the values in this case.
To implement the message-oriented style, we should use a dispatch function that takes two arguments (where the second argument is only used by the messages that understand it).
What I have so far is this:
(define (make-empty-as)
(define (dispatch msg arg)
(let ((lst '()))
(cond
((eq? msg 'cdr)
(cond ((not (null? lst)) (set! lst (cdr lst))))
dispatch)
((eq? msg 'cons)
(cond ((= (length arg) 2) (set! lst (append lst (list arg)))))
dispatch)
;; other messages ...
(else (error "Don't understand " msg)))))
dispatch)
To construct the array above, for example, we could do this:
(define a1 (make-empty-as))
(define a2 (a1 'cons '(b 2)))
(define a3 (a2 'cons '(d 4)))
(define a4 (a3 'cons '(c 5)))
(define a5 (a4 'cons '(a 6)))
(define a6 (a5 'cons '(c 4)))
(define a7 (a6 'cons '(b 7)))
(define a8 (a7 'cons '(a 1)))
;; a8 should now have the list ((a 1) (b 7) (c 4) (a 6) (c 5) (d 4) (b 2))
(a8 'cdr 'dummy) ;; should be the list ((b 7) (c 4) (a 6) (c 5) (d 4) (b 2))
My problem is the two functions that should return an associative array again.
My approach to return dispatch again does not work because this does not keep the modifications I did to lst.
Coming from object-oriented languages I tried to find a way to modify the instance variable lst and return "myself" (i.e. the modified version of the "object") which would be the function that is currently evaluated(?). Googling around did not bring up anything helpful, unfortunately.
So, the question is if there actually is a way to achieve this or if not if there's another way that I'm missing.
Thanks.
Just for completeness: #ad absurdum's comment was actually the solution for my problem.
However, the approach of simply wrapping the let around the define resulted in only one "object" being modified by the cons messages. I.e. changing the code to this
(define (make-empty-as)
(let ((lst '()))
(define (dispatch msg arg)
(cond
((eq? msg 'cdr)
(cond ((not (null? lst)) (set! lst (cdr lst))))
dispatch)
((eq? msg 'cons)
(cond ((= (length arg) 2) (set! lst (append (list arg) lst))))
dispatch)
((eq? msg 'print) (display lst) (newline)) ;; added for debugging
(else (error "Don't understand " msg))))
dispatch))
and running
(define a1 (make-empty-as))
(a1 'print 'dummy)
(define a2 (a1 'cons '(b 2)))
(a2 'print 'dummy)
(define a3 (a2 'cons '(d 4)))
(a3 'print 'dummy)
(define a4 (a3 'cons '(c 5)))
(a4 'print 'dummy)
(define a5 (a4 'cons '(a 6)))
(a5 'print 'dummy)
(define a6 (a5 'cons '(c 4)))
(a6 'print 'dummy)
(define a7 (a6 'cons '(b 7)))
(a7 'print 'dummy)
(define a8 (a7 'cons '(a 1)))
(a8 'print 'dummy)
(a1 'print 'dummy)
resulted in the following output
() ;; a1
((b 2)) ;; a2
((d 4) (b 2)) ;; a3
((c 5) (d 4) (b 2)) ;; a4
((a 6) (c 5) (d 4) (b 2)) ;; a5
((c 4) (a 6) (c 5) (d 4) (b 2)) ;; a6
((b 7) (c 4) (a 6) (c 5) (d 4) (b 2)) ;; a7
((a 1) (b 7) (c 4) (a 6) (c 5) (d 4) (b 2)) ;; a8
((a 1) (b 7) (c 4) (a 6) (c 5) (d 4) (b 2)) ;; a1
meaning all of a1 to a8 actually represented the same "object".
But the assignment actually wanted cons and cdr to return copies of the associative arrays. Therefore, I simply added a copy message that copies the internal lst from another object's lst and changed cons and cdr to return new associative arrays:
(define (make-empty-as)
(let ((lst '()))
(define (dispatch msg arg)
(cond
((eq? msg 'cdr)
(cond
((not (null? lst)) ((make-empty-as) 'copy (cdr lst)))
(else (make-empty-as))))
((eq? msg 'cons)
(cond
((= (length arg) 2) ((make-empty-as) 'copy (append (list arg) lst)))
(else (make-empty-as))))
((eq? msg 'print) (display lst) (newline))
((eq? msg 'copy)
(cond
((list? arg) (set! lst arg))
(else (set! lst '())))
dispatch)
(else (error "Don't understand " msg))))
dispatch))
Running
(define a1 (make-empty-as))
(a1 'print 'dummy)
(define a2 (a1 'cons '(b 2)))
(a2 'print 'dummy)
(define a3 (a2 'cons '(d 4)))
(a3 'print 'dummy)
(define a4 (a3 'cons '(c 5)))
(a4 'print 'dummy)
(define a5 (a4 'cons '(a 6)))
(a5 'print 'dummy)
(define a6 (a5 'cons '(c 4)))
(a6 'print 'dummy)
(define a7 (a6 'cons '(b 7)))
(a7 'print 'dummy)
(define a8 (a7 'cons '(a 1)))
(a8 'print 'dummy)
(a1 'print 'dummy)
again now gives the desired result
() ;; a1
((b 2)) ;; a2
((d 4) (b 2)) ;; a3
((c 5) (d 4) (b 2)) ;; a4
((a 6) (c 5) (d 4) (b 2)) ;; a5
((c 4) (a 6) (c 5) (d 4) (b 2)) ;; a6
((b 7) (c 4) (a 6) (c 5) (d 4) (b 2)) ;; a7
((a 1) (b 7) (c 4) (a 6) (c 5) (d 4) (b 2)) ;; a8
() ;; a1
Thanks, again to #ad absurdum for nudging me in the right direction.
I'm working with modifying a list in scheme and was wondering basically how mutability is usually done (or if it's done at all). Here is one example of "adding positions to a chess board".
; representing a chess position as (col, row), using 1-based indexing
(define (make-position col row) (cons col (list row)))
(define empty-board '())
(define (add-new-position existing-positions col row)
(append existing-positions (list (make-position col row))))
And using them:
(define B1 empty-board)
(set! B1 (add-new-position B1 1 2))
(set! B1 (add-new-position B1 2 4))
(display "B1=") (display B1) (newline)
; B1=((1 2) (2 4))
(define B2 empty-board)
(add-new-position B2 1 2)
(add-new-position B2 2 4)
(display "B2=") (display B2) (newline)
; B2=()
Is the above usually how mutability is handled (using set!)? Is that fine to do, or usually discouraged in scheme or other functional programming languages? And if it's discouraged, how would someone, for example, debug in the middle of "building a list" ?
I want to draw about 1000 shapes of two circles with tangents using this lisp file, which draws one shape a time.
I wrote a script to draw all shapes (see below), however it waits after the first argument for the next argument although it is there in the script.
Could you please guide me how to fix my script or how to edit the lisp file so that I can draw all shapes without interactive input?
Here is my current Script:
ctan
0,0,0
5
0,10,0
10
The issue is that evaluation of both the Script & AutoLISP function occurs in the same processor thread, and therefore when you evaluate the AutoLISP function from within the Script file, the AutoLISP function takes focus away from the Script, and the remainder of the Script file will be evaluated after the AutoLISP function has completed its evaluation.
To solve this, I would suggest defining a separate AutoLISP function which accepts four arguments corresponding to the centers & radii of each circle, and which constructs the 2D LWPolyline in the same manner as that of my Circle Tangents application.
You can then either evaluate such function from your Script file (perhaps on multiple drawings if required), or evaluate the function from within another AutoLISP program.
Such a function might be:
(defun ctan ( c1 r1 c2 r2 / d1 d2 a1 a2 zv )
(if (< (abs (setq d1 (- r1 r2))) (setq d2 (distance c1 c2)))
(progn
(setq a1 (atan (sqrt (- (* d2 d2) (* d1 d1))) d1)
a2 (angle c1 c2)
zv (trans '(0.0 0.0 1.0) 1 0 t)
)
(entmake
(list
'(000 . "LWPOLYLINE")
'(100 . "AcDbEntity")
'(100 . "AcDbPolyline")
'(090 . 04)
'(070 . 01)
(cons 010 (trans (polar c1 (+ a1 a2) r1) 1 zv))
(cons 042 (/ (sin (/ (- pi a1) 2.0)) (cos (/ (- pi a1) 2.0))))
(cons 010 (trans (polar c1 (- a2 a1) r1) 1 zv))
(cons 010 (trans (polar c2 (- a2 a1) r2) 1 zv))
(cons 042 (/ (sin (/ a1 2.0)) (cos (/ a1 2.0))))
(cons 010 (trans (polar c2 (+ a1 a2) r2) 1 zv))
(cons 210 zv)
)
)
)
)
)
Which, when loaded, you could call from your Script or another AutoLISP program using:
(ctan '(0 0 0) 5 '(0 10 0) 10)
(define (create-polygon ptlist)
(if (null? ptlist) '()
(cons (cons (car ptlist) (cadr ptlist)) (create-polygon (cdr ptlist)))))
(define (newlist ptlist)
(append ptlist (car ptlist)))
(define test-points
(list p1 p2 p3 p4 p5 p6))
(create-polygon test-points)
I'm trying to make a list of a polygons edge's coordinates. p1,p2 are some points like (0 0).
The final result should be ((p1 p2) (p2 p3) (p3 p4) (p4 p5) (p5 p6) (p6 p1)).
I've wasted so much time on this to try and figure out what is giving me an error. And why it is giving an error.What am I doing wrong here?
This was some fun finger exercise on my lunch break.
Petite Chez Scheme Version 8.4
Copyright (c) 1985-2011 Cadence Research Systems
> (define test-points '(p1 p2 p3 p4 p5 p6))
> (define (rotate xs) (append (cdr xs) (list (car xs))))
> (define (create-polygon ptlist)
(map list ptlist (rotate ptlist)))
> (create-polygon test-points)
((p1 p2) (p2 p3) (p3 p4) (p4 p5) (p5 p6) (p6 p1))
My rotate function does what I think you were trying to do with your newlist function. In create-polygon I used the map higher-order function to do what you did with recursion.
This is my code and I am slightly confused why I am receiving this error. My code is just to find the roots for a quadratic equation.
(define (roots a b c)
(define det
(- (* b b) (* 4 a c))
)
(if (> det 0) (
(display (/ (+ (* b -1) (sqrt det)) (* 2 a)))
(display (/ (- (* b -1) (sqrt det)) (* 2 a)))
)
)
(if (= det 0) (
(display (/ (* b -1) (* 2 a)))
(display (/ (* b -1) (* 2 a)))
)
)
(if (< det 0) (
(display "complex roots")
(display (/ (+ (* b -1) sqrt(* det -1)) (* 2 a)))
(display (/ (- (* b -1) sqrt(* det -1)) (* 2 a)))
)
)
)
(roots -2 4 5)
(roots -2 4 -5)
I believe you meant to add a begin in the body of your one armed if's. The display procedure has a void return value, and the extra parentheses will try to apply the value as a procedure. You can reproduce the error by running ((display 5)). Using begin will allow you to instead evaluate the expressions in sequence.
This code will display the values without any exceptions:
(define (roots a b c)
(define det
(- (* b b) (* 4 a c))
)
(if (> det 0) (begin
(display (/ (+ (* b -1) (sqrt det)) (* 2 a)))
(display (/ (- (* b -1) (sqrt det)) (* 2 a)))
)
)
(if (= det 0) (begin
(display (/ (* b -1) (* 2 a)))
(display (/ (* b -1) (* 2 a)))
)
)
(if (< det 0) (begin
(display "complex roots")
(display (/ (+ (* b -1) sqrt(* det -1)) (* 2 a)))
(display (/ (- (* b -1) sqrt(* det -1)) (* 2 a)))
)
)
)
The parentheses in Scheme are very special. They mean apply:
(define (test arg) arg)
((test +) 4 5) ; ==> 9
The same in JavaScript:
const plus = (a, b) => a+b; // Needed since + is not a function in JS
const test = arg => arg
test(plus)(4,5) // ==> 9
In your code you have:
((display (/ (+ (* b -1) (sqrt det)) (* 2 a)))
(display (/ (- (* b -1) (sqrt det)) (* 2 a))))
Unfortunately the expression in operator position return #<undef>. Actually accoring to the spec it can return anything because its undefined in the specification. Ib your particular implementation though it's not a function so it's like:
((test 'symbol) 4 5); ==> Error: symbol is not a function
As you saw earlier having a call to test did work earlier so expressions in operator position is perfectly valid code and almost impossible to reason about at compile time, but in runtime it will become obvious it's not possible to continue when apply gets a non function.
Now there are macros that use parentheses for something else than application and these you just have to know or read the documentation for. An example is cond
(cond ((= 3 5) #t)
(else #f))
; ==> #f
If you've never seen cond before it's easy to assume ((= 3 5) #t) is an expression and of course by looking at it it shouldn't work since (= 3 5) would not evaluate to a function object but a boolean. However each term in cond evaluates it's car then each element in the rest of the term in order if it happened to be a true value.
To do more expressions in order and return the value of the last expression one uses begin:
(begin 1 2 3)
; ==> 3
Here evaluating 1 and 2 is clearly dead code since it doesn't do anything. Thus its inherit that using begin implies a side effect where the return value is of not importance, but the side effect is. I don't think your function really needs side effects:
(define (roots a b c)
(define det
(- (* b b) (* 4 a c)))
(cond ((> det 0)
(list (/ (+ (* b -1) (sqrt det)) (* 2 a))
(/ (- (* b -1) (sqrt det)) (* 2 a))))
((= det 0)
(list (/ (* b -1) (* 2 a))))
((< det 0)
(list (/ (+ (* b -1) (make-rectangular 0 (sqrt (* det -1)))) (* 2 a))
(/ (- (* b -1) (make-rectangular 0 (sqrt (* det -1)))) (* 2 a))))))
(roots -1 4 -4) ; ==> (2 -2)
(roots 1 0 -4) ; ==> (2)
(roots 4 0 4) ; ==> (0+1i 0-1i)