How can I assert that 2012/08 (instead of Aug 2012) is returned from this function?
Thus I can start learning lisp on the job/with the function itself until the output satisfies.
I know some python unit testing (pytest) and am looking for something similar for lisp. However, my first attempt[0] C-c eval-buffer fails with Invalid function: "<2012-08-12 Mon>"
(assert (= (org-cv-utils-org-timestamp-to-shortdate ("<2012-08-12 Mon>")) "Aug 2012"))
(defun org-cv-utils-org-timestamp-to-shortdate (date_str)
"Format orgmode timestamp DATE_STR into a short form date.
Other strings are just returned unmodified
e.g. <2012-08-12 Mon> => Aug 2012
today => today"
(if (string-match (org-re-timestamp 'active) date_str)
(let* ((abbreviate 't)
(dte (org-parse-time-string date_str))
(month (nth 4 dte))
(year (nth 5 dte))) ;;'(02 07 2015)))
(concat
(calendar-month-name month abbreviate) " " (number-to-string year)))
date_str))
[0] https://www.emacswiki.org/emacs/UnitTesting
(assert (= (org-cv-utils-org-timestamp-to-shortdate ("<2012-08-12 Mon>"))
"Aug 2012"))
(defun org-cv-utils-org-timestamp-to-shortdate (...) ...)
statements are executed in sequence, which means your function will only be defined after the assertion is evaluated. This is a problem because the assertion calls that function. You should reorder your code to test it after the function is defined.
you cannot compare strings with =, if you call describe-function (C-h f) for =, you'll see that = is a numerical comparison (in fact, numbers or markers). For strings you need to use string=.
In a normal evaluation context, ie. not in a macro or a special form, the following is read as a function call:
("<2012-08-12 Mon>")
Parentheses are meaningful, the above form says: call function "<2012-08-12 Mon>" with zero arguments. This is not what you want, there is no need to add parentheses here around the string.
Related
I'm new to Clojure and found there's a piece of code like following
user=> (def to-english (partial clojure.pprint/cl-format nil
"~#(~#[~R~]~^ ~A.~)"))
#'user/to-english
user=> (to-english 1234567890)
"One billion, two hundred thirty-four million, five hundred sixty-seven
thousand, eight hundred ninety"
at https://clojuredocs.org/clojure.core/partial#example-542692cdc026201cdc326ceb. I know what partial does and I checked clojure.pprint/cl-format doc but still don't understand how it translates an integer to English words. Guess secret is hidden behind "~#(~#[~R~]~^ ~A.~)" but I didn't find a clue to read it.
Any help will be appreciated!
The doc mentions it, but one good resource is A Few FORMAT Recipes from Seibel's Practical Common Lisp.
Also, check §22.3 Formatted Output from the HyperSpec.
In Common Lisp:
CL-USER> (format t "~R" 10)
ten
~#(...~^...) is case conversion, where the # prefix means to capitalize (upcase only the first word). It contains an escape upward operation ~^, which in this context marks the end of what is case-converted. It also exits the current context when there are no more argument available.
~#[...] is conditional format: the inner format is applied on a value only if it is non nil.
The final ~A means that the function should be able to accept one more argument and print it.
In fact, your example looks like the one in §22.3.9.2:
If ~^ appears within a ~[ or ~( construct, then all the commands up to
the ~^ are properly selected or case-converted, the ~[ or ~(
processing is terminated, and the outward search continues for a ~{ or
~< construct to be terminated. For example:
(setq tellstr "~#(~#[~R~]~^ ~A!~)")
=> "~#(~#[~R~]~^ ~A!~)"
(format nil tellstr 23) => "Twenty-three!"
(format nil tellstr nil "losers") => " Losers!"
(format nil tellstr 23 "losers") => "Twenty-three losers!"
I need to implement a function called eval-math-string in Clojure, which takes a math string as input and evaluates it:
(eval-math-string "7+8/2") => 11
So I've managed to break apart an expression using re-seq, and now I want to evaluate it using Incanter. However, I have an expression like ("7" "+" "8" "/" "2"), but Incanter needs an expression like ($= 7 + 8 / 2), where $= is the incanter keyword. How can I feed the list of one-character strings into a list including $= so that it executes properly. If the arguments are strings, the function won't work, but I can't convert +, *, / etc. to numbers, so I'm a little stuck.
Does anyone know how I can do this, or if there is a better way to do this?
Incanter's $= macro just calls the infix-to-prefix function, so all you need to do is convert your list of strings to a list of symbols and numbers, then call infix-to-prefix.
I'm going to assume that the input is just a flat list of strings, each of which represents either an integer (e.g. "7", "8", "2") or a symbol (e.g. "+", "/"). If that assumption is correct, you could write a conversion function like this:
(defn convert [s]
(try
(Long/parseLong s)
(catch NumberFormatException _
(symbol s))))
Example:
(infix-to-prefix (map convert ["7" "+" "8" "/" "2"]))
Of course, if you're just writing a macro on top of $=, there's no need to call infix-to-prefix, as you would just be assembling a list with $= as the first item. I'm going to assume that you already have a function called math-split that can transform something like "7+8/2" into something like ["7" "+" "8" "/" "2"], in which case you can do this:
(defmacro eval-math-string [s]
`($= ~#(map convert (math-split s))))
Example:
(macroexpand-1 '(eval-math-string "7+8/2"))
;=> (incanter.core/$= 7 + 8 / 2)
I am struggling to understand how the -> and ->> expand.
If I have the following:
(-> query
(write-query-to-excel db csv-file)
(archiver archive-password)
(send-with-attachment send-to subject body)
(clean-up))
How does this expand, I understand that -> is a thread-first macro which inserts the the value as the second item as the first form, and after looking at examples I'm still unsure.
Also how does ->> differ, I know it inserts the item as the last argument of the function but again the wording confuses me.
(->> query
(write-query-to-excel db csv-file)
(archiver archive-password)
(send-with-attachment send-to subject body)
(clean-up))
When expanded how would these two macros look?
-> and ->> always remind me of Matryoshka dolls because they nest all expressions passed to them.
Let's consider (-> a (b c d) (e f g)). We can now visually cut them (with a pipe) at the 1st argument position in each expression but the first: (-> a (b | c d) (e | f g)). Now that the expressions are cut in halves we can nest them: first (-> (b a c d) (e | f g)) and then (-> (e (b a c d) f g)) which simplifies to (e (b a c d) f g).
->> works in a very similar manner except the insert point is at the end (last argument position): (-> a (b c d |) (e f g |)) which successively expands to (-> (b c d a) (e f g |)), (-> (e f g (b c d a))) and (e f g (b c d a)).
Using clojure.walk/macroexpand to expand the macros:
(clojure.walk/macroexpand-all '(-> query
(write-query-to-excel db csv-file)
(archiver archive-password)
(send-with-attachment send-to subject body)
(clean-up)))
... produces
(clean-up (send-with-attachment (archiver (write-query-to-excel query db csv-file) archive-password) send-to subject body))
Whereas
(clojure.walk/macroexpand-all '(->> query
(write-query-to-excel db csv-file)
(archiver archive-password)
(send-with-attachment send-to subject body)
(clean-up)))
... produces
(clean-up (send-with-attachment send-to subject body (archiver archive-password (write-query-to-excel db csv-file query))))
Since the result doesn't have to make sense, we can use simpler examples to illustrate the difference:
(clojure.walk/macroexpand-all '(-> a b c d))
;(d (c (b a)))
, the same with -> or ->>. But if there are arguments:
(clojure.walk/macroexpand-all '(-> a (b 1 2 3)))
;(b a 1 2 3)
whereas
(clojure.walk/macroexpand-all '(->> a (b 1 2 3)))
;(b 1 2 3 a)
The answer from #cgrand is good, but I would like to add a bit more.
You could achieve something very similar by putting your thread-first example into a (let...) form as:
; better if descriptive names used for intermediate results
(let [tmp1 (write-query-to-excel db csv-file)
tmp2 (archiver tmp1 archive-password)
tmp3 (send-with-attachment tmp2 send-to subject body)
tmp4 (clean-up tmp3) ]
<process result in tmp4>
...)
This is often the best solution since you can use descriptive variable names for the intermediate results. If, however, you won't really benefit from naming the intermediate results, you can use a generic variable it as a placeholder and still see exactly where each intermediate result is used in the next form. This is how the it-> macro from the Tupelo Core library works:
Imagine using a variable it to mark the location in each form where the result of the previous expression is inserted. Then in your -> example, we get:
(ns my.proj
(:require [tupelo.core :refer [it->]]
... ))
(it-> (write-query-to-excel db csv-file)
(archiver it archive-password)
(send-with-attachment it send-to subject body)
(clean-up it))
Then in your ->> example we would have:
(it-> (write-query-to-excel db csv-file)
(archiver archive-password it)
(send-with-attachment send-to subject body it)
(clean-up it))
However, what do we do if the expressions do not all chain together in either the first or last argument position? Consider this code:
(it-> 1
(inc it)
(+ it 3)
(/ 10 it)
(str "We need to order " it " items." )
;=> "We need to order 2 items." )
In this case, we have expressions where the previous result is chained into the only, first, last, and middle argument positions. In this case, neither -> nor ->> will work, and one must use something like it-> or a generic (let ...) form.
So for simple expression pipelines, using it-> (or the similar as->) can make the code more explicit about how the expressions are chained together. It also allows you to chain expressions that are not all "thread-first" or "thread-last". For more complicated processing chains, using a let form (possible nested) is the best answer as you can name the intermediate results and then combine them in arbitrarily complicated ways.
Would you mind taking a little tour around programming languages?
Ruby
In the world of Ruby there is a common practice of making so-called "method chains". What it is, essentially, is:
calling a method
calling a method on its result
calling a method on that method's result
etc.
Ruby is object-oriented, and such chains look like this:
(-5..5).map(&:abs)
.select(&:even?)
.count
.to_s
take a range of integers from -5 to 5 inclusive
map them into their absolute values
only select those that are even
count how many you have
convert the resuling number into a string
In Ruby, collections are objects, methods like map, count and select are their methods. map returns a collection, on which you can call select. On the result of select we call count that outputs an integer. Then we call to_s on that integer to convert it into a string. The dot-call of object.method calls a method on an object. Familiar stuff.
In some languages you may be exposed to terrible truth that object's methods may be nothing but a simple function that takes an object it acts upon and arguments. Some languages thoroughly hide that fact as an implementation detail, but could that convention actually be a limitation?
Lua
Lua is a nice little and honest language that doesn't hide from you what object's methods are. Consider these two equivalent lines:
obj.increase(obj, 5)
obj:increase(5)
It's a convention enforced on language-level: a method is a function that takes its owner object as a first argument.
...and some others with "static extension"
Defining all the possibly needed methods in a type has proven to be impossible, so some languages have adopted "static extension": it allows you to create a function that takes an "object acted upon" as its first argument (without access to sources of the type itself!). Then with some syntactic sugar you can use x.ext(y) calls instead of ext(x, y):
C# has that.
Haxe has that.
C++ doesn't have that, but there are proposals to add this, that highlight the semantic similarities of x.f(y) and f(x, y)
That feature allows us to chain operations a slightly cleaner way.
g(f(x, y), z) # Before
x.f(y).g(z) # After
Clojure
And we're back! So what does all this have to do with -> and ->>? They provide similar-looking syntax that looks good in longer chains.
We know for sure that our map and filter (same as Ruby's select) are just functions that take collections they act upon as their last (oops, that was unexpected!) argument.
(->> (range -5 6) (map #(Math/abs %)) ; 6 not included
(filter even?)
(count)
(str))
Oh, so we see a bit different way here: functions we treat as methods here take an object they act upon as their last argument. But we just make the "chain" using ->> and that fact becomes less noticeable.
If we had functions that took "object acted upon" as their first argument, as we've seen in Lua, we'd use ->. Depending on the functions you're chaining, -> might make more sense.
We can have it both ways, we can even mix them with a tad more verbose as->.
I know there are a lot of questions out there with this headline, but I can't glean my answer from them, so here goes.
I'm an experienced programmer, but fairly new to Clojure. I'm trying to parse a RTF file by converting it to a HTML file then calling the html parser.
The converter I'm using (unrtf) always prints to stdout, so I need to capture the output and write the file myself.
(defn parse-rtf
"Use unrtf to parse a rtf file"
[#^java.io.InputStream istream charset]
(let [rtffile (File/createTempFile "parse" ".rtf" (File. "/vault/tmp/"))
htmlfile (File/createTempFile "parse" ".ohtml" (File. "/vault/tmp/"))
command (str "/usr/bin/unrtf "
(.getPath rtffile)
)
]
(try
(with-open [rtfout (FileOutputStream. rtffile)]
(IOUtils/copy istream rtfout))
(let [ proc (.exec (Runtime/getRuntime) command)
ostream (.getInputStream proc)
result (.waitFor proc)]
(if (> result 0)
(
(println "unrtf failed" command result)
; throwing an exception causes a parse failure to be logged
(throw (Exception. (str "RTF to HTML conversion failed")))
)
(
(with-open [htmlout (FileOutputStream. htmlfile)]
(IOUtils/copy ostream htmlout))
; since we now have html, run it through the html parser
(parse-html (FileInputStream. htmlfile) charset)
)
)
)
(finally
(.delete rtffile)
(.delete htmlfile)
)
)))
The exception points to the line with
(IOUtils/copy ostream htmlout))
which really confuses me, since I used that form earlier (just after the try:) and it seems to be OK there. I can't see the difference.
Thanks for any help you can give.
As others have correctly pointed out, you can't just add extra parentheses for code organization to group forms together. Parentheses in a Clojure file are tokens that delimit a list in the corresponding code; lists are evaluated as s-expressions - that is, the first form is evaluated and the result is invoked as a function (unless it names a special form such as if or let).
In this case you have the following:
(
(with-open [htmlout (FileOutputStream. htmlfile)]
(IOUtils/copy ostream htmlout))
; since we now have html, run it through the html parser
(parse-html (FileInputStream. htmlfile) charset)
)
The IOUtils/copy function has an integer return value (the number of bytes copied). This value is then returned when the surrounding with-open macro is evaluated. Since the with-open form is the first in a list, Clojure will then try to invoke the integer return value from IOUtils/copy as a function, resulting in the exception that you see.
To evaluate multiple forms for side-effects without invoking the result from the first one, wrap them in a do form; this is a special form that evaluates each expression and returns the result of the final expression, discarding the result from all others. Many core macros and special forms such as let, when, and with-open (among many others) accept multiple expressions and evaluate them in an implicit do.
I didnt try to run your code, just had a look at it, and after the if (> result 0) you have ((println ...)(throw ...)) without a do. Having an extra parens causes the returned value from the inner parens to be treated as a function and get executed.
try to include it, like this (do (println ...) (throw ...))
I am trying to print a sequence such that neither the whole sequence is printed on one line, nor is each element of the sequence printed on its own line. E.g.
[10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29]
I found pprint-newline in the documentation which indicates that allows me to determine how the newline gets printed. Unfortunately, I cannot find any examples on how it is to be used in conjunction with pprint, and the doc string doesn't to offer much insight:
-------------------------
clojure.pprint/pprint-newline
([kind])
Print a conditional newline to a pretty printing stream. kind specifies if the
newline is :linear, :miser, :fill, or :mandatory.
This function is intended for use when writing custom dispatch functions.
Output is sent to *out* which must be a pretty printing writer.
pprint specifies an optional second argument for the writer, which is by default set to *out*. However, I am not sure how to 'send' pprint-writer to *out* in this case, e.g. something like the example below doesn't appear to work
(clojure.pprint/pprint [1 2 3 4] (*out* (clojure.pprint/pprint-newline :miser)))
While Guillermo explained how to change the dispatch for pretty-printing in general, if all you want to do is printing one collection differently, that's possible, too.
For example, using cl-format (after (use '[clojure.pprint :as pp)):
(binding [pp/*print-pretty* true
pp/*print-miser-width* nil
pp/*print-right-margin* 10]
(pp/cl-format true "~<[~;~#{~a~^ ~:_~}~;]~:>~%" '[foo bar baz quux]))
Set *print-right-margin* as you wish.
You don't have to use format for this. The format directives can be translated to their respective pretty-printer functions, if you want. Explanation of the format string: ~< and ~:> establish a logical block. Inside the block, there are three sections separated by ~;. The first and last section are your prefix and suffix, while the elements are printed in the middle section, using ~#{ and ~}. For each element, the element is printed using ~a, followed by a space, if needed, and a conditional fill-style newline.
(In CL, the format string could be simplified to "~<[~;~#{~a~^ ~}~;]~:#>~%", but that doesn't seem to work in Clojure 1.5.)
As the help says, the function is intended for use for custom dispatch functions.
In order to change the behavior of the pprint for sequences you need to provide a new dispatch function for clojure.lang.ISeq.
The current dispatch function for sequences you can find in clojure/pprint/dispatch.clj
(use-method simple-dispatch clojure.lang.ISeq pprint-list)
...
(defn- pprint-simple-list [alis]
(pprint-logical-block :prefix "(" :suffix ")"
(print-length-loop [alis (seq alis)]
(when alis
(write-out (first alis))
(when (next alis)
(.write ^java.io.Writer *out* " ")
(pprint-newline :linear)
(recur (next alis)))))))
Since printing is dispatched according to data type overriding seems to be the way to go.
See the source code for ideas.