Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: spec: remove complex numbers #19921

Closed
Tracked by #1
bradfitz opened this issue Apr 11, 2017 · 59 comments
Closed
Tracked by #1

proposal: spec: remove complex numbers #19921

bradfitz opened this issue Apr 11, 2017 · 59 comments
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Milestone

Comments

@bradfitz
Copy link
Contributor

Go supports complex numbers, but ~nobody uses them.

The only thing complex numbers add to Go is their complexity to Go's runtime, compiler, and standard library.

I propose we remove them from Go 2.

@bradfitz bradfitz added v2 A language change or incompatible library change LanguageChange Proposal labels Apr 11, 2017
@bradfitz
Copy link
Contributor Author

bradfitz commented Apr 11, 2017

Note: https://golang.org/wiki/NoMeToo

@cznic
Copy link
Contributor

cznic commented Apr 11, 2017

Is it still April 1st in your universe timezone @bradfitz ?

@mvdan
Copy link
Member

mvdan commented Apr 11, 2017

@cznic if you are against this proposal, it would help to illustrate why. I've never used complex numbers in Go, for example - likely the only part of the spec I skipped on purpose.

@cznic
Copy link
Contributor

cznic commented Apr 11, 2017

@mvdan After I've got fooled just a few days ago by the quaternions, my question was just an attempt to figure out if it's a joke or not.

Nonetheless, according to the Go 2016 Survey, 11% of respondents work in the "Academic/Scientific/Numeric" area (multiple choices allowed).

@mvdan
Copy link
Member

mvdan commented Apr 11, 2017

I'm fairly sure this is not a joke. After all, it's about making the language simpler, not more complex ;)

Note that the "Academic/Scientific/Numeric" category might not be much related to the use of complex numbers. Perhaps better support for multi-dimensional slices (there is an issue for that already I think) would be more important to them. A study on that demographic of users could be useful.

@cznic
Copy link
Contributor

cznic commented Apr 11, 2017

After all, it's about making the language simpler, not more complex ;)

