Showing posts with label functions. Show all posts
Showing posts with label functions. Show all posts

Tuesday, May 22, 2012

sidenum function

sidenum function

The sidenum function appends a sign to a number based on a side. The name sidenum was chosen due to it's similarities with signum in spelling and behavior (dealing with signs).

Definition

The sidenum function of a side x and a number y is defined as follows:

note: 'bid' can be replaced with 'buy', and 'ask' can be replaced with 'sell' or 'offer'. The string representation or type of side varies by trading system.

Usage

The sidenum function appears in most trading applications, though not always named 'sidenum'. It can be helpful for both position related math and conserving screen real-estate by displaying 2 concepts (side & quantity) as 1 (a signed quantity).

Examples

Java
 public static int sidenum(String side, int quantity) {
 if (side.equals("ask"))
 return -quantity;
 return quantity;
 }
Clojure
 (defn sidenum [side quantity]
 (if (= side "ask")
 (- quantity)
 quantity))
Ruby
 def sidenum(side, quantity)
 if side == "ask"
 -quantity
 else
 quantity
 end
 end

Wednesday, December 28, 2011

Clojure & Java Interop

About a year ago I got a phone call asking if I wanted to join another team at DRW. The team supports a (primarily) Java application, but the performance requirements would also allow it to be written in a higher level language. I'd been writing Clojure (basically) full-time at that point - so my response was simple: I'd love to join, but I'm going to want to do future development using Clojure.

A year later we still have plenty of Java, but the vast majority of the new code I add is Clojure. One of the big reasons I'm able to use Clojure so freely is the seamless interop with Java.

Execute Clojure from Java
Calling Clojure from Java is as simple as loading the .clj file and invoking a method from that file. I used the same example years ago, but I'll inline it here for simplicity.
; interop/core.clj
(ns interop.core)
(defn print-string [arg]
 (println arg))
// Java calling code
RT.loadResourceScript("interop/core.clj");
RT.var("interop.core", "print-string").invoke("hello world");
note: examples from this blog entry are available in this git repo. The commit with the code from the previous example is available here and I'm running the example from the command line with:
lein jar && java -cp "interop-1.0.0.jar:lib/*" interop.Example
Execute Java from Clojure
At this point we have Java executing some Clojure code, and we also have Clojure using an object that was created in Java. Even though we're in Clojure we can easily call methods on any Java object.
(ns interop.core)
(defn print-string [arg]
 (println arg "is" (.length arg) "characters long"))
commit

The above code (using the length method of a String instance) produces the following output.
hello world is 11 characters long
Calling a Java method and passing in additional arguments is also easy in Clojure.
(ns interop.core)
(defn print-string [arg]
 (println (.replace arg "hello" "goodbye")))
commit

The above code produces the following output.
goodbye world
There are a few other things to know about calling Java from Clojure. The following examples show how to call static methods, use enums, and use inner classes.
(ns interop.core)
(defn print-string [arg]
 ;;; calling a static method
 (println (String/valueOf true))
 ;;; using an enum
 (println (java.util.concurrent.TimeUnit/SECONDS))
 ;;; using a Java nested (inner) class. Note, in Clojure you
 ;;; use a $ instead of a .
 (println (java.util.AbstractMap$SimpleEntry. "key" "val")))
commit

And, the output:
true
#< SECONDS>
#<SimpleEntry key=val>
Create Java objects in Clojure
When working with Clojure you'll likely want to interact with existing Java objects, but you'll probably also want to create new instances of Java objects. You might have noticed the dot at the end of Abstract$SimpleEntry. in the previous example - that's how you instruct Clojure to create an instance of a Java object. The following example shows the dot notation for calling a constructor of the String class.
(ns interop.core)
(defn print-string [arg]
 (println (String. arg)))
commit

At this point our output is back to the original output.
hello world
When creating Java objects it's often beneficial to know which Java interfaces the Clojure data structures implement. The following examples demonstrate how you can create Java objects while passing Clojure datastructures (and functions) as constructor arguments.
(ns interop.core)
(defn print-string [arg]
 ;;; pass a Clojure vector where Java expects a java.util.Collection
 (println (java.util.HashSet. ["1" "2"]))
 ;;; pass a Clojure map where Java expects a java.util.Map
 (println (java.util.LinkedHashMap. {1 "1" 2 "2"}))
 ;;; pass a Clojure function where Java expects a Runnable
 (println (Thread. (fn [] (println "clojure fns are runnables (and callables)")))))
commit

The output shows the constructed Java objects.
#<HashSet [2, 1]>
#<LinkedHashMap {1=1, 2=2}>
#<Thread Thread[Thread-1,5,main]>
Calling constructors in Clojure is very easy, but that's not always an option when creating a Java object. At times you will likely need to create an instance of a Java interface. Clojure provides both proxy and reify for creating instances of Java interfaces. The following example demonstrates the syntax for using either proxy or reify.
(ns interop.core)
(defn proxy-coll []
 (proxy [java.util.Collection] []
 (add [o]
 (println o)
 true)))
