I think there's a distinction between idiomatic code and code written for performance. Performance-conscious code looks a lot like C in most languages, not just Julia. Julia just happens to have a lot of that kind of code because it makes it easy to write.
But look at the high-level, user APIs and you tend to see the more functional side – `fft(x)`, `plot(y)` etc., all pure functions which return expressions. Mutation is possible but discouraged via the `!` modifier.
Functions are the primary unit of abstraction – larger programs tend to be designed as collections of functions as opposed to object hierarchies. Higher-order functions like map and filter (aka "functionals") are encouraged.
So I tend to view Julia as a nice functional language which lets me drop down easily when I need to.
I recently started a project in Julia and, excited by the prospect of a smart JIT compiler, wrote everything in a declarative function style with maps, reduces, and filters. The result was slower than than equivalent Python code. I swallowed my aesthetic sense and rewrote every function imperatively, with for loops updating some mutable array, and now it is quite fast. But I am no longer enjoying coding as much. I switched to Julia for speed, but that speed seems to come at the cost of having to write very imperative code.
In terms of day-to-day programming, I'm not sure what makes Julia a better functional language than Python or Ruby. From my limited experience, it isn't speed.
I understand that work is under way to speed up anonymous function calls and to improve type inference on arrays resulting from `map`, etc. Once that is done then I will consider Julia a nice functional language.
"Idiomatic" might have been the wrong way for me to put it, but it seems like one of the biggest advantages and fundamental design decisions of Julia is that it makes numerical computing through side effects _very easy_. Most performance-conscious code doesn't just look like C in other languages, it is C! So I see your point, but I still wish there were a better way to convey exactly the mix of high and low level code that Julia's aiming for.
But look at the high-level, user APIs and you tend to see the more functional side – `fft(x)`, `plot(y)` etc., all pure functions which return expressions. Mutation is possible but discouraged via the `!` modifier.
Functions are the primary unit of abstraction – larger programs tend to be designed as collections of functions as opposed to object hierarchies. Higher-order functions like map and filter (aka "functionals") are encouraged.
So I tend to view Julia as a nice functional language which lets me drop down easily when I need to.