define and assign function call result in racket - scheme

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.

Related

Is it possible to get FORMAT to ignore undefined format directives?

I wonder if it is possible to tell FORMAT to ignore undefined format directives. I have looked at the pages for FORMAT in the CLHS but I don't see anything.
What I am trying to do is to get FORMAT to ignore ~m in a format string and just output ~m instead of trying to replace it with something. My plan is that at that point I will call another function which knows what to do with with ~m.
I guess a related question is then, is there a way to define a function to handle a format directive which is otherwise not defined?
In anticipation of some questions. (1) I guess a workaround would be to substitute a placeholder for ~m, and then substitute it back in afterwards and keep going. I guess I'll do that if all else fails. (2) I guess another general strategy would be to call the other function first, to handle ~m, then call FORMAT on the result. Unfortunately that other function recognizes some of the same directives, and barfs on others; it doesn't recognize only ~m and ignore everything else.
You can define your own format directive with ~/name/, where name is the name of the function which is called. In your case you would have:
(format t "~/m/" 1)
(defun m (stream n colon-mod at-mod)
(format stream "~a" n)) ; or do something else with n
You still need to change the control string, but you can add a preprocessing step where "~m" is replaced by "~/m/".
I don't think there is a way of doing that portably (implementations may let you do all sorts of magic). I'd write a quote-weird-tildes and dequote-weird-tildes pair of functions and then write code like:
(defun format/qw (control &rest args)
(declare (dynamic-extent args)
(type string control)) ;can't be a function
(dequote-weird-tildes
(apply #'format nil (quote-weird-tildes control) args)))
Now you have a function which looks like (format nil ...) and is no harder to use than that. For extra value the quoting and dequoting functions should not cons a string if they don't have to.
From http://www.lispworks.com/documentation/lw50/CLHS/Body/22_c.htm
The control-string argument to format is actually a format control.
That is, it can be either a format string or a function, for example a
function returned by the formatter macro.
So you can do:
(defmacro frmt (control-string)
(let ((str (cl-ppcre:regex-replace-all "~m" control-string "~~m")))
`(formatter ,str)))
Now:
(format t (frmt "~m~A") 1)
outputs:
~m1
NIL
This way you don't have to modify the control string directly.
You do have to modify the call to format to include frmt.

Dynamic function call in Racket class combined with apply

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.

In Clojurescript, how do I pass a collection's elements as arguments to a variable arity Javascript function?

This writes to console the way I would expect:
(.log js/console "hi" "there")
The output is
hi there
This, however, just writes a big mess to the console:
(defn log-it [& args] (.log js/console args))
(log-it "hello" "there")
The output is:
c…s.c…e.IndexedSeq {arr: Array[2], i: 0, meta: null, cljs$lang$protocol_mask$partition0$: 166592766, cljs$lang$protocol_mask$partition1$: 8192}
This also does NOT work:
(apply .log js/console ["hi" "there"])
Is there a way to pass the vector's elements into the .log function?
Do I have to write a macro to concat the vector on to '(.log js/console)?
The problem here is that you're trying to log the value of args (which is a Clojure IndexedSeq) rather than passing the values in the seq as individual arguments. In this case you need to use apply (or convert that sequence to a native data structure).
The reason your other example doesn't work should become clear if you look at the signature for apply.
(apply f args)
It expects the first argument to be the function you want to invoke, but here, the first argument is .log.
(apply .log js/console ["hi" "there"])
Remember that .log js/console is the syntax for invoking the log method on console. Instead, we want to get a reference to the console.log function.
(apply (.-log js/console) args)
We're using .-log to read the .log property, rather than call it as a method. Then we pass that along with our args sequence.
So instead, you can define the original function as:
(defn log-it
[& args]
(apply (.-log js/console) args))
Or if you want to get a little bit smarter.
(def log-it (partial (.-log js/console)))

re-internilizing a symbol from namespace-mapped-symbols

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.

Message passing scheme

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.

Resources