Why is racket passing #<void> to my function instead of the state? - racket

I'm learning Racket, and using the book Realm Of Racket. I reached the point where they show you how to animate an image moving down the window, and then suggest you try modifying it to react to a left or right-arrow key press to move the image sideways.
Seemed simple enough...
#lang racket
(require 2htdp/universe 2htdp/image)
(define WIDTH 500)
(define DX 0)
(define HEIGHT 500)
(define IMAGE .) ; The image doesn't show up here
(define (add3-to-state current-state)
(+ current-state 3))
(define (draw-image current-state)
(place-image IMAGE (+ DX (/ WIDTH 2)) current-state (empty-scene WIDTH HEIGHT)))
(define (state-is-500 current-state)
(>= current-state 459))
(define (set-delta current-state key)
(set! DX (+ DX 10)))
(big-bang 0
(on-tick add3-to-state)
(on-key set-delta)
(to-draw draw-image)
(stop-when state-is-500)
)
When I run this, the image moves downwards as before, but as soon as I hit a key, I get an error...
>=: contract violation
expected: real?
given: #<void>
...in the state-is-500 function.
Anyone able to explain why this is happening? As far as I can see, my function for on-key has the same form as the ones they show in the book.
I tried modifying the state-is-500 function to look like this...
(define (state-is-500 current-state)
(printf "~a\n" current-state)
(>= current-state 459))
...and the output I got was...
102
105
#<void>
...before the error happened.
So it looks like #<void> is being passed to the function, but why?
Thanks

The issue is that big-bang expects the function call on-key to return the new state of the game. You are not retuning anything thus the frameworks reports <void>
Thus if the state does not change the you should just return the input state e.g.
(define (set-delta current-state key)
current-state)
Also this framework and Racket itself makes you want to not mutate variables, that is you don't assign to them, or at least you assign to them only once. Thus set! is not something you should use often.
In this case the state of the app that the book provides is just the vertical distance so is just a single number as shown in add3-to-state. The original state is passed in as the first parameter to big-bang.
The change you have to make is that the current state is not just the up-down movement but also the side to side. This movement shows up as the second parameter to place-image. So you have to have a state that can provide the second and third parameters to that.

Related

What is the error in the following racket code?

;creating traffic signal image
(require 2htdp/image)
(define (bulb c)
(circle 10 "solid" c))
(above (bulb "red")
(bulb "yellow")
(bulb "green"))
The Error Displayed is:. Module Language: there can only be one expression in the definitions window in: (define (bulb c) (circle 10 "solid" c))
Interactions disabled.
///I can't figure out the error
DrRacket is failing to recognize the language being used in your code. You need to choose a language manually. It looks like you are following the first chapters of the HtDP textbook, so I recommend going for the Beginning Student Language. You can do so by:
adding #lang htdp/bsl at the beginning of your file
using the picker at the bottom of the DrRacket window:

Moving point to the end of the last line without reorienting the buffer

Is it possible to move point to the end of a buffer without reorienting the text around that line? This seems to be the default behaviour of goto-char. My goal is to correct a minor annoyance which places the cursor at the second last line when I press "L". I wrote a custom function to do this properly but now when I move the point to the last line the screen scrolls down half a page and it becomes the center of the buffer.
(defun cf-last-line (count) (interactive "p")
(let ((max (truncate (window-screen-lines))))
(move-to-window-line max)
(line-move (* -1 (1- count)) t t)
(beginning-of-line)))
Edit: It turns out my problem is related to the fact that the GUI shows partial lines (which may appear to be fully exposed but upon closer inspection lie just below the status bus). I suppose my question then becomes whether or not it is possible to have the point lie on such a partial line (though I suspect this is unlikely) without moving it to the center and if not whether it is possible to instead prevent the X11 frame from showing partial lines at the bottom of the window.
Solution as described by lawlist:
(setq scroll-conservatively 101)
(setq make-cursor-line-fully-visible nil)

"Package GLUT does not exist", even though cl-opengl installed in Arch Linux

