(defspel game-action (command subj obj place &rest rest)
`(defspel ,command (subject object)
`(cond ((and (eq *location* ',',place)
(eq ',subject ',',subj)
(eq ',object ',',obj)
(have ',',subj))
,#',rest)
(t '(i cant ,',command like that.)))))
Thats the code from http://www.lisperati.com/actions.html for the 'macro defining macro'. I can't seem to convert it appropriately to scheme. Can someone explain to me the process of creating this same sort of thing in Scheme?
This kind of macro is actually much simpler in Scheme, since you can do it all with define-syntax-rule (in standard Scheme code you will need define-syntax + syntax-rules). You basically do the same thing, minus the whole quote/unquote mess.
(defspel (game-action command subj obj place rest ...)
(defspel (command subject object)
(cond [(and (eq? *location* 'place)
(eq? 'subject 'subj)
(eq? 'object 'obj)
(have 'subj))
rest ...]
[else '(i cant command like that.)])))
And since this is actually most of the code, I ported the whole thing to PLT -- see the post on the mailing list.
Related
I'm making a random sentence generator using Scheme (Pretty Big), and I'm having trouble defining temporary variables. I want to make something like this:
<NOUN1> <VERB1> <NOUN2> <but> <NOUN2> <VERB1> <NOUN2> <also>
Example: Sharks eat fish, but fish eat fish also.
I have word lists, and functions to choose a word from said list. Then, I use append to create a function. I am able to do:
(define (sentence)
(append (getNoun) '(and) (getNoun) (getVerb)))
However, I am unable to figure out a way to temporarily define a variable.
I have this so far:
(define (sentence1)
(append (getNoun)
(lambda (verb getVerb)
(noun getNoun))
(verb) (noun) '(but) (noun) (verb) (noun)))
Hints/Help please?
You are looking for let.
http://docs.racket-lang.org/reference/let.html
Here is an example usage:
(define (my-proc age)
(let ([age-plus-10 (+ age 10)])
(printf "age is ~a" age)
(printf "age-plus-10 is ~a" age-plus-10)))
Notice how we can temporarily define age-plus-10 and then use it later.
I have a question about Exercise 4.54 from Section 4.3.3 of Structure and Interpretation of Computer Programs (http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-28.html#%_sec_4.3.3). This exercise concerns the Amb evaluator.
The exercise is the following:
If we had not realized that require could be implemented as an ordinary procedure that uses amb, to be defined by the user as part of a nondeterministic program, we would have had to implement it as a special form. This would require syntax procedures
(define (require? exp) (tagged-list? exp 'require))
(define (require-predicate exp) (cadr exp))
and a new clause in the dispatch in analyze
((require? exp) (analyze-require exp))
as well the procedure analyze-require that handles require expressions. Complete the following definition of analyze-require.
(define (analyze-require exp)
(let ((pproc (analyze (require-predicate exp))))
(lambda (env succeed fail)
(pproc env
(lambda (pred-value fail2)
(if <??>
<??>
(succeed 'ok fail2)))
fail))))
I completed it as follows:
(define (analyze-require exp)
(let ((pproc (analyze (require-predicate exp))))
(lambda (env succeed fail)
(pproc env
(lambda (pred-value fail2)
(if (false? pred-value)
(fail2) ;; or (fail)
(succeed 'ok fail2)))
fail))))
My doubt is the following:
I know that, during execution, when the predicate value pred-value is false, require should fail; that is, it should call a failure continuation procedure. But I'm a bit confused as to whether it should call (fail) or (fail2). Which one is correct?
(fail2) is the correct one. The procedure conforms to a continuation-passing style, and the correct continuation procedure in this case is fail2.
I think (fail) is correct.
Here we have got pred-value, which means pproc evaluates well for now. But if it is false value, we treat it as bad as pproc evaluates wrong. so the continuation here is fail not fail2.
A test can be found here:
https://wizardbook.wordpress.com/2011/01/22/exercise-4-54/
(fail2)is correct, well,most of the time it doesn't matter whichever you choose,but for the following conditons:
1.the predicate part contains (amb) such as
(require (amb false true false true true))
2.the predicate part contains (set! <...> <...>)
you can check it out,this is because most of the process's fail-continuation is the same as its caller's except for the above two kinds of processes. Though it sounds some kind of ridiculous.
probably an easy question: I want to wrap the "(format ..)" function of Scheme in order to handle my debugging output (including the wrapping of the format-string).
As "format" takes a variable number of arguments my wrapper would need to do that too yielding the question on how I tell scheme to have an ellipsis-parameter and how to reference it.
I thought of something like this:
(define debugPrint
(lambda (formatString ELLIPSIS_PARAMETER)
(if debug
(format #t (string-append "<!--" formatString "-->") ELLIPSIS_PARAMETER)
()
)
)
)
Thank You for your help in advance!
There is dot notation for this:
(define (debugPrint formatString . params)
(if debug
(apply format #t (string-append "<!--" formatString "-->") params)
'()))
Take note on apply as dot notation wraps all parameters in list and when you use (debugPrint "~a: ~a" key name), the formatString will be bound to "~a: ~a" and params will be bound to (key name) (sure the values of key and name, not symbols ;).
I will describe my problem on example.
I'll get (play '(left nothing right left)). Some of the names in the list are real procedures, others i want to skip.
(define (left)
'left
)
I need to interpret procedures with names in the list. What is the solution?
When I try ( (car '(left nothing right left))) I get error : procedure application: expected procedure, given: left (no arguments)
(car '(left nothing right left)) evaluates to the symbol left, which is the name of a procedure, but not actually a procedure, so you can't call it.
You'll want to build an association list mapping symbols to procedures:
(define actions `((left . ,(lambda () 'left))
(right . ,(lambda () 'right))
(nothing . ,(lambda () (display "I'm staying put")))))
then you can call the appropriate function for the first element in your list as
((cdr (assoc (car '(left nothing right left)) actions)))
You can also use quasiquoting to construct a list containing a mixture of symbols you want evaluated and others you don't, e.g.
(play `(,left nothing nothing ,right nothing))
left and right will expand to whatever you've defined them as (such as a procedure) while nothing is not un-quoted so it will be left as a symbol. play would then have to test each member to see if it's a procedure, something like:
(define (play xs)(for-each (lambda (x)(if (procedure? x)(x) x)) xs))
(define bootstrap-c-code
(define (from-file file-name)
(let* ((ip (open-input-file file-name))
(res (read-text-file-from-input-port ip)))
(close-input-port ip)
res))
(from-file "llvm.c"))
Error : define: bad syntax (multiple expressions after identifier)
But I can't see anything wrong with it. Can someone explain / fix it please.
It's not clear what you intended with the above code. If you were trying to load a text file and leave the loaded value in a variable called bootstrap-c-code, then try this:
(define bootstrap-c-code
(let ((from-file
(lambda (file-name)
(let* ((ip (open-input-file file-name))
(res (read-text-file-from-input-port ip)))
(close-input-port ip)
res))))
(from-file "llvm.c")))
Of course, the from-file definition will only be visible inside the let, if you need to use it outside, define it outside of the whole expression. If you only need the functionality of from-file inside the let, you can obtain the same result in a much simpler way:
(define bootstrap-c-code
(let* ((ip (open-input-file "llvm.c"))
(res (read-text-file-from-input-port ip)))
(close-input-port ip)
res))
On the other hand, if what you intended was to create a procedure called bootstrap-c-code, then the correct syntax would be:
(define (bootstrap-c-code)
(define (from-file file-name)
(let* ((ip (open-input-file file-name))
(res (read-text-file-from-input-port ip)))
(close-input-port ip)
res))
(from-file "llvm.c"))
According to R5RS, internal definitions can occur only at the beginning of the of a bunch of forms like let, let*, lambda etc. In the case of your code, that is not the case since you have an internal definition inside a non-procedural define. You could fix it by making `bootstrap-c-code' bind to a procedure.