Hacker News new | past | comments | ask | show | jobs | submit login

It would be very helpful if you provided some specific examples of code in both Julia and Fortran that is under-performant in Julia. As it stands, your concerns about things like "fancy abstractions that no engineer or scientist will ever understand" are rather too vague to be effectively resolved.



The "fancy abstractions" criticism is kind of orthogonal to the performance one.

Specific complaints about arrays are the design choice to not include dimensions in the type parameters. It means that simple errors only show up at runtime, sometimes hours into a simulation. The ability to specify not enough/too many indices is also a problem for the same reason.

It's hard to provide specific examples because a lot of the time I don't understand why something is happening. For example,

    n = 10; [i for i=1:n]
gives an Array{Any,1}, but when I try to figure out why in the interactive prompt,

    [i for i=1:10]
gives an Array{Int64,1}. In my experience the Any version is slower, and they crop up all over, deep my programs. So I have to manually use

    n = 10; [i::Int64 for i=1:n]
The type system is generally quite nice and I like working with it a lot. But none of my colleagues know what it is and don't care how it works, they just want to add doubles together. So the fact that things like

    x = Array(1)
give error messages like

    ERROR: MethodError: `convert` has no method matching convert(::Type{Array{T,N}}, ::Int64)
    This may have arisen from a call to the constructor Array{T,N}(...),
    since type constructors fall back to convert methods.
    Closest candidates are:
      call{T}(::Type{T}, ::Any)
      convert(::Type{Array{T,N}}, ::SharedArray{T,N})
      convert{T,N}(::Type{Array{T,N}}, ::AbstractArray{T,N})
      ...
     in call at essentials.jl:56
scares the living bejesus out of anyone who wants to simply use arrays without knowledge of types, parametric types, constructors, and the call and convert functions (not to mention that SharedArray and AbstractArray). All of this is too much abstraction for a normal scientist or engineer to want to have to deal with. What the error message really should just say is

    Missing type parameter in method: Array(<type>, <dimension>)
Arrays are implemented as abstract types and now constructors fall back to convert, which is all very clever and fits into the grand type system view, but the result is that the debug information is hugely complicated.

As for the performance, I've been trying to implement my own FixedSizeArrays type thing, where arrays have dimensions as type parameters. My code for 1D looks like this:

    immutable Float1D{nx}
        data :: Array{Float64,1}
        Float1D() = new(Array(Float64,nx))
        function Float1D(xs::Array{Float64,1})
            size(xs) == (nx,) || error("Size of initialization array ($(size(xs))) does not match type parameter ($nx)")
            new(xs)
        end
    end
    size{nx}(xs::Float1D{nx}) = (nx,)
    getindex(xs::Float1D, i::Int) = xs.data[i]
    setindex!(xs::Float1D, v::Real, i::Int) = xs.data[i] = v
And it's performance is much worse than the native arrays. I don't know why, since the methods seem simple enough to inline, but I'm sure there is a lot I'm missing. I think maybe it is partly because the Julia Array type and its methods seem to be implemented in C. Either way, having thought about this a lot and understand the compiler and type system reasonably well (for an end user) I still don't know how to get it to go faster. I think that is unreasonably complex for people who just want code to work fast.


I understand your concerns better now. Here's my input for what it's worth:

(1) List comprehensions are a mess and a recognized problem with the existing compiler. There's a lot of work that's been done to fix the erratic typing of comprehensions. As such, I am sure that this concern will be resolved before 1.0. I would bet that it will be resolved much sooner than that.

(2) I don't really believe that scientists can't learn that Array(Int, 1) and Array(Float64, 1) do different things. This seems like a place where education can be very effective.

(3) Julia's error messages are indeed generally poor. I'm hopeful that we'll see a push towards Elm-quality error messages in the future: http://elm-lang.org/blog/compilers-as-assistants

(4) The core problem with your fixed size array example is that you're building it on top of the wrong primitives. Julia's Array isn't a suitable data structure for building up fixed-length arrays: Julia's Array is more like C++ std::vector than like C's arrays. To build a real fixed length array, you need to build it on top of lower-level primitives. Many people are already working on that problem.

Putting it all together, I think your concerns all reflect real problems with the language. You may be better off waiting until Julia 1.0 comes out.


Waiting for 1.0 isn't an option for me; I love the language too much already, even if that wasn't apparent from my generally negative comments. Currently I can work around all the corner cases myself, but encouraging/convincing others of Julia's merits is a difficult task at the minute. Thanks for your feedback on my fixed size arrays code.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: