Re: [go-nuts] Evaluation order of return

2020-09-25 Thread Michael Jones
Another way to understand the general topic is by comparison to Lindenmayer
systems. The compiler is an iterated rewrite framework and the exact code
that you get can be a surprise the same way L-System graphics vary.

On Thu, Sep 24, 2020 at 10:36 PM cs.ali...@gmail.com <
cs.alikoyu...@gmail.com> wrote:

> I understood perfectly now, thanks for the explanations and the link! I
> really appreciate you guys!
>
> On Thursday, September 24, 2020 at 3:28:10 AM UTC+3 Ian Lance Taylor wrote:
>
>> On Wed, Sep 23, 2020 at 1:10 AM cs.ali...@gmail.com
>>
>>
>>  wrote:
>>
>>
>> >
>>
>>
>> > I am not actually questioning the current design, as you both said it
>> is not a good practice to call a return statement as I wrote above, I am
>> trying to understand the relation between memory, interface and order of
>> evaluation. It is clear that the compiler takes account of whether a return
>> statement is an interface or a struct and the memory size of the returned
>> value, If I return a struct rather than an interface, it changes the order,
>> If I add fields to the structs it changes the order. Is there a paper that
>> I can find why the compiler considers them for ordering, why it is
>> important for performance or anything else?
>>
>>
>>
>>
>>
>> I'm not aware of any paper specific to the Go compiler.
>>
>>
>>
>>
>>
>> I find it most useful to consider a compiler as creating a set of
>>
>>
>> constraints derived from the input based on the language semantics.
>>
>>
>> These are constraints like in "a = b; b = c" the read of b in the
>>
>>
>> first assignment must be completed before the store to b in the second
>>
>>
>> assignment. Once the set of constraints is created, the compiler must
>>
>>
>> solve those constraints given an instruction architecture including a
>>
>>
>> set of registers. The goal is to optimize execution time while
>>
>>
>> minimizing compilation time without violating any constraints.
>>
>>
>> Because compilation time matters, compilers do not fully analyze all
>>
>>
>> possible solutions; instead, when it comes to things like memory
>>
>>
>> load/store order, instruction selection, and register allocation, they
>>
>>
>> are full of heuristics that tend to give good results in practice.
>>
>>
>>
>>
>>
>> When you view a compiler in that way, a question like "why does adding
>>
>>
>> fields to a struct change the order of memory loads and stores"
>>
>>
>> becomes uninteresting. The reason has to do with the details of all
>>
>>
>> the constraints that applied while compiling that particular package.
>>
>>
>> There is no rule that says "if the struct has more fields, do this."
>>
>>
>> It's just that the set of heuristics happened to produce a particular
>>
>>
>> result. Changing some other piece of code in some other part of the
>>
>>
>> package might produce a different result. Or a different version of
>>
>>
>> the compiler might apply different heuristics and get different
>>
>>
>> results.
>>
>>
>>
>>
>>
>> Ian
>>
>>
>>
>
>
>
>
>
>
>
> --
>
>
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
>
>
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
>
>
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/b2aa2ac3-a7da-4415-9534-7076551da5e7n%40googlegroups.com
> 
> .
>
>
> --

*Michael T. jonesmichael.jo...@gmail.com *

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CALoEmQxuSfsGaiExNCdvHZcYkZn9qKZxD3i_yhzct4PFoz9U-Q%40mail.gmail.com.


Re: [go-nuts] Evaluation order of return

2020-09-24 Thread cs.ali...@gmail.com
I understood perfectly now, thanks for the explanations and the link! I 
really appreciate you guys!

On Thursday, September 24, 2020 at 3:28:10 AM UTC+3 Ian Lance Taylor wrote:

