3 ms·
It is funny, I usually know what I am getting in this function in my Clojure code. OCaml (or Haskell) gives entirely different comfort to me, it tells me what m
by StreamBright 8y ago
It is funny, I usually know what I am getting in this function in my Clojure code. OCaml (or Haskell) gives entirely different comfort to me, it tells me what makes sense as input and output type for my function. The downside is that I need to define different functions for different types.
utop # let avg a b = (a +. b) /. 2.0;;
val avg : float -> float -> float = <fun>
utop # avg 2 4;;
Error: This expression has type int but an expression was expected of type float
utop # avg 2.0 4.0;;
- : float = 3.
user=> (defn avg [a b] (/ (+ a b) 2))
#'user/avg
user=> (avg 2 4)
3
user=> (avg 2.0 4.0)
3.0
I think it is a matter of taste which one you prefer. With property based testing and specs you can go very far in term of pre-runtime checks and there was some data about the number of bugs per line published by Github where it turned out that Clojure did not do too bad in comparison to statically typed languages.
- deleted 8y ago[deleted]
- ff_ 8y agoI don't know about OCaml, but Haskell has typeclasses (which look like "polymorphic interfaces"?) so you can define functions generically and put a typeclass constraint to make them work on a certain class of types. E.g. your avg function would be of type: avg :: Num a => a -> a -> a Where your "a" is a number (that is, a type that implements the Num typeclass) This would work out of the box on floats, ints, etc
- StreamBright 8y agoThe signature is not really helpful. Can you show me how do you implement the actual function? If you have operators that are typed like + and +. how can you make this work with Num?
- ff_ 8y agoAlso the + operator is typed with Num; from a Haskell repl: λ> :t (+) (+) :: Num a => a -> a -> a In case of average we need /: λ> :t (/) (/) :: Fractional a => a -> a -> a So our type is going to be constrained by Fractional instead of Num). So an implementation could be (from here [1]): import Data.List average :: (Real a, Fractional b) => [a] -> b average xs = realToFrac (sum xs) / genericLength xs [1]: https://stackoverflow.com/questions/2376981 https://stackoverflow.com/questions/2376981