Improve `parse` to be able to handle complex numbers

proposal

#1

As of v0.5.0, the parse command cannot directly handle string representations of complex numbers; e.g. parse("1 + 2im") returns an Expr data type. You can use eval to convert the expression to a Complex{} number, but I suspect there’s a decent amount of overhead here because the stored expression is rather complicated. Since complex numbers are low-level built-in data types, it might be nice if parse could handle them directly, without requiring eval.


#2

Complex numbers are not “low-level built-in data types”. They are not part of the core language definition at all, in fact; the Julia parser knows nothing about them, which is why parse("3+4im") treats them as a generic expression. (A package could even redefine im to something else.) They are a component of the standard library implemented purely in Julia — you can see the entire implementation in https://github.com/JuliaLang/julia/blob/master/base/complex.jl

One of the big strengths of Julia is that the core language is powerful enough to define something as “primitive” as complex numbers in pure Julia, and have it be fast and full-featured. This means that external packages can also define new fast, full-featured “primitive” types.

That being said, it would be useful and possible to implement parse(Complex128, "3+4im"). This is something that might be a good candidate for a package (ParseComplex?). Probably it would want to also support other common formats such as 3+4i and 3+4j. It would also be nice to have a readcsv-like function for comma-delimited complex numbers.


#3

Related issue: https://github.com/JuliaLang/julia/issues/21935


#4

ReadWriteDlm2 will support this in the next Version for Julia 0.6. It is already implemented in the actual master:

https://github.com/strickek/ReadWriteDlm2.jl


#5

“Julia is a high-level, high-performance dynamic programming language for numerical computing.” -> well…


#6

I see no contradiction here. “Low-level builtins” are a small set of constructs that can be used to build up the language proper, which does of course include complex numbers. The fact that you can do this (and similarly for rationals, quantities with units, etc) makes the language not less, but more powerful.

Users need not care about what is a low-level builtin and what isn’t. The fact that they are not parsed directly is an orthogonal issue.


#7

Since julia by default provides the constant im and you can do a simple x = 3 + 2*im anywhere, I think it is only consistent to have proper parsing built into julia and not in a package.


#8

A package “can” do that, but it actually shouldn’t since that’s type piracy. parse is a Base function, and Complex128 is a Base type, so packages shouldn’t be adding this dispatch. This is a job for Base.


#9

Good point, Chris. https://github.com/JuliaLang/julia/issues/22250


#10

3 + 4im is not a literal syntax, it’s an expression involving two integer literals, a binding (im) that must be resolved in the evaluation context, multiplication (by juxtaposition) and an addition. Making parse produce a Complex value when parsing this expression completely ignores the fact that this expression can radically change meaning if any of im, + or * have different meanings in the context in which the expression is evaluated. That is not true of literal syntaxes like 3 – which is precisely the difference between a literal syntax and an expression. It would, however, be reasonable for parse(Complex, "3 + 4im") to work since the type argument determines the meaning of the expression. In that case, however, + and im and the juxtaposition would no longer mean what they mean in Julia, they would simply be part of a parsable literal syntax for complex numbers, which is independent of Julia’s syntax, but happens to coincide with it.