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.
Related
The bad code of main is (string-match "module" (help uri-path)) that returns an error
scheme#(guile-user) [5]> (string-match "module" (help uri-path))
`uri-path' is an object in the (web uri) module.
- Special Form: uri-path
While compiling expression:
Syntax error:
unknown file:9:23: sequence of zero expressions in form (begin)
scheme#(guile-user) [5]>
What I am trying to reach, is displaying only one line of help function output. How to fix it?
Use procedure-documentation to get the documentation of a procedure as a string.
scheme#(guile-user)> (help cons)
`cons' is a procedure in the (ice-9 safe-r5rs) module.
- Scheme Procedure: cons x y
Return a newly allocated pair whose car is X and whose cdr is Y.
The pair is guaranteed to be different (in the sense of `eq?') from
every previously existing object.
scheme#(guile-user)> (procedure-documentation cons)
$6 = "- Scheme Procedure: cons x y\n Return a newly allocated pair whose car is X and whose cdr is Y.\n The pair is guaranteed to be different (in the sense of `eq?') from\n every previously existing object."
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 would like to assign the result of a function call (a list) to some var/name.
I tried
(define somelist (call-a-function arg))
but when I do
(display somelist)
it prints #procedure
What is the best way of doing this?
It's a safe bet that this:
(call-a-function arg)
Is returning a function, not a list as you assumed. That's why you're getting a #procedure printed on-screen. Check your function, make sure it returns the appropriate value.
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.
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))