4 ms·
We were talking about java here. ^^ So python is offering a lot more already with it somewhat first class functions. What would you guess even? does, btw? But
by j-pb 11y ago
We were talking about java here. ^^ So python is offering a lot more already with it somewhat first class functions. What would you guess even? does, btw?
But sure, let's make things a bit harder.
As below, let's produce a sequence of the form [true false false true true true false false false false ...] of exact length 1000 without computing any more than exactly 1000 elements.
(take 1000 (mapcat (fn [i] (repeat i (odd? i))) (range)))
Of course the really interesting stuff is hard to do in one liners. But I think one of the more mind bending things is probably core.async. Go style coroutines and channels implemented as a library on top of the language. Which allows for concurrent programming inside clojurescript which is compiled to JS and thus inherently single-threaded.
http://swannodette.github.io/2013/08/02/100000-processes/ http://swannodette.github.io/2013/08/02/100000-processes/
- yeukhon 11y agoMy point was "even" and "filter" can be built by someone, just to be fair about the whole readability. If "even" is already built into the language, then that's a given. Readability and language understanding are not separable. I for one have a hard time actually understand what the code does above (although I can guess it). But I am not sure how ^ translate into [true false false true true true false false false false ...] sequence because, I thought we were calculating oddity of 1000 numbers. [1 2 3 4 5 6 7 8 9 10 ...] ==> [T F T T F T F T T T ] Perhaps the lack of understanding Clojure syntax to comprehend what the code is doing.
- j-pb 11y agoIt's part of the std lib. But yeah you're basically on the same page as me. Java doesn't have the ability to be extended in the ways that clojure or python can. Python also allows for functional programming to a certain degree, but clojure is a lot more powerful when it comes to language extensions. Threads as a library (for js environments) for clojure. https://github.com/clojure/core.async https://github.com/clojure/core.async Logic programming for clojure. https://github.com/clojure/core.logic https://github.com/clojure/core.logic Declarative UI building, with dataflow semantics. http://reagent-project.github.io http://reagent-project.github.io Additionally immutability makes your life a lot easier. Parallel computing in clojure is a no brainer, you just change your map to pmap, and that's it.
- yeukhon 11y agoThank you. I will look at the immutability part. I remember taking Racket in school a few years ago and that was a major thing about FPL like Racket / Lisp. I have always wanted to look at building something again in one of the popular FPLs.
- huahaiy 11y agoExactly the point. In many other languages, every programmer can write their own "even" and "filter" with their own idiosyncrasy. However, in Clojure, every one uses the same set of high level functions in the standard library, because they are sufficiently rich to express most of the programming concepts, without having to roll your own. In Clojure, readability is obtained through standardization. Every Clojure programmer instantly knows what the functions in the standard library do. Because there's not much syntax in a Lisp, code is very easy to read once one knows the functions.
- dragonwriter 11y ago> In many other languages, every programmer can write their own "even" and "filter" with their own idiosyncrasy. "filter" is incredibly useful, and most modern languages (including Java 8) have it built in. "even?" is sometimes useful, and languages are kind of hit-and-miss about it, but its usually small enough to inline, and the biggest cost of not having it built-in is probably things like people using modulus rather than first-bit testing in Java which, IIRC, produces somewhat slower code for that check.
- dragonwriter 11y ago> As below, let's produce a sequence of the form [true false false true true true false false false false ...] of exact length 1000 without computing any more than exactly 1000 elements. So, again, python: [i % 2 == 0 for i in range(1000)] (If you insist on Java, its fairly straightforward, though not a one-liner AFAIK, using Java 8 generators.)
- j-pb 11y agoYou misread the question. I didn't mean (map even? (range 1000)), but a sequence of length 1000 where the elements are 1 * true, 2 * false, 3 * true, 4 * false and so on. To compare it with what your code produces. [true false false true true true false false false false ...] [true false true false true false true false true false ...] Edited for more clarity.
- deleted 11y ago[deleted]
- dragonwriter 11y agoRight, sorry, in python that's something like: from itertools import chain, repeat chain.from_iterable([repeat(i % 2 != 0, i) for i in range(1,1000)]) In Java 8, I think the solution with streams would be fairly straightforward, something like: IntStream.range(1,1001).flatMap(i -> Stream<Boolean>.generate( () -> (x & 1) != 0 ).limit(i))
- sokoloff 11y agoDoesn't that python code give you a list of 500,500 elements, rather than a list of 1000 elements as originally specified?
- dragonwriter 11y agoIn both cases yes, and in both cases because I made the same stupid mistake when both languages have good means to do infinite streams and "take" equivalents. (And that's worse in the Java case, since I used those in the inner function but not the outer one.) So, I think I need to take a break from comment-box programming for a while; its clearly not working out for me today.
- SkidanovAlex 11y ago> (take 1000 (mapcat (fn [i] (repeat i (odd? i))) (range))) And this example is suppoed to support Clojure's readability?
- j-pb 11y agoYou do it in a different language that isn't haskel or ml and show me the result, then we can judge. You'd btw probably write it as. (->> (range) (map #(repeat % (odd? %))) (apply concat) (take 1000) If you want it more readable.