(defn reify-coll []
 (reify java.util.Collection
 (add [this o]
 (println o)
 (println this)
 true)))
(defn main []
 (.add (proxy-coll) "this string is printed on proxied.add")
 (.add (reify-coll) "this string is printed on reified.add"))
commit

note, I also changed Example.java (the details are available in the above linked commit). The syntax for proxy and reify are fairly similar, and both offer additional options that are worth looking into. The primary differences between these two simple examples are:
  • The proxy implementation requires an empty vector where we could specify constructor arguments (if this were an abstract class instead of an interface).
  • The arg list for all methods of reify will specify the reified instance as the first argument. In our example the Collection.add method only takes one argument, but in our reify we also get the instance of the collection.
You might have also noticed that both implementations of add have "true" at the end - in our example we're hard-coding the return value of add to always return true. The following output is the result of running the current example code.
this string is printed on proxied.add
this string is printed on reified.add
#<core$reify_coll$reify__11 interop.core$reify_coll$reify__11@556917ee>
It's worth reading the docs to determine whether you want proxy or reify; however, if you don't see a clear choice I would opt for reify.

Returning objects from Clojure to Java
Our current Example.java returns something from the call to invoke on the clojure.lang.Var that is returned from RT.var("interop.core", "main"), but we're ignoring it so we have no idea what's returned.* Let's change the code and return something on purpose.
// interop/Example.java
package interop;
import clojure.lang.RT;
public class Example {
 public static void main(String[] args) throws Exception {
 RT.loadResourceScript("interop/core.clj");
 System.out.println(RT.var("interop.core", "main").invoke());
 }
}
; interop/core.clj
(ns interop.core)
(defn main []
 {:a "1" :b "2"})
Running our changes produces the following output.
{:a "1", :b "2"}
commit

At this point we are back in Java land after making a quick trip to Clojure to get a value. Returning most objects will be pretty straightforward; however, at some point you may want to return a Clojure function. This turns out to be fairly easy as well, since Clojure functions are instances of the IFn interface. The following code demonstrates how to return a Clojure function and call it from within Java.
// interop/Example.java
package interop;
import clojure.lang.RT;
public class Example {
 public static void main(String[] args) throws Exception {
 RT.loadResourceScript("interop/core.clj");
 clojure.lang.IFn f = (clojure.lang.IFn) RT.var("interop.core", "main").invoke();
 f.invoke("hello world");
 }
}
// interop/core.clj
(ns interop.core)
(defn main [] println)
commit

The above example returns the println function from interop.core/main and then invokes the println function from within Java. I only chose to pass one argument to invoke; however, the IFn.invoke method has various overrides to allow you to pass several arguments. The above code works, but it can be simplified to the following example.
package interop;
import clojure.lang.RT;
public class Example {
 public static void main(String[] args) throws Exception {
 clojure.lang.IFn f = (clojure.lang.IFn) RT.var("clojure.core", "println");
 f.invoke("hello world");
 }
}
commit

It seems like a fitting end that our final output is the same as our original output.
hello world
*actually, it's the last thing that's returned, or "true" for this specific case.

Monday, August 30, 2010

Clojure: Using Sets and Maps as Functions

Clojure sets and maps are functions.

