什么';你最有用的东西是什么;我用了不到50行的Clojure?

什么';你最有用的东西是什么;我用了不到50行的Clojure?,clojure,Clojure,Clojure似乎很有可能成为流行的Lisp。我想知道有多少人真的采用它来解决他们遇到的一些小问题,但却是真实的问题。由于Clojure没有进入,我认为如果人们发布他们在Clojure中解决的问题的小解决方案,那将是一件好事。这将通过打印天气预报 例如: user> (weather/yahoo-weather "CAXX0328") Weather for North Vancouver, (10:00 am PDT) Temperature: 14° C Wind

Clojure似乎很有可能成为流行的Lisp。我想知道有多少人真的采用它来解决他们遇到的一些小问题,但却是真实的问题。由于Clojure没有进入,我认为如果人们发布他们在Clojure中解决的问题的小解决方案,那将是一件好事。

这将通过打印天气预报

例如:

user> (weather/yahoo-weather "CAXX0328")
Weather for North Vancouver,  (10:00 am PDT)
    Temperature: 14° C
     Wind Chill: 14° C, 8.05 kph
     Conditions: Light Rain Shower
       Humidity: 88%
      Barometer: 1018 mb
 Sunrise/Sunset: 6:01 am / 8:32 pm

Forecast:
  Thu: Few Showers. Hi 18, Lo 12.
  Fri: AM Showers. Hi 19, Lo 12.
nil

99瓶啤酒


(defn bottles [n & [capitalize]]
  (str (if (> n 0) n (if capitalize "No more" "no more"))
    " bottle" (if (= 1 n) "" "s") " of beer" ))

(defn bot-wall [n & cap] (str (bottles n cap) " on the wall"))

(defn sing
  ;  Default is 99 times.
  ([]  (sing 99))
  ([stock]
    (doseq [i (range stock -1 -1)]
      (printf "%s, %s.\n%s.\n\n"
        (bot-wall i true) (bottles i)
        (apply str
          (if (> i 0)
            ["Take one down and pass it around, " (bot-wall (dec i))]
            ["Go to the store and buy some more, " (bot-wall stock)]
          ))))))

(sing)

这将从图像创建缩略图。图像可以是本地文件、远程URL或任何其他可以读取的内容(感谢Java!)。输出可以是任何图像格式
javax.imageio.imageio
都可以写入

