I was wondering why there is no clojure reader literal for floats. Something like:
1f
I found this, but it has no responses. The clojure docs do not mention one either. Are there no plans to add it, and if not what is the rationale behind this?
As a matter of fact, there isn't a reader literal for 32-bit precisions integers either.
(class 1)
; => java.lang.Long
(class 1.0)
; => java.lang.Double
My guess is that it's an opinionated choice. 32-bits is so 20th century, it's time to move on. But you can still coerce to 32-bits types (and to short/byte as well), as #amalloy demonstrated.
I usually just make sure it has a decimal point if I need to write a true float. 1.0 vs 1
Clojure supports coercion to type float as defined here and here
(def f1 (float 1))
Further to the answer from #omiel, you can write 1. to get a float if you prefer a more terse syntax:
(class 1.)
; => java.lang.Double
Related
I'm trying to use cl-format to format money. I want (f 12345.555) ;=> "12,345.56". I get the decimals with the format string "~$" and I get the comma separators with "~:D". How do I combine them?
With Common Lisp, I would recommand using cl-l10n which supports locales and defines ~N. Alternatively, you could roll your own:
(defun money (stream number colonp atsignp &optional (decimal-places 2))
(multiple-value-bind (integral decimal) (truncate number)
(format stream
(concatenate 'string
"~"
(and colonp ":")
(and atsignp "#")
"D"
"~0,vf")
integral
decimal-places
(abs decimal))))
(setf *read-default-float-format* 'double-float)
(format nil "~2:#/money/" 123456789.123456789)
=> "+123,456,789.12"
Now, for Clojure, it seems that ~/ is not yet supported by cl-format, so you can't directly replicate the above code. It is probably quicker to use a Java libray (see e.g. this question or this other one).
Part of the problem is that the ~:d directive only adds commas when passed a whole number (whether it's a float or an integer), i.e. if there's anything other than zero after the decimal point, ~:d just prints out the number as is. That's true for CL's format as well as for Clojure's cl-format.
A solution is to split up the number into an integer and a decimal, and then format them separately. One way to do this would use a truncate function, which afaik, neither Clojure nor its standard libraries provides. Here's one way, using floor and ceil from clojure.math.numeric-tower. (Thanks to coredump for pointing out the bug in my earlier version.)
(defn truncate [x]
(if (neg? x)
(ceil x)
(floor x)))
(defn make-money [x]
(let [int-part (truncate x)
dec-part (- x int-part)]
(cl-format nil "~:d~$" int-part dec-part)))
(make-money 123456789.123456789) ;=> "123,456,7890.12"
Note that this is only designed to work with positive numbers.
(EDIT: As Xavi pointed out in a comment, this isn't a solution, since there's a 4-digit group after the last comment.)
That answers OP's question (EDIT: Not really--see above), but I'll note that in Common Lisp, ~$ behaves slightly differently; by default it prints out an initial zero before the decimal point (at least in the implementations I tried--not sure if this is standardized). This can be avoided by customizing the ~f directive--which works this way in Clojure, too (see Peter Seibel's introduction for details):
(defun make-money (x)
(let* ((int-part (truncate x))
(dec-part (- x int-part)))
(format nil "~:d~0,2f" int-part dec-part)))
You can get unexpected results with this definition if the numbers are too big. I'm sure there are ways to avoid this problem by tweaking the definition, and in any event, as Joshua Taylor's comments point out, there are other, probably better ways to do this in Common Lisp.
Imagine the following function to give an infinite lazy sequence of fibonacci in Clojure:
(def fib-seq
(concat
[0 1]
((fn rfib [a b]
(lazy-cons (+ a b) (rfib b (+ a b)))) 0 1)))
user> (take 20 fib-seq)
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
Assuming
We take the pithy definition of codata as being "Codata are types inhabited by values that may be infinite".
That this Clojure example doesn't use a static type system (from core.typed) and so any description of codata is a 'working definition'
My question is - What part of the function above is the 'codata'. Is it the anonymous function? Is it the lazy sequence?
Codata is the dual of data. You work with data via structural induction which means that data is always finite. You work with codata via coinduction which means codata is potentially infinite (but not always).
In any case, if you can't properly define a finite toString or equality then it'll be codata:
Can we define a toString for an infinite streams? No, we'd need an infinite string.
Can we always define extensional equality for two infinite streams? No, that'd take forever.
We can't do the above for streams because they're infinite. But even potentially infinite causes undecidability (i.e. we can't give a definite yes or no for equality or definitely give a string).
So an infinite stream is codata. I think your second question is more interesting, is the function codata?
Lispers say that code is data because features like S-expressions allow manipulating the program just like data. Clearly we have already have a string representation of Lisp (i.e. source code). We can also take a program and check if it's made up of equal S-expressions (i.e. compare the AST). Data!
But let's stop thinking about the symbols that represent our code and instead start thinking about the meaning of our programs. Take the following two functions:
(fn [a] (+ a a))
(fn [a] (* a 2))
They give the same results for all inputs. We shouldn't care that one uses * and the other uses +. It's not possible to compute if any two arbitrary functions are extensionally equal unless they only work on finite data (equality is then just comparing input-output tables). Numbers are infinite so that still doesn't solve our above example.
Now let's think about converting a function to a string. Let's say we had access to the source representation of functions at runtime.
(defn plus-two [a] (+ a 2))
(defn plus-four [a] (plus-two (plus-two a)))
(show-fn plus-four)
; "(plus-two (plus-two a))"
Now, referential transparency says we can take function calls and replace them with the function bodies, with the variables substituted and the program always gives the same result. Let's do that for plus-two:
(defn plus-four [a] (+ (+ a 2) 2))
(show-fn plus-four)
; "(+ (+ a 2) 2)"
Oh... The result is not the same. We broke referential transparency.
So we also can't define toString or equality for functions. It's because they're codata!
Here are some resources I found helpful for understanding codata better:
Data, Codata, and Their Implications for Equality, and Serialization
Codata and Comonads in Haskell
Data and Codata on A Neighborhood of Infinity
Some slides from University of Nottingham
My personal thought is the return value of the call to lazy-cons is the point at which the type of the thing in question could first be said to be infinate and thus that is the point that I see codata'nes starting.
In the Java/C world, people often use enums. If I'm using a Java library which using enums, I can convert between them and keywords, for example, using (. java.lang.Enum valueOf e..., (aget ^"[Ljava.lang.Enum;" (. e (getEnumConstants)) i), and some reflection. But in the Clojure world, do people ever need anything like an enum (a named integer) ? If not, how is their code structured that they don't need them ? If yes, what's the equivalent ? I sense I'm really asking about indices (for looping), which are rarely used in functional programming (I've used map-indexed only once so far).
For almost all the Clojure code I have seen keywords tend to be used instead of Enums they are name-spaced and have all the other useful properties of keywords while being much easier to write. They are not an exact standin because they are more dynamic (as in dynamic typing) than Java enums
as for indexing and looping I find it more idiomatic to map over a sequence of keywords:
(map do-stuff [:a :b :c :d] (range))
than to loop over the values in an enumeration, which I have yet to find an example of in Clojure code, though an example very likely exists ;-)
As Arthur points out - keywords are typically used in Clojure in place of enums.
You won't see numbered indexes used much - they aren't particularly idiomatic in Clojure (or most other functional programming languages)
Some other options worth being aware of:
Use Java enums directly - e.g. java.util.concurrent.TimeUnit/SECONDS
Define your own constants with vars if you want numeric values - e.g. (def ^:const PURPLE 1)
You could even implement a macro defenum if you wanted more advanced enum features with a simple syntax.
Yes, use keywords in most places where Java programmers would use enums. In the rare case that you need a number for each of them, you can simply define a map for converting: {:dog 0, :rabbit 1, ...}.
On the other hand, one of the first Clojure libraries I wrote was just this: a defenum macro that assigned numbers to symbols and created conversion systems back and forth. It's a terrible idea implemented reasonably well, so feel free to have a look but I don't recommend you use it.
Common Lisp has return-from; is there any sort of return in Clojure for when you want to return early from a function?
When you need to bail out of a computation early, you need a way to do that, not an argument from purists. Usually you need it when you're reducing a big collection and a certain value indicates that there's no point in further processing the collection. To that end, the ever-practical Clojure provides the reduced function.
A simple example to illustrate is that when multiplying a sequence of numbers, if you encounter a zero, you already know that the final result will be zero, so you don't need to look at the rest of the sequence. Here's how you code that with reduced:
(defn product [nums]
(reduce #(if (zero? %2)
(reduced 0.0)
(* %1 %2))
1.0
nums))
reduced wraps the value you give it in a sentinel data structure so that reduce knows to stop reading from the collection and simply return the reduced value right now. Hey, it's pure-functional, even!
You can see what's going on if you wrap the above if in a do with a (println %1 %2):
user=> (product [21.0 22.0 0.0 23.0 24.0 25.0 26.0])
1.0 21.0
21.0 22.0
462.0 0.0
0.0
user=> (product [21.0 22.0 23.0 24.0 25.0 26.0])
1.0 21.0
21.0 22.0
462.0 23.0
10626.0 24.0
255024.0 25.0
6375600.0 26.0
1.657656E8
There isn't any explicit return statement in clojure. You could hack something together using a catch/throw combination if you want to, but since clojure is much more functional than common lisp, the chances you actually need an early return right in the middle of some nested block is much smaller than in CL. The only 'good' reason I can see for return statements is when you're dealing with mutable objects in a way that's not idiomatic in clojure.
I wouldn't go as far as saying that it's never useful, but I think in Clojure, if your algorithm needs a return statement, it's a major code smell.
Unless you're writing some really funky code, the only reason you'd ever want to return early is if some condition is met. But since functions always return the result of the last form evaluated, if is already this function — just put the value that you want to return in the body of the if and it will return that value if the condition is met.
I'm no expert in Clojure, but it seems it does not have those construct to try to be more functional. Take a look at what Stuart Halloway says here:
Common Lisp also supports a return-from macro to "return" from the
middle of a function. This encourages an imperative style of
programming, which Clojure discourages.
However, you can solve the same problems in a different way. Here is
the return-from example, rewritten in a functional style so that no
return-from is needed:
(defn pair-with-product-greater-than [n]
(take 1 (for [i (range 10) j (range 10) :when (> (* i j) n)] [i j])))
That is, use lazy sequences and returning values based on conditions.
As an alternative you could use cond . And if on some conditions you would need to evaluate multiple expressions use do.
Here is an example:
(defn fact [x]
(cond
(< x 0) (do (println (str x " is negative number"))
(throw (IllegalArgumentException. "x should be 0 or higher")))
(<= x 1) 1
:else (* x (fact (- x 1)))))
The if option already given is probably the best choice, and note since maps are easy, you can always return {:error "blah"} in the error condition, and{result: x} in the valid condition.
There isn't a return statement in Clojure. Even if you choose not to execute some code using a flow construct such as if or when, the function will always return something, in these cases nil. The only way out is to throw an exception, but even then it will either bubble all the way up and kill your thread, or be caught by a function - which will return a value.
In short, no. If this is a real problem for you then you can get around it with
"the maybe monad" Monads have a high intellectual overhead so for many cases clojurians tend to avoid the "if failed return" style of programming.
It helps to break the function up into smaller functions to reduce the friction from this.
A while ago this code seemed to work, but now it doesn't anymore. Is there something wrong with it?
user=> (defn sum [a b] (a + b))
#'user/sum
user=> (sum 3 4)
java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)
user=>
It's probably time to take a break :)
Perhaps try:
(defn sum [a b] (+ a b))
Clojure, being a member of the Lisp family, always uses prefix notation for arithmetic expressions.
Since you're trying to write such a function, I wonder if it might be helpful to point out that + is just a regular function in Clojure, as it is in any other Lisp. In fact, there are no special "arithmetic expressions" in Clojure, just function applications whose arguments are numbers and whose operator functions perform arithmetic operations.
In fact, in most Lisps there are no special "operators" in the sense distinguished pieces of syntax which would need to be wrapped for their functionality to be available in the form of a function. Clojure is unusual as a Lisp in this regard in that it explicitly depends on its host platform for some fairly basic features; e.g. floating-point exponentiation is available in vanilla Clojure in the form of the pow method of the java.lang.Math class (but see clojure.contrib.math for some nice functions to perform various arithmetic ops not in clojure.core).
Java methods would have to be wrapped in Clojure to be used as functions (e.g. passed to map etc.), so in that way they might bring to mind operators from languages such as C, Python or indeed Java itself. They are still called using prefix notation, though.
There is already a + function in clojure.core, so be very careful when redefining it, you're probably better off avoiding this.
All Lisps including Clojure use prefix notation. You should call a function like (fn-name args). In your example Clojure tries to call an Integer as a function, because that's the first element of the list. Integers do not implement the IFn interface, so that explains the error message.
You can in fact get an infix notation for mathematical functions using a function. For this function see page 13 of the first chapter of The Joy Of Clojure, freely available here: http://www.manning.com/fogus/Fogus_MEAP_Ch1.pdf.