> On Wed, Sep 23, 2020 at 1:10 AM cs.ali...@gmail.com
>  wrote:
> >
> > I am not actually questioning the current design, as you both said it is 
> not a good practice to call a return statement as I wrote above, I am 
> trying to understand the relation between memory, interface and order of 
> evaluation. It is clear that the compiler takes account of whether a return 
> statement is an interface or a struct and the memory size of the returned 
> value, If I return a struct rather than an interface, it changes the order, 
> If I add fields to the structs it changes the order. Is there a paper that 
> I can find why the compiler considers them for ordering, why it is 
> important for performance or anything else?
>
> I'm not aware of any paper specific to the Go compiler.
>
> I find it most useful to consider a compiler as creating a set of
> constraints derived from the input based on the language semantics.
> These are constraints like in "a = b; b = c" the read of b in the
> first assignment must be completed before the store to b in the second
> assignment. Once the set of constraints is created, the compiler must
> solve those constraints given an instruction architecture including a
> set of registers. The goal is to optimize execution time while
> minimizing compilation time without violating any constraints.
> Because compilation time matters, compilers do not fully analyze all
> possible solutions; instead, when it comes to things like memory
> load/store order, instruction selection, and register allocation, they
> are full of heuristics that tend to give good results in practice.
>
> When you view a compiler in that way, a question like "why does adding
> fields to a struct change the order of memory loads and stores"
> becomes uninteresting. The reason has to do with the details of all
> the constraints that applied while compiling that particular package.
> There is no rule that says "if the struct has more fields, do this."
> It's just that the set of heuristics happened to produce a particular
> result. Changing some other piece of code in some other part of the
> package might produce a different result. Or a different version of
> the compiler might apply different heuristics and get different
> results.
>
> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/b2aa2ac3-a7da-4415-9534-7076551da5e7n%40googlegroups.com.


Re: [go-nuts] Evaluation order of return

2020-09-23 Thread Ian Lance Taylor
On Wed, Sep 23, 2020 at 1:10 AM cs.ali...@gmail.com
 wrote:
>
> I am not actually questioning the current design, as you both said it is not 
> a good practice to call a return statement as I wrote above, I am trying to 
> understand the relation between memory, interface and order of evaluation. It 
> is clear that the compiler takes account of whether a return statement is an 
> interface or a struct and  the memory size of the returned value, If I return 
> a struct rather than an interface, it changes the order, If I add fields to 
> the structs it changes the order. Is there a paper that I can find why the 
> compiler considers them for ordering, why it is important for performance or 
> anything else?

I'm not aware of any paper specific to the Go compiler.

I find it most useful to consider a compiler as creating a set of
constraints derived from the input based on the language semantics.
These are constraints like in "a = b; b = c" the read of b in the
first assignment must be completed before the store to b in the second
assignment.  Once the set of constraints is created, the compiler must
solve those constraints given an instruction architecture including a
set of registers.  The goal is to optimize execution time while
minimizing compilation time without violating any constraints.
Because compilation time matters, compilers do not fully analyze all
possible solutions; instead, when it comes to things like memory
load/store order, instruction selection, and register allocation, they
are full of heuristics that tend to give good results in practice.

When you view a compiler in that way, a question like "why does adding
fields to a struct change the order of memory loads and stores"
becomes uninteresting.  The reason has to do with the details of all
the constraints that applied while compiling that particular package.
There is no rule that says "if the struct has more fields, do this."
It's just that the set of heuristics happened to produce a particular
result.  Changing some other piece of code in some other part of the
package might produce a different result.  Or a different version of
the compiler might apply different heuristics and get different
results.

Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcX__%2BKDDnzQ2LjuYm-1gMdrQy%3DLoNB0MmMj%3DaTGJPAF1A%40mail.gmail.com.


Re: [go-nuts] Evaluation order of return

2020-09-23 Thread Jesper Louis Andersen
On Wed, Sep 23, 2020 at 10:09 AM cs.ali...@gmail.com <
cs.alikoyu...@gmail.com> wrote:

> Is there a paper that I can find why the compiler considers them for
> ordering, why it is important for performance or anything else?
>
>
A CPU has a limit to how many load/store instructions it can issue in a
given clock cycle or in a given window of clock cycles. By reordering
memory loads, you can spread them out such that they don't create conflicts
against each other. This covers the part of memory ordering optimizations.
As for function calls, you often have a call convention where some
registers are saved by the caller and some registers are saved by the
callee. Hence it can be beneficial to arrange the evaluation order in a way
to avoid having to save registers. I think Go's current ABI rules are to
use the stack for everything in its calling convention, but the same
general rules apply: you may want to reorder the work in order to save on
register pressure. It becomes especially interesting if your calling
convention allows for multiple return values passed in registers.

Note that
https://go.googlesource.com/proposal/+/refs/changes/78/248178/1/design/40724-register-calling.md
proposes a register-based calling convention for the Go compiler, which
hammers through the need of flexibility in this area.

-- 
J.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAGrdgiXN5k_d8MY1KyPK7E3i0WkjCK-wHNxi6phuAVWE2SOoOg%40mail.gmail.com.


Re: [go-nuts] Evaluation order of return

2020-09-23 Thread cs.ali...@gmail.com
Thanks Axel, Ian!