Since they are functions, you don't need functions to get values out of them. You can use the map or set as the example below shows.
(#{1 2} 1)
> 1

({:a 2 :b 3} :a)
> 2
That's nice, but it's not exactly game changing. However, when you use sets or maps with high order functions you can get a lot of power with a little code.

For example, the following code removes all of the elements of a vector if the element is also in the set.
(def banned #{"Steve" "Michael"})
(def guest-list ["Brian" "Josh" "Steve"])

(remove banned guest-list)
> ("Brian" "Josh")
I'm a big fan of using sets in the way described above, but I don't often find myself using maps in the same way. The following code works, but I rarely use maps as predicates.
(def banned {"Steve" [] "Michael" []})
(def guest-list ["Brian" "Josh" "Steve"])

(remove banned guest-list)
> ("Brian" "Josh")
However, yesterday I needed to compare two maps and get the list of ids in the second map where the quantities didn't match the quantities in the first map. I started by using filter and defining a function that checks if the quantities are not equal. The following code shows solving the problem with that approach.
; key/value pairs representing order-id and order-quantity
(def map1 {1 44 2 33})
(def map2 {1 55 2 33})

(defn not=quantities [[id qty]] (not= (map1 id) qty))
(keys (filter not=quantities map2))
> (1)
However, since you can use maps as filter functions you can also solve the problem by merging the maps with not= and filtering by the result. The following code shows an example of merging and using the result as the predicate.
; key/value pairs representing order-id and order-quantity
(def map1 {1 44 2 33})
(def map2 {1 55 2 33})

(filter (merge-with not= map1 map2) (keys map2))
> (1)
I don't often find myself using maps as predicates, but in certain cases it's exactly what I need.

Tuesday, July 20, 2010

Clojure: Composing Functions

Before Clojure, I had never used a Functional Programming language. My experience has primarily been in C#, Ruby, & Java. So, learning how to use Clojure effectively has been a fun and eye-opening experience.

I've noticed a few things:
  • The Clojure language has a lot of built in support for maps and hashes (literal syntax, destructuring, etc)
  • Rich Hickey is quoted as saying "It is better to have 100 functions operate on one data abstraction than 10 functions on 10 data structures." Clojure reflects this opinion and has loads of functions that work with Sequences.
  • I strongly dislike working with people who think Map<String, Map<String, String>> is generally a good idea in Java. However, all the support for maps and vectors in Clojure makes working with them easy and efficient.
  • Once you embrace functions, maps, vectors, etc, composing functions together to transform data becomes effortless.
Like I said, I'm still learning Clojure. Recently I refactored some code in a way that I thought was worth documenting for other people who are also learning Clojure.

Let's start with a simple example. Let's assume we want to track the score in the British Open (Golf). The data structure we will be working with will be a map of maps, keyed by country and then player.
{:England {"Paul Casey" -1}}
The above example shows that Paul Casey plays for England and currently has the score of -1. We need a function that allows you to update a players score. Let's also assume that scores for individual holes come in the following map form.
{:player "Paul Casey" :country :England :score -1}
Given the above code, you would expect the following test to pass.
(def current-score {:England {"Paul Casey" -1}})

(deftest update-score-test
(is (=
{:England {"Paul Casey" -2}}
(update-score current-score {:player "Paul Casey" :country :England :score -1}))))
(Let's ignore the fact that I'm def'ing current-score. It's only for simplicity's sake.)

There are a lot of ways to make that test pass. It took me a few tries to come up with something I liked. Below is the path I took.

Step one, get the test passing using the functions I know.
(defn update-score [current update]
(let [player (:player update)
country (:country update)
hole-score (:score update)]
(merge current {country {player (+ ((current country) player) hole-score)}})))
The above example code is a victory when you are learning Clojure. The tests pass, you've used a few features of the language. It's a great first pass. However, I'm sure the Clojure veterans are drooling over the refactoring possibilities.

Step two, learn the update-in function. Like I previously mentioned, Clojure has a lot of functions for working with sequences (maps, vectors, lists, etc). It's not always obvious which function you should be using. However, I've had loads of success learning from the mailing list, and getting immediate answers in the #clojure chat room on freenode. One way or another, I eventually found the update-in function, which is designed up update a nested key.
(defn update-score [current update]
(let [player (:player update)
country (:country update)
hole-score (:score update)]
(update-in current [country player] (fn [_] (+ ((current country) player) hole-score)))))
The switch to update-in is relatively easy and cleans up a bit of code, but now I've introduced an anonymous function. Anonymous functions are great, but if I can get away with not creating them, I always take that route.

However, before we eliminate the anonymous function, we're actually better off making sure we understand the new function (update-in). While the current version of the code works, it's much cleaner if you use the current value that is passed into the anonymous function instead of looking up the value yourself.
(defn update-score [current update]
(update-in current [(:country update) (:player update)] (fn [overall-score] (+ overall-score (:score update)))))
Since we no longer use country and player in multiple places, it seems like removing the let statement is a logical choice. As a result, the amount of code necessary to solve this problem seems to get smaller and smaller.

However, we can actually take this a step farther and use destructuring to provide an even cleaner implementation.
(defn update-score [current {:keys [country player score]}]
(update-in current [country player] (fn [overall-score] (+ overall-score score))))
If you aren't familiar with destructuring the syntax might be a bit confusing. I created a blog entry for destructuring that should help if you aren't familiar with it. There's also a good write up with destructuring examples available on clojure.org. I would also recommend writing a few simple functions and try out the examples for yourself.

There's one more step to take, but for me it was a big one. The documentation for update-in states:
Usage: (update-in m [k & ks] f & args)

'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure.
What I currently have works fine, but the additional args that update-in takes allows me to provide a more concise solution that I greatly prefer.
(defn update-score [current {:keys [country player score]}]
(update-in current [country player] + score))
This final version doesn't require any anonymous functions. Instead it relies on on update-in to apply the current value and any additional args to the function that you passed in. The final version is so concise you begin to wonder if you really need to define an update-score function.

The final snippet is an example of why I'm very intrigued by Clojure these days. The ability to compose functions and mix them in with the powerful functions of the language results in very concise code.

I consider what I would need to write to accomplish the same thing in Java or Ruby, and I have to wonder if the Functional Programming supporters might just be on to something.
Subscribe to: Comments (Atom)

AltStyle によって変換されたページ (->オリジナル) /