clementine 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +4 -2
  3. data/LICENSE.txt +22 -0
  4. data/README.md +11 -6
  5. data/Rakefile +22 -0
  6. data/clementine.gemspec +2 -1
  7. data/ext/clojure-clojurescript-bef56a7/.gitignore +13 -0
  8. data/ext/clojure-clojurescript-bef56a7/Clojurescript.iml +12 -0
  9. data/ext/clojure-clojurescript-bef56a7/README.md +29 -0
  10. data/ext/clojure-clojurescript-bef56a7/benchmark/cljs/benchmark_runner.cljs +155 -0
  11. data/ext/clojure-clojurescript-bef56a7/bin/cljsc +21 -0
  12. data/ext/clojure-clojurescript-bef56a7/bin/cljsc.bat +18 -0
  13. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/bin/cljsc.clj +0 -0
  14. data/ext/clojure-clojurescript-bef56a7/devnotes/README.org +35 -0
  15. data/ext/clojure-clojurescript-bef56a7/devnotes/bcrepl.org +13 -0
  16. data/ext/clojure-clojurescript-bef56a7/devnotes/cljs.org +500 -0
  17. data/ext/clojure-clojurescript-bef56a7/devnotes/corelib.org +583 -0
  18. data/ext/clojure-clojurescript-bef56a7/devnotes/day1.org +203 -0
  19. data/ext/clojure-clojurescript-bef56a7/devnotes/day2.org +44 -0
  20. data/ext/clojure-clojurescript-bef56a7/devnotes/talk.org +126 -0
  21. data/ext/clojure-clojurescript-bef56a7/devnotes/testing +13 -0
  22. data/ext/clojure-clojurescript-bef56a7/devnotes/todo.org +121 -0
  23. data/ext/clojure-clojurescript-bef56a7/epl-v10.html +261 -0
  24. data/ext/clojure-clojurescript-bef56a7/pom.template.xml +88 -0
  25. data/ext/clojure-clojurescript-bef56a7/samples/dom/.gitignore +2 -0
  26. data/ext/clojure-clojurescript-bef56a7/samples/dom/src/dom/test.cljs +48 -0
  27. data/ext/clojure-clojurescript-bef56a7/samples/dom/test.html +30 -0
  28. data/ext/clojure-clojurescript-bef56a7/samples/hello-js/.gitignore +2 -0
  29. data/ext/clojure-clojurescript-bef56a7/samples/hello-js/README.md +53 -0
  30. data/ext/clojure-clojurescript-bef56a7/samples/hello-js/externed-lib.js +7 -0
  31. data/ext/clojure-clojurescript-bef56a7/samples/hello-js/externs.js +3 -0
  32. data/ext/clojure-clojurescript-bef56a7/samples/hello-js/hello-extern.html +14 -0
  33. data/ext/clojure-clojurescript-bef56a7/samples/hello-js/hello-js-dev.html +18 -0
  34. data/ext/clojure-clojurescript-bef56a7/samples/hello-js/hello-js.html +17 -0
  35. data/ext/clojure-clojurescript-bef56a7/samples/hello-js/my-external-lib.js +3 -0
  36. data/ext/clojure-clojurescript-bef56a7/samples/hello-js/src/hello-js/core.cljs +9 -0
  37. data/ext/clojure-clojurescript-bef56a7/samples/hello-js/src/hello-js/extern-example.cljs +5 -0
  38. data/ext/clojure-clojurescript-bef56a7/samples/hello/.gitignore +2 -0
  39. data/ext/clojure-clojurescript-bef56a7/samples/hello/README.md +34 -0
  40. data/ext/clojure-clojurescript-bef56a7/samples/hello/hello-dev.html +18 -0
  41. data/ext/clojure-clojurescript-bef56a7/samples/hello/hello.html +13 -0
  42. data/ext/clojure-clojurescript-bef56a7/samples/hello/src/hello/core.cljs +8 -0
  43. data/ext/clojure-clojurescript-bef56a7/samples/hello/src/hello/foo/bar.cljs +4 -0
  44. data/ext/clojure-clojurescript-bef56a7/samples/nodehello.cljs +18 -0
  45. data/ext/clojure-clojurescript-bef56a7/samples/nodels.cljs +17 -0
  46. data/ext/clojure-clojurescript-bef56a7/samples/repl/.gitignore +2 -0
  47. data/ext/clojure-clojurescript-bef56a7/samples/repl/README.md +101 -0
  48. data/ext/clojure-clojurescript-bef56a7/samples/repl/index.html +27 -0
  49. data/ext/clojure-clojurescript-bef56a7/samples/repl/src/repl/test.cljs +73 -0
  50. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/.gitignore +2 -0
  51. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/README.md +42 -0
  52. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/index-advanced.html +80 -0
  53. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/index.html +88 -0
  54. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/reset.css +48 -0
  55. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/src/twitterbuzz/anneal.cljs +66 -0
  56. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/src/twitterbuzz/core.cljs +307 -0
  57. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/src/twitterbuzz/dom-helpers.cljs +95 -0
  58. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/src/twitterbuzz/layout.cljs +100 -0
  59. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/src/twitterbuzz/leaderboard.cljs +40 -0
  60. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/src/twitterbuzz/radial.cljs +91 -0
  61. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/src/twitterbuzz/showgraph.cljs +121 -0
  62. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/src/twitterbuzz/timeline.cljs +39 -0
  63. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/style.css +301 -0
  64. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/test_data.txt +1 -0
  65. data/ext/clojure-clojurescript-bef56a7/samples/twitterbuzz/tweet_maps.txt +1 -0
  66. data/ext/clojure-clojurescript-bef56a7/script/benchmark +30 -0
  67. data/ext/clojure-clojurescript-bef56a7/script/bootstrap +70 -0
  68. data/ext/clojure-clojurescript-bef56a7/script/browser-repl +16 -0
  69. data/ext/clojure-clojurescript-bef56a7/script/build +59 -0
  70. data/ext/clojure-clojurescript-bef56a7/script/clean +5 -0
  71. data/ext/clojure-clojurescript-bef56a7/script/closure-library-release/google-closure-library-third-party.pom.template +59 -0
  72. data/ext/clojure-clojurescript-bef56a7/script/closure-library-release/google-closure-library.pom.template +54 -0
  73. data/ext/clojure-clojurescript-bef56a7/script/closure-library-release/make-closure-library-jars.sh +87 -0
  74. data/ext/clojure-clojurescript-bef56a7/script/compile +41 -0
  75. data/ext/clojure-clojurescript-bef56a7/script/repl +13 -0
  76. data/ext/clojure-clojurescript-bef56a7/script/repl.bat +13 -0
  77. data/ext/clojure-clojurescript-bef56a7/script/repljs +15 -0
  78. data/ext/clojure-clojurescript-bef56a7/script/repljs.bat +14 -0
  79. data/ext/clojure-clojurescript-bef56a7/script/test +38 -0
  80. data/ext/clojure-clojurescript-bef56a7/script/test-compile +30 -0
  81. data/ext/clojure-clojurescript-bef56a7/src/clj/cljs/analyzer.clj +975 -0
  82. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/clj/cljs/closure.clj +173 -73
  83. data/ext/clojure-clojurescript-bef56a7/src/clj/cljs/compiler.clj +1081 -0
  84. data/ext/clojure-clojurescript-bef56a7/src/clj/cljs/core.clj +1158 -0
  85. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/clj/cljs/repl.clj +51 -25
  86. data/ext/clojure-clojurescript-bef56a7/src/clj/cljs/repl/browser.clj +258 -0
  87. data/ext/clojure-clojurescript-bef56a7/src/clj/cljs/repl/reflect.clj +75 -0
  88. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/clj/cljs/repl/rhino.clj +6 -5
  89. data/ext/clojure-clojurescript-bef56a7/src/clj/cljs/repl/server.clj +173 -0
  90. data/ext/clojure-clojurescript-bef56a7/src/clj/cljs/tagged_literals.clj +30 -0
  91. data/ext/clojure-clojurescript-bef56a7/src/cljs/cljs/core.cljs +7197 -0
  92. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/cljs/cljs/nodejs.cljs +1 -1
  93. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/cljs/cljs/nodejs_externs.js +0 -0
  94. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/cljs/cljs/nodejscli.cljs +1 -1
  95. data/ext/clojure-clojurescript-bef56a7/src/cljs/cljs/reader.cljs +551 -0
  96. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/cljs/clojure/browser/dom.cljs +59 -13
  97. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/cljs/clojure/browser/event.cljs +0 -0
  98. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/cljs/clojure/browser/net.cljs +8 -7
  99. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/cljs/clojure/browser/repl.cljs +2 -2
  100. data/ext/clojure-clojurescript-bef56a7/src/cljs/clojure/core/reducers.cljs +298 -0
  101. data/ext/clojure-clojurescript-bef56a7/src/cljs/clojure/data.cljs +162 -0
  102. data/ext/clojure-clojurescript-bef56a7/src/cljs/clojure/reflect.cljs +48 -0
  103. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/cljs/clojure/set.cljs +0 -0
  104. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/cljs/clojure/string.cljs +4 -10
  105. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/cljs/clojure/walk.cljs +0 -0
  106. data/{vendor/assets → ext/clojure-clojurescript-bef56a7}/src/cljs/clojure/zip.cljs +0 -0
  107. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/binding_test.cljs +7 -0
  108. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/binding_test_other_ns.cljs +3 -0
  109. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/core_test.cljs +1678 -0
  110. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/import_test.cljs +11 -0
  111. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/import_test/foo.cljs +5 -0
  112. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/letfn_test.cljs +19 -0
  113. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/macro_test.cljs +6 -0
  114. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/macro_test/macros.clj +5 -0
  115. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/ns_test.cljs +14 -0
  116. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/ns_test/bar.cljs +3 -0
  117. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/ns_test/foo.cljs +7 -0
  118. data/ext/clojure-clojurescript-bef56a7/test/cljs/cljs/reader_test.cljs +124 -0
  119. data/ext/clojure-clojurescript-bef56a7/test/cljs/clojure/data_test.cljs +22 -0
  120. data/ext/clojure-clojurescript-bef56a7/test/cljs/clojure/string_test.cljs +97 -0
  121. data/ext/clojure-clojurescript-bef56a7/test/cljs/foo/ns_shadow_test.cljs +9 -0
  122. data/ext/clojure-clojurescript-bef56a7/test/cljs/test_runner.cljs +26 -0
  123. data/lib/clementine.rb +3 -24
  124. data/lib/clementine/clojurescript_engine.rb +9 -48
  125. data/lib/clementine/clojurescript_engine/base.rb +15 -0
  126. data/lib/clementine/clojurescript_engine/jruby.rb +46 -0
  127. data/lib/clementine/{clojurescript_engine_mri.rb → clojurescript_engine/mri.rb} +17 -10
  128. data/lib/clementine/version.rb +1 -1
  129. data/test/clojurescript_engine_test.rb +36 -14
  130. metadata +177 -83
  131. data/vendor/assets/lib/clojure.jar +0 -0
  132. data/vendor/assets/lib/compiler.jar +0 -0
  133. data/vendor/assets/lib/goog.jar +0 -0
  134. data/vendor/assets/lib/js.jar +0 -0
  135. data/vendor/assets/src/clj/cljs/compiler.clj +0 -1341
  136. data/vendor/assets/src/clj/cljs/core.clj +0 -702
  137. data/vendor/assets/src/clj/cljs/repl/browser.clj +0 -341
  138. data/vendor/assets/src/cljs/cljs/core.cljs +0 -3330
  139. data/vendor/assets/src/cljs/cljs/reader.cljs +0 -360
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ Gemfile.lock
5
5
  pkg/*
6
6
  out/*
7
7
  tmp/*
8
+ lib/*.jar
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
+ # encoding: utf-8
2
+
1
3
  source "http://rubygems.org"
2
4
 
3
- # Specify your gem's dependencies in clementine.gemspec
4
- gemspec
5
+ gem 'tilt'
6
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2011 - 2012 Yoko Harada
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -19,13 +19,8 @@ Clementine supports JRuby and CRuby. When you use from CRuby, make sure java com
19
19
  Installation
20
20
  -----------
21
21
 
22
- Clone https://github.com/yokolet/clementine, then
23
- edit your Gemfile with specific path to Clemetine.
24
-
25
- For example:
26
-
27
22
  ```ruby
28
- gem 'clementine', :path => "/Users/yoko/Projects/clementine"
23
+ gem install clementine
29
24
  ```
30
25
 
31
26
  Configuration
@@ -50,3 +45,13 @@ Available options:
50
45
  :output_dir directory name (:output_dir will be converted to ":output-dir")
51
46
  :output_to file name (:output_to will be converted to ":output-to")
52
47
  ```
48
+
49
+ Copyright and License
50
+ -----------
51
+ Clementine is Copyright (c) 2011-2012 [Yoko Harada](https://github.com/yokolet) and
52
+ distributed under the MIT license.
53
+
54
+ Clojure and ClojureSript are Copyright (c) Rich Hickey and covered by the Eclipse
55
+ Public License 1.0 [http://opensource.org/licenses/eclipse-1.0.php](http://opensource.org/licenses/eclipse-1.0.php)
56
+
57
+ Google Closure Compiler and Library are covered by Apache License 2.0 license.
data/Rakefile CHANGED
@@ -1 +1,23 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ task :default => :bootstrap
5
+
6
+ task :bootstrap do
7
+ # clojurescript home
8
+ CLOJURESCRIPT_HOME = File.join(File.dirname(__FILE__), "ext/clojure-clojurescript-bef56a7")
9
+
10
+ $stdout.print "Bootrapping ClojureScript"
11
+
12
+ # command to download and create jar archives
13
+ cmd = "#{CLOJURESCRIPT_HOME}/script/bootstrap"
14
+ %x( #{cmd} )
15
+
16
+ # removes unnecessary temporary directory to create google closure jar archives
17
+ require 'fileutils'
18
+ FileUtils.rm_rf File.join(File.dirname(__FILE__), './closure')
19
+ end
20
+
21
+ Rake::TestTask.new do |t|
22
+ t.pattern = "test/*_test.rb"
23
+ end
data/clementine.gemspec CHANGED
@@ -11,7 +11,8 @@ Gem::Specification.new do |s|
11
11
  s.summary = %q{clojurescript tilt template gem}
12
12
  s.description = %q{clojurescript tilt template gem and available to use on Rails asset pipeline.}
13
13
 
14
- s.files = `git ls-files`.split("\n")
14
+ s.files = `git ls-files`.split($/)
15
+ s.extensions = ['Rakefile']
15
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
18
  s.require_paths = ["lib"]
@@ -0,0 +1,13 @@
1
+ *~
2
+ .idea
3
+ /.DS_Store
4
+ /classes
5
+ /lib
6
+ closure
7
+ /core.js
8
+ /coreadvanced.js
9
+ /coresimple.js
10
+ /out
11
+ .repl
12
+ *.swp
13
+ *.zip
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="JAVA_MODULE" version="4">
3
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
4
+ <exclude-output />
5
+ <content url="file://$MODULE_DIR$">
6
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
7
+ </content>
8
+ <orderEntry type="inheritedJdk" />
9
+ <orderEntry type="sourceFolder" forTests="false" />
10
+ </component>
11
+ </module>
12
+
@@ -0,0 +1,29 @@
1
+ ## What is ClojureScript? ##
2
+
3
+ ClojureScript is a new compiler for [Clojure](http://clojure.org) that targets JavaScript. It is designed to emit JavaScript code which is compatible with the advanced compilation mode of the [Google Closure](http://code.google.com/closure/) optimizing compiler.
4
+
5
+ ## Getting Started ##
6
+
7
+ * [Compare with JavaScript](http://himera.herokuapp.com/synonym.html)
8
+ * [Try it online](http://himera.herokuapp.com/index.html)
9
+ * Read the [Quick Start](https://github.com/clojure/clojurescript/wiki/Quick-Start) guide.
10
+ * Read the [Documentation](https://github.com/clojure/clojurescript/wiki).
11
+ * Look at the [Sample Applications](https://github.com/clojure/clojurescript/tree/master/samples).
12
+
13
+ ## Questions, Feedback? ##
14
+
15
+ Please point all of your questions and feedback [here](http://groups.google.com/group/clojure).
16
+
17
+ ## Developers Welcome ##
18
+
19
+ ClojureScript operates under the same license as Clojure. All contributors must have a signed CA (Contributor's Agreement) and submit their patch via the appropriate channels. If you're interested in contributing to the project, please see the [contributing](http://clojure.org/contributing) page on [clojure.org](http://clojure.org).
20
+
21
+ ## License ##
22
+
23
+ Copyright (c) Rich Hickey. All rights reserved. The use and
24
+ distribution terms for this software are covered by the Eclipse
25
+ Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
26
+ which can be found in the file epl-v10.html at the root of this
27
+ distribution. By using this software in any fashion, you are
28
+ agreeing to be bound by the terms of this license. You must
29
+ not remove this notice, or any other, from this software.
@@ -0,0 +1,155 @@
1
+ (ns cljs.benchmark-runner
2
+ (:refer-clojure :exclude [println])
3
+ (:require [cljs.reader :as reader]))
4
+
5
+ (def println print)
6
+
7
+ (set! *print-fn* js/print)
8
+
9
+ (simple-benchmark [x 1] (identity x) 1000000)
10
+
11
+ (println ";; array-reduce & ci-reduce")
12
+ (def arr (let [arr (array)]
13
+ (dotimes [i 1000000]
14
+ (.push arr i))
15
+ arr))
16
+ (defn sum [a b] (+ a b))
17
+ (simple-benchmark [coll (seq arr)] (ci-reduce coll + 0) 1)
18
+ (simple-benchmark [coll (seq arr)] (ci-reduce coll sum 0) 1)
19
+ (simple-benchmark [coll arr] (array-reduce coll + 0) 1)
20
+ (simple-benchmark [coll arr] (array-reduce coll sum 0) 1)
21
+
22
+ (println ";;; instance?")
23
+ ;; WARNING: will get compiled away under advanced
24
+ (simple-benchmark [coll []] (instance? PersistentVector coll) 1000000)
25
+ (println ";;; satisfies?")
26
+ (simple-benchmark [coll (list 1 2 3)] (satisfies? ISeq coll) 1000000)
27
+ (simple-benchmark [coll [1 2 3]] (satisfies? ISeq coll) 1000000)
28
+ (println)
29
+
30
+ (println ";;; list ops")
31
+ (simple-benchmark [coll (list 1 2 3)] (first coll) 1000000)
32
+ (simple-benchmark [coll (list 1 2 3)] (-first coll) 1000000)
33
+ (simple-benchmark [coll (list 1 2 3)] (rest coll) 1000000)
34
+ (simple-benchmark [coll (list 1 2 3)] (-rest coll) 1000000)
35
+ (simple-benchmark [] (list) 1000000)
36
+ (simple-benchmark [] (list 1 2 3) 1000000)
37
+ (println)
38
+
39
+ (println ";;; vector ops")
40
+ (simple-benchmark [] [] 1000000)
41
+ (simple-benchmark [] [1 2 3] 1000000)
42
+ (simple-benchmark [coll [1 2 3]] (transient coll) 100000)
43
+ (simple-benchmark [coll [1 2 3]] (nth coll 0) 1000000)
44
+ (simple-benchmark [coll [1 2 3]] (-nth coll 0) 1000000)
45
+ (simple-benchmark [coll [1 2 3]] (conj coll 4) 1000000)
46
+ (simple-benchmark [coll [1 2 3]] (-conj coll 4) 1000000)
47
+ (simple-benchmark [coll [1 2 3]] (seq coll) 1000000)
48
+ (simple-benchmark [coll (seq [1 2 3])] (first coll) 1000000)
49
+ (simple-benchmark [coll (seq [1 2 3])] (-first coll) 1000000)
50
+ (simple-benchmark [coll (seq [1 2 3])] (rest coll) 1000000)
51
+ (simple-benchmark [coll (seq [1 2 3])] (-rest coll) 1000000)
52
+ (simple-benchmark [coll (seq [1 2 3])] (next coll) 1000000)
53
+ (println)
54
+
55
+ (println ";;; large vector ops")
56
+ (simple-benchmark [] (reduce conj [] (range 40000)) 10)
57
+ (simple-benchmark [coll (reduce conj [] (range (+ 32768 32)))] (conj coll :foo) 100000)
58
+ (simple-benchmark [coll (reduce conj [] (range 40000))] (assoc coll 123 :foo) 100000)
59
+ (simple-benchmark [coll (reduce conj [] (range (+ 32768 33)))] (pop coll) 100000)
60
+ (println)
61
+
62
+ (println ";;; transients")
63
+ (print "transient vector, conj! 1000000 items")
64
+ (time
65
+ (let [v (transient [])]
66
+ (loop [i 0 v v]
67
+ (if (> i 1000000)
68
+ (persistent! v)
69
+ (recur (inc i) (conj! v i))))))
70
+
71
+ (println ";;; reduce lazy-seqs, vectors, ranges")
72
+ (simple-benchmark [coll (take 100000 (iterate inc 0))] (reduce + 0 coll) 1)
73
+ (simple-benchmark [coll (range 1000000)] (reduce + 0 coll) 1)
74
+ (simple-benchmark [coll (into [] (range 1000000))] (reduce + 0 coll) 1)
75
+ (println)
76
+
77
+ (println ";; apply")
78
+ (simple-benchmark [coll (into [] (range 1000000))] (apply + coll) 1)
79
+ (println)
80
+
81
+ (println ";;; map / record ops")
82
+ (simple-benchmark [coll {:foo 1 :bar 2}] (get coll :foo) 1000000)
83
+ (simple-benchmark [coll {:foo 1 :bar 2}] (-lookup coll :foo nil) 1000000)
84
+ (simple-benchmark [coll {:foo 1 :bar 2}] (:foo coll) 1000000)
85
+ (defrecord Foo [bar baz])
86
+ (simple-benchmark [coll (Foo. 1 2)] (:bar coll) 1000000)
87
+ (simple-benchmark [coll {:foo 1 :bar 2}] (assoc coll :baz 3) 100000)
88
+ (simple-benchmark [coll {:foo 1 :bar 2}] (assoc coll :foo 2) 100000)
89
+ (simple-benchmark [coll {:foo 1 :bar 2}]
90
+ (loop [i 0 m coll]
91
+ (if (< i 100000)
92
+ (recur (inc i) (assoc m :foo 2))
93
+ m))
94
+ 1)
95
+ (println ";;; persistent hash maps")
96
+ (def pmap (into cljs.core.PersistentHashMap/EMPTY
97
+ [[:a 0] [:b 1] [:c 2] [:d 3] [:e 4] [:f 5] [:g 6] [:h 7]
98
+ [:i 8] [:j 9] [:k 10] [:l 11] [:m 12] [:n 13] [:o 14] [:p 15]
99
+ [:q 16] [:r 17] [:s 18] [:t 19] [:u 20] [:v 21] [:w 22] [:x 23]
100
+ [:y 24] [:z 25] [:a0 26] [:b0 27] [:c0 28] [:d0 29] [:e0 30] [:f0 31]]))
101
+ (simple-benchmark [key :f0] (hash key) 1000000)
102
+ (simple-benchmark [key :unsynchronized-mutable] (hash key false) 1000000)
103
+ (simple-benchmark [key :unsynchronized-mutable] (hash key) 1000000)
104
+ (def hash-coll-test
105
+ (loop [i 0 r []]
106
+ (if (< i 1000)
107
+ (recur (inc i) (conj r (str "foo" i)))
108
+ r)))
109
+ (simple-benchmark [coll hash-coll-test] (hash-coll coll) 100)
110
+ (simple-benchmark [coll pmap] (:f0 coll) 1000000)
111
+ (simple-benchmark [coll pmap] (get coll :f0) 1000000)
112
+ (simple-benchmark [coll pmap] (-lookup coll :f0 nil) 1000000)
113
+ (simple-benchmark [coll pmap] (assoc coll :g0 32) 1000000)
114
+ (simple-benchmark [coll pmap]
115
+ (loop [i 0 m coll]
116
+ (if (< i 1000000)
117
+ (recur (inc i) (assoc m :a 1))
118
+ m))
119
+ 1)
120
+ (simple-benchmark [coll cljs.core.PersistentHashMap/EMPTY] (assoc coll :f0 1) 1000000)
121
+ (println)
122
+
123
+ (println ";;; set ops")
124
+ (simple-benchmark [] #{} 100000)
125
+ (simple-benchmark [] #{1 2 3} 100000)
126
+ (simple-benchmark [coll #{1 2 3}] (conj coll 4) 100000)
127
+ (println)
128
+
129
+ (println ";;; seq ops")
130
+ (simple-benchmark [coll (range 500000)] (reduce + coll) 1)
131
+ (println)
132
+
133
+ (println ";;; reader")
134
+ (simple-benchmark [s "{:foo [1 2 3]}"] (reader/read-string s) 1000)
135
+ (println)
136
+
137
+ (println ";;; range")
138
+ (simple-benchmark [r (range 1000000)] (last r) 1)
139
+ (println)
140
+
141
+ (defn ints-seq
142
+ ([n] (ints-seq 0 n))
143
+ ([i n]
144
+ (when (< i n)
145
+ (lazy-seq
146
+ (cons i (ints-seq (inc i) n))))))
147
+ (def r (ints-seq 1000000))
148
+ (println ";;; lazy-seq")
149
+ (println ";;; first run")
150
+ (simple-benchmark [r r] (last r) 1)
151
+ (println ";;; second run")
152
+ (simple-benchmark [r r] (last r) 1)
153
+ (println)
154
+
155
+ (println "\n")
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+
3
+ # Compile a single cljs file or a directory of cljs files into a
4
+ # single JavaScript file.
5
+
6
+ if [ "$CLOJURESCRIPT_HOME" = "" ]; then
7
+ CLOJURESCRIPT_HOME="`dirname $0`/.."
8
+ fi
9
+
10
+ CLJSC_CP=''
11
+ for next in lib/*: src/clj: src/cljs: test/cljs; do
12
+ CLJSC_CP="${CLJSC_CP}${CLOJURESCRIPT_HOME}/${next}"
13
+ done
14
+
15
+ if test "$#" -eq 0
16
+ then
17
+ echo 'Usage: cljsc <file-or-dir>'
18
+ echo ' cljsc <file-or-dir> "{:optimizations :advanced}"'
19
+ else
20
+ java -server -cp "$CLJSC_CP" clojure.main "$CLOJURESCRIPT_HOME/bin/cljsc.clj" "$@"
21
+ fi
@@ -0,0 +1,18 @@
1
+
2
+ @echo off
3
+ setLocal EnableDelayedExpansion
4
+
5
+ if "%CLOJURESCRIPT_HOME%" == "" set CLOJURESCRIPT_HOME=%~dp0..\
6
+
7
+ set CLASSPATH=%CLOJURESCRIPT_HOME%src\clj;%CLOJURESCRIPT_HOME%src\cljs"
8
+ for /R "%CLOJURESCRIPT_HOME%\lib" %%a in (*.jar) do (
9
+ set CLASSPATH=!CLASSPATH!;%%a
10
+ )
11
+ set CLASSPATH=!CLASSPATH!"
12
+
13
+ if (%1) == () (
14
+ echo Usage: "cljsc <file-or-dir> > out.js"
15
+ echo "cljsc <file-or-dir> {:optimiztions :advanced} > out.js"
16
+ ) else (
17
+ java -server -cp "%CLASSPATH%" clojure.main "%CLOJURESCRIPT_HOME%\bin\cljsc.clj" %*
18
+ )
@@ -0,0 +1,35 @@
1
+ * ClojureScript
2
+ - What: Clojure running on Javascript VMs
3
+ - Why: Clojure rocks, Javascript reaches
4
+ - When: Now! - a compiler exists, we need libraries and tool integration. Full day sessions 6/10 and 6/17
5
+ - Where: In stealth mode 'here' at Clojure/core
6
+ - How: ClojureScript -> ClojureScript-Compiler -> Javascript -> [Google-Closure-JS->JS-Compiler -> Optimized-Javascript] ->Browser/V8/Node/PhoneGap...
7
+ - Who: You, if you're interested in:
8
+ - How hand-written recursive descent compilers work (the ClojureScript compiler is about 1/6 the code of the CoffeeScript compiler)
9
+ - Writing libraries using Clojure's latest type and polymorphism tools
10
+ - How Clojure works - its data structures and abstractions
11
+ - Extending the reach of Clojure
12
+ - Google's industrial-strength JS tools
13
+ - Investigating how powerful code-emitting tools can change the face
14
+ of web and mobile development...
15
+ * Getting Started
16
+ - Clone the repo
17
+ - cd clojurescript
18
+ - run script/bootstrap
19
+ - copy clojure.jar into /lib
20
+ - script/repl will start a properly-classpathed repl
21
+ * Starting the clojurescript repl
22
+ - (require '[cljs.compiler :as comp])
23
+ - (def jse (comp/repl-env))
24
+ - (comp/repl jse)
25
+ * Reading list
26
+ - If you are interested in participating, please read:
27
+ - [[http://www.amazon.com/Closure-Definitive-Guide-Michael-Bolin/dp/1449381871][Closure-Definitive-Guide-Michael-Bolin]]
28
+ - and maybe:
29
+ - [[http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742][JavaScript-Good-Parts-Douglas-Crockford]]
30
+ - [[http://www.amazon.com/Performance-JavaScript-Faster-Application-Interfaces/dp/059680279X][Performance-JavaScript-Faster-Application-Interfaces]]
31
+ - [[http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752][JavaScript-Patterns-Stoyan-Stefanov]]
32
+ - Those looking to cram tonight can get the O'Reilly Closure book on kindle above or ebook directly:
33
+ - [[http://oreilly.com/catalog/0636920001416/]]
34
+ * More info
35
+ [[https://github.com/relevance/clojurescript/wiki][Check the Wiki]]
@@ -0,0 +1,13 @@
1
+ * ClojureScript browser connected REPL
2
+ ** send cljs compiler output to the browser to be evaluated
3
+ ** send results back to the command line process to be printed
4
+ ** side effects happen in the browser
5
+ ** abstract communication away using goog library
6
+ *** Goog abstraction for websockets? Ideal!
7
+ *** Polling? It will work everywhere.
8
+ *** Ideally an abstraction over both that prefers websockets but doesn't fail and doesn't complain loudly.
9
+ ** evaluation daemon for the browser
10
+ ** launch browser
11
+ ** transparent update of bound symbols? We should test.
12
+ ** brepl has its own solution for deps, we'd like to tie into the ClojureScript dependency story
13
+ ** require mechanisms are out; the source that forms the repl's environment will need to be updated and the page reloaded
@@ -0,0 +1,500 @@
1
+ * ClojureScript
2
+ * Rationale
3
+ ** What
4
+ *** Compiler that compiles (a subset of?) Clojure to Javascript
5
+ ** Why?
6
+ *** Because js is the only universally available client target
7
+ **** and can't be supplanted due to its browser integration and installed base
8
+ **** yet isn't very good, expressive, concise, or robust
9
+ **** but JS engines continue to get lots of optimization love, and are now quite capable perf-wise
10
+ *** Use same skillset and libs for client and server
11
+ **** only other similar options are:
12
+ ***** JS native client, JS (e.g. node) server
13
+ ****** node still much less powerful than JVM, and might be a mere fad
14
+ ***** Java (GWT) client, Java native server
15
+ ****** GWT has lots of baggage due to semantic mismatches etc
16
+ ****** but familiar tooling if already a Java dev
17
+ ***** esoteric, open question as to skills and libs:
18
+ ****** [[http://clamato.net/][Clamato Smalltalk]]
19
+ ****** [[http://www.wescheme.org/][Moby Scheme]]
20
+ *** Clojure semantics can fit well on JS
21
+ **** i.e. defn/type/protocol won't fight with js core model
22
+ *** ClojureJS arguably becomes most powerful lang on client
23
+ **** Robust, simple Clojure model
24
+ **** Macros etc
25
+ *** Might be best way to run Clojure on mobile
26
+ *** js a possible path to delivering Clojure libs to C-linkage clients
27
+ **** via embedded Google V8 js engine
28
+ **** somewhat speculative, but considering for M
29
+ **** V8 wrappers exist for Python, Ruby, PHP etc
30
+ ** How?
31
+ *** Compiler written in Clojure, generates (readable?) JS
32
+ *** Optionally run that JS through Google Closure js->js compiler
33
+ **** for minification, dead code elimination etc
34
+ *** Use Google Closure js library where needed for implementation support
35
+ **** e.g. goog.math has Long arithmetic
36
+ **** module system
37
+ **** use gclosure annotations for stronger type checking or better code gen?
38
+ **** dependency system
39
+ *** Macros written in Clojure proper, run by the compiler
40
+ **** stick to subset in macros if eval supported
41
+ *** Any runtime support written completely in itself
42
+ **** make deftype and protocols work early
43
+ ** Non-objectives
44
+ *** complete Clojure
45
+ **** feel free to subset, especially at first
46
+ **** but try to make anything present in both work identically
47
+ *** compiling e.g. core.clj as-is
48
+ **** don't want to touch Clojure itself for this
49
+ **** bootstrap will differ anyway
50
+ ** Ancillary benefits
51
+ *** Analysis component of compiler might serve Clojure-in-Clojure, or other tooling
52
+ **** maybe - we'll need far less analysis support in js than we do in Java
53
+ *** Boost for Clojure adoption due to increased reach
54
+ *** Power tool for exploring next-gen client approach
55
+ * Implementation
56
+ ** Primitives
57
+ *** DONE def
58
+ *** fn*
59
+ **** DONE basics
60
+ **** DONE recur
61
+ **** DONE variable arity
62
+ **** DONE arity overloading
63
+ **** closures shouldn't map directly to js closures? - no, they should
64
+ ***** they capture entire surrounding environment
65
+ ****** hearsay, V8 already better
66
+ ***** premature optimization to avoid that? - yes
67
+ ***** shouldn't js engines do that for us? - yes
68
+ ***** try goog.partial? - not for this
69
+ **** variable arity how?
70
+ ***** switch on arguments.length
71
+ *** DONE if
72
+ **** need to match Clojure semantics (nil/false)
73
+ ***** must deal with undefined (group with nil/false?)
74
+ *** DONE let*
75
+ **** must fix local scoping problem
76
+ ***** nested fns or renaming?
77
+ **** let* semantics
78
+ *** DONE do
79
+ **** as with Java, not an expression
80
+ **** doFn(...) -> returns last arg
81
+ ***** must alloc array for arguments?
82
+ *** TODO global
83
+ **** use 'var for this?
84
+ ***** already Clojure special op
85
+ ***** but wrong semantics, (var x) is *ns*-relative
86
+ ***** no true unqualified globals in Clojure
87
+ *** DONE recur
88
+ **** to loop
89
+ **** to fn head
90
+ ***** can't do in single pass
91
+ *** DONE invoke
92
+ *** DONE macros
93
+ *** DONE ns
94
+ **** (ns my.ns (:require your.ns ...) (:macros a-clojure-ns ...))
95
+ ***** aliases?
96
+ **** =>
97
+ ***** make a clojure ns? cljs.my.ns?
98
+ ***** goog.provide('my.ns'); goog.require('your.ns');
99
+ ***** (
100
+ *** DONE deftype*
101
+ **** maps to prototype/contructor combo
102
+ **** deftype macro is deftype* + extend-type
103
+ ***** extend-type with ::fields meta on param vectors
104
+ *** TODO reify*
105
+ **** yes, for one-off protocol impls
106
+ **** no ctor created, just put impls on object
107
+ ***** can share code with putting impls on prototype?
108
+ *** DONE defprotocol*
109
+ **** not primitive in Clojure proper
110
+ **** extend, when given ctor, modifies prototype with slot
111
+ ***** slot is ns-qualified
112
+ ***** what about core prototypes - Object, Array et al (String, Number, Boolean, Function)?
113
+ ****** poor citizenship to modify these?
114
+ ****** Object different in that it is used as map
115
+ ****** nested window scope issues?
116
+ **** protocol fns just turn (my.ns/foo x a b c) into x["my.ns/foo"](a, b ,c)
117
+ ***** foo(x, a, b, c)
118
+ ****** must pass target
119
+ ***** better - x.my$ns$foo(a, b ,c)
120
+ ****** can be minified
121
+ *** DONE extend-type
122
+ *** defrecord?
123
+ **** any way to get (:foo x) => x.foo?
124
+ ***** beware GClojure renaming
125
+ *** DONE new
126
+ **** what to do? ordinary invoke works fine
127
+ ***** new could be aliased, not special form then
128
+ ***** not ordinary - first arg not evaluated
129
+ ****** but should be in JS since new is an operator on a function, not a name
130
+ **** new itself shouldn't be evaluated, won't pass fnOf
131
+ **** (my.ns.Blah. x y z) - just macroexpander stuff
132
+ **** (Blah. x y z) - requires import and registry
133
+ ***** class aliases a bigger issue, will there be more conflicts?
134
+ ***** any interpretation will fit only one ns strategy (e.g. gclosure's, and thus ClojureScript's)
135
+ ***** start without this
136
+ *** DONE dot
137
+ **** field/zero-arg-method distinguished how?
138
+ ***** not, just support scoped var and be done
139
+ *** DONE set! (assign)
140
+ **** same binding rules?
141
+ ***** no
142
+ **** or just allow assign to scoped 'vars'?
143
+ *** DONE name munging
144
+ **** special chars
145
+ **** js reserved words
146
+ *** DONE (js* code-string)
147
+ **** with name escaping
148
+ *** TODO exceptions
149
+ **** throw
150
+ **** try
151
+ **** catch
152
+ ***** won't have exception type
153
+ **** finally
154
+ *** quote?
155
+ *** TODO Evaluated collections
156
+ **** Map
157
+ **** Vector
158
+ *** vars?
159
+ *** case?
160
+ *** callable non-function types?
161
+ **** seems not possible portably
162
+ **** could do with __proto__ (non-standard, all but IE support, even IE9 doesn't)
163
+ **** how would Clojure feel without callable collections and keywords?
164
+ **** could do with conditional every invocation:
165
+ ***** (f instanceof Function?f:f.cljs_lang_invoke)(args)
166
+ ***** but where to put f (in expr context)?
167
+ ****** needs helper fn
168
+ ****** fnOf(f)(args)
169
+ ******* function fnOf(x){return (f instanceof Function?f:f.cljs_lang_invoke);}
170
+ ****** i.e. every call is 2 calls
171
+ ******* tracing jit will inline?
172
+ ** Translation
173
+ | Op | JS | Notes | Questions |
174
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
175
+ | (def x 42) | cljs.my.ns['x'] = 42 | Following gclosure module system | No vars? Compilation-time representation of ns? |
176
+ | | cljs.my.ns.x = 42 | only this one will get minified | but this precludes special chars in names |
177
+ | | | | def returns var in Clojure, no var here |
178
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
179
+ | (fn [x y] ...) | (function (x, y) {...}) | never do named function, use anon + def | Use for closures too? |
180
+ | (fn [x y] ... (recur...) | | rewrite as fn + nested loop | require analysis to transmit recur fact up |
181
+ | | | | rewrite when? |
182
+ | | | block always in return context | access to this for methods? |
183
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
184
+ | (if test then else) | (test ? then : else) | | |
185
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
186
+ | (do e1 e2 e3) | cljs.dofn(e1,e2,e3) | dofn returns last arg, allocs array? | requires js bootstrap file? |
187
+ | | | no, forces all to be exprs | no fn needed when not expr context |
188
+ | | (function () {e1;e2;return e3;})() | | |
189
+ | | | expr context becomes return except when | |
190
+ | | | single expr | |
191
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
192
+ | (let [x 1 y 2] ...) | (function [x,y] {...})(1, 2) | need to create nested functions for let* | how to detect ref to earlier? |
193
+ | | var x__42 = 1;var y__43 = 2; ... | var numbering | statement/expr dichotomy if inline? |
194
+ | | (function [] | could wrap in no-arg function always | needed for expr anyhow |
195
+ | | {var x = 1; var y = 2; ...})() | if always wrapped, don't need numbers? | can we do var x = 42; var x = 43? |
196
+ | | | might still when nested | yes, but not var x = 42 ...nesting... var x = x |
197
+ | | | | |
198
+ | | | expr always becomes return context | |
199
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
200
+ | (. x y) | x.y or x.y()? | no type info to distinguish | bigger problem, both calling and retrieving |
201
+ | | | | fn in slot are viable, Clojure says method wins |
202
+ | (. x y ...) | x.y(...) | | |
203
+ | | | | |
204
+ | (: x y) ? | x.y | | make all calls, add special field accessor |
205
+ | x.y | x.y | . not used for classes in JS | so not global, but scoped? |
206
+ | | | can't test from Clojure | but would want resolution of first segment to locals |
207
+ | | | | what do macros use? |
208
+ | | | | |
209
+ | (. x (y)) | already defined for this case | wasn't going to carry this into cljs, but | no arg == field, penalize no-arg methods? |
210
+ | ((. x y)) | more correct, it's a slot | | rationale, it's not a method, just a slot, |
211
+ | (-> (. x y) ()) | doesn't currently work, could | | but then why do the arg-taking ones work? |
212
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
213
+ | (set! (. x y) 42) | x.y = 42 | | whither vars and binding?? |
214
+ | (set! some.global.x 42) | some.global.x = 42 | | |
215
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
216
+ | (loop [bindings] | while(true){ | | wrap in function? depends on context |
217
+ | ... (recur)) | ... rebind-continue | | |
218
+ | | ret=xxx;break;} | | |
219
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
220
+ | (deftype Foo [a b c]) | my.ns.Foo = function(a,b,c) | turn inline defs into explicit extends? | deftype inline methods split out arities |
221
+ | | {this.a = a;...this.c=c;} | can't access this and fields. | |
222
+ | | | in locals map, bind a to this.a etc | |
223
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
224
+ | (new Foo 1 2 3) | (new Foo(1,2,3)) | | |
225
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
226
+ | (defprotocol P | my.ns.foo = function(obj args) | | How to extend built-ins, default, nil, undefined |
227
+ | (foo [args])) | {obj['my.ns.foo'](obj, args);} | can't minify | |
228
+ | | | | |
229
+ | | obj.my$ns$foo(obj, args) | | |
230
+ | | P.ns = 'my.ns' | this only compile-time need, but compiler | |
231
+ | | | not in js world, can't see it | |
232
+ | | | Require fully qualified protocol names? | |
233
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
234
+ | (extend Foo my.ns.P | for each fn in map: | if no reified protocols, extend can't be | or use Object.defineProperty to add method to |
235
+ | {:foo (fn [foo]...)} | Foo.prototype['my.ns.foo'] = fn | a function, unless protocol quoted | prototype? can then set enumerable to false |
236
+ | | Foo.prototype.my$ns$foo = fn | or string | |
237
+ | | | if extend is a macro or special, could | |
238
+ | | | still evaluate fn map, but then can't be | |
239
+ | | | minified | |
240
+ | | | evaluated extend requires maps, keywords | |
241
+ | | | high bar for bootstrap if protocols | |
242
+ | | | at bottom - extend* unevaluated? | |
243
+ | | | make extend-type primitive instead? YES | |
244
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
245
+ | constants | | | |
246
+ | nil | null | | |
247
+ | "foo", true, false, 42.0 | same | | |
248
+ | 42 | goog.Long? | | |
249
+ | 'foo | symbol ctor | | |
250
+ | :foo | ? | | how to do keyword interning? |
251
+ | | | | don't want intern every reference |
252
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
253
+ | (ns my.ns | | | |
254
+ | (:require [foo.bar :as fb]...) | | | |
255
+ | (:macros [my.macros :as mm]...)) | :require-macros? | | |
256
+ |----------------------------------+------------------------------------+-------------------------------------------+------------------------------------------------------|
257
+ ** Library
258
+ *** persistent data structures?
259
+ **** make base literals create JS base literals? (array, object-as-map)
260
+ ***** seems a big waste not to leverage js optimization of dynamic properties
261
+ ****** or, that's what deftype is about, maps have always added overhead
262
+ ***** we care more about accessors than assignment/modification
263
+ ****** i.e. we will superimpose copy-on-write
264
+ ***** string/keyword problem
265
+ ****** can make {:a 1 :b 2 :c 3} => {a: 1, b: 2, c: 3}
266
+ ****** but (keys that) => ["a" "b" "c"]
267
+ ****** could use internal array of keys trick
268
+ ******* keys used as strings in property map
269
+ ******* kept intact in internal arrays, which is what is returned by keys fn
270
+ ******* means keys must be string distinct - ick
271
+ **** promote only on conj?
272
+ ***** or on size as well?
273
+ ** Questions
274
+ *** equality and hashing
275
+ *** undefined
276
+ **** turn into nil?
277
+ **** can't catch everywhere
278
+ *** vars
279
+ **** def should create slots in global ns objects?
280
+ **** what var semantics matter?
281
+ *** keywords and symbols
282
+ **** make separate object types?
283
+ ***** not many symbols make it into runtime use, but keywords do
284
+ **** need to make sure {:key val} and (:key obj) are fast
285
+ **** native maps can have only string keys
286
+ *** metadata
287
+ **** just claim a slot?
288
+ *** namespaces
289
+ **** tie into gclosure module system?
290
+ **** compile-time enumerability?
291
+ *** eval
292
+ **** runtime compiler?
293
+ **** would let you develop in the browser, repl etc
294
+ **** means compiler must self-host
295
+ ***** and needs runtime reader
296
+ ***** and syntax-quote
297
+ **** no macros?
298
+ ***** can't do without, as so many basic things are macros
299
+ **** won't have google closure compiler there
300
+ ***** ok, shouldn't rely on that
301
+ *** laziness
302
+ **** not a great fit
303
+ **** GC probably not as good
304
+ **** unlikely to be working with bigger-than-memory
305
+ **** non-lazy mapping/filtering or mapv, filterv
306
+ ***** can make it back into Clojure
307
+ *** Immutability
308
+ **** enforced?
309
+ ***** or just use safe lib fns to avoid
310
+ ****** lets you use base types
311
+ ****** no final on which to base it anyway
312
+ ****** would need fancy encapsulation techniques
313
+ ******* how fancy?
314
+ ***** correct (non-assigning) code does the same thing, but incorrect not caught
315
+ ****** fair compromise?
316
+ **** gclosure compiler can do some enforcement
317
+ ***** given some const hints in comment-based annotations
318
+ *** Interactive development
319
+ **** REPL
320
+ ***** easiest:
321
+ ***** Clojure read -> cljs analyze -> cljs emits -> embedded Rhino eval+print
322
+ **** Incompatible constructs
323
+ ***** for host interop
324
+ ****** preclude development in Clojure
325
+ **** Missing JS things
326
+ ***** e.g. DOM etc
327
+ ***** headless JS environment with DOM mocks?
328
+ * Namespaces and macros
329
+ ** Macro problem?
330
+ *** syntax quote in the reader uses Clojure namespaces
331
+ *** hardwired to Compiler.currentNS().getMapping() Compiler.resolveSymbol(), isSpecial() etc
332
+ *** ::keyword resolution uses Compiler.currentNS(), namespaceFor()
333
+ *** if it expands to calls to other macros, those need to be in clojure-land
334
+ **** maybe - they need to be the cljs-compatible versions
335
+ ***** argument for calling core clojure.core in cljs too?
336
+ ****** but we can't have 2 clojure.core namespaces during compilation
337
+ ***** translate/consider clojure.core/xxx => cljs.core/xxx during cljs compilation?
338
+ ****** doesn't work if we have separate cljs.macros
339
+ ******* some core things will be in cljs.core, some in cljs.macros
340
+ ******* put core macros on cljs/core.clj
341
+ ******* other core code in cljs/core.cljs
342
+ ******* both contain ns declarations - ok?
343
+ *** but expansions destined for cljs compilation need to be resolved in cljs-land
344
+ **** dummy vars in dummy namespaces?
345
+ ***** no - doesn't cover external nses, cljs aliases
346
+ ***** just fully qualify everything non-core in macroexpansions
347
+ **** different specials set a problem
348
+ ***** e.g. global, ns, defprotocol* not specials
349
+ ****** could use var for global
350
+ ****** could make ns a special?
351
+ ******* probably not
352
+ ******* but what macro would emit that?
353
+ ***** install all cljs specials in dummy nses?
354
+ ****** no, doesn't help macros file
355
+ *** inline defmacro in cljs?
356
+ **** calls Clojure eval of defmacro call
357
+ **** can expand to calls to enclosing cljs ns
358
+ ***** but expander can't call code in enclosing cljs ns
359
+ ***** convention - all macro helper fns are local fns in macro
360
+ **** gets icky for load/require purposes, as must be loaded with cljs compiler
361
+ ***** better to keep public macros separate - can use ordinary Clojure require then
362
+ ***** local macros would be ok for same-file consumption though
363
+ **** convention - portable libs that expose macros package them separately
364
+ ** Want some equivalent of refer clojure.core
365
+ *** else practically everything will be qualified
366
+ **** e.g. core/defn - ick
367
+ *** but fewer things brought in by default?
368
+ **** requires selectivity control, or just a smaller core.cljs?
369
+ *** this is equivalent to a 'use', which we otherwise aren't supporting
370
+ **** unfair or don't care?
371
+ ** Any 'use' equivalent (e.g. refer core) means compile-time disambiguation of unqualified references
372
+ *** if names a referred thing, that thing, else current.ns.name
373
+ **** like current namespaces
374
+ **** but if refers are limited to (entirety of) core, just look there first
375
+ **** so double lookup instead of copying core vars into name table
376
+ ** Some core things defined in js
377
+ *** where we don't want to otherwise expose things needed for their impl
378
+ **** e.g. ==, ===, math ops, instanceOf typeof etc
379
+ *** how to reserve names?
380
+ **** declare in core.cljs?
381
+ *** if in actual .js file, separate ns for deps purposes?
382
+ **** i.e. it will be a different file than that produced by compiling core.cljs
383
+ **** or just a wad of js injected into core.cljs?
384
+ ***** include a (js code-string) primitive for this purpose?
385
+ ****** yes, much better than js files
386
+ ****** accept only at top level? - no
387
+ ****** using in local scope means knowing how locals are represented
388
+ ****** some sort of escaping construct for getting (local and other) names resolved
389
+ ******* ~{identifier}
390
+ ** Are we doing forward reference detection here?
391
+ *** requires listing of contents of current ns
392
+ **** like namespaces
393
+ ** Are we doing extern-ns name validation?
394
+ *** could do for cljs names, but not others
395
+ **** e.g. goog.whatever not enumerable in cljs
396
+ **** can we discern this situation?
397
+ ***** probably not, when compiling from files
398
+ ****** since 'require' doesn't load code at compile time
399
+ **** another reason we can't support 'use'
400
+ ***** we do want to be able to (:require goog.foo)
401
+ ****** but not a compile-time enumerable ns
402
+ ***** or especially: (:require [goog.foo :as gfoo])
403
+ ***** means alias map, like namespaces
404
+ ** Macros written in separate Clojure files
405
+ *** Clojure code, in regular namespaces
406
+ *** Means core split into core.cljs, and core-macros.clj
407
+ **** both need to be auto-referred
408
+ *** if no use/only for macro ns, then can only get as succinct as (alias/macro ...)
409
+ **** could allow explicit aliasing of vars instead of use
410
+ **** extend alias for this?
411
+ ***** not really extending, alias will do this due to how nses are just vars
412
+ ***** but need not be used in that pat of resolution
413
+ ** goog.provide throws called-twice exception
414
+ *** intended to prevent providing the same ns in more than one file
415
+ *** actually prevents reloading same file? - aargh
416
+ *** can't wrap, since deps checkers look for it at top level
417
+ **** will we need to track at compilation-time?
418
+ **** will we still need *compile-file* notion?
419
+ ** Compilation needs
420
+ *** current ns
421
+ **** *cljs-ns* ?
422
+ **** is this a Clojure ns?
423
+ ***** not a fit
424
+ ****** map is sym->Var or Class
425
+ ****** aliases are sym->Namespace
426
+ *** ns has:
427
+ **** *cljs-namespaces* - {name->ns}
428
+ **** {:name "my.ns" :defs {sym qualified.sym} :deps {alias Namepsace-or-qualified.sym}}
429
+ **** defs
430
+ ***** just set of names? no map
431
+ ***** or map to fully qualified self?
432
+ **** deps
433
+ ***** can't merge macros and cljs ns in deps
434
+ ****** same ns might map to both
435
+ ******* i.e. cljs.core will
436
+ ***** aliases
437
+ ****** sym->fully-qualified-sym
438
+ ****** is this a separate mapping vs macros and requires?
439
+ ******* if not, fn alias can mask out ns alias
440
+ ******* that can't happen in Clojure
441
+ ***** macro nses
442
+ ****** map of sym->Namespaces?
443
+ ******* require an alias?
444
+ ******* (:macros {mm my.macros, ym your.macros})
445
+ ****** aliases for these same as others?
446
+ ***** required libs must have aliases too?
447
+ ****** (:require [goog.math.Long :as gml])
448
+ ****** or new (:require {gml goog.math.Long})
449
+ *** lookup 'foo - no ns, no dots
450
+ **** if special - done
451
+ **** if local - done
452
+ **** if found in cljs.macros Namespace, the macro cljs.macros/foo
453
+ **** if found in cljs.core ns, cljs.core.foo
454
+ **** whatever 'foo maps to in (-> env :ns :requires)
455
+ **** no use of deps
456
+ *** lookup 'foo.bar.baz - no ns, dot(s)
457
+ **** if foo is a local, foo_nnnn.bar.baz
458
+ **** if foo has a mapping in (:ns env) - that.mapping.bar.baz - no
459
+ ***** really? covered by alias/whatever
460
+ ****** more idiomatic for goog.stuff than goog.stuff/foo
461
+ ****** but no :as there
462
+ ***** leave out for now
463
+ **** else foo.bar.baz
464
+ *** lookup 'foo/bar - ns with no dots
465
+ **** get what 'foo maps to in (:ns env) deps
466
+ ***** if nothing - error "no alias foo"
467
+ **** if maps to Namespace, the macro 'bar in that ns
468
+ **** else a symbol, e.g. 'fred.ethel => fred.ethel.bar
469
+ *** lookup fully.qualified/foo - ns with dots
470
+ **** would only use this if local shadowed (and no alias)?
471
+ **** what doesn't have alias?
472
+ ***** cljs.core, cljs.macros
473
+ ***** could use cljs.core.foo for former
474
+ ***** always interpret as macro ns?
475
+ ****** or check deps vals for Namespace, else not
476
+ ***** if Namespace, the macro foo in Namespace
477
+ ***** fully.quallified.foo
478
+ **** everything might have alias, but macros/syntax-quote need to emit full expansions
479
+ *** how to refer to true globals?
480
+ **** e.g. Object, String, goog
481
+ **** [[https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects][JS Globals]]
482
+ **** (var Name)?
483
+ ***** that doesn't match Clojure, where (var x) means 'whatever x means in current ns'
484
+ ***** there are no unqualified globals in Clojure
485
+ **** means (extend (var Object) ...) needs to work
486
+ ***** ok if extend evaluates first arg
487
+ ***** it does in Clojure, as it is a function
488
+ * Setup
489
+ ** V8
490
+ svn co http://v8.googlecode.com/svn/trunk v8
491
+ cd v8/
492
+ scons console=readline d8
493
+ ** Closure Library
494
+ svn checkout http://closure-library.googlecode.com/svn/trunk/ closure-library
495
+ *** or download?
496
+ [[http://code.google.com/p/closure-library/downloads/detail%3Fname%3Dclosure-library-20110323-r790.zip&can%3D1&q%3D][Zip download]]
497
+ ** Closure Compiler
498
+ http://closure-compiler.googlecode.com/files/compiler-latest.zip
499
+ *** better(?):
500
+ [[http://code.google.com/p/closure-compiler/wiki/Maven][Compiler in Maven]]