I am not actually questioning the current design, as you both said it is 
not a good practice to call a return statement as I wrote above, I am 
trying to understand the relation between memory, interface and order of 
evaluation. It is clear that the compiler takes account of whether a return 
statement is an interface or a struct and  the memory size of the returned 
value, If I return a struct rather than an interface, it changes the order, 
If I add fields to the structs it changes the order. Is there a paper that 
I can find why the compiler considers them for ordering, why it is 
important for performance or anything else? 

On Monday, September 21, 2020 at 8:06:31 PM UTC+3 Ian Lance Taylor wrote:

> On Mon, Sep 21, 2020 at 9:34 AM 'Axel Wagner' via golang-nuts
>  wrote:
> >
> > The evaluation order is defined here:
> > https://golang.org/ref/spec#Order_of_evaluation
> > The important part is that the order of evaluation in a return statement 
> is only defined for function calls, method calls and communication 
> statements, but not in relation to other operations. So, in
> > return intNumber, setInteger(&intNumber)
> > It is not defined whether `intNumber` or `setInteger(&intNumber)` is 
> evaluated first, as the former is none of those. I can't really tell you 
> why, but it has been discussed a couple of times, you might find something 
> using the search function on golang-nuts.
> >
> > If you want reliable behavior, you should assign the result first
> > var intNumber Integer
> > err := setInteger(&intNumber)
> > return intNumber, err
>
> This flexibility is in the language to permit better code
> optimization. The compiler can choose how to order memory loads and
> function calls. It is not required to do a memory load, save it
> somewhere, and then do the function call.
>
> Of course, this does have the downside that different compilers will
> produce different behavior for the same code. So far we've decided
> that that is OK.
>
> My personal attitude is if a single statement writes to a variable
> other than by assigning to it directly, and the statement also reads
> from that same variable, then the program is already confusing. While
> we could lock down a specific order of evaluation, that won't help the
> fact that the program is hard to read and hard to understand. So I
> don't see a good argument for forcing many well written programs to
> run very slightly slower in order to make poorly written programs
> behave consistently. But I understand that other people feel
> differently.
>
> Ian
>
>
>
> > On Mon, Sep 21, 2020 at 6:09 PM cs.ali...@gmail.com  
> wrote:
> >>
> >> Why does the compiler change evaluation order of return when adding a 
> new field to a struct? I didn't check the compiler output, I only guess it 
> somehow changes the order.
> >> play
> >> package main
> >> import (
> >> "fmt"
> >> )
> >> type Number interface {
> >> Value() int
> >> }
> >> type Integer struct {
> >> value int
> >> additional int // remove this for different result
> >> }
> >> func (integer Integer) Value() int {
> >> return integer.value
> >> }
> >> func main() {
> >> number, _ := getNumber()
> >> fmt.Printf("number val: %d\n", number.Value())
> >> }
> >> func getNumber() (Number, error) {
> >> var intNumber Integer
> >> return intNumber, setInteger(&intNumber)
> >> }
> >> func setInteger(num *Integer) error {
> >> num.value = 2
> >> return nil
> >> }
> >>
> >> --
> >> You received this message because you are subscribed to the Google 
> Groups "golang-nuts" group.
> >> To unsubscribe from this group and stop receiving emails from it, send 
> an email to golang-nuts...@googlegroups.com.
> >> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/b7077f03-b0f4-454a-a587-ab9757164409n%40googlegroups.com
> .
> >
> > --
> > You received this message because you are subscribed to the Google 
> Groups "golang-nuts" group.
> > To unsubscribe from this group and stop receiving emails from it, send 
> an email to golang-nuts...@googlegroups.com.
> > To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHsSFfjPzoOTVz7Q4fE%3DziCXhA5mbUWzSkQ5DADMyzWFw%40mail.gmail.com
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/2a0dab1c-9835-4d26-ab46-75731a23bcd9n%40googlegroups.com.


Re: [go-nuts] Evaluation order of return

2020-09-21 Thread Ian Lance Taylor
On Mon, Sep 21, 2020 at 9:34 AM 'Axel Wagner' via golang-nuts
 wrote:
>
> The evaluation order is defined here:
> https://golang.org/ref/spec#Order_of_evaluation
> The important part is that the order of evaluation in a return statement is 
> only defined for function calls, method calls and communication statements, 
> but not in relation to other operations. So, in
> return intNumber, setInteger(&intNumber)
> It is not defined whether `intNumber` or `setInteger(&intNumber)` is 
> evaluated first, as the former is none of those. I can't really tell you why, 
> but it has been discussed a couple of times, you might find something using 
> the search function on golang-nuts.
>
> If you want reliable behavior, you should assign the result first
> var intNumber Integer
> err := setInteger(&intNumber)
> return intNumber, err

