Clojure - Get Realtime Updates with Cloud Firestore - clojure

Here is EventListener interface
package com.google.cloud.firestore;
public interface EventListener <T> {
void onEvent(#javax.annotation.Nullable T t, #javax.annotation.Nullable com.google.cloud.firestore.FirestoreException e);
}
Here is the Java section code
(refer to https://firebase.google.com/docs/firestore/query-data/listen)
DocumentReference docRef = db.collection("cities").document("SF");
docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
#Override
public void onEvent(#Nullable DocumentSnapshot snapshot,
#Nullable FirestoreException e) {
if (e != null) {
System.err.println("Listen failed: " + e);
return;
}
if (snapshot != null && snapshot.exists()) {
System.out.println("Current data: " + snapshot.getData());
} else {
System.out.print("Current data: null");
}
}
});
Here is my converted code to Clojure
(defn outlook-synced-listenning
[^DocumentReference ref]
(let []
(-> ref
(.addSnapshotListener
(reify EventListener
(^void onEvent [this ^DocumentSnapshot snapshot ^FirestoreException e]
(if-not (nil? e)
(println " Listen failed: " + e)
)
(if (and (not (nil? snapshot)) (.exists snapshot))
(println " Current data: " + (.getData snapshot))
(println " Current data null ")
)
)))
)
))
Here is the error
Caused by: java.lang.IllegalArgumentException: Can't find matching method: onEvent, leave off hints for auto match.
at clojure.lang.Compiler$NewInstanceMethod.parse(Compiler.java:8305)
at clojure.lang.Compiler$NewInstanceExpr.build(Compiler.java:7853)
at clojure.lang.Compiler$NewInstanceExpr$ReifyParser.parse(Compiler.java:7754)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6919)
I think the error with parameter types and type hints when the Clojure code does not match with Java interface.
I guess that I don't still convert correctly the code line below to Clojure
docRef.addSnapshotListener(new EventListener < DocumentSnapshot > ()
Please advise me how I do. Thank you

I removed all paramater types and type hints except for "this". It works fine
Many thanks to Frank Moyer
(defn outlook-synced-listenning
[^DocumentReference ref]
(let []
(-> ref
(.addSnapshotListener
(reify EventListener
(onEvent [this snapshot e]
(if-not (nil? e)
(println " Listen failed: " + e)
)
(if (and (not (nil? snapshot)) (.exists snapshot))
(println " Current data: " + (.getData snapshot))
(println " Current data null ")
)
)))
)
))

Related

Add object to a list in clojure and return

I am new to functional programming and have a use case where I have a list of Books, I want to iterate over it, do some mapping and return a new List.
My code
(defn map-book [books]
((doseq [x books]
(let [lst (create-response x)]
(println "data -> " (json/encode lst))
(json/encode lst)))))
(defn create-response [book]
(let [updated-book (merge {"book-name" (.getBookName book)
"book-page" (.getBookPageCount book)}]
updated-book))
when I try to run this, I am able to get json decoded response in terminal due to println but not the json list as a response from the function.
have been stucked around for some time on this.
What I want is something like :
[{
"book-name": "rick boy",
"book-page": 110
},
{
"book-name": "poor boy",
"book-page": 124
}
]
but am getting something like, when I run my unit test:
#object[book_service.book$map_book 0x7915bca3 [book_service.book$map_book#7915bca3]
thanks for any help!
If you want to return new list (or vector), you should avoid doseq (which is for side effects- for example, printing, and always returns nil) and use map or for instead.
I guess you want to return JSON string for given data and your json library is actually Cheshire:
Dependencies: [cheshire "5.11.0"]
Require in ns: [cheshire.core :as json]
Book class:
public class Book {
String bookName;
Long pageCount;
public Book(String name, Long pages) {
bookName = name;
pageCount = pages;
}
public String getBookName() {
return bookName;
}
public Long getBookPageCount() {
return pageCount;
}
}
Clojure code:
(defn get-book-map [book]
{"book-name" (.getBookName book)
"book-page" (.getBookPageCount book)})
(defn encode-books [books]
(json/encode (map get-book-map books)))
Test:
(encode-books [(Book. "rick boy" 110)
(Book. "poor boy" 124)])
=> "[{\"book-name\":\"rick boy\",\"book-page\":110},{\"book-name\":\"poor boy\",\"book-page\":124}]"
(json/decode *1)
=> ({"book-name" "rick boy", "book-page" 110} {"book-name" "poor boy", "book-page" 124})

How to use Z3 C++ API to prove a theory based on input parameter?

I am trying to use the Z3 C++ API to achieve the following:
(set-option :produce-proofs true)
(declare-const Weight Int)
(declare-const WeightLimit Int)
(declare-const P1 Bool)
(assert (= WeightLimit 10))
(assert (= P1 (>= Weight WeightLimit)))
(assert (= P1 true))
;Facts - Input
(assert (= Weight 100))
(check-sat)
And I ended up to the following function:
void test() {
try {
context ctx;
Z3_string str = "(declare-const Weight Int) (declare-const WeightLimit Int) (declare-const P1 Bool) (assert (= WeightLimit 10)) (assert (= P1 (>= Weight WeightLimit))) (assert (= P1 true)) (assert (= Weight 100)) (check-sat)"; //Generated by some other function
expr fs(ctx, Z3_parse_smtlib2_string(Z3_context(ctx), str, 0, 0, 0, 0, 0, 0));
solver s(ctx);
s.add(fs);
switch (s.check()) {
case unsat: std::cout << "not satisfied\n"; break;
case sat: std::cout << "satisfied\n"; break;
case unknown: std::cout << "unknown\n"; break;
}
model m = s.get_model();
std::cout << m << "\n";
}
catch (z3::exception e) {
std::cout << e.msg() << std::endl;
}
}
Is there any way to pass the Weight value as input parameter to the function instead of having it hard-coded?
Furthermore, how can I set-option by using the Z3 C++ API? And what is the impact if I don't set the option?
Well, this needs to be handled by the function that generates that string as its output, the one you commented as "//Generated by some other function"
You'd simply pass the Weight as a parameter to that function, which should use the correct value in generating the string.
If that function is not available to you for whatever reason, you'll have to do some string-processing; but of course that would be extremely brittle and error-prone.
The other alternative would be to not pass a string, but rather use the API to actually assert facts one at a time; but from your description it seems that's probably not a choice for you either.

Clourescript: converting array access

Problem
I am trying to convert the following piece of code: https://github.com/mdn/webgl-examples/blob/gh-pages/tutorial/glUtils.js#L13-L15
The JavaScript code is:
Matrix.Translation = function (v)
{
// ignore length 2 case for simplicty
if (v.elements.length == 3) {
var r = Matrix.I(4);
r.elements[0][3] = v.elements[0];
r.elements[1][3] = v.elements[1];
r.elements[2][3] = v.elements[2];
return r;
}
throw "Invalid length for Translation";
}
Now, I can rewrite it cljs as follows:
(defn translation [x y z]
(let [r (. js/Matrix I 4)]
r[0][3] = x ;; how do I write this?
r[1][3] = y ;; how do I write this?
r[2][3] = z ;; how do I write this?
))
Question
However, how do I write r[0][3] in cljs?
You can use aget and aset to work with Javascript arrays:
(def arr (array (array "a1" "a2") (array "b1" "b2") (array "c1" "c2")))
It creates following nested array:
#js [#js ["a1" "a2"] #js ["b1" "b2"] #js ["c1" "c2"]]
You can access nested elements with aget:
(aget arr 1 0)
;; => "b1"
And update with aset:
(aset arr 1 0 "newb1")
updates arr to:
#js [#js ["a1" "a2"] #js ["newb1" "b2"] #js ["c1" "c2"]]
You might want to take a look at other functions related to Javascript arrays: alength, array, make-array, array?.

Method definition as result of function call in ClojureScript

Here's a sample piece of JS for Knockout:
function AppViewModel() {
this.firstName = ko.observable('Bob');
this.lastName = ko.observable('Smith');
this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
}
In case you're unfamiliar with KO, each field on AppViewModel becomes a function (i.e. ko.observable and ko.computed each return a function. Also note that fullName depends on both functions.
How can I rewrite this to ClojureScript?
One thing to try is:
(deftype AppViewModel [firstName lastName]
Object
(fullName [this] (.computed js/ko (str (firstName) " " (lastName)))))
(defn my-model [first last]
(AppViewModel.
(.observable js/ko "Bob")
(.observable js/ko "Smith")))
It doesn't work though, since fullName becomes a function that calls ko.computed. That is, it compiles to:
my_namespace.AppViewModel.prototype.fullName = function() {
return ko.computed([cljs.core.str(this.firstName.call(null)), cljs.core.str(" "), cljs.core.str(this.lastName.call(null))].join(""))
};
How can I deal with it in ClojureScript?
Again, note the dependency of fullName on this and firstName/lastName.
Try this:
(defn my-model [first last]
(let [fname (.observable js/ko first)
lname (.observable js/ko last)
full-name (.computed js/ko #(str (fname) " " (lname)))]
(js-obj "firstName" fname
"lastName" lname
"fullName" full-name)))
Riffing on #Ankur's answer, seems like you could also do the following:
(deftype AppViewModel [firstName lastName fullName])
(defn my-model [first last]
(AppViewModel.
(.observable js/ko "Bob")
(.observable js/ko "Smith")
(.computed js/ko (str (firstName) " " (lastName)))))

wrapping knockout.js using clojurescript

I'm trying to wrap knockout.js in clojurescript but its turning to be very difficult. The problem that I'm having is the reference to the 'this' variable. I'm thinking of giving up and just using javascript directly.
I've taken examples off http://knockoutjs.com/examples/helloWorld.html and http://knockoutjs.com/examples/contactsEditor.html
I've managed to wrap easy functions with some macros. For example:
var ViewModel = function() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
this.fullName = ko.computed(function() {
// Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName.
return this.firstName() + " " + this.lastName();
}, this);
};
becomes:
(defviewmodel data
(observing :first_name "Bert")
(observing :last_name "Bertington")
(computing :name [:first_name :last_name]
(str :first_name " " :last_name)))
However, for something harder like:
var BetterListModel = function () {
this.itemToAdd = ko.observable("");
this.allItems = ko.observableArray(["Fries", "Eggs Benedict", "Ham", "Cheese"]); // Initial items
this.selectedItems = ko.observableArray(["Ham"]); // Initial selection
this.addItem = function () {
if ((this.itemToAdd() != "") && (this.allItems.indexOf(this.itemToAdd()) < 0)) // Prevent blanks and duplicates
this.allItems.push(this.itemToAdd());
this.itemToAdd(""); // Clear the text box
};
this.removeSelected = function () {
this.allItems.removeAll(this.selectedItems());
this.selectedItems([]); // Clear selection
};
this.sortItems = function() {
this.allItems.sort();
};
};
ko.applyBindings(new BetterListModel());
I'm not sure what I can do in clojurescript to match code like this: this.allItems.push(this.itemToAdd())
Any thoughts?
After lots of trial and error, I figured out how to have the same structure for clojurescript as for javascript.
The this-as macro has a few idiosyncrasies and only works when the method is put into the class
for example I want to create something that looks like this in javascript:
var anobj = {a: 9,
get_a: function(){return this.a;}};
I have to do a whole lot more coding to get the same object in clojurescript:
(def anobj (js-obj))
(def get_a (fn [] (this-as me (.-a me))))
(aset anobj "a" 9)
(aset anobj "get_a" get_a)
which is seriously ugly for a language as beautiful as clojure. Things get worse when you have got functions that link to each other, like what happens in knockout.
I found that the best way to create an js-object with lots of this's in there is to define a __init__ method, add it to the class and then run it, then remove it from the class. For example, if I wanted to make another object:
var avobj = {a: this,
b: 98,
c: this.a
get_a: function(){return str(this.a) + str(this.c);}};
written as clojurescript with and __init__ method looks like this:
(def avobj (js-obj))
(def av__init__
#(this-as this
(aset this "a" this)
(aset this "b" 9)
(aset this "c" (.-a this))
(aset this "get_a" (fn [] (str (.-a this) (.-c this))))))
(aset avobj "__init__" av__init__)
(. avobj __init__)
(js-delete stuff "__init__")
There's still a whole bunch more code than javascript... but the most important thing is that you get the same object as javascript. Setting all the variables using this form also allows the use of macros to simplify. So now I have defined a macro:
(defmacro defvar [name & body]
(list 'do
(list 'def name
(list 'map->js
{
:__init__
(list 'fn []
(list 'this-as 'this
(list 'aset 'this "a" "blah")))
}))
;(. js/console log ~name)
(list '. name '__init__)
(list 'js-delete name "__init__")))
and with map->js taken from jayq.utils:
(defn map->js [m]
(let [out (js-obj)]
(doseq [[k v] m]
(aset out (name k) v))
out))
Now I can write code like this:
(defvar avobj
a this
b 9
c (.-a this)
get_a (fn [] (str (.-a this) (.-c this))))
and for the answer to knockout:
(defvar name_model
first_name (observable "My")
last_name (observable "Name")
name (computed (fn [] (str (. this first_name) " " (. this last_name)))))
(. js/ko (applyBindings name_model));
Which is really nice for me as it matches javascript really well and its entirely readable!
If you need an explicit reference to JavaScript's this dynamic binding, ClojureScript provides a this-as macro:
https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L324