I am really happy with thoughts and points shared so far, thank you all! 
Unfortunately I am not able to edit original my post, so to make sure I got 
all of these points I will just sum up everything below,  I think  this 
summary may be valuable for any less experienced gopher, please correct me 
in case I misunderstood something:

1. Types are for representing things, they are things
2. Funcs are for performing actions, calculating things
3. Methods identifies that computation belongs to a given type and should 
be considered in the context of given type

var a net.TCPAddr
var b net.UDPAddr

a.family() // family computation belongs to TCPAddr and is done in a 
context of TCPAddr
b.family() // family computation belongs to UDPAddr and is done in a 
context of UDPAddr

4. Methods let type vary and are great classifier tool ( interfaces )

type Family interface {
   family() int
}

function ComputationBasedOnFamily(f Family, otherparams int...) {
     // ...
}

5. Methods for namespacing, aesthetics

var a net.TCPAddr
var b net.UDPAddr

tcpAddrFamily(a)
tcpAddrFamily(b)

vs
var a net.TCPAddr
var b net.UDPAddr

a.family()
b.family() 

-

Deividas
On Thursday, 2 June 2022 at 23:05:36 UTC+3 atd...@gmail.com wrote:

>
> A short way to see it for me is to reason in terms of capabilities.
> What is an instance of a given type supposed to be able to do? (method) 
> versus what am I able to do with or upon a given instance (function).
> It's not always clear though but it can help.
> On Thursday, June 2, 2022 at 4:38:37 PM UTC+2 h...@deividaspetraitis.lt 
> wrote:
>
>> Background: when I am writing code mostly I end up with some clunky 
>> solutions I am not happy with and one of the reasons I think is that I 
>> might be mixing funcs vs methods.
>>
>> So the question is basically the title.
>>
>> I have searched both in this group ( without a luck )  and in the 
>> Internet for possible ideas/answers and I end up with following points:
>>
>> 1. Structs are for representing things, they are things
>> 2. Funcs are for performing actions, calculating things
>> 3. Methods for performing actions on thing state
>> 4. Methods to satisfy interface
>>
>> Based on these points, let's have a "thing":
>>
>> ```
>> type Person struct {
>>    weight float32 // pounds
>>    height float32 // inches
>> }
>> ```
>>
>> And calculate BMI:
>>
>> ```
>> func CalculateBMI(weight float32 height float32) float32 {
>>  return weight / (height * height) x 703
>> }
>>
>> p := Person{157, 66}
>>
>> CalculateBMI(p.weight, p.height)
>> ```
>>
>> However if I would want for example to implement some kind of interface I 
>> would be forced to use method over func, but it looks weird to me for some 
>> reason:
>>
>> ```
>> interface BMICalculator {
>>     CalculateBMI() float32
>> }
>>
>> // Satisfies BMICalculator
>> func (p * Person) CalculateBMI() float32 {
>>  return p.weight / (p.height * p.height) x 703
>> }
>> ```
>>
>> For example when looking at this STD code I am not longer to reason about 
>> choices funcs vs methods based on points above: 
>> https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;l=26;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708
>>
>> Why `(a 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708;bpv=1;bpt=1;l=26?gsn=a&gs=kythe%3A%2F%2Fgo.googlesource.com%2Fgo%3Flang%3Dgo%3Fpath%3Dnet%23param%2520TCPAddr.family%253Aa>
>>  *TCPAddr 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=21>
>> ) family 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708;bpv=1;bpt=1;l=26?gsn=family&gs=kythe%3A%2F%2Fgo.googlesource.com%2Fgo%3Flang%3Dgo%3Fpath%3Dnet%23method%2520TCPAddr.family>()`
>>  
>> is implemented as a method when it can be implemented as pure func like:
>>
>> ``` 
>> func Family 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708;bpv=1;bpt=1;l=26?gsn=family&gs=kythe%3A%2F%2Fgo.googlesource.com%2Fgo%3Flang%3Dgo%3Fpath%3Dnet%23method%2520TCPAddr.family>
>> (a 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708;bpv=1;bpt=1;l=26?gsn=a&gs=kythe%3A%2F%2Fgo.googlesource.com%2Fgo%3Flang%3Dgo%3Fpath%3Dnet%23param%2520TCPAddr.family%253Aa>
>>  *TCPAddr 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=21>)
>>  
>> int 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=8a56c7742d96c8ef8e8dcecaf3d1c0e9f022f708;bpv=1;bpt=1;l=26?gsn=int&gs=kythe%3A%2F%2Fgo.googlesource.com%2Fgo%3Flang%3Dgo%23int%2523builtin>
>>  
>> {
>>    if a 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=26>
>>  
>> == nil || len(a 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=26>
>> .IP 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=22>)
>>  
>> <= IPv4len 
>> <https://cs.opensource.google/go/go/+/master:src/net/ip.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=22>
>>  
>> { 
>>        return syscall <http://godoc.org/syscall>.AF_INET 
>> <https://cs.opensource.google/go/go/+/master:src/syscall/zerrors_linux_amd64.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=26>
>>  
>>    } 
>>    if a 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock_posix.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=26>
>> .IP 
>> <https://cs.opensource.google/go/go/+/master:src/net/tcpsock.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=22>
>> .To4 
>> <https://cs.opensource.google/go/go/+/master:src/net/ip.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=211>()
>>  
>> != nil { 
>>        return syscall <http://godoc.org/syscall>.AF_INET 
>> <https://cs.opensource.google/go/go/+/master:src/syscall/zerrors_linux_amd64.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=26>
>>  
>>    } 
>>    return syscall <http://godoc.org/syscall>.AF_INET6 
>> <https://cs.opensource.google/go/go/+/master:src/syscall/zerrors_linux_amd64.go;drc=46ab7a5c4f80d912f25b6b3e1044282a2a79df8b;l=27>
>>  
>> }
>> ```
>>
>> So using reasoning above based on silly example looks O.K. but I seems 
>> that I might be still missing some kind of context/information because I 
>> can't explain example from STD.
>>
>> I would like to see what other people approaches this "problem" and to 
>> learn is there any other rules/guidelines to follow.
>>
>> Cheers, Deividas
>>
>>

-- 
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/44336c52-c3a5-4eb2-94ef-f2548bafd8e0n%40googlegroups.com.

Reply via email to