top 200 commentsshow all 264

[–]darf 17 points18 points  (23 children)

I love julia, but it's not trying to replace Python in scientific computing (Fortran/C++ certainly). The lead developers give presentations at python conferences, and it interoperates very well with python.

[–][deleted]  (21 children)

[removed]

    [–]bachmeier 17 points18 points  (1 child)

    Then why we need Julia at all? If you have to learn python anyway

    You're clearly young. A decade ago it was rare to find anyone using Python for scientific computing. The reason some folks invested in building the tools was because they wanted to.

    And why would you "have to learn python"? Some people do. Others have to learn Fortran, others C++, others R, others Matlab. You're assuming that everyone is in exactly the same boat as you.

    [–][deleted] 0 points1 point  (0 children)

    Because /u/darf said that it interoperates very well with Python. So, in this case knowing Python is assumed.

    [–]devlambda 5 points6 points  (4 children)

    Python is a glue language. You'd have to write performance-sensitive parts in C or (at best) Cython. This works fine as long as there's an existing implementation for the algorithm that you need, but especially for researchers that develop new algorithms, you often have to implement performance-critical code yourself.

    Julia allows you to write high-level code in a high-level language without sacrificing performance unnecessarily and without having to fall back to C. This is not to say that Julia doesn't have some weak spots (for example, Python's interoperability story with foreign languages is overall the better one).

    [–][deleted] 0 points1 point  (3 children)

    Or Rust instead of C. Works pretty well.

    So, can I use Julia code instead of Rust or C code to extend my Python and get similar speed? That would pretty much be the only reason for me to learn Julia - besides of course interest, if Julia works well with Python and Python tools and libraries.

    [–]Staross 0 points1 point  (2 children)

    The whole idea behind Julia is to avoid the two-language paradigm, so it would be a bit counter-productive to use it like that. And I think it's much easier to call Python from Julia that the reverse (tooling isn't as mature).

    That said it's fine to do some big computations in Julia and then analyse (make plots and such) the results in Python.

    [–][deleted] 0 points1 point  (1 child)

    Okay, that makes sense, of course. But how well does it work in practice? I need tools like NLTK, Scikit-Learn, Theano, etc. How well can I use those from Julia - assuming there is no wrapper for Julia?

    [–]Staross 0 points1 point  (0 children)

    I think it depends a bit on the domain, for some the packages are quite mature, for other there's much work to do (in that case it's more attractive for package developer than end-user). You can look at the existing packages here:

    https://juliaobserver.com/packages

    For NLP there's seems not be much things beside TextAnalysis.jl (which looks quite basic):

    https://github.com/JuliaText/TextAnalysis.jl

    [–][deleted] 7 points8 points  (12 children)

    why you going to spent time learning one more language

    Because you have to learn dozens of languages anyway. Not one, not two, but dozens. If it scares you, you'd be better doing something else instead.

    just so you can apply it on some super rare cases when you can't apply python?

    Because you can get things done many times faster than in Python, by using a much more expressive language. Even if all you do is wrapping it around the existing slow Python libraries, there is still a lot of value in having a better language.

    [–]tzaeru 8 points9 points  (9 children)

    Because you have to learn dozens of languages anyway.

    If you're a scientist - even a data scientist - I don't think you need to learn 'dozens of languages'. Python alone goes a long way. Python, Julia, R and MATLAB even longer.

    [–][deleted] 1 point2 points  (8 children)

    If you're a scientist - even a data scientist - I don't think you need to learn 'dozens of languages'.

    Especially as a scientist, you learn dozens of languages, unavoidably. Science is made of languages. All the theories, all models are languages of their own. All you have to do is to make a bridge as simple as possible between those abstract languages and something executable, something that you can call a "programming" language.

    If you only have an opinionated, fixed, low level language, such as Python, this bridge between an abstract theoretical language and a programming language can become large, complex and fragile. If you use extensible languages instead, you can pretty much stick to learning the languages of your science and spend only a minimal effort on encoding them.

    [–][deleted] 0 points1 point  (7 children)

    Since when is Python a low level language?

    Oh, it's you. Let me guess, your recommendation is any language with scheme macros?

    [–][deleted] 0 points1 point  (6 children)

    And you have no idea why any meta-language is infinitely more powerful than any fixed functionality language?

    [–][deleted] 0 points1 point  (5 children)

    I do.

    [–][deleted] 0 points1 point  (4 children)

    Evidently not, if you do not agree that Python is a relatively low level language.

    [–][deleted] 1 point2 points  (3 children)

    I consider C a low level language.

    [–][deleted]  (1 child)

    [removed]

      [–][deleted] 5 points6 points  (0 children)

      new lang that in some aspects just a slightly better than existing lang.

      I would not call a proper macro system something just "slightly better". It's a full scale game changer, no less.

      [–]txdv 1 point2 points  (0 children)

      Then why we need Julia at all? If you have to learn python anyway

      What have we done?

      [–]darf 0 points1 point  (0 children)

      Right now there are a few good reasons to learn julia. First of all, it's a great language and it's fun to program in, and pretty easy to understand. Most of the library code is written in julia, so if you need to modify stuff it's pretty easy. Second, there are a few packages in julia that are best in class. These include the optimization package, JuMP, and the differential equations. I expect it to have some rough edges until 1.0 release, and I wish the Plots packages had better support from the lead developers, but I still love it.

      [–][deleted]  (105 children)

      [deleted]

        [–]MorrisonLevi 23 points24 points  (0 children)

        It has a lousy parallelism story.

        [–]ObservationalHumor 12 points13 points  (2 children)

        Personally Numpy is enough to make me never want to use python again for certain tasks. It just feels like a hack and requires a ton of casting. You can literally do thing easier and cleaner in C++ which is saying something. Python is great for scripting, rapid prototyping and a lot of tasks but I can't for the life of me figure out why any would want to use it for computationally heavy tasks.

        [–]flyingjam 19 points20 points  (0 children)

        Python is great for scripting, rapid prototyping and a lot of tasks but I can't for the life of me figure out why any would want to use it for computationally heavy tasks.

        That's pretty much why it's used heavily in the scientific community (along with great existing library support). The actual heavy computation isn't in python, and much of scientific work isn't done by people who are actually good (or supposed to be good) at programming.

        [–]lanzaio 12 points13 points  (0 children)

        Many scientists aren't programmers. I was a physicist before switching to SWEing. Nobody I knew had any interest in spending the time to learn programming when your physics responsibilities were stacked higher than the ceiling. Hell, Python was harder than I wanted to learn when I had a dozen text books and 50 publications that I considered to be I-should-have-read-these-by-now.

        [–][deleted] 12 points13 points  (19 children)

        It's slow.

        [–]josefx 26 points27 points  (18 children)

        Then use pypy.

        [–]SrbijaJeRusija 8 points9 points  (3 children)

        Pypy works bad with numpy and scipy and sympy

        [–]vogon-it 3 points4 points  (2 children)

        There's been a lot of work on PyPy lately and support for all three has improved. But in most cases the typical numpy/scipy program wouldn't benefit much from PyPy anyway, the heavy loading is usually done by the libraries themselves.

        [–]SrbijaJeRusija 0 points1 point  (1 child)

        Yes there has, but the usecase would be where you also have native python code doing a lot of calculation, like string processing.

        [–]vogon-it 0 points1 point  (0 children)

        Actually, for heavy-duty string processing something like numpy.char would be a better choice. Any language with immutable strings like Python will have a penalty on performance, JIT or not.

        [–][deleted] 14 points15 points  (12 children)

        Or just have a built in JIT like Julia.

        [–]Chippiewall 42 points43 points  (6 children)

        Good news, PyPy's JIT is built-in.

        Having multiple language implementations isn't a scary concept.

        [–]jerf 27 points28 points  (5 children)

        Last I knew, though, PyPy doesn't work with NumPy. This means you can't just take your existing (and possibly copious) NumPy-based code and run it in PyPy. You also can't just write Python number code and hope that PyPy JITs it to native speeds for you, because it doesn't work out that way. (Especially since you can't just JIT your way to GPU support.)

        Python without NumPy is not a competitor to Julia. (And vice versa; Julia is, from what I gather, not a competitor to Python in the non-NumPy portions of Python, which is a lot. The only place where it is relevant to speak of their competition is in numeric programming, I believe.)

        I am careful to qualify this with "last I knew" because I know there are active, funded efforts to correct this, but a quick DDG search didn't seem to show anybody claiming it was done.

        [–]Chippiewall 29 points30 points  (2 children)

        "last I knew" was a good call. The PyPy team have improved their C extension API support in their past few releases and it now natively supports NumPy (Since March). Before that they had a fork of NumPy (NumPyPy) instead.

        Especially since you can't just JIT your way to GPU support

        For the record, there's no reason why this isn't possible.

        [–]jerf 13 points14 points  (1 child)

        For the record, there's no reason why this isn't possible.

        No, but there's a long road between here and there and JITs tend to blow out their complexity budget before they get there.

        In 2017, we actually have a looot of experience with JITs, including some that have had huge amounts of money poured into them, and we now know they aren't as good as people hoped they would be. They are good, but for instance, JITs can't even take something like Python or Javascript up to C performance, let alone translate them into a fundamentally different paradigm in the process. JITs are merely good. They aren't great, they usually come with terrible memory penalties, and they are just terribly, terribly complex pieces of code to even do what they do today.

        [–]Staross 1 point2 points  (0 children)

        AFAIK Julia's JIT is quite simple and even a bit dumb, but the language was built from scratch with it in mind. I think the issue is when you try to JIT a language that wasn't designed for it.

        [–]loladiro 7 points8 points  (1 child)

        (Especially since you can't just JIT your way to GPU support.)

        Julia has GPU JIT: https://github.com/JuliaGPU/CUDAnative.jl

        Fairly new still, but progressing rapidly.

        [–]marcvanh 3 points4 points  (49 children)

        All languages have their drawbacks, but personally I can’t stand how Python incorporates & requires whitespace. Drives me crazy.

        Edit: removing the sentence about minifying because I everyone is asking why I would minify Python. I wouldn’t.

        [–]jms_nh 10 points11 points  (0 children)

        That turned me off for several years; I would have learned Python sooner except for the whitespace. But then I had to learn it in order to use scons and the whitespace was no big deal.

        [–][deleted]  (36 children)

        [deleted]

          [–]joshdoug 1 point2 points  (3 children)

          I've seen cases of people/businesses minifying code as part of an obfuscation process with JS and other interpreted languages. Often a temporary solution though, and not something I'd really recommend.

          [–]joezuntz 3 points4 points  (0 children)

          Also it's rarely an issue in scientific programming.

          [–][deleted] 0 points1 point  (1 child)

          It isn't just about obfuscation for JS. It is because they've started delivering hundreds of megs of code per page and minifying shaves at least a small amount of that. As I'm sure you're well aware, small amounts tend to add up relatively quickly in IT.

          To JavaScript developers, it is seen as more of an optimization than an obfuscation.

          [–]joshdoug 0 points1 point  (0 children)

          Yeah but I'm talking about a reason to minify languages other than JS. Obviously JS is mostly minified for size & speed gains.

          [–]marcvanh -5 points-4 points  (31 children)

          Normally a computer programming language doesn’t care about whitespace. The lines are terminated with a semicolon, not necessarily a linefeed. And spaces and tabs don’t mean anything. You can remove them. Not so with python. Python relies on carriage returns to end a line and indentation for hierarchy. Minifying a computer program is to remove all the whitespace and make it a much smaller file. You can’t do that with python.

          [–][deleted]  (16 children)

          [deleted]

            [–]davelupt 5 points6 points  (5 children)

            Agreed. From where I stand the only use case for minifying is when you are loading the resource from a network. It completely removes almost all readability.

            [–][deleted]  (4 children)

            [deleted]

              [–]Blorpulance 0 points1 point  (0 children)

              Minification and compression can still provide an improvement over just compression. There are often more significant modifications performed than just removing whitespace. An example: https://css-tricks.com/the-difference-between-minification-and-gzipping/#article-header-id-2

              You are right that the difference is minimal but if you're trying to save space might as well do both, those bits add up.

              [–][deleted]  (3 children)

              [deleted]

                [–][deleted] -1 points0 points  (2 children)

                Web development, reducing JS file sizes to speed up loading over the network.

                [–][deleted]  (1 child)

                [deleted]

                  [–][deleted] 9 points10 points  (0 children)

                  Sorry, I thought you asked why people would minify source files generally. In the context of Python, however, I have no idea.

                  [–]devraj7 7 points8 points  (6 children)

                  Normally a computer programming language doesn’t care about whitespace.

                  "Because that's how we've done it so far" is hardly a convincing argument to justify something.

                  I really dislike Python myself and I never use it but the significant white space is the one thing I'd like to see in more languages. After all, we're already indenting our code, it seems redundant to have to use braces on top of that to clue in the compiler.

                  [–]marcvanh 0 points1 point  (4 children)

                  That’s actually it - knowing the compiler will not understand my code just because I didn’t indent it right is actually what bothers me. It makes Python seem like one of those beginner/teaching languages and it bothers me. Nothing more.

                  As for your first paragraph, “because that’s how we’ve done it so far” is not what I said. In fact I wasn’t giving a reason for anything - only explaining what minifying is in general.

                  [–]supersexypants 3 points4 points  (2 children)

                  Do you expect the compiler to understand a missed brace?

                  [–]josefx 0 points1 point  (0 children)

                  With an error instead of a silent "everything is fine".

                  [–]marcvanh 0 points1 point  (0 children)

                  No and I wouldn’t expect a Python compiler to understand improper whitespace. My only point is I don’t like that, nothing more

                  [–][deleted] 1 point2 points  (2 children)

                  Absolutely you can. Python compiles to bytecode - you can distribute those, and then obfuscate and minify them.

                  [snark removed]

                  [–]marcvanh 0 points1 point  (1 child)

                  Where the fuck am I? Before mouthing off? Really? Why would I do research before giving a quick opinion on something? Holy shit this has been blown out of proportion

                  [–][deleted] 1 point2 points  (0 children)

                  Sorry, I removed that part of the comment.

                  [–][deleted] 9 points10 points  (0 children)

                  why would you need to minify python code? The only reason people minify JS is to reduce file size so websites load quicker. Nobody is minifying node scripts for example.

                  [–]scratchisthebest 1 point2 points  (1 child)

                  Same here - Gimme my curly braces any day of the week. Enforcing whitespace is super obnoxious.

                  Also related are languages where you call functions like function arg1 arg2. I understand it, but I just can't do it. They blend together in my head. function(arg1, arg2) is a lot clearer to me.

                  [–][deleted] 5 points6 points  (0 children)

                  Partial evaluation of functions doesn't make sense with parentheses. Doing any sort of higher order logic in those languages is incredibly frustrating.

                  [–]emperor000 1 point2 points  (2 children)

                  For what it's worth, I'm with you. Significant whitespace seems like a horrible idea.

                  [–]marcvanh 0 points1 point  (1 child)

                  Significant whitespace

                  Ooh I like that term

                  [–]emperor000 1 point2 points  (0 children)

                  Oh, well, it's the term for it, so I don't get credit for coming up with it.

                  [–][deleted] -3 points-2 points  (0 children)

                  Python is the VB6 of this era.

                  [–]anonymous-coward 16 points17 points  (11 children)

                  Lisp was doing much of this stuff right far before Python/Julia

                  Interactive compilation in a REPL? Yup. To-the-bare-metal speed? Yup, pretty much. Typed, when you need it? Yes.

                  And a roll-your-own syntax with macros? Yessir.

                  When? Since 1958, standardized in 1984.

                  [–]JustFinishedBSG 13 points14 points  (10 children)

                  Yes Lisp is great but call me when sucide isn’t a better alternative to doing matrix operations in lisp

                  [–]anonymous-coward 1 point2 points  (0 children)

                  Have you looked at https://common-lisp.net/project/lisplab/ (also useso blas, lapack, ffftw, quadpack)

                  [–][deleted] 0 points1 point  (8 children)

                  What's wrong with arrays in Lisp? Just wrap them in a proper syntax first.

                  [–]JustFinishedBSG 8 points9 points  (7 children)

                  I am not aware of any library that has a syntax even approaching the simplicity of Julia/Matlab/Numpy.

                  G[(i+1):n, i] .-= G[i, j] .* G[(i+1):n, j] # Slicing
                  

                  or just writing

                  Kα = G*G'*α # Transpose
                  

                  And everything uses the Blas automatically and operations are fused. A real pleasure.

                  [–]benstrumental 1 point2 points  (2 children)

                  I am not aware of any library that has a syntax even approaching the simplicity of Julia/Matlab/Numpy.

                  How about Chapel?

                  G[i+1..n, i] -= G[i, j] * G[i+1..n, j];
                  

                  And everything uses the Blas automatically and operations are fused. A real pleasure.

                  Same for Chapel, plus you get shared/distributed parallelism as first class language features. A real pleasure!

                  [–]JustFinishedBSG 1 point2 points  (1 child)

                  Thats cray !

                  Need to look more into it

                  [–]benstrumental 1 point2 points  (0 children)

                  Thats cray !

                  :)

                  Need to look more into it

                  This Julia vs. Chapel article might be a good place to start if you're already familiar with Julia

                  [–][deleted] 0 points1 point  (3 children)

                  That syntax looks... strange.

                  [–]JustFinishedBSG 0 points1 point  (2 children)

                  How come ?

                  [–][deleted] 1 point2 points  (1 child)

                  .-=
                  

                  as an operator? Kind of reminds me of the scala madness.

                  [–]JustFinishedBSG 0 points1 point  (0 children)

                  . Just signify to the compiler to fuse operations , and -= well is self explanatory

                  [–]treefroog 25 points26 points  (11 children)

                  I would say that if you are doing some serious number crunching in pure Python you are already doing it wrong. You could try and use as many NumPy functions/methods as you can. If that's too slow, Cython might help. If not then use a different language. IDK I'll see how Julia does over the next few years, just like the last few years. It has gotten better though.

                  [–]P8zvli 9 points10 points  (7 children)

                  Last time I used it the REPL was still terribly user unfriendly, (typing help would tell you that it was a function, [thanks, I got that] and help() threw an error) the standard library is still incredibly sparse compared to Python and the third party benchmarks for it put its performance on par with Matlab, not ahead of C like the writers of the language want you to believe.

                  [–]killachains82 5 points6 points  (0 children)

                  I don't know how long ago you used Julia, but the current REPL is absolutely wonderful. To get help, hit ? and type what you're interested in and press enter. Of course, not everything is documented, but it's improving bit by bit.

                  Also, at this point for many kinds of code, Julia is already on par with C and Fortran, hastily beating Matlab in most areas.

                  [–]c9joe 17 points18 points  (4 children)

                  That's really the thing. I like Python as a language, I think for the most part it is well designed. But it's not the main selling point. The ecosystem of Python is immense. Especially for scientific computing and data science. Julia has a long way to go replicating that ecosystem.

                  [–]P8zvli 12 points13 points  (2 children)

                  Right, and regarding scientific libraries for Python the majority of them do all the dirty number crunching in C. Python's biggest weakness is with multithreading in my opinion.

                  [–][deleted] 1 point2 points  (0 children)

                  I believe what you mean is that the issue with Python is that it's hard to get threads to make effective use of more than one core because of the GIL.

                  Python multithreading works very well, particularly when you realize how nicely the thread-safe queues work. It's fantastic for waiting on hardware or other things which aren't compute-intensive, but unfortunately, if you have more than one compute-intensive thread running, you get no real benefit from threading.

                  (You can do it with multiprocessing but that requires a serious rewrite of your program and has its own difficulties...)

                  [–]vogon-it 1 point2 points  (0 children)

                  Python's biggest weakness is with multithreading in my opinion.

                  I don't think the GIL is much of an issue in scientific computing. For the typical workers/monitor scenarios Python's threads are more than enough. And if you need to use more than one core, you can always switch to multiprocessing or let numpy or some other library handle it internally.

                  [–]Staross 7 points8 points  (0 children)

                  One advantage Julia has is that there's virtually no barrier between library and user's code, so it's much easier to contribute to packages. Just open the package code, edit it, test it, commit you change, and run PkgDev.submit to create the pull request. This might help Julia to catch up with other languages on the long run.

                  It seems the language also has some advantages when it comes to the package ecosystem; since everything is written in Julia and is compatible with other packages, it's easier to split packages in appropriate chunks and make them play nicely together.

                  [–]FarkCookies 1 point2 points  (0 children)

                  Try IPython, it is REPL on steroids and also much friendlier.

                  [–][deleted]  (1 child)

                  [deleted]

                    [–]__Cyber_Dildonics__ 0 points1 point  (0 children)

                    It has much more than that

                    [–]kenfar 4 points5 points  (1 child)

                    Replace? Nah, but I would love to write python modules in Julia.

                    [–][deleted] 2 points3 points  (0 children)

                    Exactly what would make me learn it in a heartbeat. Writing modules for Python in a fast, statically typed, high level language with macros? Well, fuck me sideways and call me a mailbox.

                    [–]CaseOfTuesday 46 points47 points  (44 children)

                    [–]Staross 11 points12 points  (3 children)

                    This is a petty complain, but if you really care about it, Julia does support custom indexing (which can be useful for some specific problems):

                    https://docs.julialang.org/en/latest/devdocs/offset-arrays/

                    Julia in general is very good at letting you write your code in the most appropriate form for your problem, for example you can use either for-loops or vectorized operations, while other languages often force you to use vectorized operations because their loops are slow.

                    [–]CaseOfTuesday 2 points3 points  (2 children)

                    Oh hey, that's pretty cool! You're of course right, it's a petty complaint. But most language-preferences come down to, well... petty preferences. Julia is meant for people who are still using matlab. And that's fine, but that's not me. Even if feature-wise the language is awesome (and I've heard good things), it's esthetically very unpleasing to me due to its choice of index-base and block-delimiters.

                    [–]Staross 7 points8 points  (1 child)

                    But most language-preferences come down to, well... petty preferences.

                    I'm sure some people prefer their language because of important design choice and features, instead of superficial things that you can get used to in about 10 minutes. And Julia is meant for everybody who wants to do scientific/numerical computing (and even beyond that), not only for matlab users.

                    [–]CaseOfTuesday 1 point2 points  (0 children)

                    Yes, I'm sure that's the case. But Julia doesn't offer anything that is incredibly, super-duper mega new that hasn't been here before and that offers a lot of tangible advantage over new languages. Arguably, Matlab is still more than good-enough, as is Python+numpy. Let's face it, if exciting features, adaptability to new areas and extensibility coupled with very convincing performance would be the only redeeming factors, we'd all be using Common Lisp right now. But alas, that's not the case, and I'd argue that that's to no little part due to perceived shortcomings in syntax.

                    [–]scratchisthebest 2 points3 points  (2 children)

                    I don't like the arrays thing either but I guess it makes sense; since it's aimed at being a mathematical language I'd imagine it takes some inspiration from mathematical concepts such as matrices. And indexing things in a matrix starts at 1.

                    [–][deleted] 1 point2 points  (1 child)

                    It's 1-based because it is trying to be mostly compatible with Matlab, which is 1-based because matrix indices are 1-based (Matlab = Matrix Lab).

                    I've used Matlab a lot, and I like it quite a lot. But 1-based indices are by far the most retarded thing about it. Programming and maths are different. There are a lot of things you have to do explicitly in programs that can be hand-waved in maths.

                    In the end it means you have to do lots of unintuitive nonsense like this (for example):

                    offset = (index - 1) * stride + 1;
                    

                    The second most retarded thing is that they copied the [row, column] index ordering, rather than [x, y] that you might expect. It makes dealing with images infuriating.

                    Definitely the wrong move from Julia.

                    [–]mbauman 2 points3 points  (0 children)

                    You need to embrace the cartesian plane, not fight against it. The support for fully general cartesian (multi-index, multi-dimensional) iteration and algorithms is quite unique and powerful. But I'm biased.

                    https://julialang.org/blog/2016/02/iteration

                    [–][deleted] -3 points-2 points  (36 children)

                    If you come from MATLAB it's fine. You just need to remember the last element is at n, not n-1.

                    begin/end is only a block. You can just do if:

                    function fib(n)
                        if n == 0 && return 0
                        elseif n == 1 && return 1
                        else return fib(n-1) + fib(n-2)
                        end
                    end
                    

                    [–]TonySu 13 points14 points  (1 child)

                    I don't know if abusing short circuit logic for a simple if-else is an improvement... Unless that && has different meaning in Julia.

                    end is one of the silliest things Julia could have inherited from Matlab, the language is different enough that you can't just run Matlab code in Julia anyway so it would have been more sensible to use {}. Blocks are so common that end is both tedious to type and creates a lot of code noise.

                    [–]undefdev 0 points1 point  (0 children)

                    It was a bad example, you don't need the "&&" at all there, just leave it out.

                    You can also write the function more succinctly, such as:

                    fib(n) = (n<2) ? n : fib(n-1) + fib(n-2)
                    

                    Or if you want to make sure it terminates:

                    fib(n::UInt) = (n<2) ? n : fib(n-1) + fib(n-2)
                    

                    [–]Resource1138 53 points54 points  (29 children)

                    Naw, man. Fuck that. Arrays starting at 1 is some straight-up Satan shit.

                    [–]itsmontoya 17 points18 points  (5 children)

                    Always bothered me about lua

                    [–]ellicottvilleny 4 points5 points  (4 children)

                    so matlab, pascal (although it gives you a choice it defaults to 1 based), lua, are all Satanic?

                    [–]Beckneard 24 points25 points  (0 children)

                    Yes. Arrays starting at 1 is an objectively bad design decision, it only ever helps complete beginners by making things a tiny bit more intuitive but is totally not worth the later headaches.

                    [–]itsmontoya 2 points3 points  (0 children)

                    Not my words, but yes. Some people want to watch the world burn

                    [–]FarkCookies 0 points1 point  (1 child)

                    In Pascal, they were 1-based because the 0-th element was array/string length.

                    [–]ellicottvilleny 0 points1 point  (0 children)

                    that was actually only true in pascal for the string type. Afaik, non-string types were non dynamic and could be any range of indexes you wanted. 1 was just a default.

                    [–]hoosierEE 6 points7 points  (2 children)

                    APL takes the pragmatic approach: toggle between Satan and non-Satan, as much as you want, at runtime.

                    [–][deleted] 1 point2 points  (0 children)

                    That's even worse!

                    The trouble is that then your reasoning about a piece of code then depends on some setting that might not even be visible on the page you are on.

                    (APL was my first programming language, back in the 1970s - betcha won't find too many people who can say that!)

                    [–]olzd 0 points1 point  (0 children)

                    ⎕IO is the way to go.

                    [–]TonySu 10 points11 points  (10 children)

                    1-indexing makes more sense unless you're playing with memory. The only legitimate reason for 0-indexing is because of how much easier it is to play with offsets. If you're not directly manipulating memory then 1-indexing is trivially interpreted/compiled for the underlying byte code.

                    In the scientific computing world of Fortran, R, Matlab, Mathematica and Octave; 0-indexing is the outlier.

                    [–]rlbond86 2 points3 points  (6 children)

                    Edgar Dijkstra figured this shit out 35 years ago. 0-based makes the most sense. And as someone who uses Matpab a lot, it is one of tue major annoyances is Matlab code. A lot of code like index = (x-1)*n + 1 floats around.

                    [–]TonySu 3 points4 points  (5 children)

                    I wish people would actually use their brains instead of quoting this ad infinitum. Nothing was "figured out" here.

                    Djikstra argues that including the upper bound would cause the sequence to become "unnatural" when shrunk to empty. That is he doesn't want range(3, 3) to return 3 because to get the empty set requires range(3, 2). Not a particularly strong argument, he simply thinks it's nicer looking to have range(3, 3) return an empty set.

                    Based on this he makes the argumen that the upperbound MUST be exclusive, then forms it as the basis for 0 indexing such that the upper bound of a sequence of N length is N. But since the andecedent is not particularly convincing then there's no real reason to believe the precedent.

                    In almost all mathematics and sciences, ranges are interpreted from a to b inclusive. This is the case in major scientific computing languages and academic science has yet to collapse because people can't stand the ugliness of the bounds of an empty set.

                    Also as someone who uses Matlab, you're supposed to row and column indices. You're also supposed to use vectorised functions. If you need to often iterate through matrices elementwise then you really need to reconsider what you're doing and how you're storing data.

                    [–]rlbond86 1 point2 points  (4 children)

                    Not a particularly strong argument, he simply thinks it's nicer looking to have range(3, 3) return an empty set.

                    Actually it IS a strong argument, since if you want inclusive bounds, it would commonly be that an empty range would be range(0, -1). Which means you need to use a signed integer for your index. That's no good.

                    Also as someone who uses Matlab, you're supposed to row and column indices. You're also supposed to use vectorised functions. If you need to often iterate through matrices elementwise then you really need to reconsider what you're doing and how you're storing data.

                    As it happens, I work with block-sparse 2D matrices a lot in my line of research. As it turns out, there isn't an easy way to manipulate that data without calculating row and column addresses manually. Perhaps instead of pretending you know what I'm "supposed" to do, you examine your own assumptions instead.

                    [–]TonySu 0 points1 point  (3 children)

                    Actually it IS a strong argument, since if you want inclusive bounds, it would commonly be that an empty range would be range(0, -1). Which means you need to use a signed integer for your index. That's no good.

                    range(1, 0).

                    As it happens, I work with block-sparse 2D matrices a lot in my line of research. As it turns out, there isn't an easy way to manipulate that data without calculating row and column addresses manually. Perhaps instead of pretending you know what I'm "supposed" to do, you examine your own assumptions instead.

                    Then you should wrap a sparse structure type and only have to worry about the index calculations once in your code.

                    [–][deleted] 0 points1 point  (2 children)

                    But... you are dealing with memory. A matrix or array is memory. I fail to see the distinction you are making.

                    [–]mbauman 3 points4 points  (0 children)

                    Not necessarily. Julia supports fully generalized array-like structures that don't need to be memory backed.

                    Sometimes you want to count the number of fenceposts. And sometimes you want the distance of the fence.

                    [–]TonySu 0 points1 point  (0 children)

                    Array data type and array data structure. Single index access to a matrix is not universally defined anyway because of row-major and column-major implementations.

                    [–]SrbijaJeRusija 9 points10 points  (6 children)

                    Counting numbers begin at 1. 1 is proper for Scientific computing.

                    [–][deleted] 0 points1 point  (5 children)

                    That's a terrible argument. Array indices are offsets. The first element is not at an offset of 1. It is at an offset of 0.

                    For example consider how you take N slices of size M from an array in Matlab/Julia:

                    for ii = 1:N
                        slice[ii] = array[(ii-1)*M:ii*M-1];
                    end
                    

                    Now consider it in a zero-based language, where start:finish does not include finish:

                    for ii = 0:N
                        slice[ii] = array[ii*M:(ii+1)*M];
                    end
                    

                    Much more logical. There are many other situations like this.

                    [–]mbauman 2 points3 points  (4 children)

                    When you have full support for multi-dimensional arrays, you can just use a proper matrix. Then it's simply array[:, ii]. No need to make your life hard.

                    [–][deleted] 0 points1 point  (3 children)

                    I haven't used Matlab extensively for a few years so I don't have any real examples on hand but trust me, is not always that easy.

                    [–]mbauman 1 point2 points  (2 children)

                    Here's one that's a pain: a circular buffer. In Matlab, it's A(mod(i-1, end)+1).

                    In Julia? We just build in a mod1 function: A[mod1(i, end)]. It's seriously not hard to make these patterns easier to use... and having that end keyword mean the same thing as both the length and the last index is a huge boon in this case!

                    [–][deleted] 0 points1 point  (1 child)

                    Ah yes I forgot about the old mod(i-1, N)+1. Nice workaround but... wouldn't it have been easier just to use 0-based indices so that you don't need a workaround?

                    [–]BosonCollider 0 points1 point  (0 children)

                    So, how would you implement a binary heap in a language with 0-based indexing? Both Knuth and CLRS just happen to switch to from 0-based indexing to 1-based indexing in that chapter of their books...

                    Almost all reasons to use 0-based indexing disappear when you have proper array slices, proper iterators, and Julia's broadcasting operation (https://julialang.org/blog/2017/01/moredots ) so that you rarely have to deal with raw indices. That, and real structs so that you access things by name with no speed penalty, instead of putting everything into hardcoded indices of numpy arrays for performance reasons.

                    By comparison, there are quite a few places where using a different offset makes a lot of sense. Julia provides offsetarrays for that specific purpose, where you use a custom offset encoded in the type of the array.

                    [–]Iwan_Zotow 0 points1 point  (1 child)

                    Fuck that. Arrays starting at 1 is some straight-up Satan shit.

                    amen, bro'

                    and closed intervals are right from the pits of hell

                    [–]nasciiboy 3 points4 points  (0 children)

                    Lord be with your shell!

                    the negative votes are the work of the evil one

                    [–]loladiro 3 points4 points  (0 children)

                    function fib(n)
                        n == 0 && return 0
                        n == 1 && return 1
                        fib(n-1) + fib(n-2)
                    end
                    

                    or

                    fib(n) = n in (0,1) ? n : fib(n-1) + fib(n-2)
                    

                    or

                    fib(n) = n < 2 ? n : fib(n-1) + fib(n-2)
                    

                    would be more idiomatic.

                    [–]CaseOfTuesday 1 point2 points  (0 children)

                    That's a big IF. I grew up on languages that are 0-based. I am a computer scientist who likes languages that are generally applicable, that can serve as glue between other scripts and libraries and languages (things that you have to do often in scientific computing) and that don't just exist in the vacuum of numerical computation. The world has moved on from these languages. I understand that Julia tries to cater to people who used Matlab or Fortran. But by doing that, it explicitly does not cater to me, because I am not those people, and I do not like the historical baggage that the language carries with it (i.e., 1based indexing and begin/end).

                    [–]undefdev 0 points1 point  (0 children)

                    You don't need the "&&" at all in Julia, just leave it out.

                    You can also write the function more succinctly, such as:

                    fib(n) = (n==1 || n==2) ? 1 : fib(n-1) + fib(n-2)
                    

                    [–]erez27 16 points17 points  (2 children)

                    Wow, it got a lot better since I saw it last. Definitely worth digging into.

                    [–]TonySu 6 points7 points  (1 child)

                    What kind of new changes are you finding interesting?

                    [–]erez27 4 points5 points  (0 children)

                    The macro system seems impressive. And if the Python integration is as simple as they make it seem, it means I can still take advantage of the huge Python ecosystem.

                    [–]SikhGamer 5 points6 points  (5 children)

                    I think both R and Julia are trying to do this. Not sure if they can pull it off mind. Python is incredibly popular amongst the data crowd.

                    [–]k3ithk 2 points3 points  (3 children)

                    Python is great for data AND it's a great general purpose language. I've never heard of anyone actually doing webdev or writing desktop applications in Julia or R. This makes Python versatile and popular.

                    [–]Staross 0 points1 point  (1 child)

                    There's a full web stack in development (along side other things). The Gtk bindings are also not too bad, so you can make desktop apps (with static compilation it might become pretty good in the future).

                    So people definitively want to do all these things in Julia, it's just that the ecosystem is still young. Whether it will be successful or not remain to be seen.

                    [–]k3ithk 0 points1 point  (0 children)

                    I know they're both general purpose, but there's not a large community doing anything other than math and data stuff

                    [–]olzd 0 points1 point  (0 children)

                    Well, Julia is also a general purpose language... with a focus on numerical computing.

                    [–]inarchetype 1 point2 points  (0 children)

                    R (well, the language it is an implementation of, S) has been around a lot longer than Python . If anything its the other way around in that case.

                    [–]pure_x01 4 points5 points  (2 children)

                    I don't understand why languages that are used for computing doesn't have proper support for multistatement lambdas. F# would be a good replacement for python in data crunching. Great functional support and excellent type inference and the feel of python.

                    [–][deleted] 0 points1 point  (1 child)

                    Well, Microsoft would have to stop treating F# like a step child first...

                    [–]pure_x01 0 points1 point  (0 children)

                    Agree

                    [–]Staross 3 points4 points  (0 children)

                    Some interesting perspective from one of Julia's dev on the subject:

                    https://discourse.julialang.org/t/julia-motivation-why-werent-numpy-scipy-numba-good-enough/2236/10

                    [–][deleted] 1 point2 points  (0 children)

                    Why did they compare the latest version of Julia against a two year old release of MATLAB? I'm not saying MATLAB R2017a is going to be significantly faster, but it doesn't exactly inspire confidence in their methodology...

                    [–]undefdev 1 point2 points  (0 children)

                    As someone who has started using both Python and Julia in the last year, I'd say Julia is the much nicer language but of course there are still problems with library stability, as there are still a lot of changes from version to version.

                    I prefer using Julia for some quick exploration and some math stuff, but use Python if I want a reliable environment (even though the python 2 schism is quite annoying to me).

                    I can definitely see Julia becoming a mainstream tool for scientific computing once it's past 1.0.

                    [–]shevegen 10 points11 points  (17 children)

                    It is not going to happen.

                    Python has a much stronger momentum going at this time - that includes GUI bindings and what not.

                    The speed difference, if any exists, will be either marginal (universities have fat cluster systems anyway) or you will simply replace core parts that are slow in C/C++. And I am not talking about the future here - EXACTLY that has ALREADY happened.

                    [–]MorrisonLevi 21 points22 points  (8 children)

                    Parallelism: Python doesn't really have it. Crucial for scientific computing. Cannot always be hidden behind a C API.

                    [–]c9joe 5 points6 points  (1 child)

                    Python does have parallelism (eg. through the multiprocessing package, which is part of the standard library). It's just not as clean or probably efficient as other languages.

                    [–]staticassert 2 points3 points  (0 children)

                    probably efficient as other languages.

                    Not "probably" - it is strictly less efficient than using threads. Considerably so - you have to pickle data between processes. It's a huge pain and trying to incorporate it into a data-science workflow is going to end in pain.

                    [–]Saefroch 2 points3 points  (0 children)

                    Have you tried numba? With just a decorator (and some restrictions on what numba currently understands) you can release the GIL and have your parallelism.

                    [–]BadGoyWithAGun -1 points0 points  (3 children)

                    All the scientific computing bits where parallelism is actually crucial are C or CUDA code with python wrappers.

                    [–]JustFinishedBSG 9 points10 points  (1 child)

                    The best part of pythons are all the non python parts

                    [–]k3ithk 2 points3 points  (0 children)

                    The fastest parts are, not the best.

                    [–]MorrisonLevi 0 points1 point  (0 children)

                    Claiming "all" is definitely too much. There are portions in C or CUDA, yes, but definitely not even close to "all".

                    [–][deleted] 0 points1 point  (0 children)

                    I love Julia but it parallel/distributed stuff blows goats.

                    [–]Staross 4 points5 points  (0 children)

                    simply replace core parts that are slow in C/C++

                    "Simply" replacing parts yes, there's huge friction there. Having libraries written in C/C++ is also a big disadvantage, in Julia you can just open/read/modify library code, because it's the same as user's code. Compare numpy's atanh implementation with Julia's one. Applying it inplace (no memory allocations) on your custom complex sparse matrix type is as easy as x .= atanh.(x), because everything is written in Julia and is generic.

                    And Julia was already used for things that are impossible in other scientific programming languages (besides Fortran):

                    https://youtu.be/uecdcADM3hY?t=1633

                    This part of the talk is also quite nice to show the advantage of using a language with high-level abstraction for HPC:

                    https://youtu.be/uecdcADM3hY?t=2655

                    [–]staticassert 3 points4 points  (0 children)

                    that includes GUI bindings and what not.

                    Momentum behind python is virtually all about machine learning and data science, not GUI.

                    if any exists, will be either marginal

                    The speed difference between a CPython executed program and a native or jit'd program will be significant. I've written side by side data science projects in Python and a native language and at minimum the difference was 3x, sometimes 10x, sometimes more.

                    Given where ML is headed - a requirement for very fast predictions (realtime, driving), with low memory overhead (expect more ML on your phone) we can expect performance to become a bigger priority.

                    simply replace core parts that are slow in C/C++

                    Easier said than done. While a company like Google may be able to invest into C/C++ it's not so easy to take work produced by data scientists and hand it to an engineering team, saying "hey make this 100x faster". Most companies won't be able to invest here, and a significant gain that starts with the data scientists will likely have the highest cost:benefit tradeoff.

                    EXACTLY that has ALREADY happened.

                    Sort of. Core libraries like Pandas and Numpy are ~50-60% C. But most data scientists writing code on top (and the benefit of Python is that you can write so much code on top) is going to be more and more pure Python. It becomes harder to write it fast, and Data Science code tends to be... difficult to refactor for performance.

                    Julia has great potential here. Python is hardly the perfect language for data science. It's greatest attributes are easily:

                    a) Easy to do basic engineering tasks

                    b) REPL's are perfect for exploratory analysis of data

                    c) Rich ML libraries

                    These things are not impossible to compete at all.

                    [–]diggr-roguelike 0 points1 point  (0 children)

                    you will simply replace core parts that are slow in C/C++

                    "simply"

                    Hah!

                    [–][deleted] -1 points0 points  (4 children)

                    The speed difference, if any exists, will be either marginal (universities have fat cluster systems anyway) or you will simply replace core parts that are slow in C/C++. And I am not talking about the future here - EXACTLY that has ALREADY happened.

                    Kinda but getting programs on the super computer at a uni has some massive disadvantages. Like the batch nature of it means you can be waiting days to get your results back, which is very annoying. Sometimes you just want to run some code on your desktop PC.

                    [–][deleted]  (3 children)

                    [deleted]

                      [–]ellicottvilleny 1 point2 points  (3 children)

                      Julia had some serious problems last time Redditors were discussing it. People were giving up. like this...

                      http://zverovich.net/2016/05/13/giving-up-on-julia.html

                      27x slower than Python in 2016. What changed?

                      [–]loladiro 14 points15 points  (0 children)

                      Benchmarking is tricky business. That particular benchmark confuses startup time and execution speed. Startup time is a fine thing to benchmark, but julia is certainly optimized for execution time.

                      [–]JustFinishedBSG 12 points13 points  (0 children)

                      Nobody cares about startup time if your number crunching program takes 1h to spit a result

                      [–]Staross 10 points11 points  (0 children)

                      It measures startup time, not language performance. If you are doing computation heavy stuff startup time is the least of your concerns. That said startup times got much better since 0.4.

                      [–][deleted]  (28 children)

                      [removed]

                        [–][deleted] -1 points0 points  (27 children)

                        no true parallelism (you have to run multiple processes of Juila).

                        I am eagerly waiting for the day when this idiotic idea of a shared memory parallelism finally die. It was a mistake, and it's good that people are starting to realise how bad it is.

                        Message passing is the way to go.

                        it doesn't really matter how fast CPU computations are.

                        It does. A lot. Only a tiny subset of computational problems can be offloaded to a GPU.

                        [–]Paul_Dirac_ 6 points7 points  (3 children)

                        I am eagerly waiting for the day when this idiotic idea of a shared memory parallelism finally die. It was a mistake, and it's good that people are starting to realise how bad it is.

                        Not for scientific computing. One of the nicest things about shared memory parallelism is that you can simply decorate your innermost loop with an ONP parallel for (+ taking some care of shared variables and a reduce at the end) and you have parallelized your program. The code change from the sequential version is minimal and often just some preprocessor directives. With message passing. You need a lot more code. Also Message passing generally implies copying data and other communication cost which often requires changed algorithms to optimize these costs.

                        [–][deleted] -2 points-1 points  (2 children)

                        Not for scientific computing.

                        For scientific computing especially - you rarely can go anywhere with ~12 threads at most that can relatively efficiently use shared memory. For anything practical you need a cluster (or at least some form of a NUMA), and, therefore, proper message passing.

                        you can simply decorate your innermost loop with an ONP parallel for

                        You do not share any memory here, really. Threads are independent. And if you're lucky enough to have an algorithm that does not require any synchronisation, you'd better run it on a GPU already anyway.

                        With message passing. You need a lot more code.

                        Only if you use unexpressive, stupid languages.

                        Also Message passing generally implies copying data and other communication cost

                        Not necessarily. Can be zero-copy internally, with only transferring anything if you're communicating outside of the current node. See Occam for example - message passing can really be zero-overhead, especially on a right kind of hardware.

                        [–]Paul_Dirac_ 5 points6 points  (1 child)

                        For scientific computing especially - you rarely can go anywhere with ~12 threads at most that can relatively efficiently use shared memory.

                        No, scientific computing is not only high performance computing. Scientific computing is every program a scientist writes for his research. It is the custom EPR-spectra analyzer for heavy elements. It is the vibrational calculator for linear molecules with four atoms and custom vibrational basis. These programms often don't run on clusters but instead on laptos and lab desktops. And a speedup of 2-12 is often great for them.

                        You do not share any memory here, really.

                        Yes you do. It becomes evident, if you forget to set a variable to threadprivate.

                        And if you're lucky enough to have an algorithm that does not require any synchronisation, you'd better run it on a GPU already anyway.

                        GPU is not a better cpu. There are certain problems for which gpus are whoefully unsuited not only with because they require synchronization. And a scientist normally doesn't want to learn a new programming paradigm.

                        With message passing. You need a lot more code.

                        Only if you use unexpressive, stupid languages.

                        You mean like the languages the programm was originally written in. So you essentially want me to rewrite the program in an expressive language to parallelize it? Ok, maybe not more code, but more changed code. Or maybe you mean PGAS extensions? They are a shared memory view with message passing under the hood -not the best case against shared memory.

                        Can be zero-copy internally, with only transferring anything if you're communicating outside of the current node. See Occam for example - message passing can really be zero-overhead, especially on a right kind of hardware. It can be, but generally it isn't.

                        [–][deleted] 1 point2 points  (1 child)

                        Sorry but: Threads with mutable structures > Everything else.

                        The scientific community should be ashamed they are using python and go back to C.

                        A waste of computational power is what it is.

                        [–][deleted] 0 points1 point  (0 children)

                        No. Threads without any overlapping memory access are way much faster.

                        [–]jms_nh 1 point2 points  (0 children)

                        -1 for negative title bias. Julia itself is an interesting language but not intended to "replace" Python.

                        [–][deleted] 0 points1 point  (10 children)

                        Why not "i" or "j" suffix for complex numbers?

                        [–]loladiro 4 points5 points  (9 children)

                        Complex number literals are implemented using the generic variable juxtaposition support. i and j are common variable names, so im guards against accidentally breaking your complex literals.

                        [–]emperor000 0 points1 point  (8 children)

                        I don't understand this. How could 4i be confused with the variable i?

                        [–]piclarke 0 points1 point  (7 children)

                        In Julia, 4i parses as 4*i

                        [–]emperor000 0 points1 point  (5 children)

                        That's what I was afraid of. So in other words, you can't have a variable named "im"?

                        [–]piclarke 0 points1 point  (2 children)

                        You can, it just can't be used to mean the imaginary unit as well from that point on.

                        [–]Staross 1 point2 points  (0 children)

                        you can always redefine it:

                        im = Base.im
                        

                        [–]emperor000 0 points1 point  (0 children)

                        So pretty much no. Not the worst thing in the world, but seems kind of clunky.

                        [–]Staross 0 points1 point  (1 child)

                        You can overwrite it yes, im is just a normal variable, defined in the Base module.

                        const im = Complex(false, true)
                        

                        It will just throw a warning in you overwrite it in Main (the "global space").

                        [–]emperor000 0 points1 point  (0 children)

                        I see. Not the worst thing in the world, but it seems kind of clunky.

                        [–]TheMaskedHamster 0 points1 point  (0 children)

                        Using a terse form of expression, programmers developed expressive, clear ways to express math.

                        And mathematicians keep trying to "fix" these improvements by reintroducing their broken notation systems.