Newbie questions coming from Python/C++

Well, I would say that that is a very “numeric computing oriented” position. I know that’s the focus of Julia, but I’m currently exploring it as an intermediate between Python and C++ (as high-level as the former, as fast as the latter) and I suspect others approach Julia that way as well. So I might potentially use it for all kinds of things, not necessarily numeric computing (e.g. text processing, web apps, visualization).

Again, this might be my different approach in using Julia, as I’m currently (as a first step) doing OO-style programming, where you have a set of structs each with their own specific methods of which only a subset needs to be accessible outside the module. The methods are usually not really applicable to other types of structs. Overcoming this with the MyModule.foo(obj, ...) style is a bit suboptimal, having a form that suggests an object-oriented method call (which is impossible in Julia, I know) but still having to pass the actual object as first parameter.

I can actually at this point foresee that I might draw the conclusion that Julia is not a good fit for when you really want to do OO-style programming, but with higher (potential) performance than Python while not wanting to use C++.

Edit: After reading Julia OOP example I’d say OO-style here doesn’t necessary mean using inheritance and such, but working with a set of interrelated objects each with their own methods and performing operations on those objects. I hardly use inheritance in practice.

I actually like that form, it’s very much like Python’s with open(...) as obj: ..., with the same cleaning guarantees

Yuck, both using and import, that’s horrible :slight_smile:

You can do this only with using (although you’ll still need to write two lines)

using HTTP
using HTTP: listen

I’m not sure why there’s more than one way to do this, although at one point, only the import syntax existed.

Cheers,
Kevin

An illustrative example of one difference between using and import

julia> using Base: +

julia> +(a::String, b::String) = a*b
ERROR: error in method definition: function Base.+ must be explicitly imported to be extended
Stacktrace:
 [1] top-level scope at none:0
 [2] top-level scope at REPL[2]:1
 [3] eval(::Module, ::Any) at ./boot.jl:331
 [4] eval_user_input(::Any, ::REPL.REPLBackend) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:86
 [5] run_backend(::REPL.REPLBackend) at /Users/alexames/.julia/packages/Revise/MgvIv/src/Revise.jl:1023
 [6] top-level scope at none:0

julia> import Base.+

julia> +(a::String, b::String) = a*b
+ (generic function with 167 methods)

julia> "piracy" + "is" + "dangerous"
"piracyisdangerous"

Packages are the unit of precompilation, so if you structure your code in terms of packages, then you will benefit from it. Each package corresponds to a module, but otherwise modules are just for namespacing global variables.

What’s the best way to have a struct member that is an editable fixed-size 1-dimensional array of simple values

If you want it to behave fully like a vector that is both fixed-size and mutable (presumably that’s what “editable” means) then you can use MVector from StaticArrays. If you don’t really care about the vectorness and want a mutable container for a single value, then RefValue is what you want, but this behaves like a zero-dimensional container, rather than a one-dimensional container.

Why are certain text outputs being produced so slowly and in chunks? For example, I usually see ERROR: LoadError: being produced, followed by the exception message noticeably later, followed by the first part of the stack trace, etc.

Likely due to compilation of printing methods for previously-unprinted error types. Of course, this is a situation where you don’t really want to spend time compiling, but it’s not straightfoward to mechanically determine when one should or shouldn’t generate specialized code.

Is there a formal grammar of Julia somewhere, as I can’ seem to find one. I occasionally get surprised by what is/isn’t accepted by the compiler and would like to understand why.

There is not an official one. The grammar is implicitly included in the recursive descent parser code here:

If you want an outdated but close-to-correct grammar, there’s on included here:

3 Likes

That may be the correct conclusion, but why would you want to do C++-style OO when you have a more powerful alternative? OO is a tool, not an end.

4 Likes

Well, the more I think about that point the fuzzier it gets. I guess I need some more experience with Julia building an application to see how being unable to use classical OOP forces/allows a different style. By the way, Julia’s multiple dispatch might be more powerful than OOP, but that doesn’t imply it’s a better way to write and structure code in general, as it’s just a tool as well. But not being able (yet) to wield that tool very effectively at this point isn’t making it easier for me to judge it for my own case of using Julia.

2 Likes

This may be the case.

If you consider the amount of time for you to write the code to solve a problem/challenge and the execution time thereof, it’s often (by far) preferable to use a tool/language that you are familiar with.

Then again it might be fun to learn wielding a new weapon, eh tool.

2 Likes

If only the former (code production time) and the latter (execution time) could be minimal in all cases :wink:

Definitely!

1 Like

Of course it doesn’t, but generally people find that it is, once they learn their way around multiple dispatch (it may take a while, at least 20k LOC if you have no prior experience with multiple dispatch).

You may find this part of the manual useful, but there are plenty of other tricks in the sources of various packages.

2 Likes