> Rust is essentially C/C++, but without their ugliness
I'd rephrase that, folks coming primarily from a coding background would probably find this off-putting since Rust's contribution is something quite different from what C/C++ does. It's fairly clear what author means, though.
What exactly do you mean? If you ask C/C++ programmers, what they don't like about C/C++ and fix that, you got Rust. C++ wants to stay backwards compatible, which is holding the language back. Rust was a fresh start.
What I mean is that Rust brings the ownership tracking of memory as a primary concept. With C++ that's more of an add-on. I should add that I'm an old time C++er and don't have Rust hands-on experience
This article is representative of my experiences as well. I'm thankful to the author for writing it. My favorite parts:
> This slowness affects other software written in Julia as well. For example, my editor formats on save. For most languages, the formatting time-delay is not noticable, but for Julia it sometimes took more than 10 seconds.
> The idea of “You only need to start the interpreter once a day” failed for me.
For me, this is the biggest obstacle to using Julia. It's not designed to support the traditional C/Python/whatever workflow of editing a text file and then interpreting/compiling it; it wants you to be in the REPL all the time. If you don't use the REPL, you have horrible problems with package loading times. So if you're someone who doesn't like developing in a REPL, you're out of luck.
And even if you're in a REPL you're out of luck since you cannot reload maybe kinds of code changes without restarting the REPL. Revise.jl is supposed to solve this problem, but last time I tried writing a Julia project (v1.6), I ran into a lot of issues.
Eventually I abandoned Julia because while in theory it seemed like a very nice language, in practice I ran into so many issues that I began to wonder if the core devs even use their own product at all.
I think you’re probably referring to how redefining a struct breaks Revise.jl and you have to restart the REPL? There are some other rough edges but IME this is the most noticeable
You can use Pluto.jl for this kind of rapid prototyping where you might want to change your structs a lot. It works pretty well with Revise, so when you get things the way you like it can move that struct definition out into your package code.
The other common suggestion is to prototype with NamedTuples instead of structs
It's interesting how hard this nut is to crack. I have hit all the same types of problems (R is obscene as a programming language, Python too slow and lacks multicore, C is too low level etc etc). I've ended up using Groovy (JVM) for a lot of my scientific work because it is the "least worst" language - dynamic when you want it to be, static when you want it to be, decent if not stellar set of scientific libraries and performant enough (mostly as fast as Java). I have hopes for Nim but it's still not quite there.
But why isn't there something else? Can we really never have our cake and eat it too in this domain?
I'm assuming "this domain" refers to scientific computing. My theory is that the typical scientist crunching data is just proficient enough to write specialized code for themselves but doesn't have time to develop a scalable, "professional" solution. Very large organizations tend to have capable internal systems but they may not make it into public view or they are too specific to their niche.
On the other hand you have premade, proprietary packages that can become quite popular (Matlab, JMP, etc.) for non-programmers, which dilutes the user base.
That leaves us with things like "R" (horrible, like you say) or Julia (eternally promising) or Python (stitch together low-level Fortran and C code). The latter solution is winning, it seems.
If you're okay with JVM, I'm a big fan of Clojure. There are some great scientific libraries in the SciCloj community and you get the untyped but performant characteristics you're looking for.
I'm kinda the same, but chose Kotlin over Groovy. Especially with IDE hotkeys and smart refactoring a, I'm as fast as in Python Jupyter, if not faster.
I like Kotlin and would probably use it but I just couldn't get over the lack of list / map literals. Seems like they never could figure out how to get them to mesh with the static typing. It's just too useful to be able to write nested structures cleanly and simply inline for ad hoc / exploratory analysis.
yes, they are fine at top level, but they fall apart when you try to nest them unfortunately (lists of maps of lists etc ... ). In groovy / javascript / python these just look completely natural.
That's interesting. I had always considered Groovy as a good language for such tasks. Because fast JVM and many JVM-native libs to work with big data. And also because Groovy is perfect for building a Domain Specific Language.
Personally I feel JITs have gotten too much hype. While they have some advantages in optimization, it seems far outweighed by the downsides. I’d rather have an interpreter for development and a static compiler for production.
Cython has long been an interesting alternative here - a gradually typed amalgam of Python & C that lets you write/compile Python extension modules without needing to learn much of the CPython API. You can even use --embed to compile your whole script file and -X infer_types.verbose=True to let you know where types are dynamic/implicit rather than declared. Several big core packages like scipy use Cython. Few seem to mention it as a wholesale replacement for CPython which it absolutely can be.
Personally, I prefer Nim [2] which has more compile-time meta-programming support, is strongly typed from the outset, and has a lot of syntactic flexibility like UFCS, a "command call syntax" and many other goodies.
I still prefer to use Julia, but this is a good summary of the problems that affect me personally as an experienced user (although I do like dynamic typing for most of the work I do).
these are all very valid pain points with Julia, except I disagree with calling Julia "way more dynamically typed than Python."
I think of Julia as statically duck-typed, which sounds cursed but is incredibly useful IMO. like if you have `foo(x,y,z)=x+ycow(z)`, foo() will work for any x and y with compatible `+` operators, if there's a `cow()` that will accept whatever type `z` is. But it's still static - your code will throw a compile error* if x and y can't be added, or if cow() won't take your z. And unlike Python, Julia can dispatch on types, so you can implement cow() for whatever you want. the type system is, in fact, absurdly powerful. the downside seems to be that it's formally undecidable sometimes, and that you fundamentally can't enforce output types for functions passed as arguments.
the speed is a drag, but it feels like getting a train up to speed - it's slow getting ready to do absurdly heavy lifting.
> I disagree with calling Julia "way more dynamically typed than Python."
What I meant was the following: Take an example Python codebase. Pick a random function. Put a `print(type(arg))` in there. Run it in many different use-cases. Chances are, it will only print a single type. If you do the same in Julia, chances are, it will print multiple very different types.
Well, if you do so for python method it will print different types too. It's just python has functions with no dispatch ability and methods with dispatch ability. In Julia it's just functions.
> The authors of Julia argued that member functions are a bad idea, because it connects a function to a specific datatype
That's actually the thing I love most in Java-like languages. I want to type "foo." and see everything that I can do with foo. If it's not in auto complete -- it doesn't exist.
Compare that with, for example, "len()" in other languages.
29 comments
[ 3.5 ms ] story [ 68.8 ms ] threadI'd rephrase that, folks coming primarily from a coding background would probably find this off-putting since Rust's contribution is something quite different from what C/C++ does. It's fairly clear what author means, though.
> This slowness affects other software written in Julia as well. For example, my editor formats on save. For most languages, the formatting time-delay is not noticable, but for Julia it sometimes took more than 10 seconds.
> The idea of “You only need to start the interpreter once a day” failed for me.
For me, this is the biggest obstacle to using Julia. It's not designed to support the traditional C/Python/whatever workflow of editing a text file and then interpreting/compiling it; it wants you to be in the REPL all the time. If you don't use the REPL, you have horrible problems with package loading times. So if you're someone who doesn't like developing in a REPL, you're out of luck.
Some comments by Julia users on the post are available here: https://discourse.julialang.org/t/blog-post-about-my-experie...
Eventually I abandoned Julia because while in theory it seemed like a very nice language, in practice I ran into so many issues that I began to wonder if the core devs even use their own product at all.
You can use Pluto.jl for this kind of rapid prototyping where you might want to change your structs a lot. It works pretty well with Revise, so when you get things the way you like it can move that struct definition out into your package code.
The other common suggestion is to prototype with NamedTuples instead of structs
But why isn't there something else? Can we really never have our cake and eat it too in this domain?
On the other hand you have premade, proprietary packages that can become quite popular (Matlab, JMP, etc.) for non-programmers, which dilutes the user base.
That leaves us with things like "R" (horrible, like you say) or Julia (eternally promising) or Python (stitch together low-level Fortran and C code). The latter solution is winning, it seems.
And for exploratory .filter{} and .map{} are much better than Python's awkward map(lambda x: ...) and filter(lambda x: ...).
The JIT involved is really a static compiler that has been adapted for use as a JIT compiler: https://llvm.org/docs/ORCv2.html
https://juliadebug.github.io/JuliaInterpreter.jl/stable/ https://julialang.github.io/PackageCompiler.jl/stable/apps.h... https://github.com/tshort/StaticCompiler.jl
Personally, I prefer Nim [2] which has more compile-time meta-programming support, is strongly typed from the outset, and has a lot of syntactic flexibility like UFCS, a "command call syntax" and many other goodies.
[1] https://cython.org/
[2] https://nim-lang.org/
I think of Julia as statically duck-typed, which sounds cursed but is incredibly useful IMO. like if you have `foo(x,y,z)=x+ycow(z)`, foo() will work for any x and y with compatible `+` operators, if there's a `cow()` that will accept whatever type `z` is. But it's still static - your code will throw a compile error* if x and y can't be added, or if cow() won't take your z. And unlike Python, Julia can dispatch on types, so you can implement cow() for whatever you want. the type system is, in fact, absurdly powerful. the downside seems to be that it's formally undecidable sometimes, and that you fundamentally can't enforce output types for functions passed as arguments.
the speed is a drag, but it feels like getting a train up to speed - it's slow getting ready to do absurdly heavy lifting.
What I meant was the following: Take an example Python codebase. Pick a random function. Put a `print(type(arg))` in there. Run it in many different use-cases. Chances are, it will only print a single type. If you do the same in Julia, chances are, it will print multiple very different types.
That's actually the thing I love most in Java-like languages. I want to type "foo." and see everything that I can do with foo. If it's not in auto complete -- it doesn't exist.
Compare that with, for example, "len()" in other languages.