I have been giving a language in Scheme.
(define-datatype statement statement?
(add1 (V symbol?))
(sub1 (V symbol?))
(skip (V symbol?))
(if-goto (V symbol?)
(l symbol?)))
(define-datatype instruction instruction?
(labeled (l symbol?)
(i statement?))
(unlabeled (i statement?)))
(define-datatype program program?
(a-program (l (list-of instruction?))))
I am trying to create a new function which will be able to convert the program into a list of instructions. How would I go about doing this?
Here is what I have so far:
(define pgm->list
(lambda (pgm)
;what goes here
sorry if this is wrong, if it is could you share a working implementation of your code?
i am really confused with
(define-datatype program program?
(a-program (l (list-of instruction?))))
what is list-of? i should imagine here that you want to declare some variants of programs.
a-program would be defined as a list of instructions... ok. if list-of returns a lambda that is a correct predicate (that returns true only when acted on a list of instructions) then
does this work?
(define pgm->list
(lambda (pgm)
(cases program pgm
(a-program (l) l))))
Edit : Since define-datatype was unknown to most of us except OP, i'm adding some documentation:
[syntax] (define-datatype TYPENAME [PREDICATE] VARIANT ...)
Defines a record type named TYPENAME, where VARIANT ... defines one or more
constructors for instances of this type. VARIANT should be of the form
VARIANT = (CONSTRUCTOR (FIELDNAME FIELDPRED) ...)
CONSTRUCTOR is the name of a constructor procedure that will be defined with as
many arguments as fields are specified. (FIELDNAME FIELDPRED) ... specify the name
for each field and a procedure of one argment that should return a true value for
legal field values.
The optional PREDICATE should be the name of a procedure that will be defined and
which returns #t when applied to an instance of this variant record.
[syntax] (cases TYPENAME EXP CLAUSE ...)
A facility for matching and deconstructing the instance EXP of the variant record
with the name TYPENAME. Each CLAUSE specifies a constructor with field-names and
a body to execute when the constructor matches the record instance:
CLAUSE = (CONSTRUCTOR (FIELDNAME ...) BODY ...)
| (else BODY ...)
cheers!
Related
TL;DR
What I'm looking for is a combination of the functions send/apply and dynamic-send. So that it finds a method of an object based on a symbol and unpacks a list of arguments.
Background and more info
For a project I am sending some "commands" trough the network with Racket's tcp-connect. At the receivers end this command should execute a method from a class and pass along its parameters.
Consider the following received 'message':
(define message (list 'set-switch! '3 'on))
(define method-name (car msg)) ;'set-switch!
(define parameters (cdr msg)) ;(list '3 'on)
And the following class:
(define light%
(class object%
(super-new)
...
(define/public (set-switch! id mode)
(vector-set! switches id mode))))
The problem now is that when executing this statement
(dynamic-send light-class method-name parameters)
it perfectly finds the method set-switch! but it calls it with only one parameter (list '3 'on).
The Racket docs mention those three functions for classes:
(send obj-expr method-id arg) which just executes a method of an object
(send/apply obj-expr method-id arg-list-expr) which executes a method AND unpacks the argument list
(dynamic-send obj method-name v) which finds a method-name based on a symbol
What I think I need is something like (dynamic-send/apply obj method-name arg-list-expr) which combines the last two mentioned.
Note: I know that I could just simply accept lists as parameters and use car and cdr in the functions itself to get the right values. But that's not what I want.
dynamic-send is a function (also known as procedure; e.g., car, vector-set!, +), so you can use apply:
(apply dynamic-send light-class method-name parameters)
Or even simply:
(apply dynamic-send light-class message)
The reason why send has the send/apply variant is that send is a form (also known as syntax; e.g., let, define, if), so apply doesn't work and hence send/apply is separately provided.
I'm learning SICP and do the programming exercises. I have a question about exercise 4.5. The exercise 4.5 is:
Scheme allows an additional syntax for cond clauses, (<test> => <recipient>). If <test> evaluates to a true value, then <recipient> is evaluated. Its value must be a procedure of one argument; this procedure is then invoked on the value of the <test>, and the result is returned as the value of the cond expression. For example:
(cond
((assoc 'b '((a 1) (b 2))) => cadr)
(else false))
As shown above,if <test> is true,the value of the cond clause should be (<recipient> <test>) (i.e.
then <recipient> is evaluated. Its value must be a procedure of one argument; this procedure is then invoked on the value of the <test>, and the result is returned...
But when I search the solution on the Internet, almost all I found are (list (extended-cond-recipient first) (extended-cond-test first)). It's a list consist of <recipient> and <test> , not a function call.
What should I do? It has troubled me a long time...
In The Core of the Evaluator, under “Special Forms”, is written:
• A case analysis (cond) is transformed into a nest of if expressions and then evaluated.
That is, first a transformation at the program level is done, and only after this transformation the resulting expression is evaluated. The transformation is done by the function cond->if, which does not evaluate the cond expression, only transform it in a nested list containing multiple if. This can be seen in the definition of the eval function, where there is the case:
((cond? exp) (eval (cond->if exp) env))
In the solutions that you have seen, the cond->if function is modified so that it transforms the => syntax in a list (as you have correctly observed), a list that contains the function as first element, and its argument as second element, and that list will be evaluated correctly in the subsequent steps of the interpreter.
I'm not sure if the question title is appropriate but here is what I wonder:
From the repl, I wanted to get the list of bindings defined in the current module. After some searching this seemed like a good solution:
(define (racket-symbols-set)
(list->set (namespace-mapped-symbols (module->namespace 'racket))))
(define (namespace-symbols-set)
(list->set (namespace-mapped-symbols)))
(define (module-bindings)
(set->list (set-subtract
(namespace-symbols-set)
(racket-symbols-set))))
so, calling (module-bindings) returns a list of symbols. But if I try to call a symbol from that result, such as doing ((first (module-bindings))), I get a "application: not a procedure" error although the first symbol is a procedure.
How do I call the corresponding procedure of that symbol?
You can look up the value of a namespace variable using namespace-variable-value. And since your namespace-symbols-set just uses the current namespace, which is also the default namespace for namespace-variable-value, using it is very simple.
For example, to invoke the procedure associated with the first item in the list returned by your module-bindings procedure:
((namespace-variable-value (car (module-bindings))))
Alternatively, specify your preferred namespace as the fourth argument of the namespace-variable-value call.
You need to evaluate that symbol in order for it to return the corresponding procedure.
> (define (foo) 'bar)
> (eval 'foo)
#<procedure:foo>
> ((eval 'foo))
'bar
Hence in your case
((eval (car (module-bindings))))
will call the first procedure of the list returned by module-bindings.
Can anyone briefly explain to me how message passing is implemented in scheme? I think I am little off on the whole concept of message passing.
Take a look at SICP.
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-17.html#%_sec_2.4.1
http://www.michaelharrison.ws/weblog/?p=50
Message passing in the context of closures
The following example defines a closure implementing a simple calculator. The function make-calculator is similar to what object oriented languages call the constructor. The difference is: make-calculator returns a function, while constructors return object values. In object oriented languages object values are first class values. Scheme does not have such values. An object first class values provides the functionality to access object member variables and object methods. In Scheme this functionality has to be emulated by the definition of a dispatch function. make-calculator returns such a function. The body of make-calculator defines
two variables a and b (member variables)
two mutation functions set-a! and set-b! (accessors)
four evaluation functions addition, subtraction, multiplication and division (methods)
The above definitions are local to the closure make-calculator. In an object oriented language they are called private. The dispatch function makes the functions public and keeps the variables private. This works, because the dispatch function has access to the local scope of the make-calculator closure. The dispatch function accepts a message and returns the matching function. This exposes the local functions to the caller of the dispatch function.
(define (make-calculator)
(define a)
(define b)
(define (set-a! value)
(set! a value))
(define (set-b! value)
(set! b value))
(define (addition)
(+ a b))
(define (subtraction)
(- a b))
(define (multiplication)
(* a b))
(define (division)
(/ a b))
(lambda (message)
(case message
((set-a!) set-a!)
((set-b!) set-b!)
((addition) addition)
((subtraction) subtraction)
((multiplication) multiplication)
((division) division))))
First the constructor has to be called to create an "object". calc is the dispatch function, which accepts different messages, which are just symbols.
(define calc (make-calculator))
Sending a message means calling the dispatch function with a symbol argument. The following sends the message set-a! to calc, which returns the value of the local function set-a!. The name of the message and the name of the local function are the same in this case. This helps to avoid confusion, but it is not required.
(calc 'set-a!) ;; => #<procedure set-a!>
Because calc returns a function, an additional application is necessary to call the accessor. The following sets a to 3 and b to 5.
((calc 'set-a!) 3)
((calc 'set-b!) 5)
Now we can calculate:
((calc 'addition)) ;; => 8
((calc 'subtraction)) ;; => -2
((calc 'multiplication)) ;; => 15
((calc 'division)) ;; => 3/15
The code works this way in Chez Scheme.
In Racket this gives me an error:
(struct point-in-plane (pos_x pos_y))
(struct pixel point-in-plane (color))
(define a-pixel (pixel 1 2 "blue"))
(pixel-color a-pixel)
(pixel-pos_x a-pixel)
(pixel-pos_y a-pixel)
For it to work I need to replace the last two lines with:
(point-in-plane-pos_x a-pixel)
(point-in-plane-pos_y a-pixel)
Similarly in R6RS
#!r6rs
(import (rnrs))
(define-record-type point (fields x y))
(define-record-type cpoint (parent point) (fields color))
(define blue-point (make-cpoint 1 2 "blue"))
(write (cpoint-x blue-point))
Gives a similar error.
What is the reason Scheme (and Racket) don't allow you to access the fields of a subtype that were defined in the parent by:
subtypeID-fieldID instead of by parenttypeID-fieldID
I.e. in my case allowing me to use pixel-pos_x and pixel-pos_y .
One reason is that struct allows you to define sub-structs with identically named fields. For example:
(struct base (x y))
(struct sub base (x y))
(define rec (sub 1 2 3 4))
(base-x rec) ; => 1
(sub-x rec) ; => 3
This is because structs don't really know about field names. From the Racket documentation: "A structure type’s fields are essentially unnamed, though names are supported for error-reporting purposes." You would have to disallow this behavior in order to get extra accessors for sub-structs.
The documentation of the struct form says that it provides accessors and setters for the given fields, but doesn't say that it will automatically re-expose the existing accessors and setters of the parent type with the extra names you're expecting.
When I'm dealing with structs and pulling out the components by name, I often use the racket/match library, especially with the struct* pattern matcher. Usually, I have to deal with multiple components of a struct, and the matcher makes it easy to do so.