[HN Gopher] JuliaLang: The Ingredients for a Composable Programm...
       ___________________________________________________________________
        
       JuliaLang: The Ingredients for a Composable Programming Language
        
       Author : mindB
       Score  : 307 points
       Date   : 2020-02-10 13:06 UTC (9 hours ago)
        
 (HTM) web link (white.ucc.asn.au)
 (TXT) w3m dump (white.ucc.asn.au)
        
       | lightsighter wrote:
       | Except they have no story for building composable libraries in a
       | distributed setting. The story for distributed execution in Julia
       | today is just use MPI, which is a terrible answer. Anyone who has
       | ever use libraries backed by MPI in any language knows that they
       | are inherently not composable. You can't just take an object
       | partitioned across multiple nodes one way by one library and pass
       | it into a second library that expects it to be partitioned a
       | different way. As far as I can tell the Julia language has
       | nothing to say about that, and that makes them a non-starter
       | today for anyone trying to build composable libraries for
       | distributed memory machines.
        
         | xiaodai wrote:
         | Just curious, is there anything that's composable in the
         | distributed world
        
       | tgflynn wrote:
       | Julia is a language I really wanted to like, and to a certain
       | extent I do. However after spending some time working with it and
       | hanging out on the Discourse channels (they certainly have a very
       | friendly and open community, which I think is a big plus), I've
       | come to the tentative conclusion that its application domains are
       | going to be more limited than I would have hoped.
       | 
       | This article hits on some of the issues that the community tends
       | to see as advantages but that I think will prove limiting in the
       | long run.
       | 
       | > Missing features like:
       | 
       | > Weak conventions about namespace pollution
       | 
       | > Never got around to making it easy to use local modules,
       | outside of packages
       | 
       | > A type system that can't be used to check correctness
       | 
       | These are some of my biggest gripes about Julia, especially the
       | last two. To these I would add:
       | 
       | * Lack of support for formally defined interfaces.
       | 
       | * Lack of support for implementation inheritance.
       | 
       | Together with Julia's many strengths I think these design choices
       | and community philosophy lead to a language that is very good for
       | small scale and experimental work but will have major issues
       | scaling to very complex systems development projects and will be
       | ill-suited to mission critical applications.
       | 
       | In short I think Julia may be a great language for prototyping an
       | object detection algorithm, but I wouldn't want to use it to
       | develop the control system for a self-driving car.
       | 
       | Unfortunately this means that Julia probably isn't really going
       | to solve the "2 language problem" because in most cases you're
       | still going to need to rewrite your prototypes in a different
       | language just like you would previously in going from, for
       | example, a Matlab prototype to a C++ system in production.
        
         | short_sells_poo wrote:
         | You touch upon some interesting pain points. I really like
         | Julia and working with it is a pleasure.
         | 
         | Except the Module system, which feels unnecessarily arcane. I'm
         | happy to be educated on why, but it seems to successfully
         | combine the awkwardness of C-style #include with the mess of a
         | free-form module system. The end result is a Frankenstein
         | monster where technically everything is possible, everything
         | could be included anywhere, there are no boundaries or even
         | conventions. It makes for a frustrating experience for a
         | newbie.
         | 
         | Say you have a package, and inside is a file called `xyz.jl`.
         | You open the file and it defines a module called Xyz. But this
         | tells you absolutely nothing about where in the package Xyz
         | will appear. It could be included somewhere deep in the
         | hierarchy, or it could be a submodule. It could be included
         | multiple times in multiple places! That's bad design for sure,
         | but the language places no boundaries on you. You open another
         | file `abc.jl`, and see no modules at all, just a bunch of
         | functions, which in turn call other functions that are defined
         | God knows where. A julia file does not have to contain any
         | information about where the symbols it's using come from, since
         | it will be just pasted in verbatim to some location somewhere.
         | 
         | The whole module system feels like one big spaghetti of spooky
         | action at a distance.
         | 
         | It's a shame too, because the rest of the language is very
         | neat. Once one gets over the hurdle of the modules, it is
         | possible to establish conventions to bring some sanity in
         | there, but it's a hurdle that many people will probably not
         | want to deal with.
        
           | [deleted]
        
           | improbable22 wrote:
           | How would you like modules to work?
           | 
           | It seems great to me that paths & source files are mostly
           | irrelevant, you're free to re-organise without changing
           | anything. And that `using Xyz` is always talking to the
           | package manager. You can make sub-modules and say `using
           | .Xyz`, but there's very little need to do so, and few
           | packages do.
           | 
           | You can shoot yourself in the foot by including source twice,
           | as you can by generating it with a macro, or simply copy-
           | pasting wrong.
        
             | Seanny123 wrote:
             | I mean, I'd like them to work like Python, Ruby and
             | TypeScript, but you're right to say I can't describe _why_
             | I want this.
             | 
             | Is there some guide I could read about structuring a large
             | Julia project? It was pretty easy to intuit with Python,
             | wherein I would put related files in a folder. But with
             | Julia, everything is everywhere and I'm baffled.
        
               | short_sells_poo wrote:
               | > But with Julia, everything is everywhere and I'm
               | baffled.
               | 
               | This is exactly it. Julia allows you to import and
               | include anything, anywhere. You open a file and it
               | doesn't say anything about where the dependencies are
               | coming from and where this particular piece of code will
               | go. Both of those are defined at the place where this
               | file is included, which itself could be anywhere. It
               | could be a different directory, different file, tucked
               | away in a module. It could be in a dozen other files, or
               | no files at all, and you can't tell from looking at just
               | the source of the file.
        
               | improbable22 wrote:
               | Just reading what everyone does may work. Here's a tiny
               | package:
               | 
               | https://github.com/ChrisRackauckas/EllipsisNotation.jl
               | 
               | I think that `/src/Name.jl` must have the main module,
               | and `/test/runtests,jl` tests. And the package manager
               | cares about `Project.toml`. But beyond this there are no
               | real rules enforced, although there really seems to be
               | one way to do things.
               | 
               | Here's a much bigger project, organised the same way.
               | `include(file.jl)` literally copies in the text, and it's
               | somewhat conventional to collect all imports & exports in
               | the main file:
               | 
               | https://github.com/JuliaNLSolvers/Optim.jl/blob/master/sr
               | c/O...
               | 
               | Still no sub-modules. No files included in mysterious
               | locations. Methods being defined for functions from
               | elsewhere are all qualified, like `Base.show(io::IO,
               | t::OptimizationState) = ...`
        
             | short_sells_poo wrote:
             | Languages like Python, Rust, C# or even Java have module
             | systems that I find are more restrictive, but much easier
             | to follow. You always have the pertinent information at
             | hand. Each file containing code clearly tells you two
             | crucial pieces of information:
             | 
             | 1. Where the code fits in the greater picture
             | 
             | 2. Where the dependencies of the code in a file come from
             | 
             | Python, whose module story is actually pretty poor, is
             | still easier to follow than Julia, because it just matches
             | the file/directory structure. You can reason about the
             | hierarchy of a python library by just navigating the
             | directories. In a normal python project, each file is one
             | module and it's dependencies are clearly specified as
             | imports.
             | 
             | Rust relies on the file system as well, and much better
             | defined rules than Python. I find this great, because the
             | file system is already hierarchical and we are used to the
             | way it works. When I open a file in a Rust project, I know
             | immediately where it fits in the hierarchy - because it is
             | implied from the file system. Rust gives you a bit more
             | flexibility in that you can define submodules in each file.
             | 
             | C# & Java qualify the namespaces fully in each file. While
             | the file structure is not as clear anymore at the file
             | system level, a single file contains all the information
             | necessary to determine where the code fits in and where
             | it's dependencies come from.
             | 
             | Now let's take Julia:
             | 
             | A single module will be often split across multiple files.
             | Since they share a single namespace, the imports happen at
             | the top level where the module is defined and includes all
             | it's source files. When you open a source file, you have
             | zero information where all the functions and data types are
             | coming from (or where they are going for that matter).
             | 
             | I see the following pattern systematically emerge in Julia
             | code:
             | 
             | - A function is defined in file A
             | 
             | - File A is `included` in file B, where it forms part of
             | module X
             | 
             | - It is then imported into module Y in file C, but it is
             | not actually used there
             | 
             | - As it is finally used in file D, which is `included` in
             | module Y in file C itself
             | 
             | The problem is that there is no link from file A to file B,
             | or module X for that matter. File A could be part of a
             | dozen modules, or zero. Neither is there a link between the
             | usage of the function in file D and where it is coming
             | from. You actually have to find all the places where file D
             | is included, and then check what flavor of the function
             | does each location import. The relationships are
             | established at some indeterminate level in the hierarchy.
             | 
             | Again, don't get me wrong, this is just a wart on an
             | otherwise very pleasant language. I wouldn't be complaining
             | if I weren't using it.
        
               | gugagore wrote:
               | That was helpful, especially realizing that part of the
               | problem (at least as you see it) is that the "linking" is
               | unidirectional.
               | 
               | Function definitions/calls are also unidirectionally
               | linked. You can see at the call site which function is
               | called, but you can't see at the function definition the
               | references. But unlike a function, which might be called
               | from many places, it really should be the case that a
               | file is `include`d exactly once.
        
         | oxinabox wrote:
         | Author of post here: there were a major gripe for me starting
         | out too. It took me a fair while to conclude that they allowed
         | to useful things in the bigger picture. and it __certainly __is
         | not a pure win.
         | 
         | I do miss static typing.
         | 
         | I would question the claim it doesn't scale to production. I
         | know people who have build hugely complex production systems in
         | perl that are still running today 20 years later.
         | 
         | Further, I myself work on what we believe to be the largest
         | closed source julia code base, in terms of number of
         | contributors, number of packages and total size. (Its also
         | pretty large in general, though i have yet to work out how it
         | stacks up against DiffEq-verse). And I have seen thing go from
         | research prototype into running in production. It works.
         | 
         | I am not going to deny though there are advantages to other
         | languages. There are many trade-offs in the world
        
           | tgflynn wrote:
           | > I know people who have build hugely complex production
           | systems in perl that are still running today 20 years later.
           | 
           | Sure, but there aren't many programmers who would want to
           | maintain such a system.
        
             | fludlight wrote:
             | Most programmers want to build new things, not work on
             | maintenance projects, regardless of tech stack.
             | 
             | That said, many people do enjoy that sort of work and
             | finding them is not unusually difficult unless the project
             | is so big that you need dozens of bodies.
        
             | klyrs wrote:
             | Perl's just another language I've known. Maintaining a 20yo
             | codebase in a language that people find distasteful sounds
             | like comfortable job security, to me.
        
         | Seanny123 wrote:
         | I don't understand type systems very well. When you say "check
         | correctness" do you mean something beyond static linting with
         | type-hints, like in Python? Or do you mean something deeper,
         | like in functional languages like Elm and F#?
         | 
         | Also, is there always a trade-off between types and flexible
         | meta-programming? Like, OCaml has meta-programming
         | capabilities, but they make type-checking way harder, according
         | to my PhD friend who's written extensively in Scheme and OCaml.
        
         | cultus wrote:
         | People write large-scale systems in dynamically-typed languages
         | all the time. Multiple dispatch and macros make clean scaling
         | easier than it would be in most other dynamic languages. Its
         | competitors in numerical performance are C/C++ and Fortran,
         | which are both minefields (C much more so). Julia is definitely
         | safer in practice than these kind of languages with weak,
         | unsafe type systems.
         | 
         | I'm not saying static types don't have benefits as well, but it
         | would also be very against the design goals as a Matlab/R
         | competitor.
         | 
         | Inheritance would also directly clash and overlap with multiple
         | dispatch, which is strictly more powerful.
        
           | tgflynn wrote:
           | > multiple dispatch, which is strictly more powerful.
           | 
           | In a language that supports classes I can have class B
           | inherit from class A and automatically provide all of class
           | A's functionality without adding a single extra line of code.
           | I can extend class B's functionality by adding only code that
           | is specific to it.
           | 
           | I don't see how to do that with multiple dispatch, at least
           | the way it's implemented in Julia.
        
             | byt143 wrote:
             | This can be done better with traits in Julia, which are
             | more powerful, safer and faster.
             | 
             | See here:
             | https://white.ucc.asn.au/2018/10/03/Dispatch,-Traits-and-
             | Met...
        
               | tgflynn wrote:
               | Perhaps. The feeling I get with Julia is that the devs
               | are sort of making it up as they go along. I don't mean
               | just making up the language (which of course they're
               | doing), but making up whole new approaches to programming
               | that aren't necessarily well-understood and tested in the
               | real world and certainly aren't very familiar to most
               | programmers.
               | 
               | Maybe in the end they will succeed and will invent a
               | generally superior approach to software development. But
               | for the moment it all feels very experimental and so not
               | a language I'd want to commit to at present if I were
               | starting a major, non-solo project.
        
               | chalst wrote:
               | A lot of the ideas come from Common Lisp.
        
             | cultus wrote:
             | Single-dispatch OOP dispatches (implicitly) only on the
             | first argument, self. That is how Class B can provide the
             | functionality of A. Multiple dispatch can dispatch on all
             | arguments. Thus, OOP single dispatch is a special case of
             | multiple dispatch.
             | 
             | In your example, functionality in class B can be written
             | simply as ordinary generic functions, which are inferred to
             | their most general compatible type without annotations.
             | Because of this, all functionality for class A will work
             | for class B, as long as B is a superset of A. Not a single
             | line of code, and no brittle inheritance hierarchies.
             | 
             | Multiple dispatch is one solution to the expression
             | problem, which both OOP and functional programming suffer
             | from in dual ways. Other ones include Haskell's typeclasses
             | and Ruby's mixins.
        
               | tgflynn wrote:
               | Yes, but in Julia the problem is that inheritance isn't
               | allowed from concrete types. So this example in Julia
               | would mean that A is an abstract type whose objects can
               | contain no data. So you have to figure out a way to
               | implement functionality on A without having any data to
               | work with. There are several ways to work around this but
               | they all involve considerably more code complexity than
               | would be required in a language like C++ that supports
               | classes.
        
             | oxinabox wrote:
             | Generally via wrapping (Composition).
             | 
             | ``` struct Foo <: AbstractFoo ... end
             | 
             | struct SpecialFoo{T<:AbstractFoo} <: AbstractFoo backing::T
             | end ```
             | 
             | and then delegating calls to the wrapped object
        
               | tgflynn wrote:
               | Yes, but delegation requires a lot of extra code to get
               | what you have for free in a class based language. And yes
               | I know you can probably write macros to handle much of
               | that but having to use meta-programming to get what other
               | languages give you for free doesn't seem ideal to me.
        
             | logicchains wrote:
             | >In a language that supports classes I can have class B
             | inherit from class A and automatically provide all of class
             | A's functionality without adding a single extra line of
             | code.
             | 
             | And people will abuse this to create horrible brittle
             | inheritance hierachies. There's a reason modern languages
             | like Go and Rust deliberately don't support implementation
             | inheritance; to many people it's an antifeature.
        
               | tgflynn wrote:
               | The thing about software is that the "one true way"
               | changes every 2 or 3 years.
               | 
               | A few decades ago inheritance was considered a key
               | software design principle, then it was abused by many
               | (especially Java programmers, I think), just like any
               | other powerful feature, now it's considered evil. If
               | multiple dispatch becomes as popular as
               | classes/inheritance was, I suspect it will go through the
               | same love/hate cycle.
               | 
               | All I know is that I have used implementation inheritance
               | to good effect on multiple occasions and found it to be a
               | very valuable feature.
        
               | gugagore wrote:
               | It's interesting to think about what multiple dispatch
               | abuse would be.
               | 
               | As far as I know, implementation inheritance can be
               | misapplied when you try too hard to use the language's
               | type system to capture some domain-specific model. e.g.
               | you're dealing with multiple kinds of entities, and they
               | all have a `name`, so you decide that all of the classes
               | should inherit from `class Named`, because they have that
               | in common with each other.
               | 
               | Well, there's lots of different taxonomies possible for
               | your entities, probably. And single implementation
               | inheritance lets you express just one taxonomy.
               | Interfaces and multiple inheritance aim to allow multiple
               | co-existing taxonomies, but I can't really explain the
               | ways in which its misapplied.
               | 
               | I agree that there are some clear situations for
               | implementation inheritance, so it seems like a useful
               | pattern to be able to support. I think the discussion is
               | whether it should be a key design principle, and built
               | into the language design, or if the language design
               | should be more general, so that implementation
               | inheritance can be built on top of that.
        
               | jdmichal wrote:
               | Inheritance is not really all that powerful, assuming
               | that one follows SOLID and especially Liskov
               | substitution. There's very few places where it's actually
               | applicable. Interfaces are much more widely applicable --
               | defining contracts instead of behaviour makes it much
               | easier to follow SOLID.
               | 
               | I mostly only use inheritance for patching the behaviour
               | of some code I don't own by overriding some specific
               | method. Because that's the only mechanism the language
               | provides to perform such a modification. This is
               | basically the use-case that Julia's multiple dispatch
               | addresses.
        
               | kazinator wrote:
               | It's important to always remember the context that SOLID
               | is a collection of one man's opinions.
               | 
               | When we mix classes to create a new class, the
               | ingredients in the mixture retain their adherence to
               | their respective contracts, and we didn't have to re-
               | implement them.
               | 
               | > _I mostly only use inheritance for patching the
               | behaviour of some code._
               | 
               | That's good for you, but you have to realize that classes
               | _specifically designed as inheritance bases_ are also a
               | thing and the experience of using those kinds of classes
               | with inheritance is not the same as deriving from any
               | random class whose behavior we don 't like in some
               | aspect.
               | 
               | The conventions by which a class supports inheritance are
               | also a form of contract! The contract says that if you
               | derive from me, you can expect certain behaviors, and
               | also have certain responsibilities regarding what to
               | implement and how, and what not to depend on or not to do
               | and such.
               | 
               | If a class is not designed for inheritance, then there is
               | no contract, beyond some superficial expectations that
               | come from the OOP system, some of which can fall victim
               | to hostilities in the way the class is implemented, or
               | maintained in the future.
        
               | kazinator wrote:
               | In TXR Lisp, I doubled down on OOP and extended the
               | object system to support multiple inheritance, just this
               | December.
               | 
               | Real inheritance of code and data allows for mixin
               | programming, which is very useful.
               | 
               | If you don't give OOP programmers the tools for mixing
               | programming, they will find some other way to do it, such
               | as some unattractive design pattern that fills their code
               | with boilerplate, secondary objects, and unnecessary
               | additional run-time switching and whatnot, all of which
               | can be as brittle as any inheritance hierarchy, if not
               | more.
        
           | mumblemumble wrote:
           | > I'm not saying static types don't have benefits as well,
           | 
           | It's funny; formerly I was a die-hard fan of static typing,
           | but, lately, my opinions have become more nuanced. Something
           | more along the lines of, "Yeah, I'd never want to just remove
           | the type annotations from my Java code and then try to
           | maintain the result, but some dynamic languages allow me to
           | have a fraction as much code to maintain in the first place."
           | 
           | I'm also beginning to wonder if my feelings about dynamic
           | languages have been unduly influenced by some particularly
           | popular, and also particularly undisciplined, dynamic
           | languages. JavaScript and PHP, for example.
        
             | harikb wrote:
             | Java's code verbose-ness is not entirely due to static
             | typing though. IMHO, it is ecosystem, people, SO-copy-
             | culture
        
             | masklinn wrote:
             | > It's funny; formerly I was a die-hard fan of static
             | typing, but, lately, my opinions have become more nuanced.
             | Something more along the lines of, "Yeah, I'd never want to
             | just remove the type annotations from my Java code
             | 
             | That might be one of the issues. Even when it comes to
             | static typing java is high investment low rewards.
             | 
             | Things are admittedly less bad than they were 15 years ago,
             | but it remains that java has very high overhead both
             | syntactically and at runtime and yet is pretty limited in
             | its static expressivity. So when you do away with java for
             | a dynamically typed langage most of what you lost from
             | missing static types you gain back from having so much less
             | LOCs and ceremony and architectural astronautics to deal
             | with.
             | 
             | In theory you could probably write terser java but that's
             | not what the community does or what the ecosystem
             | encourage, so if you do you're on your own and then why
             | keep using java? There's plenty of better langages with no
             | community and no ecosystem out there. And they have way,
             | _way_ better type systems.
        
               | mumblemumble wrote:
               | > Even when it comes to static typing java is high
               | investment low rewards.
               | 
               | My sense is that it's because Java isn't _really_ all
               | that static a language. In terms of the syntax, sure. But
               | it also relies very heavily on run-time reflection, run-
               | time type casting, and run-time type checking. Since the
               | introduction of generics, there are even some situations
               | where the types are known and declared statically in the
               | source code, but the compiler is unable to do static type
               | verification, and so the type checking only happens
               | dynamically at run time.
               | 
               | Meaning that you kind of get the worst of both worlds:
               | High-ceremony programming, but not a whole lot of help
               | from the compiler in return for it.
               | 
               | Anyway, yeah, that does mean that the debate does get
               | more hair-splitty if we're talking Haskell vs. Racket.
               | But, realistically, that's not usually the languages
               | people have in mind when they're talking static vs
               | dynamic - it's much more likely to be Java or Python.
               | Both of which, like most languages, fall short of being
               | the ideal examples of their respective type checking
               | approaches.
        
       | dzonga wrote:
       | though, Julia is faster than Python. Does anyone mind explaining
       | why Python can't have a JIT ?
        
         | eigenspace wrote:
         | As others have mentioned, Python does have JIT compilers. The
         | problem is that havign a JIT doesn't solve the problem.
         | 
         | PyPy is often a factor of 10 behind julia performance and
         | projects like Numba, PyTorch (the PyTorch people had to build
         | their own Python JIT compiler yikes!), etc. will always have a
         | more restricted scope than a project like Julia because
         | Python's very semantics make many optimizations impossible.
         | 
         | Here's a great talk from the author of the famous Flask library
         | in Python: https://www.youtube.com/watch?v=qCGofLIzX6g where he
         | discusses the fundamental problems with Python's semantics.
         | 
         | If you fix these problems, you will end up changing Python so
         | fundamentaly that you'll really have a new language. Generic
         | CPython 3._ code will certainly not be compatible with it.
        
           | dzonga wrote:
           | so in this case, once say the Julia ecosystem grows then
           | migrate to Julia. or wait for optimizations to be done, e.g
           | have pandas, numpy etc handle multi-core processors etc ?
        
             | ChrisRackauckas wrote:
             | There's quite fundamental optimizations that will be
             | missing if separately compiled pieces cannot optimize
             | together. These barriers disallow many things.
             | Additionally, anything that relies on higher order
             | functions provided by the user, such as optimization or
             | differential equations, will run into issues because those
             | functions cannot be optimized by some super good package
             | developer, but instead have to come from the user.
             | 
             | This blog post highlights the massive performance
             | advantages Julia can have when you start integrating
             | optimized packages and allow for optimizing across these
             | barriers in Julia, and also the pros and cons of allowing
             | these kinds of cross-function optimizations.
             | 
             | https://www.stochasticlifestyle.com/why-numba-and-cython-
             | are...
        
             | simonbyrne wrote:
             | > or wait for optimizations to be done, e.g have pandas,
             | numpy etc handle multi-core processors etc ?
             | 
             | All those exist already. Indeed, other than DataFrames.jl
             | (the pandas equivalent) they are part of the language
             | itself.
        
         | throwlaplace wrote:
         | http://www.pypy.org/
        
         | [deleted]
        
         | setr wrote:
         | Pypy exists, but as I recall, cpython never made use of a JIT
         | simply because they wanted to keep the compiler intentionally
         | simpler.
         | 
         | However as a result, the language isn't well designed for a
         | JIT, and pypy has run into several headaches/blockers. Not sure
         | if there's anything fundamentally blocking usage, or simply
         | lack of manpower
        
       | smabie wrote:
       | Julia is great. It's significantly simpler than Python while also
       | being much more expressive. It's too bad the typing is only for
       | dispatch, but hopefully someone will write a typechecker someday.
       | I've found it surprisingly refreshing to not have to think about
       | classes and just add functions on objects wherever I want. Some
       | languages solve this with monkey patching (which is bad), others
       | like Scala with an extension class (reasonable, but you still
       | don't get access to private properties), but the Julia approach
       | is cleaner.
       | 
       | I wouldn't use Julia for a non-scientific computing app as I
       | don't think it's suitable, but for anything data science related,
       | it's great! And with the Python interop, I don't really think
       | there's any reason _not_ to use Julia for your next data science
       | project. I suspect that over the next 5 years Python will no
       | longer be used for these applications at all.
        
         | mark_l_watson wrote:
         | I have a collection of short Julia code snippets that do non
         | numeric things like text processing, semantic web clients, etc.
         | 
         | But in general I agree. Fir me, Lisp languages, Haskell, and
         | Python are more general purpose.
        
           | vasili111 wrote:
           | >Fir me, Lisp languages, Haskell, and Python are more general
           | purpose.
           | 
           | You mean Julia as language is not enough good for general
           | purpose or it lacks ecosystem (frameworks, libraries) for
           | general purpose use?
        
             | smabie wrote:
             | A little of both, I guess. The biggest issue is that I,
             | personally, get uncomfortable with dynamic typing when the
             | project starts becoming over 1-5 Kloc. So I tend to stick
             | with stuff like Scala, Rust, or OCaml for non data science
             | tasks.
        
             | mark_l_watson wrote:
             | I didn't express that correctly. What I meant to say was
             | that I investigated Julia as a possible "use it for
             | everything language."
             | 
             | For me, general purpose has to include deep learning tools.
             | 
             | I really prefer Lisp and Haskell, but although Haskell's
             | TensorFlow support is pretty good, I found it easier to
             | just use Python. I have had problems with the SBCL Common
             | Lisp TensorFlow C bindings, but perhaps that was my fault.
        
           | e12e wrote:
           | What part of Julia isn't lispy enough that you don't consider
           | it a lisp? I'm not saying you're wrong, just because there a
           | scheme in there, just curious.
        
             | mark_l_watson wrote:
             | The internal Scheme language was not easy for me to access.
        
               | jamescont wrote:
               | Same here bro
        
         | ScottPJones wrote:
         | I've been using Julia for non-scientific computing programs for
         | almost 5 years now, and (especially now that it is stable since
         | the 1.0 release) have found it well suited for general
         | programming as well. Having a language that is easy to write
         | (like Python), runs fast (like C/C++), and incredibly flexible
         | & expressive (like Lisp) makes programming fun again!
        
           | skybrian wrote:
           | Interesting, how does deployment work for you? What sort of
           | executables do you ship?
        
             | nnq wrote:
             | Don't people mostly ship containers nowadays? Or deploy
             | code but standardize on language version.
             | 
             | Why t f would you want to ship / deploy a naked executable
             | in 2019?!
        
               | skybrian wrote:
               | Containers are common for server-side code but not for
               | mobile, desktop, or client-side web code.
        
               | MiroF wrote:
               | e: ignore
        
               | unlinked_dll wrote:
               | Not all of us are web developers.
        
               | throwaway894345 wrote:
               | * Container images are generally huge. Layer caching
               | helps to the extent that layers are reusable. If you're
               | lucky, you can use something like alpine for smaller huge
               | images. If you write in a language that supports
               | statically linked executables (e.g., Go) then you can get
               | by with a scratch in many cases, but then you could more
               | easily ship a naked executable
               | 
               | * Container images take a long time to build and build
               | caching only works well if your dependency tree is linear
               | (it's not). (Caveat: there are niche alternatives to
               | docker build for which this may not hold, but then you're
               | subject to the other issues with niche tools--support,
               | docs, compat, etc)
               | 
               | * Your deployment target has to have a container runtime
               | compatible with your image format. This is a PITA for end
               | users in many cases.
               | 
               | * Most popular container runtimes make container
               | processes children of the daemon process, not children of
               | the client process. This means killing the parent process
               | will not kill the child process, which means CI
               | environments need to handle all sorts of edge cases. For
               | example, a CI job is waiting on a stuck container to
               | terminate, but eventually times out or the job is killed
               | or similar; each time this happens a container is leaked
               | --this means that CI tools have to support the container
               | runtime explicitly and handle all of these edge cases
               | because it's prohibitively complex for users to manage.
               | 
               | IMO the only advantage (and this is a huge advantage
               | where applicable) for containers is that they can be
               | orchestrated by things like Kubernetes or AWS Fargate.
        
         | real_eng_ wrote:
         | Why every Julia user can't help but trash Python at every
         | occasion?
         | 
         | It's getting really tiring
        
           | smabie wrote:
           | Trashing is a little harsh, but Julia devs probably were
           | mostly Python devs back in the day and are intimately
           | familiar with the inadequacies of the language: the work
           | required when you had to drop into C, the bad syntax for
           | math, the constant conversions between ndarray, array, and
           | lists, etc etc.
           | 
           | At my old bioinformatics lab, Python literally wasted
           | thousands and thousands of collective man-hours which would
           | have been saved by Julia if it had existed at the time. Since
           | a lot of these researchers couldn't really program that well,
           | they would write code that would literally take weeks to run.
           | And then they would call me and I would rewrite it in C and
           | it would then take an hour or two. Julia solves this problem.
           | 
           | The amount of unnecessary supercomputer time (and
           | electricity) that our lab (and others) were wasting with
           | Python was, honestly, disgusting.
        
             | elcritch wrote:
             | Exactly... well I didn't do supercomputing but still wasted
             | a lot of time dealing with Python 2/3 issues among others.
             | Then there's the ability to do things like fast
             | bootstrapping, Monte-Carlo and other handy statistical
             | techniques without writing kernel functions in C. Python
             | was great for it's time and enabled a lot and still let's
             | lots of people do great things, it's just not for me
             | anymore.
        
           | hpcjoe wrote:
           | Hrm ... I recall Pythonistas trashing Perl as line noise, and
           | other languages as well, for many many years. I'm not saying
           | its right, just that karma, sometimes, comes back into focus.
        
           | oxinabox wrote:
           | This post doesn't even mention python. Not even once.
        
           | ScottPJones wrote:
           | I haven't seen that at all - many Julia programmers are (or
           | were) also Python programmers. I think there is a lot of
           | respect in the Julia community for Python & the Python
           | ecosystem. There have even been a number of Julia talks at
           | various PyCons over the past few years.
        
             | oxinabox wrote:
             | There was a python talk at the 2019 juliacon.
        
         | sgt101 wrote:
         | could you expand on the "too bad typing is only for dispatch"?
         | I've enjoyed the way that the Julia type system can be used...
        
           | smabie wrote:
           | It can't be used for compile time correctness checking? i.e
           | Julia isn't a statically typed language.
        
             | sgt101 wrote:
             | Yes - I understand why some people are keen on static
             | types, but type inference is a powerful way to create
             | funcetionality and I believe that the separation of
             | concerns between the dispatcher and the programming code
             | (removing the logic of decisioning from the code and using
             | type inference instead) leads to clearer programs. I can't
             | think how you can have that and have static checking as
             | well (although I know that there are some compilers for
             | some Julia code as mentioned in this thread)
        
               | Symmetry wrote:
               | Lots of languages with static typing use type inference.
               | Haskell, OCaml, Go, Rust, Nim, etc. Even C++ has auto
               | these days which I think when combined with templates
               | gives you what you're talking about though it is a bit
               | clunky.
               | 
               | EDIT. For instance in Haskell I can just declar a
               | function to sum the things in a container by saying
               | summer a = folder (+) 0 a
               | 
               | And the compiler will figure out that the function
               | accepts a Foldable container of some sort full of things
               | that are Nums without ever having to tell the compiler
               | that (though it's a good idea for maintainability. And
               | then I can just pass in a list of floats and the compiler
               | will Do The Right Thing. And if I pass in a list of
               | booleans instead the compiler will yell at me at compile
               | time because there's no (+) operation for booleans.
        
             | throwaway894345 wrote:
             | Presumably this means that no one has implemented a
             | suitable static type checker or its type annotations don't
             | provide sufficient information for a static type checker to
             | work in principle?
        
               | eigenspace wrote:
               | The problem is more the former (nobody has gotten around
               | to it yet), but also a bit of the opposite of the latter,
               | i.e. the type system is so rich, type-checking may be
               | undecidable in too many contexts.
               | 
               | Julia's parametric types are incredibly rich. You can
               | look up 'dependant types' which are similar in the static
               | world and see the sorts of hoops static language
               | designers jump through to have dependant types and still
               | be able to reliably prove theorems.
        
         | vanderZwan wrote:
         | > _It's too bad the typing is only for dispatch, but hopefully
         | someone will write a typechecker someday_
         | 
         | I was under the impression that if you write a function that
         | takes very specific sub-types as its parameters, and then try
         | to call it with invalid parameters (that is, values that cannot
         | be converted to the right type via the promotion rules) that
         | Julia will complain about this?
        
           | tgflynn wrote:
           | It will complain, but typically only at run time.
        
           | [deleted]
        
         | FranzFerdiNaN wrote:
         | Python will still be used 20 years from now. The clear
         | advantage of Python is the enormous ecosystem that is
         | available, the millions of questions on SO giving solutions to
         | every problem you can run into, the books and learning
         | materials etc, programmers and corporations having invested
         | loads of time and effort in building, maintaining and battle-
         | testing libraries.
         | 
         | Don't get me wrong, i think Julia is an amazing language, but
         | being an amazing language is neither necessary or sufficient to
         | succeed. R shows how you can succeed just fine with a kinda
         | weird language.
        
           | mumblemumble wrote:
           | I would be careful treating this too much like a popularity
           | contest. Python will still be used 20 years from now, but
           | that doesn't necessarily mean that it's going to be dominant
           | 20 years from now.
           | 
           | Source: I used to do a _lot_ of programming in various
           | dialects of Basic, which, a bit over 20 years ago, was
           | popular largely because of its own ubiquity and popularity.
           | And, while I still maintain some Basic code, I was surprised
           | how quickly it died. One day everything was being written in
           | it. The next day, we were were writing new things in a fancy
           | new language that everyone agreed was more productive, and
           | talking to the existing stuff through an FFI. And, a day
           | later, we were replacing modules in order to get them off of
           | the  "legacy" platform.
        
           | dcolkitt wrote:
           | > R shows how you can succeed just fine with a kinda weird
           | language.
           | 
           | One thing that most people don't appreciate about R is the
           | subtle influence from lisp world. This makes it really feel
           | like the language is optimized for data science down to the
           | most basic syntax level.
        
             | gugagore wrote:
             | I'd love an example of the subtle influence. In any case,
             | the influence of lisp on julia is pretty obvious if you're
             | familiar with lisp, I believe.
        
               | cwyers wrote:
               | I believe that R was originally an implementation of S in
               | Scheme, because of the restrictive commercial licensing
               | of S and the desire to have a free-as-in-beer alternative
               | that was S-compatible. This comes through in things like
               | R's metaprogramming:
               | 
               | https://adv-r.hadley.nz/meta-big-picture.html#meta-big-
               | pictu...
        
           | socialdemocrat wrote:
           | > The clear advantage of Python is the enormous ecosystem
           | that is available
           | 
           | Could have said that about Perl back in the day too, or a
           | great number of languages.
           | 
           | The key problem Python faces competing against Julia in the
           | long run is that Julia runs faster with less resources. By
           | that I mean that because packages in Julia combine easier and
           | are written all in Julia, it is simply much faster to develop
           | equivalent functionality in Julia compared to Python.
           | 
           | Thus as Julia grows the speed of advancement will just keep
           | growing. There is also a sort of asymptotic curve for most
           | software. As you reach certain complexity advancing gets
           | slower. Python due to its age has acquired a lot of cruft
           | which will slow development down.
           | 
           | I know exactly how this feels from having worked on very
           | similar software products of different age. The older
           | software really had problems keeping up speed. The younger
           | software moved ahead faster due to cleaner design. We needed
           | far less people to add more features than the competition.
           | 
           | Python will struggle with old design decisions it can no
           | longer undo. Look at e.g. the enormous amount of man hours
           | required to get JIT compilation working in Python. It still
           | does not work well. Meanwhile Julia has require less manpower
           | making a whole language with better JIT compilation.
           | 
           | Language design matters over time. I don't claim Julia will
           | overtake Python any time soon. But over a long time frame I
           | think it is inevitable, because legacy goes against Python in
           | too many areas.
        
           | awb wrote:
           | > Python will still be used 20 years from now
           | 
           | So much technology has come and gone since 2000. If
           | innovation continues to accelerate I'd be hesitant to predict
           | what 2040 will look like.
           | 
           | Programming might become so simple and automated that we
           | won't need StackOverflow to the extent we do today.
           | 
           | It's really hard to predict the next year or two let alone
           | the next 20.
        
             | earenndil wrote:
             | > If innovation continues to accelerate
             | 
             | It won't; that is a naive view. Innovation can't keep
             | accelerating forever, and I would be surprised if it even
             | keeps up its current pace; far likelier it's a sigmoid
             | curve - https://en.wikipedia.org/wiki/Sigmoid_function
        
               | gugagore wrote:
               | I don't know if you're talking about like the heat death
               | of the universe, and so like nothing is "forever", but I
               | don't see signs of programming language innovation
               | slowing down at all.
        
             | goatlover wrote:
             | Programming languages from 2000 remain, though. C, C++,
             | Java, JS, Python, etc. Even Fortran, Cobol and Lisp remain
             | in use. There's been attempts since the 80s to popularize
             | visual and and higher level approaches to programming, but
             | the traditional languages still dominate. And the newer
             | ones like Go, Elixir and Julia are like the traditional C,
             | Lisp and Fortrans.
        
               | elcomet wrote:
               | More than this, C is from the 70s, and C++ is from the
               | 80s.
               | 
               | This is 50 years from now for C. So I'd say python is
               | likely to be still here 20 years from now, given how
               | popular it is.
        
               | cygx wrote:
               | Python will still be around, but how popular it'll be is
               | an open question. For example, Pascal or Perl were huge
               | in their prime, and while they continue to stick around,
               | the torch has been passed on.
        
               | goatlover wrote:
               | Sure, but if Julia relegates Python to a niche and Rust
               | does the same thing to C, they're still the same kind of
               | approach to programming, and not some high level, mostly
               | automated thing. They don't fundamentally change how
               | people program.
        
               | hpcjoe wrote:
               | When you write idiomatic Julia ... not C in a Julia
               | syntax, but actually leverage the native power of Julia,
               | yeah, you write code differently.
        
               | awb wrote:
               | Sure, some do, but past adoption is not a guarantee of
               | future adoption. 20 years in the future is a long time.
               | Just look at Flash. Who knows, maybe a Quantum OS will
               | dominate that doesn't support Python.
               | 
               | So yes, if someone will still be using Python in 20
               | years, I'm sure you're right. But Python just as easily
               | could be relegated to a niche domain while other
               | languages take over a broader range of applications.
               | 
               | Especially if someone's able to build a programming
               | translator where you can easily port your code base from
               | one language to another.
        
               | coldtea wrote:
               | > _Sure, some do, but past adoption is not a guarantee of
               | future adoption._
               | 
               | Not a guarantee but still the best predictor.
               | 
               | > _20 years in the future is a long time. Just look at
               | Flash._
               | 
               | Flash had a lot of things against it. Proprietary (aside
               | from niche implementations nobody really cared about or
               | used), single vendor, not owing its platform (browser
               | vendors owned it), and not really that useful (aside from
               | casual online games its main other use was small
               | animations and intro pages).
               | 
               | And even then, it also took the combined effort of 3
               | browser vendors to kill it, and its public ousting from
               | its mobile platform from the biggest company on Earth...
        
               | goatlover wrote:
               | I'm more responding to the idea that programming might
               | become simple and automated, and we can't even predict
               | technological changes a year or two out. You're right
               | that Python could be relegated to a niche language in 20
               | years. That does happen.
               | 
               | What hasn't happened is a fundamental change to
               | programming languages since the 1960s, despite the
               | incredible increase in computing power, ubiquity of
               | computers and much better tooling and environments for
               | programming languages. There's no evidence that this is
               | going to change anytime soon. All the popular new
               | languages are similar to the popular older languages. If
               | people don't want to program in JS, they transpile from
               | Typescript. Even web assembly is a means to use a
               | language like Rust on the web.
               | 
               | There's no simple, automated PL on the horizon that is
               | going to replace JS, Java, Python, etc. There isn't one
               | for spreadsheets, either, which is a technology from the
               | 80s.
        
               | JadeNB wrote:
               | > What hasn't happened is a fundamental change to
               | programming languages since the 1960s
               | 
               | I think the rise of HLLs is an example of a fundamental
               | change. It was still reasonable to be hand-writing
               | assembler for lots of applications in the '60s.
        
               | goatlover wrote:
               | Sure, but HLLs are decades old and ubiquitous by the 80s.
               | There's no reason to think PLs are going to fundamentally
               | change in 20 years. They could, but it's just speculation
               | at this point.
        
               | edw wrote:
               | The argument over whether C was fast enough to obviate
               | the need to write in assembly raged across the pages of
               | Dr Dobb's Journal and Byte Magazine well into the mid
               | '80s.
        
               | pjmlp wrote:
               | Which while true for home micros, was already a proven
               | fact since the early 60's in the big warehouse
               | mainframes, with the Algol derived systems programming
               | languages.
        
               | goatlover wrote:
               | And that supports the argument that PL evolution is slow
               | and unlikely to fundamentally change in 20 years time.
               | Anyway, while people where arguing over C vs Assembly,
               | there were Lisp and Smalltalk machines that didn't become
               | the future.
        
             | coldtea wrote:
             | > _So much technology has come and gone since 2000. If
             | innovation continues to accelerate I 'd be hesitant to
             | predict what 2040 will look like._
             | 
             | Not much core technology -- e.g. programming languages and
             | their ecosystems.
             | 
             | Frameworks, or specific business cases or tools ('grid
             | computing', 'big data', 'no sql' etc) sure...
        
           | dv_dt wrote:
           | Perl used to be in somewhere similar to Pythons place 20
           | years ago...
        
           | gugagore wrote:
           | > the millions of questions on SO giving solutions to every
           | problem you can run into
           | 
           | I definitely know what you mean. I too have the experience of
           | typing in basically natural language queries into Google and
           | have stack overflow turn it into copy-paste-able code for me.
           | 
           | But what's also true is that in 20 years the problems being
           | solved will likely be bigger, and more complicated, and in
           | many cases we'll be solving them on platforms that require
           | good abstractions over multiple cores. So none of that is
           | really in Python's wheelhouse. (Complexity is an issue
           | because abstrations in Python almost always come at a cost.)
        
           | logicchains wrote:
           | >The clear advantage of Python is the enormous ecosystem that
           | is available, the millions of questions on SO giving
           | solutions to every problem you can run into
           | 
           | All of this is also available in Julia via its near-seamless
           | Python interop. Its package manager even does a better job of
           | managing Python packages than Python does.
        
           | ScottPJones wrote:
           | Python's ecosystem is great - but Julia's is growing
           | incredibly fast, and in some cases Julia has already
           | surpassed what is available in other languages (for example,
           | take a look at the whole differential equations ecosystem:
           | https://github.com/JuliaDiffEq). Also, Python's ecosystem is
           | only a 'pyimport(name)' away (using the PyCall.jl package).
           | Same thing is true for R and a number of other languages
           | (RCall.jl, JavaCall.jl, etc.) I've been using SymPy, QisKit,
           | matplotlib and other Python packages with no problem in
           | Julia.
        
           | baron_harkonnen wrote:
           | I remember when Python was a new and exciting language and
           | people said the exact same thing about Perl. "You'll never
           | see Python replace Perl for string processing, Perl has such
           | a huge ecosystem!". At the time Perl was the de facto
           | interpreted/"scripting" language.
           | 
           | Sure Perl is around still, but it has become a rather niche
           | language used in a small number of specific communities.
           | 
           | I use Python everyday, and still haven't had enough time to
           | properly learn Julia, and I would certainly not be shocked to
           | see Julia take over the lion's share of numeric computing
           | from Python in 20 years.
        
             | cwyers wrote:
             | Yes, some things succeed. Most things don't succeed. If you
             | bet on failure 100% of the time, you'll have your misses,
             | but you'll hit more than you miss.
        
             | int_19h wrote:
             | Python replaced Perl in many niches, because Python was
             | better suited to _general_ tasks. For string processing, it
             | wasn 't as convenient, but there were so many other things
             | where it was clearly a better choice. And being able to use
             | a single "good enough" language for everything is itself a
             | major convenience.
             | 
             | Julia is the opposite - it's better than Python in one
             | particular narrow niche, and cannot replace it broadly. So
             | it has to offer enough to justify going from one language
             | to two.
        
               | Recurecur wrote:
               | "Julia is the opposite - it's better than Python in one
               | particular narrow niche, and cannot replace it broadly.
               | So it has to offer enough to justify going from one
               | language to two."
               | 
               | How so? Julia is a fine general purpose language. I'd go
               | so far as to say it's more appropriate than Python for a
               | wide class of problems!
        
               | hpcjoe wrote:
               | In many ways, Julia is a better python than python, if
               | only for the lack of the (quite insane in the 2000s)
               | program structure by text formatting. That is a
               | misfeature.
               | 
               | Julia is fast out of the box. You don't need Julia +
               | some-other-language to get performance. You can use your
               | GPUs fairly trivially from within the language (though
               | this is implemented as FFI, it still has an idiomatic
               | feel to it).
               | 
               | As for the previous comments on Perl, I am reminded of
               | Mark Twain's famous retort. Rumors of its demise are
               | greatly exaggerated.
        
               | kwertzzz wrote:
               | Did you know that Java for instance, was originally
               | designed to run on interactive TVs? But then, Java run on
               | many type of devices and in broad range of use-cases
               | (maybe with the exception of TVs :-)).
               | 
               | The original niche for which a programming language is
               | designed may or may not be indicative for what it is used
               | in the end. Julia strikes a very good balance between
               | performance, flexibility (macros) and ease-of-use
               | (default type inference). I won't be surprised if there
               | are other niches outside of scientific computing where
               | these characteristics are desirable.
               | 
               | The biggest obstacle I see for the adoption of Julia
               | outside of the scientific computing realm are the
               | latencies due to compilation. There are already 3-party
               | solutions for this (like PackageCompiler{X,}.jl) but imho
               | they are not robust yet enough for widespread adoption,
               | but this might be about to change when different effort
               | join forces [1].
               | 
               | [1]
               | https://github.com/JuliaLang/PackageCompiler.jl/pull/304
        
       | StefanKarpinski wrote:
       | I think the top-level take away here is not that Julia is a great
       | language (although it is) and that they should use it for all the
       | things (although that's not the worst idea), but that its design
       | has hit on _something_ that has made a major step forwards in
       | terms of our ability to achieve code reuse. It is actually the
       | case in Julia that you can take generic algorithms that were
       | written by one person and custom types that were written by other
       | people and just use them together efficiently and effectively.
       | This majorly raises the table stakes for code reuse in
       | programming languages. Language designers should not copy all the
       | features of Julia, but they should at the very least understand
       | why this works so well, and be able to accomplish this level of
       | code reuse in future designs.
        
         | ViralBShah wrote:
         | This visualization of dependencies among Julia packages in this
         | twitter thread by cormullion shows it pretty well.
         | 
         | https://twitter.com/_cormullion/status/1224640188518932483
        
       | UncleOxidant wrote:
       | I really like Julia a lot and actually used it in a work project
       | a few years back.
       | 
       | However, there's the debugger issue. There are several debugger
       | alternatives. It's tough to figure out which debugger is
       | canonical (or is any of them the canonical debugger?). The one
       | that seems to being used most at this point is Debugger.jl.
       | However, it's exceedingly slow if you're debugging sizeable
       | operations (matrix multiplies, for example) - I'm talking hitting
       | 'n' to step to the next line and then waiting several minutes for
       | it to get there. There's also Rebugger.jl, MagneticReadHead.jl
       | (IIRC) and Infiltrator.jl among others. I finally found that
       | Infiltrator.jl was a lot faster for that machine learning program
       | I was trying to debug, but it's rather limited in features (the
       | only way to set breakpoints it seems is by editing your source,
       | for example).
       | 
       | And this isn't the only case where there are multiple packages
       | for achieving some task and you're not quite sure which one is
       | the one that's the most usable. I think what the Julia community
       | needs to do is maybe add some kind of rating system for packages
       | so you can see which packages have the highest rating.
        
         | pjmlp wrote:
         | Hardly any different than other programming languages with
         | multiple implementations.
        
         | nwvg_7257 wrote:
         | Couple comments on the Debugger situation:
         | 
         | 1. Debugger.jl is A LOT smoother if you run it in compiled
         | mode, which is a checkbox in the Juno interface. I've found
         | that stepping to next line is instant in compiled mode, but
         | takes forever without it.
         | 
         | 2. Infiltrator.jl is great at what it's designed for, which is
         | to dump you in a REPL deep within a call stack and let you see
         | what's going on. But, Debugger in compiled mode also does this
         | well.
        
           | UncleOxidant wrote:
           | > 1. Debugger.jl is A LOT smoother if you run it in compiled
           | mode, which is a checkbox in the Juno interface. I've found
           | that stepping to next line is instant in compiled mode, but
           | takes forever without it.
           | 
           | Is there a way to do this if I'm not running Juno? I'd guess
           | there must be some parameter that can be passed to @enter or
           | @run?
        
             | Sukera wrote:
             | Sure! 'C' in the debug REPL enters compiled mode.
             | 
             | https://github.com/JuliaDebug/Debugger.jl#compiled-mode
        
               | elcritch wrote:
               | Thanks! Didn't even know that was a thing.
        
               | UncleOxidant wrote:
               | I guess what I don't understand is this part (regarding
               | the compiled mode):
               | 
               | "The drawback is of course that breakpoints in code that
               | is stepped over are missed."
               | 
               | what exactly does that mean?
        
               | StefanKarpinski wrote:
               | It means that if you would have hit a breakpoint in code
               | that is run in compiled mode, the breakpoint doesn't
               | trigger--because it's being run normally at full speed
               | without breakpoints, not being interpreted in the
               | debugger (which knows about breakpoints).
        
               | UncleOxidant wrote:
               | I read this as in compiled mode breakpoints don't trigger
               | at all. Is that correct?
               | 
               | Edit: Ok, I tried out compiled mode and it does stop at
               | my breakpoint. The verbage in the documentation is a bit
               | difficult to understand on this point. I'd guess you need
               | to first set your breakpoints prior to going into compile
               | mode?
        
               | mkborregaard wrote:
               | Learning a lot from this thread, seems really usfeul
        
       | Iwan-Zotow wrote:
       | Composable? Julia and composable?!?
       | 
       | They decided on sequence range [1...N], instead of [0...N) like
       | Python.
       | 
       | Try to compose that.
        
         | stellalo wrote:
         | What does that have to do with anything?
        
           | Iwan-Zotow wrote:
           | Simple example - I have Python sequence [0...N) to process.
           | If members are independent, I could split it with easy in
           | Python and do it in parallel: [0...N) -> [0...M) + [M...N)
           | for any M between 0 and N. Basically, Python
           | sequences/ranges/etc are monoids in many cases. Simplest
           | composition rule - monoid, with unit element and associative
           | composition. In Julia it really looks ugly, you have to make
           | some effort to do it right. For me, Julia people don't get
           | range/sequence composition right, so ...
        
         | eigenspace wrote:
         | https://news.ycombinator.com/item?id=22163210
        
         | socialdemocrat wrote:
         | Depends on what you work on. When doing more computer science
         | like stuff, such as computing memory offsets etc, then 0-based
         | indexing is practical. But for numerical work 1-based indexing
         | is usually easier to work with. Mathematical texts are already
         | using 1-based indexing and hence that is what people are used
         | to when thinking about math.
         | 
         | I work with both and I never found this a big problem. This is
         | on par with complaining about whitespace in Python. I prefer
         | languages to not be whitespace sensitive but it is not a big
         | problem.
         | 
         | Although I pretty sure you will accidentally get more problem
         | from Python whitespace usage than from Julia 1-based indexing.
         | 
         | And frankly since Julia can use any indexing, you can use
         | A[begin:end] to refer to the whole range of an object. If you
         | want the second item in any array you can just write
         | A[begin+1].
        
           | wnoise wrote:
           | > Mathematical texts are already using 1-based indexing
           | 
           | For matrices and vectors, usually. For series and sequences
           | 0-based comes up quite often too.
        
           | Iwan-Zotow wrote:
           | Whatever I'm doing this is wrong. Simple example - I have
           | Python sequence [0...N) to process. If members are
           | independent, I could split it with easy in Python and do it
           | in parallel: [0...N) -> [0...M) + [M...N) for any M between 0
           | and N. Basically, Python sequences/ranges/etc are monoids in
           | many cases. Simplest composition rule - monoid, with unit
           | element and associative composition. In Julia it really looks
           | ugly, you have to make some effort to do it right.
           | 
           | For me, Julia people don't get range/sequence composition
           | right, so ...
        
             | JustFinishedBSG wrote:
             | You're inventing problems that don't exist. Every thing you
             | said is applicable exactly with 1, 2 or whatever based
             | indexing. It literally doesn't matter.
             | 
             | Julia's sequences/arrays are monoids too, I don't see what
             | it has to do with anything.
        
           | giornogiovanna wrote:
           | > But for numerical work 1-based indexing is usually easier
           | to work with.
           | 
           | That's not really true in my experience, since all the nice
           | properties of zero-based indexing transfer perfectly over to
           | mathematics.
           | 
           | But you're right, this isn't anything to abandon an otherwise
           | wonderful language over.
        
         | SolarNet wrote:
         | It's pretty easy, you use an OffsetArray.
         | 
         | Because Julia _is composable_ the shape of the array and the
         | values in it are orthogonal while reaming performant (as
         | discussed by the article). As demonstrated by OffsetArray how
         | one access an array is also orthogonal to those other factors,
         | _while remaining performant_ (it 's a zero runtime cost
         | abstraction).
        
           | Iwan-Zotow wrote:
           | Why I have to make special efforts to make simple things?
           | Simple example - I have Python sequence [0...N) to process.
           | If members are independent, I could split it with easy in
           | Python and do it in parallel: [0...N) -> [0...M) + [M...N)
           | for any M between 0 and N. Basically, Python
           | sequences/ranges/etc are monoids in many cases. Simplest
           | composition rule - monoid, with unit element and associative
           | composition. In Julia it really looks ugly, you have to make
           | some effort to do it right. For me, Julia people don't get
           | range/sequence composition right, simple thing, basic thing,
           | thus ...
        
         | JustFinishedBSG wrote:
         | If subtracting 1 when needed is too much work then you have
         | more serious problems that the choice of programming language.
        
         | whataflag wrote:
         | 1 based indexing introduces a whole class of errors that are
         | solved in Rust. Why aren't you using Rust?
        
         | sgt101 wrote:
         | Errm : https://docs.julialang.org/en/v1/devdocs/offset-arrays/
        
       | byt143 wrote:
       | Anyone know how this compares to swift and its protocols etc?
        
         | socialdemocrat wrote:
         | I am a big fan of Julia, but Swift is perhaps the only
         | statically typed object-oriented language (apart from
         | Objective-C) which I have found offers some similarity in
         | flexibility to Swift's way of dealing with types.
         | 
         | With the ability in Swift of adding extensions to conforming to
         | a particular protocol to a class, you gain some of the same
         | flexibility in Swift as in Julia.
         | 
         | It means you can take an existing class which was not designed
         | in particular for some kind of abstraction and add conformance
         | to an abstraction (protocol) you later added.
         | 
         | That is kind of what Julia gives you, with the ability to
         | easily add functions dispatching on an existing type.
         | 
         | Say you got a `Polygon` and `Circle` type in Swift and Julia
         | which you want to add serialization to without either one
         | having been designed for it originally. In Swift I would define
         | a `Serializable` protocol with a `serialize` method taking an
         | `IO` object to serialize to. Then I would extend `Polygon` and
         | `Circle` to implement this protocol.
         | 
         | In Julia I would simply add two functions:
         | serialize(io::IO, poly::Polygon)        serialize(io::IO,
         | circle::Circle)
         | 
         | The challenge in Julia is that I might want to define that only
         | objects of type `Shape` can be serialized, but if `Polygon` and
         | `Circle` was not already defined as subtypes of `Shape` I
         | cannot do anything about that without changing source code.
         | Swift has an advantage in his case.
         | 
         | My only alternative in Swift would be to create a Union type of
         | all tye types I want to be serializable.
        
           | ken wrote:
           | > With the ability in Swift of adding extensions to
           | conforming to a particular protocol to a class, you gain some
           | of the same flexibility in Swift as in Julia.
           | 
           | You can add methods or computed properties, but that's about
           | it. That's only one axis of flexibility, and it's really only
           | syntactic sugar for writing and calling your own functions.
           | You can't add any other kinds of features, unless they chose
           | to use protocols in their interfaces -- which they usually
           | didn't.
           | 
           | For example, that page gives the example of adding precision
           | to numbers in Julia. I'm not sure how you could do something
           | analogous in Swift, short of writing your own numeric tower
           | from scratch. In Swift 4 they did add a Numeric protocol, but
           | it's not used much. It's probably hard to retcon this sort of
           | interface onto a framework which was built around concrete
           | structs from the start.
        
             | socialdemocrat wrote:
             | > You can add methods or computed properties, but that's
             | about it. That's only one axis of flexibility, and it's
             | really only syntactic sugar for writing and calling your
             | own functions. You can't add any other kinds of features,
             | unless they chose to use protocols in their interfaces --
             | which they usually didn't.
             | 
             | I don't fully agree with this. I can add an extension
             | implementing a protocol. That allows me to use classes I
             | did not create in some kind of new subsystem I have just
             | made, which requires objects adhering to a particular
             | interface.
             | 
             | For instance I can take a library X somebody else made in
             | Swift and made my own serialization library Y. Then I can
             | add a serialization protocol to all classes in X. I can
             | then have object graphs consisting of X objects which can
             | now be serialized by my serialization library Y. This is
             | beyond just adding syntax sugar for function calls. You are
             | dispatching on the object type.
             | 
             | > For example, that page gives the example of adding
             | precision to numbers in Julia. I'm not sure how you could
             | do something analogous in Swift, short of writing your own
             | numeric tower from scratch.
             | 
             | Yes this is the limitation of Swift which I have tried to
             | articulate elsewhere in this discussion. In Julia I can
             | make a subtype of AbstractArray or Number and this type can
             | be used in all sorts of existing Julia libraries. That
             | possibility does not exist Swift and I am uncertain if it
             | ever can be made to exist.
             | 
             | If a Swift function took an abstract number type as
             | argument, then the value I believe would have to be boxed.
             | I don't see how an AOT compiler could avoid boxing. I mean
             | inside a library perhaps, but across library/framework
             | boundaries I don't see how you could avoid it.
             | 
             | Unless Swift is fundamentally redesigned as a language, I
             | don't think it can ever match Julia in numerical computing
             | and composability. Although I find it far easier to work
             | with than C++ with respect to composability. My language
             | preference is probably Julia, Go and then Swift. Go is
             | somewhat primitive but it is kind of fun to work with. I
             | like that they dialed back the static typing a bit. Swift
             | feels a bit too Nazi at times.
        
             | byt143 wrote:
             | So it's a package, not a language issue?
             | 
             | Here's a revamp based on protocols
             | https://github.com/apple/swift-numerics
        
           | byt143 wrote:
           | Thanks. I mean in julia you can use traits for that, but it's
           | not built in (yet). Though there's no speed penalty, as you
           | probably know.
           | 
           | So this is about extending types, but it sounds like swift is
           | strictly "better" then, since it's also statically checked?
           | Or is there something that multiple dispatch gives that
           | substantively better?
           | 
           | I'm trying to get a feel for if the Swift for Tensorflow
           | project will afford the same kind of composability, while
           | keeping static type checking, modules etc (assuming they work
           | out cross module code specialization, which I think is
           | happening).
        
             | e12e wrote:
             | Does swift have macros?
             | 
             | Looks like there's some work in bolting type checking on to
             | Julia (small surprise, as we've seen that with eg: python
             | and ruby as well).
             | 
             | I'd hazard it's easier to bolt on typechecking than a
             | proper macro system.
        
           | eigenspace wrote:
           | > The challenge in Julia is that I might want to define that
           | only objects of type `Shape` can be serialized, but if
           | `Polygon` and `Circle` was not already defined as subtypes of
           | `Shape` I cannot do anything about that without changing
           | source code. Swift has an advantage in his case.
           | 
           | You can do this with traits. One pattern is that you can
           | define                   struct Shape{T} end         struct
           | Not{T}   end              has_shape_trait(::T) where {T} =
           | Not{Shape}         has_shape_trait(::Circle)      =
           | IsShape{Circle}         has_shape_trait(::Polygon)     =
           | IsShape{Polygon}
           | 
           | and then you can write                  serialize(io::IO, x)
           | = serialize(io, has_shape_trait(x), x)
           | serialize(io::IO, ::Shape, x) = # shape serialization here
           | serialize(io::IO, ::Not{Shape}, x) = # Fallback code, or an
           | error here (or just leave it undefined)
           | 
           | This requires a bit more boiler-plate than regular abstract
           | types but it's a pretty powerful technique (and has no
           | runtime overhead). I do dream of having built in traits
           | someday though to remove some of the boiler plate.
           | 
           | __________
           | 
           | By the way, is this a typo in your first paragraph?
           | 
           | > I am a big fan of Julia, but Swift is perhaps the only
           | statically typed object-oriented language (apart from
           | Objective-C) which I have found offers some similarity in
           | flexibility to Swift's way of dealing with types.
           | 
           | You seem to be saying Swift is the only language which is
           | similar in flexibility to Swift. Maybe you meant to reference
           | another language?
        
             | socialdemocrat wrote:
             | Great example with the traits. Yes I seemed to have made a
             | whole series of typos. Must have been tired then.
             | 
             | In this quote, I meant Julia and not Swift ;-)
             | 
             | " some similarity in flexibility to Swift's way of dealing
             | with types."
        
         | eigenspace wrote:
         | Julian interfaces are less formal than swift protocols. We use
         | sub-typing and/or traits together with multiple dispatch to
         | define generic pluggable interfaces.
         | 
         | There's a lot of discussion around making a more formal
         | protocol-like system but so far what we have works surprisingly
         | well, so we're not in a huge hurry to implement something and
         | want to slowly explore the design space.
        
           | byt143 wrote:
           | Sure, but I'm more looking for something from the swift side
           | of whether Swift can do the same sort of composable generic
           | programming.
        
             | socialdemocrat wrote:
             | To some degree it can, but there are a number of problems
             | with using Swift for this:
             | 
             | (1) Swift does not support multiple dispatch. That limits
             | the way you can glue together unrelated libraries.
             | 
             | (2) Swift does not use abstract type hierarchies very much.
             | E.g. in Julia one frequently define functions to use
             | arguments of type Number, AbstractArray, AbstractString
             | etc. This means it is easy for somebody in the future and
             | define an array that works on a GPU or which is statically
             | allocated and all existing functions operating on arrays
             | work just fine.
             | 
             | I can invent a whole new number type and make it a subtype
             | of Number and all my existing algorithms operating on
             | numbers work just fine. One example of this would be Dual
             | Numbers, which allow automatic differentiation. This was
             | fairly easy to accomplish in Julia, but has been a major
             | undertaking on Swift, which I don't think is done yet. I
             | think they actually have to change the whole compiler. For
             | Julia this is just a library thing.
             | 
             | (3) Swift function and method syntax is a pain to work
             | with. For purely object oriented code it is very nice to
             | read with parameter names. But once you get into functional
             | programming and composition I find that it just creates a
             | mess. I have to fiddle way too much with my Swift code to
             | get function composition working as I desire. With Julia it
             | is straightforward.
             | 
             | I would say composition is easier when everything is just
             | based on the same function syntax.
        
               | byt143 wrote:
               | That makes sense. Swift is also way too complex and
               | syntatically noisy imo. I like that Julia has a smaller
               | set of very powerful abstractions.
               | 
               | Though isn't point (2) just a convention thing? Protocols
               | can refine other protocols. So in S4TF there's a layer
               | protocol and an RNN protocol which extends that, IIRC.
        
               | socialdemocrat wrote:
               | I don't think so, I may be wrong, but I am quite sure you
               | would get a significant performance penalty in Swift if
               | you used protocols all over the place.
               | 
               | For instance if `func foo(bar: Number)` in Swift would
               | give bad performance I believe as the number object would
               | have to be boxed.
               | 
               | Julia can work with abstract types in a lot of instance
               | without getting any performance penalty due to how the
               | Julia type system works and Just in Time compilation. I
               | don't quite see how a statically typed AOT compiled
               | language could achieve the same.
        
               | byt143 wrote:
               | Perhaps this helps? https://github.com/apple/swift-
               | evolution/blob/master/proposa...
               | 
               | and this
               | 
               | https://twitter.com/jckarter/status/1202260205074968578
        
               | socialdemocrat wrote:
               | Must confess I am a bit too tired to parse that text
               | effectively at the moment, but I don't think that is a
               | solution. It is basically a solution to deal with
               | generics across libraries. In C++ this is a big problem
               | right. Templates cannot really be put in libraries. You
               | put them in header files.
               | 
               | So if you put generics in a library and link it, how are
               | you going to know what to specialize and what not to
               | specialize? That is the problem it seems to be they are
               | solving here.
               | 
               | But this is still a compile time issue they are solving.
               | What I am talking about is an issue that happens at
               | runtime.
               | 
               | If I call a function f(x, y, z) and don't know the exact
               | types of x, y, z at compile time, then Swift has no way
               | of generating an efficient implementation of f. Julia
               | OTOH due to its support for multiple dispatch CAN create
               | an efficient implementation of f(x, y, z) for all
               | possible types of x, y and z.
               | 
               | Actually on further reflection I cannot see any way an
               | AOT compiler can solve this problem. Say you got this
               | definition:                   f(x: Number, y: Number, z:
               | Number)
               | 
               | A Swift library could in theory compile all sorts of
               | concrete variations of this function for concrete number
               | types. However there is no way it can provide all number
               | types. The user could provide new subtypes of Number not
               | known when the library containing f was created.
               | 
               | I was a big Swift fan before and did not like JITs but
               | Julia really convinced me how absolutely amazing Just in
               | Time compilation is, especially combined with a dynamic
               | language. You can just do so much crazy stuff that you
               | have no way of achieving in a sane way in a statically
               | type ahead of time compiled language.
        
             | eigenspace wrote:
             | Ah I see, I assumed you were already knowledgable about
             | Swift. Cant help there, I only have a passing familiarity
             | with it.
        
       | xvilka wrote:
       | I hope Julia will be more popular in bioinformatics. Personally,
       | I have a high hopes for BioJulia[1][2][3] and the amazing AI
       | framework FluxML[4][5] + Turing.jl[6][7]. Apart from the speed,
       | they offer some interesting concepts too - I recommend to check
       | them out.
       | 
       | [1] https://biojulia.net/
       | 
       | [2] https://github.com/BioJulia
       | 
       | [3] https://github.com/BioJulia
       | 
       | [4] https://fluxml.ai/
       | 
       | [5] https://github.com/FluxML/
       | 
       | [6] https://turing.ml/dev/
       | 
       | [7] https://github.com/TuringLang
        
         | [deleted]
        
         | mark_l_watson wrote:
         | FluxML is amazing, so much nicer than using TensorFlow.
        
           | krastanov wrote:
           | I will have to disagree. FluxML is indeed great, but it
           | changes often and it does not support many of the advanced
           | features of TensorFlow (neither is there a package that
           | seamlessly works with Flux in order to support these
           | features). It is getting there, but Tensorflow v2 is pretty
           | great itself, and frequently faster. But FluxML might soon be
           | as good or better.
           | 
           | Also, to be fair, FluxML is backed by a couple of people
           | while Tensorflow is backed by megacorps, so it is already
           | impressive how much they have done.
        
         | totalperspectiv wrote:
         | I've always found Julia a little lacking for bioinformatics,
         | but I'm not doing ML. I have very high hopes for Nim, which I
         | think has better performance potential than Julia across
         | domains and can produce binaries.
        
         | CreRecombinase wrote:
         | How much of the BioJulia stuff would you say currently works?
         | It looks like a lot of repos have been created, and the scope
         | is pretty impressive (looks like there are repos for everything
         | from structural bioinformatics to population genetics), but a
         | lot of them look to be basically
         | empty(https://github.com/BioJulia/PopGen.jl), or have really
         | scary looking issues:(e.g
         | https://github.com/BioJulia/GeneticVariation.jl/issues/25).
        
           | improbable22 wrote:
           | Not my field, but at least some of it appears to be worked on
           | seriously. This was an interesting recent blog post about
           | making DNA-sequence processing go fast:
           | 
           | https://biojulia.net/post/seq-lang/
        
           | kescobo wrote:
           | % of the repos in the org on github? That number is lower
           | than I'd like. % of the repos that are actively maintained?
           | Much higher.
           | 
           | One of the great things about julia is that it's really easy
           | to throw together a package and register it. One of the bad
           | things about julia is how easy it is for those one-off
           | projects or idea dumps to pollute the space. We could
           | definitely do a better job labeling the repos that are no
           | longer being maintained or that aren't actually ready for
           | prime time. There's a tradition in julia of a lot of really
           | functional libraries to stay < v1.0, because we all take
           | semver seriously, and if the interface is still in a bit of
           | flux, making the switch to 1.0 is a big deal (DataFrames.jl,
           | looking at you). But it does make it hard for new users to
           | distinguish between a super robust package and someone's
           | weekend hobby.
        
       | classified wrote:
       | Is it possible yet to compile ahead-of-time to a stand-alone
       | binary executable?
        
         | newen wrote:
         | Look under Static Julia Compiler here [1]. I've successfully
         | done it in Linux, don't know about Windows. It doesn't work
         | when you have binary dependencies like GTK, etc.
         | 
         | [1] https://github.com/JuliaLang/PackageCompiler.jl
        
         | cultus wrote:
         | Yes, with PackageCompiler.jl. There are some restrictions IIRC
         | since it is a dynamically typed language.
         | 
         | https://github.com/JuliaLang/PackageCompiler.jl
        
         | [deleted]
        
         | cmcaine wrote:
         | The other replies are slightly out of date and imprecise.
         | 
         | PackageCompilerX replaced PackageCompiler (and there's a PR
         | open that will pull all the X work in soon).
         | 
         | The binaries produced bundle the whole Julia sysimage by
         | default and they're quite big, but they are quite fast!
         | 
         | A more traditional static compilation approach is being tried
         | with StaticCompiler.jl by tshort, but it's in early
         | development.
        
           | cosmojg wrote:
           | > A more traditional static compilation approach is being
           | tried with StaticCompiler.jl by tshort, but it's in early
           | development.
           | 
           | The moment this ships, there will no longer be any reason to
           | use any other garbage-collected language.
        
             | eigenspace wrote:
             | What does this have to do with garbage collection?
             | 
             | If your concern is about latency in real time systems,
             | Garbage collection isn't the problem, heap allocating
             | memory is. Julia makes it easy to never allocate anything
             | on the heap (unlike most garbage collected langauges).
             | 
             | Check out this talk this discusses this in detail in the
             | context of robotics:
             | https://www.youtube.com/watch?v=dmWQtI3DFFo
        
               | gugagore wrote:
               | Julia doesn't make it easy to guarantee that you won't
               | allocate anything on the heap. The semantics of the
               | language don't include really any control over that, yet.
               | I hope one day it does. It seems like a tough problem,
               | because the allocation strategy can depend on the results
               | of inference and compilation, which is another thing that
               | is hard to control since the language try hard to have
               | the semantics not depend on inference.
               | 
               | Of course, you can measure the allocations, and you can
               | see as a matter of fact whether some code allocates, but
               | I would say that it's hard to predict what allocates and
               | what doesn't, and that this is still changing (e.g.
               | https://github.com/JuliaLang/julia/pull/32448)
        
               | snicker7 wrote:
               | I think the above poster is referring to languages like
               | Go/Java/C#/Nim/whatever. Like Julia, these languages have
               | a significant runtime. Unlike Julia, their apps can be
               | compiled AOT into standalone executables.
        
               | cosmojg wrote:
               | My point exactly! Thanks for clarifying.
        
               | eigenspace wrote:
               | Right, but you said
               | 
               | > there will no longer be any reason to use any other
               | __garbage-collected language __.
               | 
               | (emphasis mine). I was just curious as to why you
               | specified garbage collected there.
        
               | cosmojg wrote:
               | I equate garbage collection with larger static binaries.
               | Julia's static binaries are especially large since they
               | package the entire sysimage. I'm excited about
               | StaticCompiler.jl because, by cutting out the sysimage,
               | it promises to make Julia more competitive with other
               | garbage-collected languages like Nim, Go, Crystal, etc.,
               | all of which produce relatively small static binaries.
               | 
               | However, like these other garbage-collected languages,
               | Julia is unlikely to ever compete with the likes of Zig,
               | Rust, C++, etc. which produce _even smaller_ static
               | binaries since they don 't have to ship a GC runtime.
               | That's why I specified garbage-collected languages as, in
               | my opinion, the addition of proper static compilation
               | will allow Julia to completely supersede other garbage-
               | collected general programming languages but not manually
               | managed systems programming languages.
        
               | eigenspace wrote:
               | I see, thanks for the explanation!
               | 
               | I think with StaticCompiler.jl, if you create a binary
               | where the compiled code knows there won't be any GC, for
               | instance, say you only ever work with Tuples and floating
               | point numbers, I don't think there will be any GC runtime
               | in the compiled binary.
               | 
               | I could be wrong about this though.
        
       | ColanR wrote:
       | I've been meaning to learn Julia. Is there a recommended text for
       | doing so?
        
         | cosmojg wrote:
         | Check out Think Julia:
         | https://benlauwens.github.io/ThinkJulia.jl/latest/book.html
        
       | huijzer wrote:
       | Julia is by far the favorite language I have written code in. It
       | is extremely expressive, while also being easy to read. Most
       | design decisions are spot on. For example, the language has
       | syntactic sugar, but not too much. Everything in the base library
       | makes sense and seems to be there for a purpose.
       | 
       | Other niceties are the meta-programming capabilities, which allow
       | for things like inspecting the llvm code and printing a variable
       | name `x` plus output by only typing `@show x`. Then there is the
       | fact that anonymous functions actually look like how you would
       | describe a math function! (That is, `f(x) = 2x` is a valid
       | function, as is `f(x) = 2p`.)
       | 
       | However, there is one thing I do not like at all. That is the
       | loading time of packages. When starting julia and running `@time
       | using DataFrames` it takes about 38 seconds when recompiling some
       | stale cache. If all caches are good, the the load times for some
       | common packages still add up to 1.1 + 4.5 + 1.1 seconds according
       | to `@time using Test; @time using CSV; @time using Dates`.
       | Therefore, nowadays I prefer to use R. For most of my use cases R
       | outperforms Julia by a factor 10.
        
       | fishmaster wrote:
       | I've been using Julia along with python and Pytorch, not yet for
       | machine learning until flux is more mature but for NLP scripts,
       | and I have to say that I'm starting to like it. Multiple
       | dispatch, linear algebra and numpy built in, dynamic language but
       | with optional types, user defined types, etc.
        
       ___________________________________________________________________
       (page generated 2020-02-10 23:00 UTC)