(use '(clojure.contrib java-utils)) (defn make-thumbnail "Given an input image (File, URL, InputStream, ImageInputStream), output a smaller, scaled copy of the image to the given filename. The output format is derived from the output filename if possible. Width should be given in pixels." ([image out-filename width] (if-let [format (re-find #"\.(\w+)$" out-filename)] (make-thumbnail image out-filename width (nth format 1)) (throw (Exception. "Can't determine output file format based on filename.")))) ([image out-filename width format] (let [img (javax.imageio.ImageIO/read image) imgtype (java.awt.image.BufferedImage/TYPE_INT_RGB) width (min (.getWidth img) width) height (* (/ width (.getWidth img)) (.getHeight img)) simg (java.awt.image.BufferedImage. width height imgtype) g (.createGraphics simg)] (.drawImage g img 0 0 width height nil) (.dispose g) (javax.imageio.ImageIO/write simg format (as-file out-filename))))) 从远程JPG创建GIF缩略图:

(make-thumbnail (java.net.URL. "http://blog.stackoverflow.com/wp-content/uploads/justice-league-small.jpg") "small.gif" 250)

它本身并不是特别有用,但其思想类似于Javascript中的JSON——您可以在文件系统中来回移动Clojure数据结构。从示例中采用:

用法示例:

user=> (dump-data "test.dat" {:a [1 2 3] :b "hello" :c true})
#<FileWriter java.io.FileWriter@186df0f>

user=> (load-data "test.dat")
{:a [1 2 3], :b "hello", :c true}
user=>(转储数据“test.dat”{:a[1 2 3]:b“hello”:c true})
#
用户=>(加载数据“test.dat”)
{:a[1 2 3],:b“你好”,:c true}

当然比为程序编写自己的(复杂的)保存机制要好。我确信,仅仅通过更改Java提供的一些阅读器就可以完全从字符串中读取数据。

Clojure可能具有幂函数,但当我发现这一点时,我真的很兴奋:

(defn pow [base exp] (reduce * (replicate exp base)))

编写Swing应用程序时,JMenuBar的东西总是令人讨厌。多亏了dorun/map,这更容易:

(let [menus
[
 {:name "File" :mnemonic \F
  :items
  [
   {:name "Open" :mnemonic \O :fn file-open}
   :separator 
   {:name "Exit" :mnemonic \x :fn file-exit}
   ]
  }

 {:name "Help" :mnemonic \H
  :items
  [
   :separator 
   {:name "About..." :mnemonic \A :fn help-about}
   ]
  }
 ]

menu-fns
(into
 {}
 (mapcat
  (fn [menu]
    (map
     (fn [item] [(:name item) (:fn item)])
     (:items menu)))
  menus))

ui-frame
(proxy [JFrame ActionListener] ["UI Frame"]
  (actionPerformed
   [event]
    (let [command (.getActionCommand event)
      menu-fn (get menu-fns command)]

      ;; Handle menu commands
      (if menu-fn
    (apply menu-fn [this]))
      ))
  )
]

(defn new-menu [listener]
  (let [menubar (JMenuBar.)]
(dorun
 (map
  (fn [x]
    (let [menu (JMenu. (:name x))]
      (.setMnemonic menu (int (:mnemonic x)))
      (.add menubar menu)
      (dorun
       (map
    (fn [item]
      (if (= :separator item)
        (.addSeparator menu)
        (let [menu-item
          (if (:mnemonic item)
            (JMenuItem. (:name item) (int (:mnemonic item)))
            (JMenuItem. (:name item)))]
          (.addActionListener menu-item listener)
          (.add menu menu-item))))
    (:items x)))))
  menus))

menubar))

现在我不需要子菜单,但只需对
new menu
做一点小小的更改即可获得它们。另外,添加图标、活动/非活动状态等只是
菜单中的更多字段

我在Clojure中为自己编写的最有用的东西是几乎微不足道的函数:

(defn tally-map
 " Create a map where the keys are all of the unique elements in the input
   sequence and the values represent the number of times those elements
   occur. Note that the keys may not be formatted as conventional Clojure
   keys, i.e. a colon preceding a symbol."
  [aseq]
  (apply merge-with + (map (fn [x] {x 1}) aseq)))
我在工作中总是用这个。非常有用的直方图

非常友好地提出了以下函数的改进形式

(defn tally-map [coll]
  (reduce (fn [h n]
            (assoc h n (inc (or (h n) 0))))
          {} coll))

嗯,这段代码真的是为我而不是其他人编写的。前几天,我花了二十分钟把它拼凑起来,参加了一门关于马尔可夫过程的课程。我当然觉得它很有用。我用它来说服教授我对一个问题的理论分析是正确的。老实说,酷点(我想!)实际上只是第一个函数,
sample
。我在我的许多项目中都使用了这样的函数,不知何故,当我匆忙地解决这个问题时,我偶然发现了我最好的解决方案

(defn sample
   "Samples once a discrete random distribution defined by
   a vector. E.g., (sample [0.25 0.2 0.1 0.45]) should output
   '0' 25% of the time, '1' 20% of the time, etc."
   [p]
   (let [r (rand)]
      (count (take-while #(< % r) (reductions + p)))))
(defn transition
   "Given a transition matrix and a history vector, returns
   the history with an additional time step added."
   [m h]
      (conj h (sample (nth m (last h)))))
(defn process-gen
   "Takes a transition probability matrix, initial state
   probabilities, and a function.
   The initial state probs should take the form [p .. q].
   The function should accept the full process history
   and return true if the process should stop.  
   Returns a function of no arguments that returns a full
   simulated history of the process."
   [m i f]
   (fn [] (loop [h [(sample i)]] (if (f h) h (recur (transition m h))))))
(defn transition2
   "Given a transition matrix and the current state, returns
    a sampled state for the next time step."
   [m s]
   (sample (nth m s)))
(defn lazy-process
   "Takes a transition probability matrix, initial state
   probabilities, and a function.
   The initial state probs should take the form [p .. q].
   Returns a function which, when run, produces an infinite
   lazy list sampling the process."
   [m i]
   (fn [] f
      ([] (f (sample initial)))
      ([s] (let [i (transition2 m s)]
            (cons i (lazy-seq (f i)))))))
通过过度的模拟,这两个数字回答了这个问题的两种不同解释

我必须承认我为你们清理了我的代码。我写这篇文章的那天,我发现Clojure允许在符号名中使用Unicode。在修改语言时,我可能有点过火了所以…前三个函数在我的文件中看起来像这样

(Λ σ [p] (let [r (rand)] (|| (take-while #(< % r) (∮ + p)))))
(Λ Δ [Ξ ξ] (⊞ ξ (σ (§ Ξ (last ξ)))))
(Λ Π [Ξ i ω] (λ [] (⟳ [ξ [(σ i)]] (⇒ (ω ξ) ξ (⟲ (Δ Ξ ξ))))))
(λσ[p](让[r(rand)](| | |)(花时间#)(<%r)(∮ + p) )))
(Λ Δ [Ξ ξ] (⊞ ξ(σ(§Ξ(最后一个ξЮЮ)Ю)
(λ∏[Ξiω](λ[](⟳ [ξ[(σi)]](⇒ (ω ξ) ξ (⟲ (Δ Ξ ξ))))))

这次更严肃的回答是:

我经常对REPL stacktrace函数只显示八行感到失望。这是我所有项目的开发文件:

(defn stack
   [n]
   (clojure.stacktrace/print-stack-trace (clojure.stacktrace/root-cause *e) n))
我一直想要
argmin
argmax

(defn argmin
([f x]x)
([f x y](如果(<(f x)(f y))x y))
([f x y&更多](减少(部分argmin f)(argmin f x y)更多)))
(定义argmax)
([f x]x)
([f x y](如果(>(f x)(f y))x y))
([f x y&更多](减少(部分argmax f)(argmax f x y)更多)))
最后,为了可靠地评估算法,我经常在数据集上使用此函数:

(defn kfolds
   "Given an integer k and a collection of data, this
   partitions the data into k non-overlapping collections,
   then returns a list of length k, where the ith item is
   itself a list of two items: 
      (1) the union of all but the ith partition
      (2) the ith partition.
   If (count data) is not divisible by k, a few points (< k)
   will be left out."
   [k data]
   (let [total (count data)
         fold-size (int (/ total k))
         folds-test (take k (partition fold-size fold-size [] data))
         folds-train (map #(apply concat %)
                        (map #(take (dec k)
                                 (drop %
                                       (cycle folds-test)))
                           (range 1 (inc k))))]
         (map list folds-train folds-test)))
(defn kfolds
给定一个整数k和一组数据,此
将数据划分为k个不重叠的集合,
然后返回长度为k的列表,其中第i项为
它本身包含两个项目的列表:
(1) 除第i个分区外的所有分区的并集
(2) 第i个分区。
如果(计数数据)不能被k整除,则几个点(
我可以。对于这样的问题,我应该这样做吗?每行有多少个字符?正如你所知,Clojure的一句台词可以永远持续下去……是的,50也是任意的。没有硬性规定。我只是想收集很多人们用来解决某些问题的“小”有用的Clojure程序……我想是为了“有用”的某些价值。我知道,吹牛的评论,但请允许我有一次表明立场。人们怎么会喜欢这种语言?它在风格上是不可读的:(如果你花足够的时间,任何东西都是可读的。正确的语法高亮显示有帮助的(Stack Overflow的高亮脚本在Lisp上阻塞)。许多人都有一个颜色方案,可以使paren在背景中稍微褪色。这段代码也是一个奇怪的例子,因为我不得不左对齐巨大的字符串(因为我想把所有的东西都塞进50行文字中)我想反驳。不能命名的语言(brainf*k)在任何情况下都无法阅读,不管你花了多少时间。但是,我尝试在vim中导入你的脚本,并进行适当的突出显示。这有帮助,但不多。函数式语言的主要问题是它们本质上是深度嵌套的,而深度嵌套由许多部分组成(GUI设计、重构、代码气味)报告为可用性或代码质量差的警告标志。函数方法很酷(永远不会从python中漏掉map()),但必须适度使用
(defn sample [p]
   (let [r (rand)]
      (count (take-while #(< % r) (reductions + p)))))
(defn transition [m h]
      (conj h (sample (nth m (last h)))))
(defn process-gen [m i f]
   (fn [] (loop [h [(sample i)]] (if (f h) h (recur (transition m h))))))
(defn transition2 [m s]
   (sample (nth m s)))
(defn lazy-process-gen [m i]
   (fn [] f
      ([] (f (sample initial)))
      ([s] (let [i (transition2 m s)]
            (cons i (lazy-seq (f i)))))))
user=>(def squirrel-matrix [[0.8797 0.0212 0.0981 0.0010]
[0.0382 0.8002 0.0273 0.1343]
[0.0527 0.0041 0.8802 0.0630]
[0.0008 0.0143 0.0527 0.9322]])
user=>(def my-process (process-gen squirrel-matrix [1 0 0 0] #(and (> (count %) 1) (= 0 (last %)))))
user=> (/ (reduce + (map (comp dec count) (repeatedly 1000000 my-process))) 1000000.)
5.820319
user=> (let [hs (reduce + (filter #(> % 1) (map (comp dec count) (repeatedly 1000000 my-process))))] (/ (reduce + hs)) (count hs)))
5002699/120880 ; ~41.386
(Λ σ [p] (let [r (rand)] (|| (take-while #(< % r) (∮ + p)))))
(Λ Δ [Ξ ξ] (⊞ ξ (σ (§ Ξ (last ξ)))))
(Λ Π [Ξ i ω] (λ [] (⟳ [ξ [(σ i)]] (⇒ (ω ξ) ξ (⟲ (Δ Ξ ξ))))))
(defn stack
   [n]
   (clojure.stacktrace/print-stack-trace (clojure.stacktrace/root-cause *e) n))
(defn argmin
   ([f x] x)
   ([f x y] (if (< (f x) (f y)) x y))
   ([f x y & more] (reduce (partial argmin f) (argmin f x y) more)))
(defn argmax
   ([f x] x)
   ([f x y] (if (> (f x) (f y)) x y))
  ([f x y & more] (reduce (partial argmax f) (argmax f x y) more)))
(defn kfolds
   "Given an integer k and a collection of data, this
   partitions the data into k non-overlapping collections,
   then returns a list of length k, where the ith item is
   itself a list of two items: 
      (1) the union of all but the ith partition
      (2) the ith partition.
   If (count data) is not divisible by k, a few points (< k)
   will be left out."
   [k data]
   (let [total (count data)
         fold-size (int (/ total k))
         folds-test (take k (partition fold-size fold-size [] data))
         folds-train (map #(apply concat %)
                        (map #(take (dec k)
                                 (drop %
                                       (cycle folds-test)))
                           (range 1 (inc k))))]
         (map list folds-train folds-test)))