clementine 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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]]