I think after a while people tend to come up with their own best practices 
when using Go. Each person has their own preference. There is really no 
right or wrong here. The argument for method vs function usually comes down 
to the domain and which makes more sense. 

For my own 'rules', I prefer to keep only the essential methods to my types 
and leave the rest of functionalities to functions. The reason is because 
Go has no inheritance, and functions allow better reusability across types 
without needing inheritance. 

On Friday, June 3, 2022 at 1:21:43 PM UTC+7 h...@deividaspetraitis.lt wrote:

> 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/79552e16-edb1-4471-b556-ed35cdf931a0n%40googlegroups.com.

Reply via email to