forked from marick/fp-oo
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Code and test case for javascript functions.
- Loading branch information
Showing
9 changed files
with
344 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
(load-file "sources/javascript.clj") | ||
|
||
;;; Exercise 1 | ||
(def js-apply | ||
(fn [javascript-function object arguments] | ||
(binding [this object] | ||
(apply (:__function__ javascript-function) arguments)))) | ||
|
||
|
||
;;; Exercise 2 | ||
(def Function | ||
(make-function (fn [fn-value & property-pairs] | ||
(merge this | ||
{:__function__ fn-value} | ||
(apply hash-map property-pairs))))) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
|
||
cat pieces/javascript-*.clj > javascript.clj |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
(def dot get) | ||
|
||
(def ^:dynamic this {:shift (fn [x y] "the default version of `shift`")}) | ||
|
||
(def default-this | ||
(fn [] (.getRawRoot #'this))) | ||
|
||
(def js-apply | ||
(fn [javascript-function object arguments] | ||
(binding [this object] | ||
(apply javascript-function arguments)))) | ||
|
||
(def js-call | ||
(fn [javascript-function object & args] | ||
(js-apply javascript-function object args))) | ||
|
||
(def send-to | ||
(fn [object message & arguments] | ||
(js-apply (get object message) object arguments))) | ||
|
||
(def plain-call | ||
(fn [message & arguments] | ||
(apply send-to (default-this) message arguments))) | ||
|
||
(def js-new | ||
(fn [constructor & arguments] | ||
(js-apply constructor {} arguments))) | ||
|
||
|
||
|
||
;;; Here are some test cases. With the following definition of | ||
;;; `make-function`, they work even the exercise code changes. | ||
;;; Your job is to make them work after. | ||
|
||
(def make-function identity) | ||
|
||
;; js-apply | ||
(println (js-apply (make-function (fn [x] [this x])) | ||
{:an :object} | ||
[1])) | ||
|
||
;; js-call | ||
(println (js-call (make-function (fn [x] [this x])) | ||
{:an :object} | ||
1)) | ||
|
||
;; send-to | ||
(def object {:some-property 5, | ||
:some-method | ||
(make-function | ||
(fn [x] (+ x (dot this :some-property))))}) | ||
(println (send-to object :some-method 3)) | ||
|
||
;; plain-call | ||
(def ^:dynamic this {:some-property -3838383838 | ||
:value-returner | ||
(make-function | ||
(fn [] (dot this :some-property)))}) | ||
(def object {:value-returner | ||
(make-function | ||
(fn [] "SHOULD NOT BE CALLED")) | ||
:some-method | ||
(make-function | ||
(fn [] (plain-call :value-returner)))}) | ||
|
||
(println (send-to object :some-method)) | ||
|
||
;; js-new | ||
(def Point | ||
(make-function | ||
(fn [x y] | ||
(assoc this | ||
:x x, :y y, | ||
:get-x (make-function (fn [] (dot this :x))))))) | ||
(def point (js-new Point 1 2)) | ||
|
||
(println (send-to point :get-x)) | ||
|
||
|
||
|
||
;;; For Exercise 1 | ||
;;; This function will be used to bootstrap the replacement | ||
;;; of Clojure functions with Javascript Functions: | ||
|
||
(def make-function | ||
(fn [fn-value & property-pairs] | ||
(merge {:__function__ fn-value} | ||
(apply hash-map property-pairs)))) | ||
|
||
|
||
|
||
;;; For Exercise 2 | ||
|
||
;;; This is a Function constructor that doesn't work. | ||
|
||
(def Function | ||
(fn [fn-value & property-pairs] | ||
(merge this | ||
{:__function__ fn-value} | ||
(apply hash-map property-pairs)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
(def dot get) | ||
|
||
(def ^:dynamic this {:shift (fn [x y] "the default version of `shift`")}) | ||
|
||
(def default-this | ||
(fn [] (.getRawRoot #'this))) | ||
|
||
(def js-apply | ||
(fn [javascript-function object arguments] | ||
(binding [this object] | ||
(apply javascript-function arguments)))) | ||
|
||
(def js-call | ||
(fn [javascript-function object & args] | ||
(js-apply javascript-function object args))) | ||
|
||
(def send-to | ||
(fn [object message & arguments] | ||
(js-apply (get object message) object arguments))) | ||
|
||
(def plain-call | ||
(fn [message & arguments] | ||
(apply send-to (default-this) message arguments))) | ||
|
||
(def js-new | ||
(fn [constructor & arguments] | ||
(js-apply constructor {} arguments))) | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
;;; Here are some test cases. With the following definition of | ||
;;; `make-function`, they work even the exercise code changes. | ||
;;; Your job is to make them work after. | ||
|
||
(def make-function identity) | ||
|
||
;; js-apply | ||
(println (js-apply (make-function (fn [x] [this x])) | ||
{:an :object} | ||
[1])) | ||
|
||
;; js-call | ||
(println (js-call (make-function (fn [x] [this x])) | ||
{:an :object} | ||
1)) | ||
|
||
;; send-to | ||
(def object {:some-property 5, | ||
:some-method | ||
(make-function | ||
(fn [x] (+ x (dot this :some-property))))}) | ||
(println (send-to object :some-method 3)) | ||
|
||
;; plain-call | ||
(def ^:dynamic this {:some-property -3838383838 | ||
:value-returner | ||
(make-function | ||
(fn [] (dot this :some-property)))}) | ||
(def object {:value-returner | ||
(make-function | ||
(fn [] "SHOULD NOT BE CALLED")) | ||
:some-method | ||
(make-function | ||
(fn [] (plain-call :value-returner)))}) | ||
|
||
(println (send-to object :some-method)) | ||
|
||
;; js-new | ||
(def Point | ||
(make-function | ||
(fn [x y] | ||
(assoc this | ||
:x x, :y y, | ||
:get-x (make-function (fn [] (dot this :x))))))) | ||
(def point (js-new Point 1 2)) | ||
|
||
(println (send-to point :get-x)) | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
;;; For Exercise 1 | ||
;;; This function will be used to bootstrap the replacement | ||
;;; of Clojure functions with Javascript Functions: | ||
|
||
(def make-function | ||
(fn [fn-value & property-pairs] | ||
(merge {:__function__ fn-value} | ||
(apply hash-map property-pairs)))) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
;;; For Exercise 2 | ||
|
||
;;; This is a Function constructor that doesn't work. | ||
|
||
(def Function | ||
(fn [fn-value & property-pairs] | ||
(merge this | ||
{:__function__ fn-value} | ||
(apply hash-map property-pairs)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
(ns solutions.ts-javascript | ||
(:use midje.sweet)) | ||
|
||
(load-file "solutions/javascript.clj") | ||
|
||
|
||
|
||
(fact "js-apply" | ||
(js-apply (make-function (fn [x] [this x])) | ||
{:an :object} | ||
[1]) => [{:an :object} 1]) | ||
|
||
|
||
(fact "js-call" | ||
(js-call (make-function (fn [x] [this x])) | ||
{:an :object} | ||
1) => [{:an :object} 1]) | ||
|
||
;; send-to | ||
(def object {:some-property 5, | ||
:some-method | ||
(make-function | ||
(fn [x] (+ x (dot this :some-property))))}) | ||
|
||
(fact (send-to object :some-method 3) => 8) | ||
|
||
;; plain-call | ||
(def ^:dynamic this {:some-property -3838383838 | ||
:value-returner | ||
(make-function | ||
(fn [] (dot this :some-property)))}) | ||
|
||
(def object {:value-returner | ||
(make-function | ||
(fn [] "SHOULD NOT BE CALLED")) | ||
:some-method | ||
(make-function | ||
(fn [] (plain-call :value-returner)))}) | ||
|
||
(fact (send-to object :some-method) => -3838383838) | ||
|
||
;; js-new | ||
(def Point | ||
(make-function | ||
(fn [x y] | ||
(assoc this | ||
:x x, :y y, | ||
:get-x (make-function (fn [] (dot this :x))))))) | ||
(def point (js-new Point 1 2)) | ||
|
||
(fact (send-to point :get-x) => 1) | ||
|
||
(load-file "sources/pieces/javascript-3.clj") | ||
|
||
(fact "make-function" | ||
(make-function identity) => {:__function__ identity } | ||
(make-function identity :key :value) => {:__function__ identity, :key :value}) | ||
|
||
(load-file "sources/pieces/javascript-4.clj") | ||
|
||
|
||
(def this {}) | ||
(fact "Function constructor" | ||
(Function identity :key :value) => (make-function identity :key :value)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
(ns sources.t-javascript | ||
(:use midje.sweet)) | ||
|
||
(load-file "sources/pieces/javascript-1.clj") | ||
(load-file "sources/pieces/javascript-2.clj") | ||
|
||
(fact "js-apply" | ||
(js-apply (make-function (fn [x] [this x])) | ||
{:an :object} | ||
[1]) => [{:an :object} 1]) | ||
|
||
|
||
(fact "js-call" | ||
(js-call (make-function (fn [x] [this x])) | ||
{:an :object} | ||
1) => [{:an :object} 1]) | ||
|
||
;; send-to | ||
(def object {:some-property 5, | ||
:some-method | ||
(make-function | ||
(fn [x] (+ x (dot this :some-property))))}) | ||
|
||
(fact (send-to object :some-method 3) => 8) | ||
|
||
;; plain-call | ||
(def ^:dynamic this {:some-property -3838383838 | ||
:value-returner | ||
(make-function | ||
(fn [] (dot this :some-property)))}) | ||
|
||
(def object {:value-returner | ||
(make-function | ||
(fn [] "SHOULD NOT BE CALLED")) | ||
:some-method | ||
(make-function | ||
(fn [] (plain-call :value-returner)))}) | ||
|
||
(fact (send-to object :some-method) => -3838383838) | ||
|
||
;; js-new | ||
(def Point | ||
(make-function | ||
(fn [x y] | ||
(assoc this | ||
:x x, :y y, | ||
:get-x (make-function (fn [] (dot this :x))))))) | ||
(def point (js-new Point 1 2)) | ||
|
||
(fact (send-to point :get-x) => 1) | ||
|
||
(load-file "sources/pieces/javascript-3.clj") | ||
|
||
(fact "make-function" | ||
(make-function identity) => {:__function__ identity } | ||
(make-function identity :key :value) => {:__function__ identity, :key :value}) | ||
|
||
(load-file "sources/pieces/javascript-4.clj") | ||
|
||
|
||
(def this {}) | ||
(fact "Function constructor" | ||
(Function identity :key :value) => (make-function identity :key :value)) |