Testing throws from recursion - recursion

I can't catch throws from second recursive call from map.
For some reason, exceptions bubbles from (call-rec (first node)) but not from (map call-rec node).
Consider following example:
(deftest recursion-test
(testing "Testing recursion throws" ;; => OK
(is (thrown? Exception
(map #(throw (Exception. "e") [:a :b])))))
(testing "Testing throws from recursion lvl 1" ;; => OK
(is (thrown?
Exception
(letfn [(call-rec [node]
(cond
(vector? node)
(do
(throw (Exception. "e"))
(map call-rec node))
:else
node))]
(call-rec [:one :two])))))
(testing "Testing throws from map recursion lvl 2" ;; => FAILURE
(is (thrown? Exception
(letfn [(call-rec [node]
(cond
(vector? node)
(map call-rec node)
:else
(throw (Exception. "e"))
))]
(call-rec [:one :two])))))
(testing "Testing throws from first recursion lvl 2" ;; => OK
(is (thrown? Exception
(letfn [(call-rec [node]
(cond
(vector? node)
(call-rec (first node))
:else
(throw (Exception. "e"))
))]
(call-rec [:one :two]))))))

Laziness. The form
(map call-rec node)
creates a lazy sequence that never gets realised, thus never gets the chance to throw an exception. Try the eager version:
(mapv call-rec node)
Or realise the sequence outside of call-rec using:
(doall (call-rec [:one :two]))

Related

ClojureScript file preloader - function or pattern to emulate promise?

I'm trying to create a file preloader within ClojureScript. My idea was a pattern like this:
(def urls (atom[]))
(def loaded-resources (atom []))
(def all-resources (promise))
(defn loading-callback []
(if (= (count urls) (count loaded-resources))
(deliver all-resources loaded-resources)))
;; fill urls array
;; start ajax-loading with loading-callback on success
So my main function could go on until it would require the resources and then wait for them, which works well in Clojure.
Unfortunately, promises don't exist in ClojureScript, so how can I work around that issue? There's promesa bringing promises to CLJS based on core.async channels, but it only allows future-like promises that wait for a single function to execute which won't suffice my needs (at least in the way I've been thinking about it yesterday...).
Any suggestions to solve this issue? Maybe use a completely different pattern? I want to keep the code as simple as possible to convince people in my team to try out CLJ/S.
EDIT:
After Alan's second idea:
(def urls (atom[]))
(def loaded-resources (atom []))
(defn loading-callback [data]
(swap! loaded-resources conj data))
(defn load! [post-loading-fn]
(add-watch loaded-resources :watch-loading
(fn [_ _ _ cur]
(if (= (count cur) (count #urls)) (post-loading-fn))))
;; init ajax loading
)
(defn init []
;; fill urls array
(load! main))
(main []
(do-terrific-stuff #loaded-resources))
Meanwhile I had tried to use core.async
(def urls (atom []))
(def loaded-resources (atom []))
(def resource-chan (chan))
(defn loading-callback [data]
(go (>! resource-chan data)))
;; fill url array from main
(load! []
;; init ajax loading
(go-loop []
(when-not (= (count #loaded-resources) (count #urls))
(swap! loaded-resources conj (<! resource-chan))
(recur)))
Not sure which version is better.
I can think of 2 approaches.
Change all-resources to another atom, initialized at nil. Poll it 2x-5x/sec until it is not nil and has the "delivered" result.
Use add-watch to register a callback function to execute when the value is changed. This takes the place of blocking until the value is delivered. It is described here: http://clojuredocs.org/clojure.core/add-watch
They show a good example:
(def a (atom {}))
(add-watch a :watcher
(fn [key atom old-state new-state]
(prn "-- Atom Changed --")
(prn "key" key)
(prn "atom" atom)
(prn "old-state" old-state)
(prn "new-state" new-state)))
(reset! a {:foo "bar"})
;; "-- Atom Changed --"
;; "key" :watcher
;; "atom" #<Atom#4b020acf: {:foo "bar"}>
;; "old-state" {}
;; "new-state" {:foo "bar"}
;; {:foo "bar"}
Assuming your load resource function returns a channel (like cljs-http/get).
In clj, all you need to do is hold on to them to do a "wait-all".
(let [cs (doall (map load-resource urls)) ;; initiate the get
... ;; other initialisation
res (map <!! cs)] ;; wait-all for the resources
(do-other-things res))
In cljs, you can accumulate the responses before you continue:
(go
(let [res (atom [])]
(doseq [c cs]
(swap! res conj (<! c)))
(do-other-things #res)))
JavaScript is a single threaded environment so there is no blocking wait.
If you wish to request multiple resources and continue iff they have all been served, I do recommend using core.async and especially pipeline-async. It has a knob to finetune the parallelism of asynchronous requests. Here is idiomatic ClojureScript code to achieve what you want:
(ns example.core
(:require [cljs.core.async :refer [chan take! put! pipeline-async]
:as async]))
(defn load-resources [urls on-resources]
(let [urls-ch (chan (count urls))
resources-ch (chan)]
;; Create pipeline:
(pipeline-async 10 ;; have at most 10 requests in flight at
;; the same time, finetune as desired
resources-ch
(fn [url done-ch]
;; Pseudo code:
(request-resource
url
(fn [loaded-resource]
(put! done-ch loaded-resource))))
urls-ch)
;; Eagerly aggregate result until results-ch closes, then call back:
(take! (async/into [] resources-ch) on-resources)
;; Start the party by putting all urls onto urls-ch
;; and then close it:
(async/onto-chan urls-ch urls)))

Cannot get input stream working in SBCL sb-ext:run-program

While the following works:
(let* ((i (make-string-input-stream "foo bar baz"))
(p (sb-ext:run-program "/bin/cat" '()
:input i :output *trace-output* :wait t)))
(sb-ext:process-close p))
the code below does not - it will stop after writing "001":
(let* ((_1 (format t "001~%"))
(p (sb-ext:run-program "/bin/cat" '()
:input :stream :output *trace-output* :wait t))
(_2 (format t "010~s~%" p))
(s (sb-ext:process-input p)))
(declare (ignore _1 _2))
(format s "foo bar baz~%")
(finish-output s)
(sb-ext:process-close p))
So it seems to silently leave execution in sb-ext:run-program.
This is with SBCL 1.3.6 on Ubuntu 16.04.1.
Any ideas? Thanks in advance, Frank
As I mentioned in the comments, the problem is the :WAIT T argument. It causes the call to SB-EXT:RUN-PROGRAM to not return until the child process exits.
In the first example you passed a string input stream to the child process. cat will read input from the stream, and when the input ends there will be a End of File, so cat exits. In the second example there is no input available for the program, so it's effectively an infinite loop (just like if you run cat on the command line, and don't give any input to it; it will never exit).
The solution is to use :WAIT NIL. You will also have to close the input stream with CLOSE, because otherwise there will be no EOF and cat keeps listening for more input. You'll also want to use SB-EXT:PROCESS-WAIT after closing the stream to wait for cat to exit itself.
(let* ((p (sb-ext:run-program "/bin/cat" '()
:input :stream
:output *standard-output*
:wait nil))
(s (sb-ext:process-input p)))
(format s "foo bar baz~%")
(finish-output s)
(close s)
(sb-ext:process-wait p)
(sb-ext:process-close p))
I'm not sure why you used *TRACE-OUTPUT* for the child output, so I changed it to *STANDARD-OUTPUT*.
Also, using FORMAT for debugging like that is kind of ugly. Common Lisp provides actual debugging tools. In this case you could use STEP:
(step (let* ((p (sb-ext:run-program "/bin/cat" '()
:input :stream
:output *standard-output*
:wait nil))
(s (sb-ext:process-input p)))
(format s "foo bar baz~%")
(finish-output s)
(close s)
(sb-ext:process-wait p)
(sb-ext:process-close p)))
This will put you in the debugger, showing the call being evaluated next. You can invoke the STEP-NEXT-restart to continue to the next call.
This is what works, as suggested by jkiiski:
(let* ((p (sb-ext:run-program "/bin/cat" '()
:input :stream
:output *standard-output*
:wait nil))
(s (sb-ext:process-input p)))
(format s "foo bar baz~%")
(finish-output s)
(sb-ext:process-wait p)
(sb-ext:process-close p))

How to integrate flowtype with spacemacs

I'm spacemacs fan. I want to use Facebook Flow but I have not idea how to integrate it with spacemacs. I'm using flow with nuclide but I need to relearn everything to be productive. There is this script on flow repository to use it with emacs. I need a guide for how to use it within spacemacs.
Thanks.
I used Bodil's flow flycheck config here: https://github.com/bodil/emacs.d/blob/d28264cf072bb8a62459a48813d0cb30804b4f5b/bodil/bodil-js.el#L121-L154
I made it work with spacemacs's react-mode and default eslint flychecker by adding the following to my dotspacemacs/user-config (https://github.com/saltycrane/.spacemacs.d/blob/9d985ace9251529c2b8d7857e2ec9835b103084c/init.el#L383-L414):
;; Flow (JS) flycheck config (http://flowtype.org)
;; from https://github.com/bodil/emacs.d/blob/master/bodil/bodil-js.el
(require 'f)
(require 'json)
(require 'flycheck)
(defun flycheck-parse-flow (output checker buffer)
(let ((json-array-type 'list))
(let ((o (json-read-from-string output)))
(mapcar #'(lambda (errp)
(let ((err (cadr (assoc 'message errp))))
(flycheck-error-new
:line (cdr (assoc 'line err))
:column (cdr (assoc 'start err))
:level 'error
:message (cdr (assoc 'descr err))
:filename (f-relative
(cdr (assoc 'path err))
(f-dirname (file-truename
(buffer-file-name))))
:buffer buffer
:checker checker)))
(cdr (assoc 'errors o))))))
(flycheck-define-checker javascript-flow
"Javascript type checking using Flow."
:command ("flow" "--json" source-original)
:error-parser flycheck-parse-flow
:modes react-mode
:next-checkers ((error . javascript-eslint))
)
(add-to-list 'flycheck-checkers 'javascript-flow)
Also be sure the Flow command line tool is installed. Install it like this:
npm install -g flow-bin
I think Bodil intended to make the messages short, but I would like to have flycheck display more verbose messages. If anyone knows how to do that, I'd appreciate it.
EDIT 2016-08-12: the original version I posted gave a Symbol's function definition is void: flycheck-define-checker error on initial load. I updated the code above to add a require 'flycheck to get rid of that error.
The answer by saltycrane worked fine for me. Thanks! The solution gives a very short error messages as he points out. I have improved the error messages to be more verbose and look more like the output from flow cli output.
A note to new users who wants to use this script is to make sure you edit it to use the correct mode in flycheck-define-checker at the bottom. I use this in js2-mode, and saltycrane uses react-mode. Edit it to use whatever you are using.
(require 'f)
(require 'json)
(require 'flycheck)
(defun flycheck-parse-flow (output checker buffer)
(let ((json-array-type 'list))
(let ((o (json-read-from-string output)))
(mapcar #'(lambda (errp)
(let ((err (cadr (assoc 'message errp)))
(err2 (cadr (cdr (assoc 'message errp)))))
(flycheck-error-new
:line (cdr (assoc 'line err))
:column (cdr (assoc 'start err))
:level 'error
:message (concat (cdr (assoc 'descr err)) ". " (cdr (assoc 'descr err2)))
:filename (f-relative
(cdr (assoc 'path err))
(f-dirname (file-truename
(buffer-file-name))))
:buffer buffer
:checker checker)))
(cdr (assoc 'errors o))))))
(flycheck-define-checker javascript-flow
"Static type checking using Flow."
:command ("flow" "--json" source-original)
:error-parser flycheck-parse-flow
:modes js2-mode)
(add-to-list 'flycheck-checkers 'javascript-flow)

Clojure - core.async interface for apache kafka

I am using clj-kafka, and I am trying to make a core.async interface to it in the REPL.
I am getting some messages, but my structure feels wrong : I either cannot stop receiving messages, or have to launch the go routine again to receive more messages.
Here is my attempt :
(defn consume [topic]
(let [consume-chan (chan)]
(with-resource [c (consumer config)]
shutdown
(go (doseq [m (messages c "test")]
(>! chan message) ;; should I check the return value?
)))
consume-chan)) ;; is it the right place to return a channel ?
(def consume-chan (consume "test"))
;;(close! consume-chan)
(go (>! consume-chan "hi")) ;; manual test, but I have some messages in Kafka already
(def cons-ch (go
(with-resource [c (consumer config)]
shutdown
(doseq [m (messages c "test")]
(>! consume-chan m))))) ;; should I check something here ?
;;(close! cons-ch)
(def go-ch
(go-loop []
(if-let [km (<! consume-chan)]
(do (println "Got a value in this loop:" km)
(recur))
(do (println "Stop recurring - channel closed")))))
;;(close! go-ch)
How do I consume a lazy-sequence of messages with a core.async interface ?
Here's what I would do:
>! and <! return nil if the channel is closed, so make sure that the loop exits when this happens - that way you can easily end the loop from the outside by closing the channel.
Use a try/catch to check for exceptions inside the go block, and make any exception the return value so that they don't get lost.
Check for exceptions on read values, to catch anything from inside the channel.
The go blocks return a channel, and the return value of the code inside the block (like the exceptions from above) will be put on the channel. Check these channels for exceptions, possibly to rethrow.
You can now write to a channel like this:
(defn write-seq-to-channel
[channel
values-seq]
(a/go
(try
(loop [values values-seq]
(when (seq values)
(when (a/>! channel (first values))
(recur (rest values)))))
(catch Throwable e
e))))
and you read like this:
(defn read-from-channel-and-print
[channel]
(a/go
(try
(loop []
(let [value (a/<! channel)]
(when value
(when (instance? Throwable value)
(throw value))
(println "Value read:" value)
(recur))))
(catch Throwable e
e))))
You will now have two channels, so use something like alts! or alts!! to check for your loops exiting. Close the channel when you are done.

Clojurescript async <? macro

I keep seeing this macro <?, in swanodette's code which looks really useful :
In this gist :
;; BOOM!!! we can convert async errors into exceptions
(go (try
(let [x (<? (run-task (.-readFile fs) "foo.txt" "utf8"))]
(.log js/console "Success" x))
(catch js/Error e
(.log js/console "Oops" e))))
In this blog post :
(go (try
(let [tweets (<? (get-tweets-for "swannodette"))
first-url (<? (expand-url (first (parse-urls tweets))))
response (<? (http-get first-url))]
(. js/console (log "Most recent link text:" response)))
(catch js/Error e
(. js/console (error "Error with the twitterverse:" e)))))
<? is just a touch of macro sugar that expands into something like
(throw-err (<! [expr])). In core.async <! serves the same purpose as
ES6's yield operator. If an asynchronous process writes an error onto
its channel we will convert it into an exception.
But I can't find a definition for it. How is it implemented in Clojure{Script} ?
Alright so here is what I am using so far. There is probably room for improvement.
In Clojure :
(defn throw-err [e]
(when (instance? Throwable e) (throw e))
e)
(defmacro <? [ch]
`(throw-err (<! ~ch)))
In ClojureScript :
(defn error? [x]
(instance? js/Error x))
(defn throw-err [e]
(when (error? e) (throw e))
e)
(defmacro <? [ch]
`(throw-err (<! ~ch)))
I am completely unsure about the readability of my solution though (throw-err looks like it should throw an error, but it doesn't. At least not every time).

Resources