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.