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

Open
bradfitz opened this Issue Apr 11, 2017 · 52 comments

Comments

Projects
None yet
@bradfitz
Member

bradfitz commented Apr 11, 2017

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

This comment has been minimized.

Show comment
Hide comment
@bradfitz
Member

bradfitz commented Apr 11, 2017

@cznic

This comment has been minimized.

Show comment
Hide comment
@cznic

cznic Apr 11, 2017

Contributor

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

Contributor

cznic commented Apr 11, 2017

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

@mvdan

This comment has been minimized.

Show comment
Hide comment
@mvdan

mvdan Apr 11, 2017

Member

@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.

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

This comment has been minimized.

Show comment
Hide comment
@cznic

cznic Apr 11, 2017

Contributor

@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).

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

This comment has been minimized.

Show comment
Hide comment
@mvdan

mvdan Apr 11, 2017

Member

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.

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

This comment has been minimized.

Show comment
Hide comment
@cznic

cznic Apr 11, 2017

Contributor

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.

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

This comment has been minimized.

Show comment
Hide comment
@dgryski

dgryski Apr 11, 2017

Contributor

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.

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

This comment has been minimized.

Show comment
Hide comment
@mremond

mremond Apr 11, 2017

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

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

This comment has been minimized.

Show comment
Hide comment
@ALTree

ALTree Apr 11, 2017

Member

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.

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

This comment has been minimized.

Show comment
Hide comment
@griesemer

griesemer Apr 11, 2017

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...)

Contributor

griesemer commented Apr 11, 2017

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

This comment has been minimized.

Show comment
Hide comment
@dongweigogo

dongweigogo Apr 11, 2017

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.

dongweigogo commented Apr 11, 2017

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

This comment has been minimized.

Show comment
Hide comment
@bradfitz

bradfitz Apr 11, 2017

Member

@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.

Member

bradfitz commented Apr 11, 2017

@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

This comment has been minimized.

Show comment
Hide comment
@griesemer

griesemer Apr 11, 2017

Contributor

@bradfitz good point!

Contributor

griesemer commented Apr 11, 2017

@bradfitz good point!

@maj-o

This comment has been minimized.

Show comment
Hide comment
@maj-o

maj-o 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.

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

This comment has been minimized.

Show comment
Hide comment
@as

as Apr 13, 2017

Contributor

Go supports complex numbers, but ~nobody uses them.

What percentage of the current userbase is ~nobody?

Contributor

as commented Apr 13, 2017

Go supports complex numbers, but ~nobody uses them.

What percentage of the current userbase is ~nobody?

@urandom

This comment has been minimized.

Show comment
Hide comment
@urandom

urandom 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.

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

This comment has been minimized.

Show comment
Hide comment
@pierrre

pierrre commented May 7, 2017

@griesemer

This comment has been minimized.

Show comment
Hide comment
@griesemer

griesemer May 8, 2017

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)).

Contributor

griesemer commented May 8, 2017

@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

This comment has been minimized.

Show comment
Hide comment
@pierrre

pierrre commented May 8, 2017

@griesemer thanks

@kortschak

This comment has been minimized.

Show comment
Hide comment
@kortschak

kortschak May 22, 2017

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.

Contributor

kortschak commented May 22, 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.

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

This comment has been minimized.

Show comment
Hide comment
@btracey

btracey May 23, 2017

Contributor

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.

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

This comment has been minimized.

Show comment
Hide comment
@rhedile

rhedile May 23, 2017

rhedile commented May 23, 2017

@JonathanFraser

This comment has been minimized.

Show comment
Hide comment
@JonathanFraser

JonathanFraser May 23, 2017

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

JonathanFraser commented May 23, 2017

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

@bezigon

This comment has been minimized.

Show comment
Hide comment
@bezigon

bezigon May 26, 2017

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

bezigon commented May 26, 2017

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

@btracey

This comment has been minimized.

Show comment
Hide comment
@btracey
Contributor

btracey commented May 26, 2017

@maj-o

This comment has been minimized.

Show comment
Hide comment
@maj-o

maj-o 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).

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).

@andlabs

This comment has been minimized.

