News for hackers. Stuff that matters.
Re:Metabase: Why we picked Clojure by yeukhon on Wednesday December 02, 2015 @05:12PM (#10666243)
But what is even?

I am sure functional programming has its natural appealing in areas like recursion, but this example doesn't seem too convincing for winning readability, I can always write this in python

filter(even, range(0, 101)))

where even is a function I wrote.

Please give an example for "Clojure allows me to express thoughts that I wouldn't know how to express in for, while, if, variables and objects." if you can.

Re:Metabase: Why we picked Clojure by ane on Wednesday December 02, 2015 @05:38PM (#10666395)
Your Python example is functional programming! You're doing exactly the same thing as in Clojure, just not in a Lisp syntax.

Therefore, in your question, you could substitute Clojure with functional programming, and the examples in which FP allows you to express thoughts you wouldn't know how to express in for, while and so on -- are plentiful.

I may not be answering your question, but there's a reason for that: the functional programming aspect isn't Clojure's main selling point. It's the other ideas. Software transactional memory, immutability, its emphasis on state and identity, the protocol system, transients, concurrency, transducers, the list goes on.

Re:Metabase: Why we picked Clojure by yeukhon on Wednesday December 02, 2015 @05:44PM (#10666428)
You are referring to higher-order function I assume. I don't think that is a property of FPL.

I am definitely not dismissing FPL, I am just arguging about the actual examples given were not strong enough to dismiss Java being hard to read.

Re:Metabase: Why we picked Clojure by yogthos on Wednesday December 02, 2015 @05:50PM (#10666474)
The big difference is that Clojure defaults to immutable data structures. While you can chain functions together in Java and Python, you still have to manually keep track of all the references.

The main benefit of modern functional languages is in their use of revisioned data structures. This has same benefits as garbage collection.

Without GC you have to manually track where you allocate and deallocate things, and this is highly error prone. With GC the runtime does this for you, and you can focus on other things.

Same thing applies with mutable and immutable data. With mutable data structures all the changes are done in place, and you have to keep track of everywhere it's used to update it predictably. With immutable data structures you're "copying" the data any time you make a change, and the runtime keeps track of the references for you.

Re:Metabase: Why we picked Clojure by erikpukinskis on Wednesday December 02, 2015 @07:35PM (#10666957)
There's nothing preventing you from writing analogous data structures in any language.

No one wants to admit that their language choice is because of the cultural norms in their language community, but if you can hide some complexity behind a language construct, you can hide the same complexity behind a function call. It's just a question of how much of the work required to do that has already been done by the community.

You're just not going to win the "my language can do x more concisely than a function called x in your language!" argument. You're better off with "this is easy and my language and you'd have to write a function to do it in yours."

Re:Metabase: Why we picked Clojure by dkersten on Thursday December 03, 2015 @08:20AM (#10669387)
There's nothing preventing you from writing analogous data structures in any language.

The problem is the language culture and what is idiomatic. I write Python in my day job and while I could certainly write immutable data structures in Python and code in a way that treats data as immutable, it would be going against what is idiomatic in the language, which means that it won't play well with libraries and that my coworkers can still trample over my data without my knowledge. That is, the language gives me no guarantees whatsoever that my immutability is actually respected and that other code somewhere else that I did not write (either application code written by a coworker or library code written by a stranger) respects the immutability.

I find this argument similar to asking why bother writing in any high level language when you can implement the same things in assmembly. Hell, why don't we all just program turing machines directly?

Languages carry a lot more with them than just the features - they carry idioms and culture and community trends. All of these (and even small syntax differences) influence how we think about problems and how we create and structure solutions. They also influence how my code will interact with other peoples (and theirs with mine).

Re:Metabase: Why we picked Clojure by erikpukinskis on Friday December 04, 2015 @04:15PM (#10679179)
Exactly. But there are also cultures within languages. Just because your language has a clique doesn't mean you have to hang out with them.
Re:Metabase: Why we picked Clojure by dkersten on Friday December 04, 2015 @08:44PM (#10680426)
True, but how far away you can get or how well you can play with libraries or other code can be limited.
Re:Metabase: Why we picked Clojure by escherize on Wednesday December 02, 2015 @10:24PM (#10667536)
You're right, _you_ can write immutable data structures in any language. But for example, immutable.js and/or mori do practically nothing to fix the mutability problems with javascript, since immutability is not the default.
Re:Metabase: Why we picked Clojure by j-pb on Wednesday December 02, 2015 @05:49PM (#10666468)
Higher order functions are _the_ defining property of FPL. Even though a lot of FPL people might want you to believe it's types.

Lambda calculus (the theoretical foundation for all functional languages) was initially untyped.

Re:Metabase: Why we picked Clojure by NhanH on Wednesday December 02, 2015 @05:53PM (#10666496)
Arguably, first class higher order function (and immutability) is defining characteristics of functional programming.

Although, I don't think the functional/ imperative is necessary a good axis for categorizing languages. There are potentially more differences between Clojure/Ocaml than Python/Clojure, for example.

Re:Metabase: Why we picked Clojure by mvc on Wednesday December 02, 2015 @10:38PM (#10667601)
They are no longer exclusive to FPLs but higher order functions are definitely a property of FPLs
Re:Metabase: Why we picked Clojure by xtian on Wednesday December 02, 2015 @05:23PM (#10666304)
I'd say the argument for FP in general is not that it allows for the expression of thoughts that are impossible to express with for, while, if, etc., but rather that functional programs are still able to be reasoned about at the point of complexity where imperative programs become completely intractable.

Not an FP expert so I don't know if this is entirely accurate or how it plays out in reality.

Re:Metabase: Why we picked Clojure by huahaiy on Wednesday December 02, 2015 @05:34PM (#10666357)
even? is a predicate that test if the parameter is an even number, as the name suggests. ? is part of the function name, not a syntax symbol (there's not much syntax in a Lisp, after all). By convention, function name ends with ? are predicates (or Boolean functions) in Clojure.

Any competent Clojure programmer would likely have known most of the Clojure core functions by heart: map, reduce, filter, etc. There are maybe about a hundred of them?

Unlike imperative programming languages, where you use three primitives (assignment, condition and loop) to construct everything, in Clojure, you use these core functions to construct your program. In a sense, the process of learning Clojure is the process of learning the use of core functions. These functions are simply at a higher level of abstraction than the three primitives, hence some people say that Clojure is more expressive, because it's closer to human thoughts than Von Neumann machine specificity.

Re:Metabase: Why we picked Clojure by sanderjd on Wednesday December 02, 2015 @07:43PM (#10666982)
> Any competent Clojure programmer would likely have known most of the Clojure core functions by heart

I really like Clojure, but I've always found the relatively huge set of core functions to be a major barrier to entry. I always have this nagging feeling of "there's probably a core function I'm missing to make doing this or that easier", and end up spending a lot of time poring over documentation instead of just programming. Maybe that's just how it is, and the answer is to push through it until you know the functions better, but there's something to be said for shipping a language with fewer, simpler, more primitive operations.

Re:Metabase: Why we picked Clojure by cobaltblue on Wednesday December 02, 2015 @09:06PM (#10667265)
It's definitely a taste thing. I found going from the batteries-included Python to the very limited strict C89 ansi-pedantic-standard rather annoying, but at the same time I got a lot of pleasure building a game from scratch in SDL instead of using a full-fledged engine that would have replaced a lot of my code with one-liners or even automagically managed bits in the background. I think a more overkill approach is better economically than being conservative, and in Lisp especially including a ton of common macros like 'or out of the box saves every other programmer from writing their own. I could go the rest of my life without seeing yet another custom <insert data structure here> in C or C++ which has a good implementation natively in almost every other language. I wish JavaScript had more builtin as I'm often in the position that things I take for granted as being there in Python, Java, or Clojure require me to roll my own in JS and that can easily take hundreds of lines of my own code or dependencies depending on what it is. (e.g. anything involving large integers.) I'm greatly thankful for regex support in my daily languages. I remember in a high school programming contest, one guy didn't know Java had regexes (or even what regexes were) while I knew them from using them in PHP to validate form inputs... Needless to say, he never got a fully working parser in the time he had for the problem.

You may find https://github.com/jonase/kibit helpful for some things. Otherwise I'd recommend just dedicating time to exploring the builtins so that you can resist the urge to wander while you should be programming -- there was a very interesting series a few years back some blogger made that covered all of Python's builtin modules, doing it yourself (or maybe there's one now for Clojure) is worthwhile. I also like to visit things like http://www.clojure-toolbox.com/ from time to time to see if there's anything new and exciting in areas of my interest.

Re:Metabase: Why we picked Clojure by huahaiy on Wednesday December 02, 2015 @08:00PM (#10667038)
From a cognitive point of view, learning a large number of idioms is more manageable for human beings than having to reinvent the mental constructs from primitives every time. This human capacity of dealing with idioms is what called "chunking" in psychology (https://en.wikipedia.org/wiki/Chunking_%28psychology%29)

Human has unlimited memory capacity and fast memory access, whereas human logical processing power is fairly limited and error prone. That's why any real human language has a large vocabulary.

Re:Metabase: Why we picked Clojure by dkersten on Thursday December 03, 2015 @08:29AM (#10669424)
"there's probably a core function I'm missing to make doing this or that easier"

Would you prefer if there wasn't such a function to make it easier? You lose nothing if there isn't (or you don't know about it) and gain if there is. Why is this a barrier to entry?

Re:Metabase: Why we picked Clojure by sanderjd on Thursday December 03, 2015 @06:32PM (#10673546)
I would prefer if there were very few un-namespaced functions which are limited to those I'm likely to use on any given line of code, and an intuitive namespace hierarchy for everything else. Basically, I think the core functions should be similar to reserved syntax is in other languages: a limited set of things that form the structure of most code, with more specific stuff imported from elsewhere. Note I'm not saying that the clojure way is "wrong", just that this[0] is a daunting set of information to be expected to "know by heart".

[0]: https://clojure.github.io/clojure/clojure.core-api.html

Re:Metabase: Why we picked Clojure by dkersten on Friday December 04, 2015 @02:53AM (#10675176)
Ah, I see. I can't disagree with that :)
Re:Metabase: Why we picked Clojure by j-pb on Wednesday December 02, 2015 @05:21PM (#10666292)
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/

Re:Metabase: Why we picked Clojure by SkidanovAlex on Wednesday December 02, 2015 @05:35PM (#10666372)
> (take 1000 (mapcat (fn [i] (repeat i (odd? i))) (range)))

And this example is suppoed to support Clojure's readability?

Re:Metabase: Why we picked Clojure by j-pb on Wednesday December 02, 2015 @05:42PM (#10666416)
You 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.
Re:Metabase: Why we picked Clojure by sanderjd on Wednesday December 02, 2015 @07:44PM (#10666985)
You missed a closing paren :)
Re:Metabase: Why we picked Clojure by huahaiy on Wednesday December 02, 2015 @08:10PM (#10667068)
It shows that Lisp programmers really don't care about balancing parenthesis, because editors do that for them.
Re:Metabase: Why we picked Clojure by j-pb on Thursday December 03, 2015 @04:37AM (#10668707)
Yeah, I really love the new parinfer stuff :D
Re:Metabase: Why we picked Clojure by j-pb on Thursday December 03, 2015 @04:36AM (#10668701)
whops ^^°
Re:Metabase: Why we picked Clojure by yeukhon on Wednesday December 02, 2015 @05:34PM (#10666364)
My 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.

Re:Metabase: Why we picked Clojure by huahaiy on Wednesday December 02, 2015 @05:49PM (#10666465)
Exactly 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.

Re:Metabase: Why we picked Clojure by dragonwriter on Wednesday December 02, 2015 @06:32PM (#10666674)
> 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.

Re:Metabase: Why we picked Clojure by j-pb on Wednesday December 02, 2015 @05:47PM (#10666447)
It'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

Logic programming for clojure. https://github.com/clojure/core.logic

Declarative UI building, with dataflow semantics. 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.

Re:Metabase: Why we picked Clojure by yeukhon on Wednesday December 02, 2015 @05:51PM (#10666480)
Thank 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.

Re:Metabase: Why we picked Clojure by dragonwriter on Wednesday December 02, 2015 @05:35PM (#10666368)
> 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.)
Re:Metabase: Why we picked Clojure by j-pb on Wednesday December 02, 2015 @05:40PM (#10666407)
You 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.

Re:Metabase: Why we picked Clojure by dragonwriter on Wednesday December 02, 2015 @06:22PM (#10666631)
Right, 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))
Re:Metabase: Why we picked Clojure by sokoloff on Wednesday December 02, 2015 @07:11PM (#10666860)
Doesn't that python code give you a list of 500,500 elements, rather than a list of 1000 elements as originally specified?
Re:Metabase: Why we picked Clojure by dragonwriter on Wednesday December 02, 2015 @07:13PM (#10666871)
In 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.

Re:Metabase: Why we picked Clojure by cobaltblue on Wednesday December 02, 2015 @07:43PM (#10666979)
Great Clojure feature:

    user=> (source even?)
    (defn even?
      "Returns true if n is even, throws an exception if n is not an integer"
      {:added "1.0"
       :static true}
       [n] (if (integer? n)
            (zero? (bit-and (clojure.lang.RT/uncheckedLongCast n) 1))
            (throw (IllegalArgumentException. (str "Argument must be an integer: " n)))))
Re:Metabase: Why we picked Clojure by jrumbut on Wednesday December 02, 2015 @07:09PM (#10666847)
Even as someone who prefers a functional style, that quote is pretty unfortunate. Any Turing complete language is going to be able to express the same ideas (with varying degrees of gracefulness, resource usage, ease of debugging, etc).