Understanding send/suspend/dispatch in Racket Web Framework - webserver

I am trying to understand the example that relates to the send/suspend/dispatch code in the Racket Web Framework Tutorial http://docs.racket-lang.org/continue/.
For ease here is the code that puzzles me:
#lang web-server/insta
; start: request -> response
(define (start request)
(show-counter 0 request))
; show-counter: number request -> doesn't return
; Displays a number that's hyperlinked: when the link is pressed,
; returns a new page with the incremented number.
(define (show-counter n request)
(local [(define (response-generator embed/url)
(response/xexpr
`(html (head (title "Counting example"))
(body
(a ((href ,(embed/url next-number-handler)))
,(number->string n))))))
(define (next-number-handler request)
(show-counter (+ n 1) request))]
(send/suspend/dispatch response-generator)))
I have two questions:
(Most important) Where is embed/url defined? I can't see that it is defined in this code, but my understanding of continuations is rudimentary so it may be I am missing something.
What is the purpose of local? I can remove it and the code seems to work just the same.

The function embed/url is the argument to response-generator:
(define (response-generator embed/url) ...)
When (send/suspend/dispatch response-generator) is evaluated, the following happens:
1. a procedure `p` given a "continuation" (here next-number-handler)"
generates an url
2. the function `response-generator` is called with `p` as argument.
3. the page `(html ... ,(embed-url next-number-handler)) is generated
(note: (embed-url next-number-handler) calls `p` and the resulting url is inserted into the page)
4. [send] the page is sent to the client
5. [suspend] the server suspends the program
6. [dispatch] receives an request generated by clicking link whose url were
generated in 3. The handler associated to the url
(here next-number-handler) is looked up, and the handler
is called.
Although not necessary for using send/suspend/dispatch here is a sketch:
(define (send/suspend/dispatch response-generator )
(let/ec escape
(define (callback->url callback)
(let/ec return-url
(escape (callback (send/suspend return-url)))))
(send/back (response-generator callback->url))))

Related

Racket code generation

When you want to use Racket's D-Bus binding (https://docs.racket-lang.org/dbus/index.html) you must write definition of interface by hand. D-bus protocol is defined by .xml file and basically gives you method name with arguments and their types definition. Type definitions are coded so y = byte, s = string etc. Xml file example:
<node>
<interface name="com.test.Callable">
<method name="TestMethod">
<arg name="data_in" type="sa(yyd)" direction="in" /> ;;
<arg name="data_in2" type="y" direction="in" /> ;;
<arg name="data_out" type="i" direction="out" />
</method>
</interface></node>
In Racket's dbus must all type fields of arg elements with direction=in be joined and produced code like this:
(define-dbus-interface dbus-interface<%> "com.test.Callable"
(TestMethod "sa(yyd)y") ;; pay attention to this line
)
Now you can finally implement this interface in your own class as you wish and start sending some messages through D-bus.
Problem is, that you can have several methods with nontrivial arguments and you can make easily mistake, so I wanted to create a code generator, that will take name of an .xml file and produces definition of interface (define-dbus-interface) automatically.
My progress so far can be found here: https://gitlab.com/Ondra009/dbus-interface It is only one file about 90 lines long.
I want to make this call:
(parse-xml/file "org.freedesktop.Avahi.ServiceBrowser.xml")
on my testing file and I am expecting to receive definition of interface back. So far, I was able to parse file and generate, what I believe, is correct syntax of (define-dbus-interface ...) method call.
I think this should be last step but here I got stuck. I am not able to see definition of interface from top level. Listing of error I am getting:
../../../.racket/6.10.1/pkgs/dbus/dbus/main.rkt:228:11: define: not allowed in an expression context in: (define org.freedesktop.DBus.Introspectable<%>/c (class/c (Introspect (->m any)) (TestMethod (->m string? (listof (list/c (integer-in 0 255) (integer-in 0 255) real?)) (integer-in 0 255) (cons/c (integer-in 0 255) (integer-in 0 255)) any))))
This is obviously expansion done by dbus package itself as my generated code look like code listing starting with (define-dbus-inteface ...).
So my question here could be:
Can I even use this as C-macro like system, in a manner that call is completelly replaced by another definition or do I have to bind generated code to some identifier? (or list of idetifiers in case more interface definitions in one file.
If so, how can I achieve it?

How should list be represented in ASP (Answer Set Programming)?

A processor 'a' takes care the header 'a' of a message 'a_b_c_d' and passes the payload 'b_c_d' to the another processor in the next level as following:
msg(a, b_c_d).
pro(a;b;c;d).
msg(b, c_d) :- pro(X), msg(X, b_c_d).
msg(c, d) :- pro(X), msg(X, c_d).
msg(d) :- pro(X), msg(X, d).
#hide. #show msg/2. #show msg/1.
How should I represent list 'a_b_c_d' in ASP, and change the above to general cases?
No, official way, but I think most people don't realize you can construct cons-cells in ASP.
For instance, here's how you can get items for all lists of length 5 from elements 1..6
element(1..6).
listLen(empty, 0).
listLen(cons(E, L), K + 1) :- element(E); listLen(L, K); K < 5.
is5List(L) :- listLen(L, 5).
#show is5List/1.
resulting in
is5List(cons(1,cons(1,cons(1,cons(1,cons(1,empty))))))
is5List(cons(1,cons(1,cons(1,cons(1,cons(2,empty))))))
is5List(cons(1,cons(1,cons(1,cons(1,cons(3,empty))))))
...
There is no 'official' way to handle lists in ASP as far as I know. But, DLV has built-in list handling similar to Prolog's.
The way you implement a list, the list itself cannot be used as a term and thus what if you want to bind between variables in the list and other elements of a rule? Perhaps you would like something such as p(t, [q(X), q(Y)]) :- X != Y.
You can try implementing a list as (a, b, c) and an append predicate but the problem is ASP requires grounding before computing answer-sets. Consequently a list defined in this way whilst more like lists in Prolog would mean the ground-program contains all ground-instances of all possible lists (explosion) regardless of whether they are used or not.
I therefore come back to my first point, try using DLV instead of Clingo if possible (for this task, at least).
By using index, I do have a way to walk a list, however, I do not know this is the official way to handle a list in ASP. Could someone has more experience in ASP give us a hand? Thanks.
index(3,a). index(2,b). index(1,c). index(0,d).
pro(a;b;c;d). msg(3,a).
msg(I-1,N) :- pro(P), msg(I,P), index(I,P), I>0, index(I-1,N).
#hide. #show msg/2.
You can use s(ASP) or s(CASP) ASP systems. Both of them support list operations like prolog. You might need to define the list built-in in ASP .

How do you unwrap the metadata from a ClojureScript object?

Adding meta data to an object returns a new object with the metadata attached:
(def plain-data [1 2 3])
(def decorated-data (with-meta plain-data {:url "http://stackoverflow.com"}))
;; returns false
(identical? plain-data decorated-data)
How do I recover the original plain-data from the decorated-data?
I'd like to do something like,
(def undecorated-data (with-meta decorated-data nil))
;; how can I make this return true?
(identical? plain-data undecorated-data)
Adding metadata doesn't wrap the value, it returns a clone of the value with metadata attached - there's no way to recover the original thing. However it's not clear why you would ever need to do that, use = if you need to check for equality.

fiveam: fail to understand why this test fails

So I'm at a loss as to why this test fails. When I run the statements in the repl everything appears to work correctly but the fiveam test fails.
There is a test case in the following gist: https://gist.github.com/PuercoPop/5765844
the fiveam test fails with the following message. I don't understand why the second board is displayed differently (with new lines):
EXPECTED-BOARD evaluated to (:EMPTY :|2| :|3| :|4| :|5| :|6| :|7| :|8| :|9|),
which is not EQUAL to (:EMPTY
:|2|
:|3|
:|4|
:|5|
:|6|
:|7|
:|8|
:|9|)..
You are modifying constant data. Weird things are allowed to happen when you modify constant data. If there's even half a chance you'll be unleashing a destructive function (as in "modify the data...") create your lists using (list ...) instead of '(...).

How do I prevent #<ObjectId..> to break my map with CongoMongo?

using Clojure 1.3.0 with CongoMongo 0.1.7 and doing a simple (fetch-one :my_collection) return something like the following:
{:_id #<ObjectId 4f10d46c56bad557a7729f95>,
:key2 "value2",
:etc "etc
}
and that '#<ObjectId' breaks everything but I'm surprised I cannot find anyone with the issue anywhere.
In fact I do a simple (type *the_result_above*) I get clojure.lang.PersistentArrayMap while manually removing the # bit I correctly get clojure.lang.PersistentHashMap
Any idea? Thanks!
You are not the only one with this issue. In one of my projects I created a workaround by adding the following function:
(defn string-id [map]
(assoc map :_id (str (map :_id))))
Feed it with any map from CongoMongo, and it will replace the _id with it's string representation and return the updated map.