I'm trying to dig a little deeper into clojure and functional programming.
At some point of my code I have a (def server (spawn-server)). Now I want a short function for the REPL to check the state of this socket.
This is what I have at the moment:
(defn status []
(if server
(
(println "server is up and running")
(println "connections:" (connection-count server))
)
(println "server is down")))
If server is nil, everything works fine, but this is the output on the REPL if the server is running:
=> (status)
server is up and running
connections: 0
#<CompilerException java.lang.NullPointerException (NO_SOURCE_FILE:0)>
I'm not really sure if I see the problem, but I can't figure out how this should work :-)
What I have here is this:
((println "foo")(println "foo"))
which will be evaluated to (nil nil) which results in the NullPointerException ?
Usally I wouldn't use the outer parentheses but how can I create some kind of "block" statement for the if-condition. If I don't use them, the second println will be used as else.
What would work is the usage of let as some kind of "block"-statement:
(let []
(println "server is up and running"),
(println "connections:" (connection-count server)) )
But I'm not really sure if this the "right" solution?
Use do:
(defn status []
(if server
(do
(println "server is up and running")
(println "connections:" (connection-count server)))
(println "server is down")))
In Lisps, generally, you can't just add parens for grouping.
((println "foo") (println "foo"))
Here, the return value of the first (println "foo") will be tried to be called (as a function), with the return value of the second as an argument. Those are very basic evaluation rules, so I suggest that you hit some introductory books or documentation about Clojure or Lisps in general.
From the evaluation section of the Clojure homepage:
Non-empty Lists are considered calls
to either special forms, macros, or
functions. A call has the form
(operator operands*).
Macros or special forms may "break" this rule.
Related
I'm currently in the start of making a tool that should modify all the functions in another namespace, and the run the "main" function in that (other) namespace. Almost like mocking in unit-testing, but for another purpose. The first step to this is to redefine functions from another namespace. The first listing shows code that works, where I explicitly name the function to be replaced.
(ns one)
(defn a-fun []
(println "original"))
(defn caller []
(a-fun))
(ns two)
(with-redefs [one/a-fun #(println "replaced")]
(one/caller))
;; replaced
;; nil
The next step is getting the functions programmatically from the other namespace. This is where I have run into a wall. I've experimented much with ns-publics, but so far no luck. So I try to break the problem down. And the problem is that the replacement of the function is not working. The output should print "replaced" not "original".
(ns two)
(def target (ns-resolve 'one (symbol "a-fun")))
(def caller (ns-resolve 'one (symbol "caller")))
(with-redefs [target #(println "replaced")]
(caller))
;; original
;; nil
Now, the #'two/target shows #'one/a-fun when I evaluate it in the repl. I can call one/a-fun by entering ((ns-resolve 'one (symbol "a-fun"))) in the repl, so I don't understand what part is not working.
I've been through a lot of documentation today, and I'm not really getting any closer.
You could try using with-redefs-fn like so:
(defn p [] "old")
(with-redefs-fn
{(ns-resolve *ns* 'p) #(println "new")}
(fn []
(p)))
;; => new
This does mean that the body of with-redefs-fn must be a function that uses your redefined Vars.
In core.async, if you call the >! function outside of a go block, it throws error saying <! used not in (go ...) block. How does the function know that its not being executed inside of a go block? I need to create something very similar where I need to ensure that a function can only be called from inside of a macro. How can I approach that? I've looked at the core.async source but I couldn't really figure out how it worked.
Here is the source code for <!:
(defn <!
"Takes a value from the channel. Must be called inside a (go ...) block. Will
return nil if closed. Will park if nothing is available."
[port]
(assert nil "<! used not in (go ...) block"))
Note that assert will throw an exception for any falsey value, so you get this error message if you use <! outside of a go block.
When you use the go macro, it recursively walks all of the code expressions it encloses, replacing symbols like <! with other code that does not call the "error case" code shown above.
Addition to Alan Thompson's answer here is the code(go macro) that replacing symbols like <! with other code that does not call the error case:
Also [clojure.core.async.impl.ioc-macros :as ioc] namespace used for this purpose.
(dispatch/run
(^:once fn* []
(let [~#(mapcat (fn [[l sym]] [sym `(^:once fn* [] ~(vary-meta l dissoc :tag))]) crossing-env)
f# ~(ioc/state-machine `(do ~#body) 1 [crossing-env &env] ioc/async-custom-terminators)
state# (-> (f#)
(ioc/aset-all! ioc/USER-START-IDX c#
ioc/BINDINGS-IDX captured-bindings#))]
(ioc/run-state-machine-wrapped state#))))
I think this is a bug in clojure/tools.logging. I have the following db.clj file. What it does is unimportant. The important part is that for safety I have disabled the *read-eval*. I invoke db/start with no problems. However, if I uncomment the #_(log/info "Failed to bootstrap") form, it throws an EvalReader not allowed error. I've tried all sorts of combinations for the log/info call. If it's outside of the try block, it's fine. Inside the try block anywhere, whether it's in the body, catch, or finally, it raises this exception. However, when I wrap a try around log/info elsewhere, it's fine.
What gives?
(ns extenium.db
(:require [clojure.tools.logging :as log]
[clojure.java.io :as io])
(:import com.thinkaurelius.titan.core.TitanGraph
com.thinkaurelius.titan.core.TitanFactory))
(def ^:private
sentinel- (Object.))
(def ^:private
db- (atom nil))
...
(defn start [^String path]
(locking sentinel-
(log/info "Starting database at path" path)
(let [exists (.exists (io/file path))
^TitanGraph db_ (TitanFactory/open path)]
(if exists
(log/info "Path" path "exists")
(log/info "Path" path "does not exist"))
(log/info "Starting database engine")
(swap! db- (constantly db_))
(log/info "Started database engine")
(if (not exists)
(try
(bootstrap-)
(catch Throwable t
#_(log/info "Failed to bootstrap")
(stop)
(.delete (io/file path))
(throw t)))))
(log/info "Started database")
true))
EDIT: Trimmed down code per #alex-taggart. bootstrap- implementation not shown. I had originally included everything because this seemed like a context-specific bug and I felt it was safer to provide as much context as possible.
EDIT: Per #chouser, added how I'm disabling *read-eval*. This is the template that is generated by lein new app.
(defn -main
"The main entry point into Extenium."
[& args]
;; Prevent arbitrary eval injection
(alter-var-root #'*read-eval* (constantly false))
;; Initialize system settings from the command line and configuration file
(init!- args)
;; Start the service
(start!-))
It's not a bug, really. The clojure.tools.logging library is just an abstraction upon other Java logging facilities. To discover which one is available, it uses eval expression. You're welcome to check for your own: here is a quick search result and a certain file where it gets used.
In your case, I believe it's not necessary to care about the global read-eval. This is an internal feature and who knows what other libraries depend on it. If you validate the user input and prevent it from being evaluated, it's fine to leave the flag as is. I would say, SQL injections and XSS are the things you should be worried about first.
Context
I'm playing with ClojureScript, so Ajax works as follows for me:
(make-ajax-call url data handler);
where handler looks something like:
(fn [response] .... )
Now, this means when I want to say something like "fetch the new data, and update the left sidebar", my end ends up looking like:
(make-ajax-call "/fetch-new-data" {} update-sidebar!) [1]
Now, I'd prefer to write this as:
(update-sidebar! (make-ajax-call "/fetch-new-data" {})) [2]
but it won't work because make-ajax call returns immediately.
Question
Is there some way via monads, or macros, to make this work? So that [2] gets auto rewritten into [1] ? I believe:
there will be no performance penality, since it's rewritten into [1[
it's clearer for me to reason about since I can think in synchronous steps rather than async events
I suspect I'm not the first to run into this problem, so if this is a well known problem, answers of the form "Google for Problem Foo" is perfectly valid.
Thanks!
Since Jun 28, 2013, the time that is released clojure core.async lib, you can do it, more or less, in this way: https://gist.github.com/juanantonioruz/7039755
Here the code pasted:
(ns fourclojure.stack
(require [clojure.core.async :as async :refer :all]))
(defn update-sidebar! [new-data]
(println "you have updated the sidebar with this data:" new-data))
(defn async-handler [the-channel data-recieved]
(put! the-channel data-recieved)
)
(defn make-ajax-call [url data-to-send]
(let [the-channel (chan)]
(go
(<! (timeout 2000)); wait 2 seconds to response
(async-handler the-channel (str "return value with this url: " url)))
the-channel
)
)
(update-sidebar! (<!! (make-ajax-call "/fetch-new-data" {})))
More info in:
* http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html
* https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj
a macro would change the appearance of the code while leaving the Ajax call asynchronous.
it's a simple template macro. another approach would be to wrap the call to make-ajax-call in a function that waits for the result. while either of these could be made to work they may seem a bit awkward and "un ajax like". will the benefits be worth the extra layer of abstraction?
What about using the threading macro? Isn't good enough?
(->> update-sidebar! (make-ajax-call "/fetch-new-data" {}))
We had rough ideas about this in the async branch of seesaw. See in particular the seesaw.async namespace.
I'm working with a messaging toolkit (it happens to be Spread but I don't know that the details matter). Receiving messages from this toolkit requires some boilerplate:
Create a connection to the daemon.
Join a group.
Receive one or more messages.
Leave the group.
Disconnect from the daemon.
Following some idioms that I've seen used elsewhere, I was able to cook up some working functions using Spread's Java API and Clojure's interop forms:
(defn connect-to-daemon
"Open a connection"
[daemon-spec]
(let [connection (SpreadConnection.)
{:keys [host port user]} daemon-spec]
(doto connection
(.connect (InetAddress/getByName host) port user false false))))
(defn join-group
"Join a group on a connection"
[cxn group-name]
(doto (SpreadGroup.)
(.join cxn group-name)))
(defn with-daemon*
"Execute a function with a connection to the specified daemon"
[daemon-spec func]
(let [daemon (merge *spread-daemon* daemon-spec)
cxn (connect-to-daemon daemon-spec)]
(try
(binding [*spread-daemon* (assoc daemon :connection cxn)]
(func))
(finally
(.disconnect cxn)))))
(defn with-group*
"Execute a function while joined to a group"
[group-name func]
(let [cxn (:connection *spread-daemon*)
grp (join-group cxn group-name)]
(try
(binding [*spread-group* grp]
(func))
(finally
(.leave grp)))))
(defn receive-message
"Receive a single message. If none are available, this will block indefinitely."
[]
(let [cxn (:connection *spread-daemon*)]
(.receive cxn)))
(Basically the same idiom as with-open, just that the SpreadConnection class uses disconnect instead of close. Grr. Also, I left out some macros that aren't relevant to the structural question here.)
This works well enough. I can call receive-message from inside of a structure like:
(with-daemon {:host "localhost" :port 4803}
(with-group "aGroup"
(... looping ...
(let [msg (receive-message)]
...))))
It occurs to me that receive-message would be cleaner to use if it were an infinite lazy sequence that produces messages. So, if I wanted to join a group and get messages, the calling code should look something like:
(def message-seq (messages-from {:host "localhost" :port 4803} "aGroup"))
(take 5 message-seq)
I've seen plenty of examples of lazy sequences without cleanup, that's not too hard. The catch is steps #4 and 5 from above: leaving the group and disconnecting from the daemon. How can I bind the state of the connection and group into the sequence and run the necessary cleanup code when the sequence is no longer needed?
This article describes how to do exactly that using clojure-contrib fill-queue. Regarding cleanup - the neat thing about fill-queue is that you can supply a blocking function that cleans itself up if there is an error or some condition reached. You can also hold a reference to the resource to control it externally. The sequence will just terminate. So depending on your semantic requirement you'll have to choose the strategy that fits.
Try this:
(ns your-namespace
(:use clojure.contrib.seq-utils))
(defn messages-from [daemon-spec group-name]
(let [cnx (connect-to-deamon daemon-spec))
group (connect-to-group cnx group-name)]
(fill-queue (fn [fill]
(if done?
(do
(.leave group)
(.disconnect cnx)
(throw (RuntimeException. "Finished messages"))
(fill (.receive cnx))))))
Set done? to true when you want to terminate the list. Also, any exceptions thrown in (.receive cnx) will also terminate the list.