This flexibility is in the language to permit better code
optimization.  The compiler can choose how to order memory loads and
function calls.  It is not required to do a memory load, save it
somewhere, and then do the function call.

Of course, this does have the downside that different compilers will
produce different behavior for the same code.  So far we've decided
that that is OK.

My personal attitude is if a single statement writes to a variable
other than by assigning to it directly, and the statement also reads
from that same variable, then the program is already confusing.  While
we could lock down a specific order of evaluation, that won't help the
fact that the program is hard to read and hard to understand.  So I
don't see a good argument for forcing many well written programs to
run very slightly slower in order to make poorly written programs
behave consistently.  But I understand that other people feel
differently.

Ian



> On Mon, Sep 21, 2020 at 6:09 PM cs.ali...@gmail.com  
> wrote:
>>
>> Why does the compiler change evaluation order of return when adding a new 
>> field to a struct?  I didn't check the compiler output, I only guess it 
>> somehow changes the order.
>> play
>> package main
>> import (
>> "fmt"
>> )
>> type Number interface {
>> Value() int
>> }
>> type Integer struct {
>> value int
>> additional int // remove this for different result
>> }
>> func (integer Integer) Value() int {
>> return integer.value
>> }
>> func main() {
>> number, _ := getNumber()
>> fmt.Printf("number val: %d\n", number.Value())
>> }
>> func getNumber() (Number, error) {
>> var intNumber Integer
>> return intNumber, setInteger(&intNumber)
>> }
>> func setInteger(num *Integer) error {
>> num.value = 2
>> return nil
>> }
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/b7077f03-b0f4-454a-a587-ab9757164409n%40googlegroups.com.
>
> --
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHsSFfjPzoOTVz7Q4fE%3DziCXhA5mbUWzSkQ5DADMyzWFw%40mail.gmail.com.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcUAEwdMHrNaLKvDyiPEBdXNH8uQ4Uq2WY77s2QFOR8-uA%40mail.gmail.com.


Re: [go-nuts] Evaluation order of return

2020-09-21 Thread 'Axel Wagner' via golang-nuts
The evaluation order is defined here:
https://golang.org/ref/spec#Order_of_evaluation
The important part is that the order of evaluation in a return statement is
only defined for function calls, method calls and communication statements,
but not in relation to other operations. So, in
return intNumber, setInteger(&intNumber)
It is not defined whether `intNumber` or `setInteger(&intNumber)` is
evaluated first, as the former is none of those. I can't really tell you
why, but it has been discussed a couple of times, you might find something
using the search function on golang-nuts.

If you want reliable behavior, you should assign the result first
var intNumber Integer
err := setInteger(&intNumber)
return intNumber, err


On Mon, Sep 21, 2020 at 6:09 PM cs.ali...@gmail.com 
wrote:

> Why does the compiler change evaluation order of return when adding a new
> field to a struct?  I didn't check the compiler output, I only guess it
> somehow changes the order.
> play 
> package main
> import (
> "fmt"
> )
> type Number interface {
> Value() int
> }
> type Integer struct {
> value int
> additional int // remove this for different result
> }
> func (integer Integer) Value() int {
> return integer.value
> }
> func main() {
> number, _ := getNumber()
> fmt.Printf("number val: %d\n", number.Value())
> }
> func getNumber() (Number, error) {
> var intNumber Integer
> return intNumber, setInteger(&intNumber)
> }
> func setInteger(num *Integer) error {
> num.value = 2
> return nil
> }
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/b7077f03-b0f4-454a-a587-ab9757164409n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHsSFfjPzoOTVz7Q4fE%3DziCXhA5mbUWzSkQ5DADMyzWFw%40mail.gmail.com.


[go-nuts] Evaluation order of return

2020-09-21 Thread cs.ali...@gmail.com
Why does the compiler change evaluation order of return when adding a new 
field to a struct?  I didn't check the compiler output, I only guess it 
somehow changes the order. 
play 
package main
import (
"fmt"
)
type Number interface {
Value() int
}
type Integer struct {
value int
additional int // remove this for different result
}
func (integer Integer) Value() int {
return integer.value
}
func main() {
number, _ := getNumber()
fmt.Printf("number val: %d\n", number.Value())
}
func getNumber() (Number, error) {
var intNumber Integer
return intNumber, setInteger(&intNumber)
}
func setInteger(num *Integer) error {
num.value = 2
return nil
}

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/b7077f03-b0f4-454a-a587-ab9757164409n%40googlegroups.com.