你在不到50行Clojure中做过的最有用的事情是什么?

25 clojure

Clojure似乎喜欢它可能会成为一个受欢迎的Lisp.我想知道有多少人真正采用它来解决他们遇到的一些小而实际的问题.由于Clojure没有在Pleac输入,我认为如果人们将他们的小解决方案发布到他们在Clojure中解决的问题会很棒.

Bri*_*per 15

这将通过Yahoo!打印天气预报 天气.

(ns weather
  (:use (clojure [xml :only [parse]] [zip :only [xml-zip]])
        (clojure.contrib duck-streams str-utils pprint)
        (clojure.contrib.zip-filter xml)))

(defn fetch-xml [uri]
  (xml-zip
   (parse
    (org.xml.sax.InputSource.
     (java.io.StringReader.
      (slurp* (java.net.URI. (re-gsub #"\s+" "+" (str uri)))))))))

(defn yahoo-weather
  ([loc-code] (yahoo-weather loc-code "c"))
  ([loc-code unit]
     (let [rss (fetch-xml (str "http://weather.yahooapis.com/forecastrss?p=" loc-code "&u=" unit))]
       (if (= (text (xml1-> rss :channel :item :title)) "City not found")
         "City not found.  Go to http://weather.yahoo.com/, search for your city, and look in the URL for the location code."
         (let [[units loc wind atm ast] (map #(xml1-> rss :channel (keyword (str "yweather:" %)))
                                             ["units" "location" "wind" "atmosphere" "astronomy"])
               conditions (xml1-> rss :channel :item :yweather:condition)
               date (re-find #"\d+:\d+.*" (xml1-> rss :channel :item :pubDate text))
               fors (xml-> rss :channel :item :yweather:forecast)]
           (cl-format true
"Weather for ~a, ~a (~a)
    Temperature: ~a\u00B0 ~a
     Wind Chill: ~a\u00B0 ~a, ~a ~a
     Conditions: ~a
       Humidity: ~a%
      Barometer: ~a ~a
 Sunrise/Sunset: ~a / ~a

Forecast:
~{  ~{~a: ~a. Hi ~2d, Lo ~2d.~}~^~%~}
"
                      (attr loc :city) (attr loc :region) date
                      (attr conditions :temp) (attr units :temperature)
                      (attr wind :chill) (attr units :temperature) (attr wind :speed) (attr units :speed)
                      (attr conditions :text)
                      (attr atm :humidity)
                      (attr atm :pressure) (attr units :pressure)
                      (attr ast :sunrise) (attr ast :sunset)
                      (map #(list (attr % :day)
                                  (attr % :text)
                                  (attr % :high)
                                  (attr % :low))
                           fors)))))))
Run Code Online (Sandbox Code Playgroud)

例如:

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
Run Code Online (Sandbox Code Playgroud)

  • 如果你花了足够的时间,任何东西都是可读的.适当的语法突出显示有助于(Stack Overflow的突出显示脚本在Lisp上扼杀).很多人都有一个配色方案,可以将parens逐渐淡入背景.这段代码也是一个奇怪的例子,因为我必须左对齐的巨大字符串(因为我试图把所有东西塞进50行). (14认同)
  • Lisp无疑是密集的,但是这可以让你同时在屏幕上放置更多的代码,这样可以很容易地快速扫描大量代码.所以有利有弊.还有一些结构可以让你认识到; 例如,`let`表格总是看起来像某种方式.这一切都很主观,我不能评论你的经历,但是Lisp一开始也很难读,而且在一两年后我没有任何问题.我读过许多其他人的经历,他们最初对Lisp感到恐惧,但最终变得喜欢甚至更喜欢它的语法.YMMV当然. (7认同)
  • 我知道,吹嘘评论,但允许我一次采取立场.人们怎么会喜欢这种语言?这在风格上是不可读的:( (4认同)
  • 我认为最大的问题是/你/在阅读Lisp时遇到了麻烦.我,也不是布莱恩,也没有99%的人在#Clojure上实际/使用/ Lisp和freenode上的#lisp在阅读Lisp时遇到了问题. (4认同)

Jef*_*eff 9

本身并不是特别有用,但这个想法类似于Javascript中的JSON - 您可以将Clojure数据结构移入和移出文件系统.从Practical Common Lisp的数据库示例中采用:

(ns storage (:import (java.io File PushbackReader FileReader FileWriter)))

(defn load-data
  "Loads data from the given file."
  [filepath]
  (do
    ;; the let block creates the file if it doesn't exist
    ;; reader throws an exception if there's no parsable data struct
    (let [file (new File filepath)]
      (if (not (.exists file))
        (do
          (.createNewFile file)
          (doto (new FileWriter filepath) (.write "{}") .close))))
    (read (new PushbackReader (new FileReader filepath)))))

(defn dump-data
  "Exports data structure to a file."
  [filepath data]
  (doto (new FileWriter filepath) (.write (str data)) .close))
Run Code Online (Sandbox Code Playgroud)

用法示例:

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}
Run Code Online (Sandbox Code Playgroud)

当然可以为您的程序编写自己的(复杂的)保存机制.我确信只需改变一些通过Java提供的读者就可以完全从字符串中读取.


Ste*_*ven 6

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)
Run Code Online (Sandbox Code Playgroud)

http://99-bottles-of-beer.net/language-clojure-1996.html

  • ...对于某些"有用"的值,我想. (8认同)
  • 这是一个很棒的网站! (3认同)

Bri*_*per 6

这会从图像创建缩略图.图像可以是本地文件,远程URL或其他任何javax.imageio.ImageIO可以读取的内容(感谢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)))))

从本地PNG创建JPG缩略图:

(make-thumbnail (java.io.File. "some-image.png") "thumb.jpg" 150)
Run Code Online (Sandbox Code Playgroud)

从远程JPG创建GIF缩略图:

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

  • 我的代码在JVM上工作,没有任何其他依赖,这是它的主要吸引力.我需要这个我正在制作的网站.这样做比自己验证URL并进行系统调用和检查返回值等更容易.Java版本在失败时抛出异常并处理标准Java对象我可以做其他事情(轻松传递到其他库等).我也尝试过针对Java的ImageMagick绑定,但是它们非常痛苦. (2认同)

cla*_*taq 6

我在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)))
Run Code Online (Sandbox Code Playgroud)

我在工作中一直使用这个.对直方图非常有用.

Brian Carper非常友好地建议以下改进形式的功能.

(defn tally-map [coll]
  (reduce (fn [h n]
            (assoc h n (inc (or (h n) 0))))
          {} coll))
Run Code Online (Sandbox Code Playgroud)

  • 一个名为`频率`的函数,添加到Clojure 1.2,现在提供此功能. (4认同)