Show comment
Hide comment
@andlabs

andlabs Jun 7, 2017

Contributor

How would splitting complex numbers out into the library impact performance of code that uses them heavily?

I notice there's a number of standard library functions, particularly in math, that have special SSA rules that mean those functions are handled at compile-time. (Please correct me if I am wrong.) If we remove complex numbers, but they eventually get moved alongside these special cases, would we have a zero net sum for the change? It'd just be swapping syntax for syntax.

And if Go 3 reverses the decision, I hope it doesn't introduce _Complex

Contributor

andlabs commented Jun 7, 2017

How would splitting complex numbers out into the library impact performance of code that uses them heavily?

I notice there's a number of standard library functions, particularly in math, that have special SSA rules that mean those functions are handled at compile-time. (Please correct me if I am wrong.) If we remove complex numbers, but they eventually get moved alongside these special cases, would we have a zero net sum for the change? It'd just be swapping syntax for syntax.

And if Go 3 reverses the decision, I hope it doesn't introduce _Complex

@rsc rsc changed the title from proposal: remove complex numbers from Go2 to proposal: spec: remove complex numbers Jun 16, 2017

@emkatz

This comment has been minimized.

Show comment
Hide comment
@emkatz

emkatz Jul 17, 2017

I'm on the way to reimplement some network analysis tool in go - where complex number are really basic to linear networks. It would be awkward if complex number would be dropped and i have to do something less performent or a less KISS thing.
I'v first put the proposed functionality to public domain in the early 80s (neviza) http://downloads.atari-home.de/Public_Domain/Serie_CCE/0100/CCE_0112.TXT and so i do not see that the YAGNI thesis of this proposal is reasonable.
Please dont drop the needs of engineering calculation in a way that is worse then the todays solution!
To my point of view matrix operation would be a candidate to integrate into the language :-) so if there is a lib that is as stable, easy and fast as the the given complex number integration besides enabling matix operation it would be acceptable.

emkatz commented Jul 17, 2017

I'm on the way to reimplement some network analysis tool in go - where complex number are really basic to linear networks. It would be awkward if complex number would be dropped and i have to do something less performent or a less KISS thing.
I'v first put the proposed functionality to public domain in the early 80s (neviza) http://downloads.atari-home.de/Public_Domain/Serie_CCE/0100/CCE_0112.TXT and so i do not see that the YAGNI thesis of this proposal is reasonable.
Please dont drop the needs of engineering calculation in a way that is worse then the todays solution!
To my point of view matrix operation would be a candidate to integrate into the language :-) so if there is a lib that is as stable, easy and fast as the the given complex number integration besides enabling matix operation it would be acceptable.

@Quasilyte

This comment has been minimized.

Show comment
Hide comment
@Quasilyte

Quasilyte Sep 8, 2017

Contributor

This repository can be useful for someone who has doubts that complex numbers can be implemented as a user-defined type without significant performance changes (if any at all).
It contains benchmarks and machine code output for amd64.

Contributor

Quasilyte commented Sep 8, 2017

This repository can be useful for someone who has doubts that complex numbers can be implemented as a user-defined type without significant performance changes (if any at all).
It contains benchmarks and machine code output for amd64.

@dmitshur

This comment has been minimized.

Show comment
Hide comment
@dmitshur

dmitshur Sep 9, 2017

Member

@Quasilyte That's very interesting to see, thanks for sharing.

Just want to ask, but are there any edge cases that your implementation handles differently compared to the builtin complex types, or does it behave identically for all input? It's interesting that some operations are actually faster compared to the builtin type.