I have emacs configured with SLIME for developing in Common Lisp (sbcl) on Arch Linux. The thing is, I now want to start working with OpenGL as well, so I've installed cl-opengl to provide the necessary bindings. I have also set up a symlink on .local/share/common-lisp to /usr/share/common-lisp (I should be able to load all systems using ASDF that way).
However, when I try to compile the following code in SLIME (using C-c C-k)
(require :asdf) ; need ASDF to load other things
(asdf:load-system :cl-opengl) ; load OpenGL bindings
(asdf:load-system :cl-glu) ; load GLU bindings
(asdf:load-system :cl-glut) ; load GLUT bindings
(defclass my-window (glut:window)
()
(:default-initargs :width 400 :height 300
:title "My Window Title"
:x 100 :y 100
:mode '(:double :rgb :depth)))
(defmethod glut:display-window :before ((win my-window))
(gl:shade-model :smooth) ; enables smooth shading
(gl:clear-color 0 0 0 0) ; background will be black
(gl:clear-depth 1) ; clear buffer to maximum depth
(gl:enable :depth-test) ; enable depth testing
(gl:depth-func :lequal) ; okay to write pixel if its depth
; is less-than-or-equal to the
; depth currently written
; really nice perspective correction
(gl:hint :perspective-correction-hint :nicest)
)
(defmethod glut:display ((win my-window))
(gl:clear :color-buffer-bit :depth-buffer-bit)
(gl:load-identity))
(defmethod glut:reshape ((win my-window) width height)
(gl:viewport 0 0 width height) ; reset the current viewport
(gl:matrix-mode :projection) ; select the projection matrix
(gl:load-identity) ; reset the matrix
;; set perspective based on window aspect ratio
(glu:perspective 45 (/ width (max height 1)) 1/10 100)
(gl:matrix-mode :modelview) ; select the modelview matrix
(gl:load-identity) ; reset the matrix
)
(glut:display-window (make-instance 'my-window))
I get the following error:
READ error during COMPILE-FILE:
Package GLUT does not exist.
even though cl-glut.asd exists in /usr/share/common-lisp/systems.
What am I doing wrong?
ASDF:LOAD-SYSTEM doesn't take effect until load time, since it's a plain function. If you want the effect to happen at compile time, you have to wrap it in an eval-when form. But it's better to write a system definition that :depends-on those other systems.

How to interactively read in two inputs and use them in a function call

I am currently taking a class to learn elisp so I have no experience with this language. I am trying to interactively read in two inputs (the width and length of a rectangle) and then use them to call a function to compute the area of the rectangle. The code I have is as follows:
(defun rectangle_Area(w l)
"Compute the area of a rectangle, given its width and length interactively."
(interactive "nWidth: ")
(interactive "nLength: ")
(setq area (rectangleArea w l))
(message "The rectangle's area is %f." area))
Currently I get a wrong number of arguments error.
Like I said, I have no previous experience... all I really need to know is how to store/read in two separate values using interactive.
Thank you for any help
C-hf interactive RET:
To get several arguments, concatenate the individual strings,
separating them by newline characters.
So we have:
(defun rectangle_Area(w l)
"Compute the area of a rectangle, given its width and length interactively."
(interactive "nWidth: \nnLength: ")
(setq area (rectangleArea w l))
(message "The rectangle's area is %f." area))

How to resize a buffer so it only takes a small part of the screen?

In Emacs how can I resize a buffer so it only takes a small part of the screen ?
Is there any way ?
I would like to have the src taking 70% of the screen and a file manager in the other 30%
Set width of current window on current frame to ~ 70%:
(window-resize nil (- (truncate (* 0.7 (frame-width))) (window-width)) t)
The other windows are shrunk automatically. If you want to adjust more than one it gets more difficult.
As command:
(defun window-resize-to-70-percent ()
(interactive)
(window-resize nil (- (truncate (* 0.7 (frame-width))) (window-width)) t))
Use separate window-manager frames for individual buffers (by default). Automatically shrink-fit the frames to fit the buffer content.
See One-On-One Emacs, in particular, libraries fit-frame.el and autofit-frame.el.