As a hobby project, I am working on an alternate futures and promises implementation based on "From Events to Futures and Promises and back". The original author uses channels/events under the hood, which is why I am using core.async. A future, expressed in pseudo Go syntax, looks as follows:
func future(func f() (T, bool)) Future <T> {
ch = newChannel ()
spawn(func() {
x := f()
for { syncEvt(sndEvt(ch, x)) }
})
return rcvEvt(ch)
}
Using valid Go syntax, type definitions and a get function:
type Comp struct {
value interface{}
ok bool
}
type Future chan Comp
func future(f func() (interface{}, bool)) Future {
future := make(chan Comp)
go func() {
v, o := f()
c := Comp{v, o}
for {
future <- c
}
}()
return future
}
func (ft Future) get() (interface{}, bool) {
c := <-ft
return c.value, c.ok
}
Now, when I port this to Clojure, I was thinking to implement it as followed:
(defrecord Comp [value ok])
(defn future [f]
(let [future (chan)]
(go-loop [comp (f)]
(>! future comp)
(recur comp))
future))
(defn get [future]
(<!! future))
Since I'm pretty new to Clojure (and core.async), I worry about the infinite go-loop. Will the IOC thread ever be released? Should I provide some kind of poison pill to stop the loop (though I think this would be pretty error-prone)? Any suggestions?
Go blocks in Clojure are not like they are in Go. In core.async go blocks exist as callbacks attached onto channels, and as such they live as long as the channel itself lives. So think of go blocks as being syntactic sugar over callbacks and it'll all star to make sense.
This video tutorial goes into a bit more detail: https://www.youtube.com/watch?v=VrwVc-saWLw
Related
I am taking an example from the clojure site.
(defmulti foo class)
(defmethod foo ::collection [c] :a-collection)
(defmethod foo String [s] :a-string)
(foo [])
:a-collection
(foo (java.util.HashMap.))
:a-collection
(foo "bar")
:a-string
This functionality is cool. I'm trying to understand the technical reasons why this is superior to an instanceof based implementation in (for example) java. It seems to me essentially equivalent in function with nicer syntax.
public <T> String foo(final T t) {
if (t instanceof Collection) {
return "a-collection";
} else if (t instanceof String) {
return "a-string";
} else {
throw new IllegalArgumentException("Undefined - no available dispatch");
}
}
What are the reasons why multimethods are considered a great alternative to visitor pattern based double dispatch while instanceof is not when they seem like they're essentially doing the same thing?
One of the benefits discussed in the comments is that the defmulti and defmethod can be done in different files, by different users. An excellent example is Clojure's own print-method multi-method.
From the docs, we see how we can define a custom print-method for a new record type we create:
(deftype XYZ [])
; without custom print-method defined:
user=> (prn (XYZ.))
#<XYZ user.XYZ#2670d85b>
; Note, this hooks into the pre-existing `(defmulti print-method ...)`
(defmethod print-method XYZ [v ^java.io.Writer w]
(.write w "<<-XYZ->>"))
; with print-method
user=> (prn (XYZ.))
<<-XYZ->>
So while it has similarity to a giant cond statement, it is more flexible & cleaner.
Provided that abs and avg are defined:
(defn sqrt [x]
(letfn [(s [guess]
(if (good-enough? guess)
guess
(s (improve guess))))
(good-enough? [guess]
(< (abs (- (square guess) x)) 0.0001))
(improve [guess]
(avg (/ x guess) guess))]
(s 1.0)))
Please ignore for a sec that I'm reinventing the wheel here. :) This only serves as an example.
If so, is there a way to get around this so the names won't be bound again and again every time the function is called, and without introducing more names outside the function?
Will the functions defined in letfn be redefined every time sqrt is called?
Yes.
The bindings of s and good-enough will be remade every time the sqrt function is entered. The things they are bound to are constructed afresh.
The s and good-enough functions (effectively fn special forms)
are compiled once, when the (defn sqrt ... ) is
performed.
They are closed over x for every call of sqrt.
The closures might be implemented on the JVM as inner classes
complying with the IFn interface.
The closures/function-objects are constructed every time sqrt is
entered, though the classes that they exemplify have been long compiled.
It depends what you mean by redefined. I thought not, but the elements on both sides of the bindings are renewed. So now I think so.
is there a more idiomatic way to write the square root function?
Yes.
On the JVM ...
(defn sqrt [x] (Math/sqrt x))
(sqrt 2);1.4142135623730951
The short answer is "yes", the bindings will be renewed. However, this is as cheap as instantiating a very simple class. You can see below the decompiled java classes how the clojure is implemented with a simple parameter and how nested functions will result in just some more classes. So this is still very cheap.
public final class user$sqrt extends AFunction {
public static final Object const__0 = Double.valueOf(1.0D);
public static Object invokeStatic(Object x) {
user$sqrt$s__44945 s = null;
user$sqrt$good_enough_QMARK___44947 good_enough_QMARK_ = null;
user$sqrt$improve__44949 improve = null;
s = new user$sqrt$s__44945(good_enough_QMARK_, improve);
good_enough_QMARK_ = new user$sqrt$good_enough_QMARK___44947(x);
Object var10002 = x;
x = null;
improve = new user$sqrt$improve__44949(var10002);
user$sqrt$s__44945 var10000 = (user$sqrt$s__44945)s;
((user$sqrt$s__44945)s).good_enough_QMARK_ = good_enough_QMARK_;
var10000.improve = improve;
user$sqrt$good_enough_QMARK___44947 var4 = (user$sqrt$good_enough_QMARK___44947)good_enough_QMARK_;
user$sqrt$improve__44949 var5 = (user$sqrt$improve__44949)improve;
return ((IFn)s).invoke(const__0);
}
}
public final class user$sqrt$good_enough_QMARK___44947 extends AFunction {
Object x;
public static final Var const__1 = (Var)RT.var("user", "abs");
public static final Var const__3 = (Var)RT.var("user", "square");
public user$sqrt$good_enough_QMARK___44947(Object var1) {
this.x = var1;
}
public Object invoke(Object guess) {
DO var10000 = (DO)const__1.getRawRoot();
DO var10001 = (DO)const__3.getRawRoot();
Object var10002 = guess;
guess = null;
return Numbers.lt(var10000.invokePrim(RT.doubleCast((Number)Numbers.minus(var10001.invokePrim(RT.doubleCast((Number)var10002)), this.x))), 1.0E-4D)?Boolean.TRUE:Boolean.FALSE;
}
}
public final class user$sqrt$improve__44949 extends AFunction {
Object x;
public static final Var const__0 = (Var)RT.var("user", "avg");
public user$sqrt$improve__44949(Object var1) {
this.x = var1;
}
public Object invoke(Object guess) {
DDO var10000 = (DDO)const__0.getRawRoot();
double var10001 = RT.doubleCast((Number)Numbers.divide(this.x, guess));
Object var10002 = guess;
guess = null;
return var10000.invokePrim(var10001, RT.doubleCast((Number)var10002));
}
}
Well the wiseguy answer is that it would be most idiomatic not to define your own square root operation. (Math/sqrt x) which is an interop call against java.util.Math.sqrt() would be preferred. It's fairly common to see (defn sqrt [x] (Math/sqrt x)) floating around, or at least that's something I've perpetrated for several projects.
An even better answer would be to use clojure.algo.generic which already defines sqrt among other operations in an extensible and idiomatic fashion.
This particular implementation of Newton's Method is fine, and in a very traditional scheme style, but because it's using boxed arithmetic through multiple fns it will be vastly outperformed by Math/sqrt and it provides none of the numeric tower flexibility of algo.generic, or an equivalent implementation atop algo.generic.
As to will the functions in the letfn be redefined every time, the traditional Scheme implementation of letfn is something like:
Create a binding to nil for every fn name
setq each binding to the fn body now that there is a binding for every name
Evaluate the body form(s)
Clojure does the same thing under the hood. Each fn in the letfn is compiled to an AFn instance class, which accepts as instance arguments references to the closed over fns. The emitted bytecode is logically the same format as the Scheme implementation:
Bind the named local for each fn to a Var
Initialize each AFn instance with the Vars corresponding to the other letfn bodies that it closes over
Bind each instantiated AFn to the appropriate Var
Evaluate the body form(s)
So technically yes, each binding in the letfn needs to be re-established each time the body is executed, and the new binding is of a new (anonymous) Var to a new AFn instance of the compiled classes. No lambda lifting or any other transformation occurs to prevent this, however the overhead from doing so is negligible.
The following code shows the difference. Note that a plain let is all you need to define local functions:
(defn my-inc [x] (+ 1 x))
(defn my-square [x] (* x x))
(println :1 (my-square (my-inc 2)))
(let [my-inc-2 (fn [x] (+ 1 x))
my-square-2 (fn [x] (* x x)) ]
(println :2 (my-square-2 (my-inc-2 2))))
(println :sqrt-9 (Math/sqrt 9))
;=> :1 9
;=> :2 9
;=> :sqrt-9 3.0
The only difference between the 2 cases is that visibility of my-inc-2 and my-square-2 is restricted to the let block. I like this way better than using letfn, as I think the regular (fn ...) syntax is clearer.
With regards to sqrt, using the Java built-in function is much better than writing your own.
For numerical techniques in general, one effective technique is to use a polynomial first approximation, followed up by a few iterations of Newton's method. This is how Matlab computes the normal distribution function N(0,1), for example.
I am doing a library in ClojureScript that will expose a public JavaScript API. Since it has to mimic the API of an existing JavaScript library, I would like to present the same kind of fluent API :
myLib.prepareToDo()
.something()
.and('also')
.somethingElse()
.run(function(err, result) {
console.log("yay!");
});
In Javascript, one could create a fluent API like this site point):
var MyClass = function(a) {
this.a = a;
}
MyClass.prototype.foo = function(b) {
// Do some complex work
this.a += Math.cos(b);
return this;
}
I can then call it like :
var obj = new MyClass(5);
obj.foo(1).foo(2).foo(3);
Now, as far as I know, there is no notion of this in ClojureScript, although apparently it is possible to access it this-as.
I don't get how to use it though, hence my question.
How can I create a fluent interface in ClojureScript ?
(defrecord) and this answer to the rescue. Extending the "magic" protocol Object to our record or type causes the defined methods to appear as member functions in the JavaScript object. To enable the "fluent interface", some methods return an instance of MyClass.
(defrecord MyClass [a b]
Object
(something [this] this)
(and-then [this s] (assoc this :a s))
(something-else [this] (assoc this :b (str a "-" a)))
(run [this f] (f a b)))
Then we can have a JavaScript client like so:
var myClass = new my_namespace.core.MyClass();
myClass.something()
.and_then("bar")
.something_else()
.run(function(a, b) {
console.log(a + " - " + b) });
So I am trying to write the below in clojure (Assume all methods below return boolean)
def some_method(a, b)
if (call_this_method() )
then_call_this_method()
else
new_method()
end
What I got was this:
(defn some-method [a b]
(if (call_this_method)
:then (then-call-this-method)
:else (new-method)))
I am pretty new to clojure so am not sure if this feels like the correct manner to solve this. Is there a different approach?
if basically takes 3 params, [condition what-to-run-if-true optional-run-if-false]
(defn some-method
"My function does ..."
[ a b ]
(if (call-this-method)
(then-call-this-method)
(new-method)))
You can use if in clojure as well
(if test then-code else-code)
Or cond which is more like switch
(cond
test-A run-if-A
test-B run-if-B
...
:else else-code)
And if you wanted to do something like
if(foo) bar;
Then you would write
(when foo bar)
So there's list?, seq?, vector?, map? and so on to determine what type of collection the argument is.
What's a good way of telling the difference between
a map (i.e. something that contains key-value pairs)
a collection (i.e. something that contains values)
a non collection value like a string.
Is there a better way than
#(or (seq? %) (list? %) etc)
using seq? is about as concise and clean as it gets.
clojure.contrib.core defines:
seqable?
function
Usage: (seqable? x)
Returns true if (seq x) will succeed, false otherwise.
http://clojure.github.com/clojure-contrib/core-api.html
it does what you proposed with one big or statement of
already a seq
an instance of clojure.lang.Seqable
nil
instance of Iterable
an array
a string
instance of java.util.Map
Let's not forget about sequential?:
user=> (sequential? [])
true
user=> (sequential? '())
true
user=> (sequential? {:a 1})
false
user=> (sequential? "asdf")
false
The function seq right now does only this:
(. clojure.lang.RT (seq coll))
In RT.java in the latest version of Clojure, you'll find:
static public ISeq seq(Object coll){
if(coll instanceof ASeq)
return (ASeq) coll;
else if(coll instanceof LazySeq)
return ((LazySeq) coll).seq();
else
return seqFrom(coll);
}
static ISeq seqFrom(Object coll){
if(coll instanceof Seqable)
return ((Seqable) coll).seq();
else if(coll == null)
return null;
else if(coll instanceof Iterable)
return IteratorSeq.create(((Iterable) coll).iterator());
else if(coll.getClass().isArray())
return ArraySeq.createFromObject(coll);
else if(coll instanceof CharSequence)
return StringSeq.create((CharSequence) coll);
else if(coll instanceof Map)
return seq(((Map) coll).entrySet());
else {
Class c = coll.getClass();
Class sc = c.getSuperclass();
throw new IllegalArgumentException("Don't know how to create ISeq from: " + c.getName());
}
}
An ASeq or a LazySeq is already a seq. A Seqable is something that knows how to return a seq of itself.
That leaves things like Java core classes, which should be seqable but which Clojure can't alter to add a seq method. Those are currently hard-coded into this list. I wouldn't be surprised if the implementation changed someday, maybe using protocols to extend the Java core classes instead?
All seqables implement clojure.lang.Seqable marker:
(instance? clojure.lang.Seqable x)
Clojure 1.9 provides seqable?