Another observation I want to point out (since I haven't seen it mentioned in this thread already) is that the builtin complex types have the following property that a user-defined type could not have (at this time):

If the operands of these functions are all constants, the return value is a constant.

Member

dmitshur commented Sep 9, 2017

@Quasilyte That's very interesting to see, thanks for sharing.

Just want to ask, but are there any edge cases that your implementation handles differently compared to the builtin complex types, or does it behave identically for all input? It's interesting that some operations are actually faster compared to the builtin type.

Another observation I want to point out (since I haven't seen it mentioned in this thread already) is that the builtin complex types have the following property that a user-defined type could not have (at this time):

If the operands of these functions are all constants, the return value is a constant.

@Quasilyte

This comment has been minimized.

Show comment
Hide comment
@Quasilyte

Quasilyte Sep 9, 2017

Contributor

Just want to ask, but are there any edge cases that your implementation handles differently compared to the builtin complex types, or does it behave identically for all input?

@shurcooL, as far as I am aware, add/sub/mul/div behave identical.
Division implementation taken directly from runtime complex128div.

Complex64.Add and Complex64.Sub use single precision, while multiplication and division is done with doubles. This matches builtin operations (can't find spec description of that, unfortunately).

Contributor

Quasilyte commented Sep 9, 2017

Just want to ask, but are there any edge cases that your implementation handles differently compared to the builtin complex types, or does it behave identically for all input?

@shurcooL, as far as I am aware, add/sub/mul/div behave identical.
Division implementation taken directly from runtime complex128div.

Complex64.Add and Complex64.Sub use single precision, while multiplication and division is done with doubles. This matches builtin operations (can't find spec description of that, unfortunately).

@wsc1

This comment has been minimized.

Show comment
Hide comment
@wsc1

wsc1 Oct 6, 2017

I use them. It would be nice rather to add the ability to update the real and imaginary components individually (eg make real() and imag() addressable) Then many advantages of re-formulation as pairs of floats would disappear and more applications could use them effectively.

wsc1 commented Oct 6, 2017

I use them. It would be nice rather to add the ability to update the real and imaginary components individually (eg make real() and imag() addressable) Then many advantages of re-formulation as pairs of floats would disappear and more applications could use them effectively.

@wsc1

This comment has been minimized.

Show comment
Hide comment
@wsc1

wsc1 Oct 10, 2017

wsc1 commented Oct 10, 2017

@splace

This comment has been minimized.

Show comment
Hide comment
@splace

splace Oct 28, 2017

my immediate reaction when i first saw they were built-in was; why not a standard library?

that aside, from what i see, not commended on so far;

do they, as built-ins, bloat the runtime?

as built-ins they can be used by built-in functions generically, (complex64 , complex128) this requirement seems to me to be a defining indicator as to if something should, (needs to be ) a built-in, however here this seems to have no value, only issues, with these two being cross-usable. Even thought real(),imag(),complex() accept either, maths operators don't and math/cmplx only supports complex128 anyway.

currently adding to the real part, requires making a new complex and adding that, with performance often required for complex numbers this seems a problem, ideally a float could be regarded as a complex with zero imaginary part, and generically operator on, making built-ins a necessity.

complex numbers, often used with modelling real stuff, so often needing large datasets, (which would ideally mean complex64 support) so high speed is very important, so does being built-in mean ability to support hardware acceleration better? (i personally don’t believe it does)

splace commented Oct 28, 2017

my immediate reaction when i first saw they were built-in was; why not a standard library?

that aside, from what i see, not commended on so far;

do they, as built-ins, bloat the runtime?

as built-ins they can be used by built-in functions generically, (complex64 , complex128) this requirement seems to me to be a defining indicator as to if something should, (needs to be ) a built-in, however here this seems to have no value, only issues, with these two being cross-usable. Even thought real(),imag(),complex() accept either, maths operators don't and math/cmplx only supports complex128 anyway.

currently adding to the real part, requires making a new complex and adding that, with performance often required for complex numbers this seems a problem, ideally a float could be regarded as a complex with zero imaginary part, and generically operator on, making built-ins a necessity.

complex numbers, often used with modelling real stuff, so often needing large datasets, (which would ideally mean complex64 support) so high speed is very important, so does being built-in mean ability to support hardware acceleration better? (i personally don’t believe it does)

@andlabs

This comment has been minimized.

Show comment
Hide comment
@andlabs

andlabs Oct 29, 2017

Contributor

Again, I wouldn't be surprised if compiler intrinsics would allow for hardware optimization, especially since math/bits already has its own compiler intrinsics. I do know XMM registers are 128 bits wide, but I'm not sure if the XMM instruction set has arithmetic instructions that operate on both float64 halves at once (or if treating them independently is the correct approach).

I still wonder if the cost (in terms of work) of establishing compiler intrinsics cancel out the benefits of dropping them from the language, if that makes any sense... It shouldn't affect performance much; at least I hope not...

On a semi-related note, how performant are assembly implementations of functions vs. compiler intrinsics?

Contributor

andlabs commented Oct 29, 2017

Again, I wouldn't be surprised if compiler intrinsics would allow for hardware optimization, especially since math/bits already has its own compiler intrinsics. I do know XMM registers are 128 bits wide, but I'm not sure if the XMM instruction set has arithmetic instructions that operate on both float64 halves at once (or if treating them independently is the correct approach).

I still wonder if the cost (in terms of work) of establishing compiler intrinsics cancel out the benefits of dropping them from the language, if that makes any sense... It shouldn't affect performance much; at least I hope not...

On a semi-related note, how performant are assembly implementations of functions vs. compiler intrinsics?

@evincarofautumn

This comment has been minimized.

Show comment
Hide comment
@evincarofautumn

evincarofautumn Dec 5, 2017

I have no stake in this, but as a language designer, I have some guiding questions:

  • How much does it cost to let complex numbers remain?

  • Can the existing cost be quantified objectively, e.g., in terms of, say, implementation LOC or benchmark numbers?

  • How much developer effort would be required to remove them?

  • What is the usability impact on doing complex calculations without language support?

  • Can usability issues be mitigated by adding more general features that would subsume the existing support for complex numbers?

They’ve been around for a few centuries, and they’re taught in high school mathematics—so I’d say they’re pretty fundamental, even if they don’t come up all that often in existing Go (cf. Python).

evincarofautumn commented Dec 5, 2017

I have no stake in this, but as a language designer, I have some guiding questions:

  • How much does it cost to let complex numbers remain?

  • Can the existing cost be quantified objectively, e.g., in terms of, say, implementation LOC or benchmark numbers?

  • How much developer effort would be required to remove them?

  • What is the usability impact on doing complex calculations without language support?

  • Can usability issues be mitigated by adding more general features that would subsume the existing support for complex numbers?

They’ve been around for a few centuries, and they’re taught in high school mathematics—so I’d say they’re pretty fundamental, even if they don’t come up all that often in existing Go (cf. Python).

@splace

This comment has been minimized.

Show comment
Hide comment
@splace

splace Jan 26, 2018

They’ve been around for a few centuries, and they’re taught in high school mathematics—so I’d say they’re pretty fundamental, even if they don’t come up all that often in existing Go (cf. Python).

my understanding is fundamentally they exist for algebraic manipulation, developing mathematical formula, they arn't required for numeric computation. which means no language actually needs them, and explains why they arn't used much, all they do is make it clearer to take a formula using complex numbers and directly translate it into code, particular when using systems of related formula.

splace commented Jan 26, 2018

They’ve been around for a few centuries, and they’re taught in high school mathematics—so I’d say they’re pretty fundamental, even if they don’t come up all that often in existing Go (cf. Python).

my understanding is fundamentally they exist for algebraic manipulation, developing mathematical formula, they arn't required for numeric computation. which means no language actually needs them, and explains why they arn't used much, all they do is make it clearer to take a formula using complex numbers and directly translate it into code, particular when using systems of related formula.

@PaluMacil

This comment has been minimized.

Show comment
Hide comment
@PaluMacil

PaluMacil Feb 28, 2018

I'm mostly a web dev but still would like to see them supported first class. There are a lot of technical arguments here--whether about electrical engineering or about physics--but to me, there is another ignored aspect that developers tend to forget about (though Go does well with this)... marketing the language. If memory serves, the Go survey seems to indicate that more developers are coming from Python than any other language.

Just this last week I was speaking with a neuroscientist leaving Python due to performance concerns (probably not a candidate to use imaginary numbers). While I think more matrix functionality would be fantastic, something that stands out as unique and smooth for data scientists is a great way to get attention of the data science and academic community. Academics especially (from my experience and from seeing slow migration of data libraries from Python 2 to 3) seem to stay with languages a long time once they find a comfortable fit. They need a lot but are possibly more starved of time than a typical web developer. I'm excited to see more academics in the Go ranks, and I think they are some of the best "neighbors" since they dedicate their lives to learning and research. Complex numbers are a way to get the attention of this group in a way other languages don't.

PaluMacil commented Feb 28, 2018

I'm mostly a web dev but still would like to see them supported first class. There are a lot of technical arguments here--whether about electrical engineering or about physics--but to me, there is another ignored aspect that developers tend to forget about (though Go does well with this)... marketing the language. If memory serves, the Go survey seems to indicate that more developers are coming from Python than any other language.

Just this last week I was speaking with a neuroscientist leaving Python due to performance concerns (probably not a candidate to use imaginary numbers). While I think more matrix functionality would be fantastic, something that stands out as unique and smooth for data scientists is a great way to get attention of the data science and academic community. Academics especially (from my experience and from seeing slow migration of data libraries from Python 2 to 3) seem to stay with languages a long time once they find a comfortable fit. They need a lot but are possibly more starved of time than a typical web developer. I'm excited to see more academics in the Go ranks, and I think they are some of the best "neighbors" since they dedicate their lives to learning and research. Complex numbers are a way to get the attention of this group in a way other languages don't.

@bradfitz

This comment has been minimized.

Show comment
Hide comment
@bradfitz

bradfitz Feb 28, 2018

Member

Again, this proposal isn't about just nuking them out of spite. 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. I'd ideally like to see math/big implemented such that they can be used naturally with normal Go operators (in addition to specialized methods as needed), and then also move complex numbers to a library (into the existing math/cmplx, perhaps)

The compiler could still recognize the complex package and intrinsify cmplx.Num & operations into today's machine instructions, just like the compiler today recognizes math.Sqrt, etc in the standard library.

Member

bradfitz commented Feb 28, 2018

Again, this proposal isn't about just nuking them out of spite. 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. I'd ideally like to see math/big implemented such that they can be used naturally with normal Go operators (in addition to specialized methods as needed), and then also move complex numbers to a library (into the existing math/cmplx, perhaps)

The compiler could still recognize the complex package and intrinsify cmplx.Num & operations into today's machine instructions, just like the compiler today recognizes math.Sqrt, etc in the standard library.

@cznic

This comment has been minimized.

Show comment
Hide comment
@cznic

cznic Feb 28, 2018

Contributor

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.

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

This comment has been minimized.

Show comment
Hide comment
@bradfitz

bradfitz Feb 28, 2018

Member

@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.

Member

bradfitz commented Feb 28, 2018

@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

This comment has been minimized.

Show comment
Hide comment
@lpar

lpar 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.

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

This comment has been minimized.

Show comment
Hide comment
@sbinet

sbinet Mar 1, 2018

Member

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.

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

This comment has been minimized.

Show comment
Hide comment
@lpar

lpar 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.

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

This comment has been minimized.

Show comment
Hide comment
@andlabs

andlabs Mar 1, 2018

Contributor

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...)

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

This comment has been minimized.

Show comment
Hide comment
@bradfitz

bradfitz Mar 1, 2018

Member

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.

Member

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.

@jaekwon jaekwon referenced this issue May 4, 2018

Open

Master Issue of Go1 Issues to consider #1

0 of 2 tasks complete
@likebike

This comment has been minimized.

Show comment
Hide comment
@likebike

likebike May 30, 2018

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.

likebike commented May 30, 2018

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

This comment has been minimized.

Show comment
Hide comment
@mortdeus

mortdeus May 30, 2018

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 commented May 30, 2018

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

This comment has been minimized.

Show comment
Hide comment
@mortdeus

mortdeus May 30, 2018

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

mortdeus commented May 30, 2018

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

@sbinet

This comment has been minimized.

Show comment
Hide comment
@sbinet

sbinet May 30, 2018

Member

@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.

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

This comment has been minimized.

Show comment
Hide comment
@splace

splace 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.

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

This comment has been minimized.

Show comment
Hide comment
@wsc1

wsc1 Sep 29, 2018

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

wsc1 commented Sep 29, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment