How can i create a function using struct to create a condition - data-structures

i am trying to create a little mini game using racket and structs to creating a story telling game.i have already defined lists and the struct i need to get going but i don't know how to put into a function,for when the function is ran it will allow the user input a parameter corresponding to A or B and depending on the choice it shall print lists A or B
(define A '("Confidently stepped right in to solve the mystery atop Skelen Manor."))
(define b '( "Ran away due to my fear of death and the boredom of the paperwork after the matter"))
(define line1 '("Walking away from the police chatter, I approached the eery-looking Skelen Manor, a relic of an
;older generation; and as I opened the golden doors into the manor, I took a deep breath and"))
(define line2 '("You have failed the case, and let down the department... but worry not! Would you
;like to try again?"))
(define line3 '( "press no the game will CLOSE
or press Yes the game will restart from the Chapter 1 intro text as typed above"))
;we will use strucure to track the users choices
(struct choice1 ( A b))
(make-string string string)
(define first (choice1 A b))
(define (options choice1)
(

Related

How to follow the Simply Scheme book with DrRacket

I'd like to be able to manipulate sentences so that I can take them as an input and return an output based on things like the individual letters. For example, an ends-e command that would return all of the words that end in "e":
(ends-e '(only the good die young))
=> '(the die)
Unfortunately, "e" is a string, and '(only the good die young) is a sentence. Scheme has trouble understanding a sentence as a data type (because it isn't one). How do I turn a sentence that the user inputs with a quote and parentheses into something I can manipulate and return in the same sentence format?
This book: https://people.eecs.berkeley.edu/~bh/ssch8/higher.html#ft1 outlines some functions that can manipulate sentences and words, but posts a footnote at the bottom saying "Like all the procedures in this book that deal with words and sentences... [the] procedures in this chapter are part of our extensions to Scheme."
How do I get those extensions? I looked in a later chapter, but my understanding of the language is too rudimentary to understand how to create those procedures myself.
These are the error messages I get when I try to turn '(h) into a datatype scheme can understand.
Welcome to DrRacket, version 6.12 [3m].
Language: sicp, with debugging; memory limit: 128 MB.
> (symbol->string '(h))
. . symbol->string: contract violation
expected: symbol?
given: (mcons 'h '())
> (list->string '(h))
. . list->string: contract violation
expected: (listof char?)
given: '(h)
> (string->list '(h))
. . string->list: contract violation
expected: string?
given: (mcons 'h '())
> (string->symbol '(h))
. . string->symbol: contract violation
expected: string?
given: (mcons 'h '())
>
This means I cant ask scheme if '(h) is equal to "h". I can't even ask it if '(h) is equal to '(h)!
> (eq? '(h) "h")
#f
> (eq? '(h) '(h))
#f
>
In DrRacket there is a Simply Scheme compatibility language
1. From the Package Manager
Open the Package Manager: in DrRacket choose the menu "File" then choose "Package Manager...".
In the tab "Do What I Mean" find the text field and enter: "simply-scheme" without the quotes.
Click the "Install" button. This produces smoe output. When you can click "close output" it's finished and you may close the window.
Test it. Make sure DrRacket has "Determine language from source" in
the bottom left corner. Write the following program and click RUN:
#lang simply-scheme
(se (butlast (bf "this"))
"world")
; ==> (hi "world")
I was a little confused since SICP and Simply Scheme are two different books. SICP has their own specified procedures from their book and in DrRacket there is a specific language, #lang sicp, for that flavor of Scheme too. I've written a similar answer on how to install sicp.

Get variable value with a string in scheme

How can we get variable value with a string in scheme language as we can achieve this in Common Lisp:
> (defvar s 3)
> S
> (symbol-value (intern "S"))
> 3
I am accessing a parameter of parent function from the closure.
EDIT: I have found this solution, but I can't use eval because it evaluates at top level. Searching for alternatives.
(eval (string->symbol "s"))
EDIT 2: I have found that Common lisp code also try to find symbol in global space. So this question is basically for both Lisps(Common Lisp, Scheme).
Don't do that!
Variables are for when you know the variable at compile time. In that case it is never a string. You can still reason about strings in compile time but your code also needs to have a relation with the name for it to be interesting. When you use eval or other forms that evaluate structure and compile/run data in runtime you are probably not doing it right (but not always. I've in my 20 year career used eval intentionally in production code twice)
If you want to store values you use a data structure. An assoc would mimic a dynamic environment. You can also use a hash with a level indicator if the size is harmless.
You can't do what you want to do and in fact it is a confused thing to want to do.
Here's why what you are trying to do is confused. Consider how a Lisp system for which it was possible to do what you wanted would work. In particular consider something like this:
(define (foo a name)
(let ([b 10])
(display (get-value name))
(* a b)))
Where get-value is meant to be how you get the binding of whatever something is.
So, if I call (foo 10 "b") it should print 10 and return 100.
But wait: b is a compile-time constant in this code. Any compiler worth its salt is going to immediately turn this into
(define (foo a name)
(display (get-value name))
(* a 10))
And now there is no binding of b.
So there are two options here: what you want to work works and it is impossible to ever write a reasonable compiler for Scheme, or what you want to work doesn't work, and it is.

Change program code while running in Chicken Scheme

Is it possible to update the program code while it is being interpreted by csi, the Chicken Scheme Interpreter? If so, how?
So that I can interactively change part of the code and immediately see the effects of that changes.
For example, suppose I have written the following program:
(define (loop)
(print "Ciao")
(rest 1)
(loop))
(loop)
(assume (rest 1) has the effect of pausing the program for a second).
If I run this program, trough csi, it prints the string "Ciao" every second. If I change the string "Ciao" into something else, for example into "else", and I save the program code file, then csi continue interpreting the old program code, so I continuously see the string "Ciao". I'd like, in this case, that when I save the modified code with the string "Ciao" replaced by "else", csi continue its interpretation job by looking into the modified file, instead of the old file.
So that I obtain as output some "Ciao" followed by some "else": the "else" start to appear when I replace "Ciao" by "else" in the source code.
In general, the answer is "don't". The way you're supposed to use the REPL is by evaluating piecemeal changes against it, then evaluating a function or two to make sure everything went as expected. Part of this approach is structuring your program so that it can be easily tested in pieces, which implies not automatically starting any infinite loops. In the specific case you're asking about, you could instead write
(define (do-stuff)
(print "Ciao"))
(define (main-loop)
(do-stuff)
(rest 1)
(main-loop))
(define (start) (main-loop))
You can now incrementally develop do-stuff, periodically evaluating new versions to your interpreter and calling them to make sure they work, then eventually calling start once you're confident that it's doing the right thing.
You may get mileage out of this similar question asked about Common Lisp.
As an aside, if you were using Common Lisp and SLIME, you could now do more or less what you proposed:
(defun do-stuff ()
(format t "Ciao~%"))
(defun main-loop ()
(loop (progn (do-stuff)
(sleep 1))))
(main-loop)
Starting that up would start printing Ciao on separate lines in your SLIME REPL. If you changed do-stuff to
(defun do-stuff ()
(format t "else~%"))
then hit it with C-c C-c (the default binding for slime-compile-defun), you'd see your SLIME REPL start printing else lines in-flight.
CL-USER> (main-loop)
Ciao
Ciao
Ciao
; compiling (DEFUN DO-STUFF ...)else
else
else
else
else
else
; Evaluation aborted on NIL. User break.
CL-USER>
I'm not sure how to accomplish the same thing in Scheme, but I'm reasonably sure it's possible.
All that being said, you sometimes want to run a program part of which is an infinite loop. A real world example would be while testing a TCP server of some sort. If you're in such a situation, and your desired workflow is
Write file
Run csi my-file.scm
Edit file
Kill csi
Run csi my-file.scm
goto 3
and you basically just want to automate steps 4 through 6, you'll need an external tool to do it for you. Take a look at entr or hsandbox (the latter doesn't have Scheme support out of the box, but it doesn't look like it would be too hard to add).
There is no common way to make a running program check its source for changes but you there seems to be enough feratures available in Chicken to roll your own:
(use posix)
(use srfi-18)
(define (watch-reload! file)
(define (tsleep n)
(thread-sleep! (seconds->time (+ n (time->seconds (current-time))))))
(define (get-time)
(file-modification-time file))
(thread-start!
(lambda ()
(let loop ((filetime '()))
(let ((newtime (get-time)))
(when (not (equal? filetime newtime))
(load file))
(tsleep 10)
(loop newtime))))))
Now all you have to do is to use watch-reload! instead of load and it will check and reload every 10 seconds if the file has been modified.
If you save when the file is not valid scheme it stops working until you call watch-reload! on it again.
It may be that chicken programmers might have a better solution.

Scheme pass-by-reference

How can I pass a variable by reference in scheme?
An example of the functionality I want:
(define foo
(lambda (&x)
(set! x 5)))
(define y 2)
(foo y)
(display y) ;outputs: 5
Also, is there a way to return by reference?
See http://community.schemewiki.org/?scheme-faq-language question "Is there a way to emulate call-by-reference?".
In general I think that fights against scheme's functional nature so probably there is a better way to structure the program to make it more scheme-like.
Like Jari said, usually you want to avoid passing by reference in Scheme as it suggests that you're abusing side effects.
If you want to, though, you can enclose anything you want to pass by reference in a cons box.
(cons 5 (void))
will produce a box containing 5. If you pass this box to a procedure that changes the 5 to a 6, your original box will also contain a 6. Of course, you have to remember to cons and car when appropriate.
Chez Scheme (and possibly other implementations) has a procedure called box (and its companions box? and unbox) specifically for this boxing/unboxing nonsense: http://www.scheme.com/csug8/objects.html#./objects:s43
You can use a macro:
scheme#(guile-user)> (define-macro (foo var)`(set! ,var 5))
scheme#(guile-user)> (define y 2)
scheme#(guile-user)> (foo y)
scheme#(guile-user)> (display y)(newline)
5
lambda!
(define (foo getx setx)
(setx (+ (getx) 5)))
(define y 2)
(display y)(newline)
(foo
(lambda () y)
(lambda (val) (set! y val)))
(display y)(newline)
Jari is right it is somewhat unscheme-like to pass by reference, at least with variables. However the behavior you want is used, and often encouraged, all the time in a more scheme like way by using closures. Pages 181 and 182(google books) in the seasoned scheme do a better job then I can of explaining it.
Here is a reference that gives a macro that allows you to use a c like syntax to 'pass by reference.' Olegs site is a gold mine for interesting reads so make sure to book mark it if you have not already.
http://okmij.org/ftp/Scheme/pointer-as-closure.txt
You can affect an outer context from within a function defined in that outer context, which gives you the affect of pass by reference variables, i.e. functions with side effects.
(define (outer-function)
(define referenced-var 0)
(define (fun-affects-outer-context) (set! referenced-var 12) (void))
;...
(fun-affects-outer-context)
(display referenced-var)
)
(outer-function) ; displays 12
This solution limits the scope of the side effects.
Otherwise there is (define x (box 5)), (unbox x), etc. as mentioned in a subcomment by Eli, which is the same as the cons solution suggested by erjiang.
You probably have use too much of C, PHP or whatever.
In scheme you don't want to do stuff like pass-by-*.
Understand first what scope mean and how the different implementation behave (in particular try to figure out what is the difference between LISP and Scheme).
By essence a purely functional programming language do not have side effect. Consequently it mean that pass-by-ref is not a functional concept.

How to print structures in PLT Scheme so as to display their fields?

I would like code like this:
(define-struct thing (a b c))
(define th (make-thing 1 2 3))
to print something like this:
(make-thing 1 2 3)
when I type "th" into either the DrScheme or MzScheme repl. I am using the language "pretty big" in DrScheme with output style set to "constructor". This is what I get in DrScheme:
(make-thing ...)
(i literally get the three dots)
In MzScheme:
#<thing>
There are several ways to do that. The most obvious one is to use:
(define-struct thing (a b c) #:transparent)
which makes the struct accessible for the kind of low-level inspection that the printout does. Another alternative is to use your own printer:
(define-struct thing (a b c)
#:property prop:custom-write
(lambda (thing port write?)
(fprintf port (if write? "{~s,~s,~s}" "{~a,~a,~a}")
(thing-a thing) (thing-b thing) (thing-c thing))))
But note that the "constructor" output style tries to write some things differently. Also note that you could combine both of these to make it have its own writer as well as being transparent. (Making it transparent is basically making it possible for any code to access the fields in a thing instance, for example, equal? can dig into it.)
Finally, for some uses a more fitting facility is to use "prefab" structs:
(define-struct thing (a b c) #:prefab)
What usually happens is that each define-struct generates a new type, even if one was already defined. But with a prefab struct it's as if there is one type that pre-exists and you're just binding some functions (the constructor, predicate, and accessors) to work with this preexisting type.

Resources