Removing strings from the language would make the language simpler as well, but not simpler to use. (Don't let the absurdity miss you the point).

I don't believe the goal of making the language simpler is the right goal. Simple to use while keeping the language simple it is, IMO.

@dgryski
Copy link
Contributor

dgryski commented Apr 11, 2017

I remember grepping a large corpus of Go code for complex numbers, and aside from the standard library and a few serialization packages aiming for completeness, the only users of I found were a few people who had implemented the Mandelbrot set.

@mremond
Copy link

mremond commented Apr 11, 2017

Could those features be moved to a third-party library or do they have to be implemented inside Go runtime ?

@ALTree
Copy link
Member

ALTree commented Apr 11, 2017

The fact that nobody uses complex numbers in go1 is not that surprising, since go1 is objectively not that great as a language for scientific computing (we don't even have multidimensional slices). But this is a go2 issue. What if an hypothetical go2 turns out to be a great language for scientific programmers? In that case you would probably want to leave complex numbers in.

What I'm saying is that basing the decision of leaving out complex numbers from go2 on analyses made on a go1 code corpus makes little sense.

@griesemer
Copy link
Contributor

I appreciate the sentiment (of wanting to remove complex) and have personal sympathy, but I think this ties in with other issues that all need to be considered together:

  1. complex numbers, while requiring quite a bit of implementation support, and despite their name, don't really add much complexity to the language: if you don't use them you won't notice them.
  2. I believe that @ALTree is correct: if Go were more directly suited for numeric applications (e.g. linear algebra), complex numbers would be showing up much more often.
  3. If we remove them, I think we need a way to user-define them in a natural way, which probably means some form of operator methods.

(As an aside, Mandelbrot iteration is much (2x) faster when implemented using floats because significant parts of the complex computation can be factored out. Implementing Mandelbrot using complex is like implementing Factorial using recursion...)

@dongweigogo
Copy link

think about python. Guido never thought python comes this far in scientific computing fields today. Just don't close the door, but throwing it to the std from the language level is acceptable.

@bradfitz
Copy link
Contributor Author

@griesemer, I agree this needs to be considered alongside other issues (operator methods, etc). I'm just throwing it on the pile. It's a funny situation we're in now where *big.Ints are relatively common but awkward to use while unused complex numbers are first class.

@gopherbot gopherbot added this to the Proposal milestone Apr 11, 2017
@griesemer
Copy link
Contributor

@bradfitz good point!

@maj-o
Copy link

maj-o commented Apr 11, 2017

I love Go for its simplicitiy!
I don't realy know if more people need complex numbers or other numbers. Though if You google it, many people ask for decimals and linear algebra (vectors, multidim slices,..).
But I know that it would not realy matter, if anybody could do with his/her numbers what is natural and common to be done with numbers. Like the scientists, traders, developers, .. of tomorrow, our children, would do it - Will they use Go, if it is impossible to use it this way?
operator methods are endless more worth then complex numbers.

@as
Copy link
Contributor

as commented Apr 13, 2017

Go supports complex numbers, but ~nobody uses them.

What percentage of the current userbase is ~nobody?

@urandom
Copy link

urandom commented Apr 13, 2017

The issue seems to boil down to not whether complex numbers are used (a lot), or the current difficulty in representing different math types that aren't built in. I agree that allowing custom types to define their own behavior for existing operators would be a lot more useful. And it would generally simplify the language, since complex types (+ the builtin funcs for them) can be removed from the runtime, and implemented in a third party lib.

@pierrre
Copy link

pierrre commented May 7, 2017

I use them: https://github.com/pierrre/mandelbrot

@griesemer
Copy link
Contributor

@pierrre FWIW, using complex operations for Mandelbrot tends to be much slower than then doing it "by hand" using floats because some of the distance computation can be used later in the product (#19921 (comment)).

@pierrre
Copy link

pierrre commented May 8, 2017

@griesemer thanks

@kortschak
Copy link
Contributor

The fact that nobody uses complex numbers in go1 is not that surprising, since go1 is objectively not that great as a language for scientific computing (we don't even have multidimensional slices). But this is a go2 issue. What if an hypothetical go2 turns out to be a great language for scientific programmers? In that case you would probably want to leave complex numbers in.

The argument that Go1 is objectively a "not that great" language for scientific computing is not supported with evidence. Removing complex float support from Go2 would certainly help aid an argument in that direction for that language though.

FWIW we get requests for addition of native complex support for the gonum/blas packages - we have not done this purely because of developer time availability and we do provide a cgo interface to a BLAS implementation.

@btracey
Copy link
Contributor

btracey commented May 23, 2017

Complex numbers are really nice to have for linear algebra. They occur in basic matrix decompositions, namely eigenvalue decomposition, and it's really nice to be able to implement a complex matrix using a []complex128. Another very common case arises in signal processing with Fourier transforms. There are many useful number systems, in particular I have worked with quaternions and (hyper-)dual numbers in the past. Complex numbers occur far more often and in a much wider set of disciplines. There is good reason to include complex and not the others.

I can understand the argument that big.Int is hard to use while complex numbers are first class. Part of the goal of #19623 is to make the situation with big ints better. There doesn't need to be a "shooting down" of complex numbers at the same time.

Operator methods are possible, but they are a much bigger change to the language, and can have a big influence (for better or worse) on APIs.

@rhedile
Copy link

rhedile commented May 23, 2017 via email

@JonathanFraser
Copy link

Please don't, alot of numerical computing depends on it.

@bezigon
Copy link

bezigon commented May 26, 2017

Needs to create a separate project regarding NumPy in Go (NumGo?), if this happens...

@btracey
Copy link
Contributor

btracey commented May 26, 2017

www.godoc.org/gonum.org/v1/gonum

@maj-o
Copy link

maj-o commented May 26, 2017

I like this godoc point.
Let me repeat myself. Much more computation, data-exchange and storage depends on decimal as on complex numbers. And for this reason we have this: https://godoc.org/?q=decimal - a lot of workarounds.
For us (the company I work for), with a lot of decimal computation, this workarounds don't realy help. There are three solutions for this: #19787 or #19770 or to use a different language.

Nobody wants to remove complex numbers out of Go completely. But complex numbers don't need to be part of the core.

With operator methods as presented by Mr Griesemer many of this and other problems could be solved at once. And complex numbers could savely be moved to a separete package without braking code (just a different import and this could be automated).

@cznic
Copy link
Contributor

cznic commented Feb 28, 2018

I want to rationalize why we have complex numbers as first class in the language yet the much more common *math/big.{Int,Float} are library types requiring method calls for all operations.

Operations over complex{64,128} fit CPU into registers, operations on math/big.{Int,Float} generally do not. That's IMHO a sufficient reason why the former are part of the language and the later are not and come in a package.

@bradfitz
Copy link
Contributor Author

@cznic, that's somewhat of an implementation detail. string and map also don't fit in registers, and they're part of the language. And if we do #19623, it also doesn't fit in a register. But if we do #19623, and also don't do any sort of generics w/ operator methods, then this proposal doesn't matter much and we should keep complex numbers as built-ins. But if we did add generics w/ operator methods, we could pay for some of the extra language complexity from generics by removing complex numbers and making them a library feature instead.

@lpar
Copy link

lpar commented Feb 28, 2018

2¢: An order of magnitude more people do (for example) percentage calculations on currency values, than use complex numbers. So if a decimal float type isn't part of Go's stdlib, I have a hard time understanding the justification for a complex number type.

@sbinet
Copy link
Member

sbinet commented Mar 1, 2018

complex numbers are part of many machine learning pipelines. they're a fundamental building block for FFTs and data science: there's no question they are useful.

that said: if we indeed get some kind of generics + (numeric) operators, then I could see myself using complex numbers without much hassle.

@lpar
Copy link

lpar commented Mar 1, 2018

I'm not disputing that they're useful. I'm just pointing out that decimals are a lot more useful to almost everyone, and we don't have those, so apparently the usefulness bar is generally pretty high.

@andlabs
Copy link
Contributor

andlabs commented Mar 1, 2018

So if we were to move complex numbers into a library and intrinsify the functions that you can perform on them, what would the performance costs be?

(And I'm still curious about how much more or less complicated the compiler itself will be this way...)

@bradfitz
Copy link
Contributor Author

bradfitz commented Mar 1, 2018

So if we were to move complex numbers into a library and intrinsify the functions that you can perform on them, what would the performance costs be?

Zero, ideally. As I said above:

The compiler could still recognize the complex package and intrinsify cmplx.Num & operations into today's machine instruction.

The generated code should be identical as today.

@likebike
Copy link

Complex numbers usually result from exponentiation (for example, square roots). If Go doesn't have a built-in exponentiation operator, then it's probably not necessary to have built-in complex numbers. Either we should have both, or neither.

Personally, I'd prefer to have both built-in because I consider them as important, fundamental mathematical operations. I personally use complex numbers often in my engineering Go projects.

@mortdeus
Copy link

I think the reason people don't use Go for mathematical applications is that we don't prioritize it. Our math library is essentially a straight across Go port of C's stdlib math.h.

And I think we could steal a lot of scientists who rely on python if we took a more straightforward approach to it.

For example, awhile back I proposed that we add some things to the math package. And I was shot down simply on the basis that there are hundreds and hundreds of mathematical functions out there and that if users really wanted them they can implement them themselves or use a 3rd party library.

I just find it funny that here, it was mentioned that using complex for mandlebrot is just about as silly as using recursion for factorial.

Isn't that the reason why we should implement a factorial function for gophers, so that they don't do it the wrong way?

Wasn't Go designed to make programmer's lives easier and code more efficient? Isn't that the primary reason why we go out of our way to build a standard library for users convenience?

I am just saying that complex doesn't seem to be used as often because the math package is essentially C's math library and why would anybody who is looking for a faster alternative than python ever choose Go when they can just write their performance critical code in C?

I personally think that instead of trying to get rid of complex, lets focus on making the math package the best, so that mathematicians have a reason to choose Go over other languages.

@mortdeus
Copy link

And I am also for making things like big numbers, decimals, and 1-bit binary types builtin.

@sbinet
Copy link
Member

sbinet commented May 30, 2018

@mortdeus
I personally think it's fair not to put all of netlib or cephes inside the stdlib's math package and instead gather a community around, say, gonum.org (and gonum.org/v1/gonum/mathext).

as one of the maintainers+devs of gonum.org and go-hep.org, I wouldn't mind dropping complex from the language:

  • if we get a way to easily implement them, and
  • if we have a nice-ish syntax to use then, and
  • if we have no performance regression

I would reach for generics, operator overloading and intrinsics in another language.
but this is Go, so I am open to alternatives.

also, I don't think that people use Python because of its math module, but because of numpy, scipy, ... ie all of the scientific ecosystem that wasn't built inside the stdlib (and could thus evolve with less constraints.)
The python scientific ecosystem only needed 2 things from python-the-language:

  • operator overloading (for nice mathematical syntax)
  • multidimensional arrays (and the buffer protocol to efficiently transfer+share data and memory between python and 3rd-party C extension modules)

I think, in the context of Go, 1) is out.
but 2) should really be implemented.

@splace
Copy link

splace commented May 30, 2018

really it seems like its only the generics you really lose, going from builtin to std.lib
(maybe some 'visibility', but complex users, seem to me, to be more likely to look for themselves.)

as for multidimensional arrays..

seems that builtin support is useful for standardization, (but being in std.lib. does that.) but also, as pointed out by sbinet, a single block of memory is efficient, AND if its also standardized, will then allow simple interfacing to a world of c mathematical code.

so for multidimensional array of complex....

for a memory block storage technique the data probably needs to be in one particular type, with a particular access structure, so for that it really makes sense for the complex maths to not be generic, which then removes to only reason to be builtin.

@wsc1
Copy link

wsc1 commented Sep 29, 2018

there is also the gonum fourier package, go-dsp, software defined radio dsp, zikichombo/dsp,...

@talglobus
Copy link

talglobus commented Nov 30, 2018

Here's my 50 cents, hopefully worth more than that to most people:

Today, a Go project blog post was published giving us a defined set of criteria by which to consider potential changes, described as follows.

A proposal must at the very least:

  1. address an important issue for many people,

  2. have minimal impact on everybody else, and

  3. come with a clear and well-understood solution.

Let's consider this proposal under these new guidelines. I'll address each of the above in order, by number.

  1. There do seem to be a decent number of people interested in this proposal, with 53 comments so far, 89 upvotes, and 68 downvotes, making this the 12th most commented proposal out of the Go 2 issues list. There are two groups to be considered regarding positive impact, those working on the language and those working with the language, with the latter group significantly outnumbering the former. As mentioned repeatedly above, the presence of complex numbers in the language doesn't affect anyone who isn't using them as far as those working with the language is concerned. Regarding those working on the language, removing complex numbers could make maintenance of the language and standard library a little bit easier. However, we have to consider the balance of the former and latter groups, with the group helped being far smaller than the group being unaffected. So intriguing debate here, lots of interest, but fairly minimal positive impact. Half points for solving important, impactful problems

  2. This criterion specifically addresses who is being harmed by the change, with the goal being to minimize this number. Again, impact is divided between those working on the language and those working with the language. On the user side, this change would clearly have a strong negative impact on those that use complex numbers. On the contributor side, no negative impact, and indeed a weak positive impact. But, the criterion is worded as "everybody else", lumping those working on the language in with those working with the language, with the latter group having, again, significantly more members. So, net impact is negative. No points for not being harmful

  3. This criterion is the easiest. Moving complex numbers out of the language proper and into its own library is fairly simple, and quite elegant. There's definitely room for debate and tweaks as proven above, but overall, this has a clear and well-understood solution. Full points for solution clarity and completeness

The verdict? 1.5 out of 3. Not terrible, but not great either.

But to go a bit further and venture a few guesses about our beloved language and its users, let's speculate for a minute and consider not only current Go users, but future users as well. Given increasing demand for data science and other computation-heavy spaces within the software sector, there does seem to be a clear trend as far as the future of mathematical computation in software, for lack of a better term. This would seem to indicate that looking forward, we can only expect demand for features like complex numbers to be used more.

This is especially true considering that certain areas, like quaternion mathematics (mentioned above) are widely used in applying transformations to representations of objects in space, a cornerstone of graphics, gaming, and anything seeking to model the physical world. Additionally, complex numbers hold an important role in linear algebra, which underlies machine learning, and Fourier transforms, which form the foundation of signal processing and analysis. Therefore, it seems reasonable to posit that this change most likely stands to cast a stronger negative impact as time progresses, which is worrying.

Overall? It would seem we should leave complex numbers in.

@chipkent
Copy link

I have to say that the removal of complex numbers is a terrible idea. They are important for many areas of mathematical and scientific computing. At go's current stage, the necessary library support for doing mathematical, scientific, and AI computing is not there. (Tensorflow's second class go support is an example.) As a result, we should not expect the current usage of complex numbers to be high.

The number of relevant libraries has been increasing, and it is almost possible to get useful mathematical, scientific, or AI work done in go without having to construct all necessary libraries from scratch. In time, the libraries will exist, and scientific users will come. Complex numbers are an investment in that future.

Pulling complex numbers out and into a separate package is not a great solution. It leads to fragmented and incompatible packages, syntactically ugly code, and (often) less efficient executions. It is no accident that python and fortran have large user bases in the scientific community, even though they are poor languages -- they have native complex numbers.

@kortschak
Copy link
Contributor

Removing complex numbers from the language will anger Z̢̢̟͖̹̰̣̦̫̖͍͉̳̹͚̫̰͎͕̰̱̮͇͍̟͓̹͓̦͇̫͔̗̩͓͖͕̘̖͎̘͔͓̠͙̺̭͈͓̼̳̩̪̦͉̞̗͖̝̠̠̮̲̟̟̦͎̗̜͇̺̝̜̭͚̦̦͚̞̜̭̙̺̠̟̙̙̟̻̩͓͕͖͓̫͓̳͎̦͔̺͔̲͕̝̜̣͉̝̟̞̱̱̭͈̼̻̻͍̰͍̰̼͚̻̬̼͉͕̪̦̯̳͙̘̬͚̣̬̮͕̩̭̺̳̺̣͉̜͍̪͙̹͓̙̹͙̼͉͔͈͖̫̩̞͔̗̠̾ͧ͢͠ͅͅͅâ̷̶̸̖̫͍̱̣̹̜̮̩̬̖̝͔̭̳̲̣̟̮̲̹̖̤̠̦͎̻̥͕̰̳͖̹̣̬̼̺̠̱̣̱̻͙͎̩̪̪̳̲͓͖̥̩̩̥͕̞̱͓̝̥̻̣͙̱̹̟͚͙̥̘̼̪̣͉̪̠̩͍͔̜͉̠̪͉͉̝̙̣͔̝̭̳̥̻̤̪̙͔̟̙̱͚̗̫͉̙̺̜̞͇̪̝̰̟̟̝̫̹̭̘͈̗͔̞̲̘͔̜͍̠̰͈͙̗̭̼̟̪̼̻̲̜̞̪̝̙̫͍̫̠̗̟̯̺̞͕̳̞̣̝̫̜̯̫̯͛̕ͅͅͅͅlͦ̾ģ́͞҉̜͇͓̭̙̲̲̪̤͉͙̭̥̞͓̖̙̬̯̯̫̥̣̜̱̲͈̻̞̻̪̝̜͙̠̥͍͚̙͈͕̮̪̥̭͉̜̖̟̲͖̬̺̱̝̩̠͍̞͉̯̤̰͔̰͇̰̭̣̝̗̘̦̦̤͖͔̝̜̼̬̱͙͉̖̹̳̼̝̯̻̬̦̣͉̬͔̹̫͓̣͔̮͈̟̗͎̰̘̼͈͔̣̭̹̬̞̪̤̹̳͚͙̫͈͕͉̙̪̥͖̙͓̝̣̻̣͇̜̟̹̯̞̠̤̗̹̮̭̳͔̹̘͙̠͎͓̭̬̗͇͚̱̦̥͙̘̭͓̱ͅͅo̫̫̞̘̯͎̙̲̹̬̺̙̥͖̥̬̰͈̲͍̜̗̹̝͇̘̬͉̥̯͈̝̤͈̜̜̦̥̻̝̥̙̰̥̜͖̱̰̺̠̻̤͉̳̰͈̣̱̗̣̘͚͖̼̟̻̦̟̬̖̼͔͓̱̖͈̜̯̗̜͎̝̥̹͇͚͉̩̲̖̞̗̮̬̭̟̘̝͓̫̖͙̻̖̠͔̤̰͈̹̭͔̳̣͓͉̙̼͕͙͙̺̞̗̘͙̠͇̪͚̙̖̱̦̥͚͓̠̤͚͓̟̫͉̭̲̭̻͎̝͓̫̭̝̣̪̭̠̤̫͚̬͈̙̳͖̪̲ͥ͂ͅͅͅͅͅ, or at least stop it from building.

@claperius
Copy link

Having complex numbers as first class citizens was a strong "pro Go" argument when I started learning a language. We have great https://www.gonum.org/ library, which depends on builtin complex numbers a lot. I think we should not make Go being narrowed to some specific domains.

@bradfitz
Copy link
Contributor Author

Everybody is focusing on the "removing functionality" part of this bug and not the "it's weird that big.Int is in a library but complex is in the language" part. Ideally both would be in the library and both would be easy to use with nice syntax. (see "operator methods" references above)

It's my fault for writing the initial bug with so little detail. The audience I'd initially considered (Ian, Robert, et al) already knew the context.

@as
Copy link
Contributor

as commented Jan 18, 2019

Complex numbers in Go carry an implied algebraic representation (unlike a big integer working around hardware constraints).

Rather than ordered pairs z=(x,y), we write x+yi. This makes operations convenient.

Operator methods sound a lot scarier than complex numbers. Aside from any concerns about that:

How will operator methods allow x+yi? Specifically, what happens to the imaginary unit?
How will go remove algebraic notation and still allow this algebraic notation to exist with operator methods?

@ianlancetaylor
Copy link
Contributor

It's true that complex64 (and complex128) is an unusual type to have in the language. But it's here, and it's sometimes useful, and it's not that hard to learn. Removing it at this point will not be a significant improvement.

@dmitshur dmitshur added Proposal-Declined and removed NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. labels Jan 30, 2019
@golang golang locked and limited conversation to collaborators Jan 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Projects
None yet
Development

No branches or pull requests