shortcut to define parameterless functions in clojure - clojure

I am searching for a shortcut to define parameterless functions in clojure:
=> (def x (fn [] (println "test")))
#'x
=> (x)
test
nil
=> (def y (println "test"))
test
#'y
=> (y)
NullPointerException core/eval2015 (form-init5842739937514010350.clj:1)
I would really like to avoid typing the fn []. I know about the lambda notation #() but it requires at least one parameter. I would use them in a GUI binding to handle button click events where I don't care about the event itself, I just need to know the button was clicked.

user> (def y #(println "test"))
#'user/y
user> (y)
test

In addition to noisesmith's response (which is the right answer to the question), in this particular case you could also do:
(def y (partial println "test"))
which would print test when called as (y), or test hello when called as (y "hello").

Related

Use repl instead of println in Clojure

Let's say we need evaluate a number of clauses in a source file, e.g.
test.clj
#(def x 1)
#(def y 2)
#(def z 3)
Only the last evaluation shows up if we plainly use either clj or lein repl,
user => (load-file "test.clj")
3
We can surround each of them by println to show all of them,
test-with-println.clj
(println #(def x 1))
(println #(def y 2))
(println #(def z 3))
user => (load-file "test-with-println.clj")
1
2
3
nil
What are the better alternatives to avoid invasive printlns all over the source code while able to print out all the intended evaluations under the umbrella of REPLs?
#Solution
Thanks to tap> from the answer #Sean Corfield we can have desired results as follows,
pipe every wannabe printed out to tap>.
test-with-tap.clj
(-> #(def x 1) tap>)
(-> #(def y 2) tap>)
(-> #(def z 3) tap>)
REPLs will receive none of their outputs until tap> is turned on by add-tap.
user=> (load-file "test-with-tap.clj")
nil
user=> (add-tap #(def out (bound-fn* println)))
nil
user=> (load-file "test-with-tap.clj")
1
2
3
user=> (remove-tap out)
nil
user=> (load-file "test-with-tap.clj")
nil
tap> is probably what you're looking for - https://clojuredocs.org/clojure.core/tap%3E - This lets you send full Clojure values (not just strings) to any function registered as a listener, which can be something like Portal for example - https://github.com/djblue/portal - which is something I use all-day, every-day, but you can also use something as simple as println in add-tap to get every tap>'d value displayed.
The tap> calls can stay in your code, even in production, since there is next to no overhead to using them.
Although tap> returns a Boolean, you can use (doto expr tap>) to evaluate and return expr but still send the value to any tap listeners. tap> is a great debugging tool.
I haven't had a chance to play with tap> yet. My favorite over the years has been the spy family of functions in the Tupelo library. Specifically, check out spyx, spyx-pretty, and let-spy.

Dynamic symbols in Clojure Macro/Special Form

I have a question regarding how to define functions/macros which call other macros or special forms but where one of the symbols passed in needs to be dynamic.
The simplest version of this question is described below:
We can define variables using def
(def x 0)
But what if we wanted the name x to be determined programmatically so that we could do the equivalent of?
(let [a 'b]
(our-def a 3)) => user/b
We could try to define a function
(defn defn2 [sym val]
(def sym val))
However it does not do what we want
(def2 'y 1) => #'user/sym
At first it seems like a macro works (even though it seems like it would be unnecessary)
(defmacro def3 [sym val]
`(def ~sym ~val))
(def3 z 2) => user/z
but it is just superficial, because we're really right back where we started with regular def.
(let [a 'b]
(def3 a 3)) => user/a
I can do it if I use eval, but it doesn't seem like eval should be necessary
(defn def4 [sym val]
(eval `(def ~sym ~val)))
(let [a 'b]
(def4 a 4)) => user/b
If there are other built-in commands that could achieve this particular example, they are not really what I am looking for since def is just to show a particular example. There are macros more complicated than def that I might want to call and not have to worry about how they were internally implemented.
First: The right way to do this is to use macro that starts with def... since this is the way people have been doing defs and is of little surprise to the user.
To answer you question: Use intern:
(def foo 'bar)
(intern *ns* foo :hi)
(pr bar) ;; => :hi
(intern *ns* foo :hi2)
(pr bar) ;; => :hi2
If you want to use macros do this:
(def z 'aa)
(defmacro def3 [sym val]
`(def ~(eval sym) ~val))
(def3 z 2)
(pr aa) ;; => 2

How can I get the var of a multimethod?

I'm trying to use dire to add hooks to multimethods. The author says it might not work.
Here is an example with a normal function:
(ns mydire.prehook
(:require [dire.core :refer [with-pre-hook!]]))
(defn times [a b]
(* a b))
(with-pre-hook! #'times
"An optional docstring."
(fn [a b] (println "Logging something interesting.")))
(times 21 2) ; => "Logging something interesting."
As you can see, with-pre-hook! is passed (var times) (which is the same as #'times).
The problem is that when calling var for a multimethod I'm getting an exception:
clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol
Is there a way to make this work?
Below is my code sample:
(defmulti get-url identity)
(defmethod get-url :stackoverflow
[site]
"http://stackoverflow.com")
(with-pre-hook! (var (get-method get-url :stackoverflow))
(fn [x] (println "getting url for stackoverflow.")))
var is a macro, it does not evaluate its argument. If you give it a list, it will not evaluate the list, it will reject it, because it's a list and not a symbol.
There is no var to attach to with a specific method, because defmethod does not create a var, it modifies the dispatch of the multimethod it is attached to. The value returned by get-method is a function, not a var.
Having looked at dire, it specifically needs a var to act on, and won't work on a specific method of a multimethod without some amount of redesign. So no, you can't use with-pre-hook on a specific method, though it might work on a multimethod itself (including all of its methods).

In Clojure and Midje, how can I write prerequisites for an indirect call?

In the following code, I'd like to test the foo function before implementing the bar function.
(unfinished bar)
(def tbl {:ev1 bar})
(defn foo [ev] ((tbl ev)))
(fact "about an indirect call"
(foo :ev1) => nil
(provided
(bar) => nil))
But Midje says:
FAIL at (core_test.clj:86)
These calls were not made the right number of times:
(bar) [expected at least once, actually never called]
FAIL "about an indirect call" at (core_test.clj:84)
Expected: nil
Actual: java.lang.Error: #'bar has no implementation,
but it was called like this:
(bar )
I thought that 'provided' couldn't hook the bar function because the foo didn't directly call the bar. But I also found if I changed the second line like this:
(def tbl {:ev1 #(bar)})
then the test succeeded.
Is there any way to succeed for the first version?
Thanks.
PS: I'm using Clojure 1.5.1 and Midje 1.5.1.
provided uses a flavour of with-redefs to alter the root of a var. When defining tbl you already dereference the var #'bar, prompting tbl to contain the unbound value instead of a reference to the logic to be executed. You cannot provide replacements for already evaluated values is what I'm trying to say.
Similarly:
(defn x [] 0)
(def tbl {:x x})
(defn x [] 1)
((:x tbl)) ;; => 0
What you want is to store the var itself in tbl:
(defn x [] 0)
(def tbl {:x #'x})
(defn x [] 1)
((:x tbl)) ;; => 1
Same for your tests. Once you use (def tbl {:ev1 #'bar}), they pass.

Clojure: minimal number implementation that supports meta?

I'd like to implement some basic Physics/Chemistry formulas in Clojure.
I want to emphasize not on performance but on convenience, so the main
feature is type-checking. I was thinking that attaching meta to numbers
would accomplish the task.
For instance, this function:
(defn force [mass accel]
(* mass accel))
Should
Access the meta of first argument
Make sure it's of mass type, i.e. kilograms, grams etc. Throw an error if it's not.
Convert the numeric value to kilograms.
Do the same for acceleration.
Return the result with meta of Newtons.
I can overload * and other functions appropriately in my namespace.
The only problem is that it's impossible to attach meta to a Double.
What's a good way to get a something that behaves like a number, but can have metadata?
All this is much easier if you just create maps that contain both a number and a unit, rather than trying to smuggle the unit in as part of the number's metadata. After all, the unit is not conceptually bookkeeping data about the number: it is an integral part of the computation you are performing. And it's not as if you can ever use the number while ignoring its unit, so the ability to pass a decorated number into some "dumb" unit-unaware function such as + is not interesting either.
Given all this, it's easy to implement your force example function:
(defn force [{munit :unit :as mass} {aunit :unit :as accel}]
(assert (mass? munit))
(assert (accel? aunit))
{:unit :newton, :magnitude (* (:magnitude (to-kg mass))
(:magnitude (to-mss accel)))})
And of course if your to-kg and to-mss functions check the types themselves, you can omit them in force. Don't give up on the simplicity and transparency of maps for the imagined convenience of having numbers with metadata on them.
Here's an approach using gen-class. I just mocked the functions for checking and normalizing units. The only operation implemented is * which is used in force.
Please note that since the code is using gen-class and compile you'll need to save the following code to a file named big_decimal_meta.clj in the src folder of your leiningen project folder and then load it.
BigDecimalMeta using gen-class:
(ns big-decimal-meta
(:refer-clojure :exclude [* force])
(:gen-class
:name BigDecimalMeta
:extends java.math.BigDecimal
:state metadata
:init init
:implements [clojure.lang.IObj]))
(defn -init [& args]
[args (atom nil)])
(defn -withMeta [this metadata]
(reset! (.metadata this) metadata)
this)
(defn -meta [this]
(deref (.metadata this)))
(compile 'big-decimal-meta)
* and force functions with some example code:
(def x (with-meta (BigDecimalMeta. 1) {:unit :kg}))
(def y (with-meta (BigDecimalMeta. 3.5) {:unit :mss}))
(def z (with-meta (BigDecimalMeta. 4.5) {:unit :V}))
(defn unit [x]
(-> x meta :unit))
(defn * [x y]
(BigDecimalMeta. (str (.multiply x y))))
(defn mass? [x]
(#{:kg :gr :mg ,,,} (unit x)))
(defn accel? [x]
(#{:mss ,,,} (unit x)))
(defn to-kg [x] x)
(defn to-mss [x] x)
(defn force [mass accel]
(assert (mass? mass))
(assert (accel? accel))
(let [mass (to-kg mass)
accel (to-mss accel)]
(with-meta (* mass accel) {:unit :N})))
(println (force x y) (meta (force x y)))
(println (force x z) (meta (force x z)))