One more try : )
 

> I think what you're saying is that it's more natural and obvious that when 
> you have a function that changes something it would be more obvious and 
> simple if it actually did modify the thing you gave it.
>

That the receiver always act as a ref to a value stored /wherever/
That only the consumer decides where that value is stored using 
pointer/not.,
unless the declarer installed a barrier.



On Thursday, May 11, 2017 at 1:10:21 PM UTC+2, Chris Hopkins wrote:
>
> I think what you're saying is that it's more natural and obvious that when 
> you have a function that changes something it would be more obvious and 
> simple if it actually did modify the thing you gave it.
> Having to jump through hoops to actually make the change you asked for 
> stick is annoying.
>
> Yes? Is that what you mean? Is this a commentary on the effect this has on 
> ease of code read and writability?
>
> What I have come to realise recently by working on ever larger projects is 
> that no that's not annoying. When debugging code I don't understand often 
> half the challenge is working out how a piece of data has changed that 
> shouldn't have been. 
>

 

> In the world you describe anything that touched that variable could be to 
> blame for my problems. If instead you have to jump through hoops to make 
> modifications and those modifications are really obvious where they are 
> happening you make debugging easier.
>
same as today with pointer no ?
 

> Forcing the behaviour that "functions/methods don't modify their 
> associated structures" means people structure their code differently that 
> in my experience means instead of code that reads:
> foo.DoUsefulStuff(i) // has foo become corrupted? changed, who knows?
>
> if foo is not referencable, then the method DoUsefulStuff() 
necessarily provides an out param such DoUsefulStuff() <myself>
That you did not copied back the returned value in your scope
is already an error today.

 

> you instead see code like:
> fred = foo.Lookup(i) // Complex function that changes nothing in foo
> foo = foo.ReturnUsefulStuff(fred) // This returns a corrupted structure
>

I dont get it, to return a corrupted state shall we not use an extra error 
parameter?
Still, that situation will apply if you use pointer.
 

For a start you look at the function definitions and see quickly that they 
> are not modifying the underlying structures so it's quick to discount a 
> large chunk of code as the a source of the problem. This is not so much of 
> a problem in your examples but in large undocumented projects where you 
> don't understand 99% of the code the small things make it much faster to 
> isolate where things could be going wrong.
>

because you focus on the type definition to lookup for possible suspects.
yes i argue its all about var definition and func in params.
yes it looks like they way i think multiply the place of errors.
 

>
> Please don't take this though as anything other than a commentary on the 
> code I like to read. "Code is written for humans to read and only 
> incidentally for machines to execute". I believe code is read by humans way 
> more times than it is written, so anything at all that isolates the code 
> and makes it easier to understand is worth putting time and effort into. 
>
> YMMV
>
>
I sincerely thanks everyone on the thread,
not easy task.

After all,
Happy we kindly disagree  :) 


On Thursday, 11 May 2017 11:39:18 UTC+1, mhh...@gmail.com wrote:
>>
>> Hi,
>>
>> thanks again!
>>
>> I m not the one to validate a perfect answer,
>> i can simply tell that from my go learning and understanding,
>> i agree top notch 200% no question there 
>> on this description,
>> which is weird in fact.
>>
>> I d only remark about this,
>> > so there are actually just two cases: Method is on pointer receiver or 
>> not. 
>>
>> From the declarer side, 
>> there is indeed only 2 cases, 
>> which accounts for 50% of the whole,
>> declaration + consumption,
>> the consumer is still accountable for the remaining
>> 50% of the instance consumption and usage.
>>
>> Does it make it less dead simple ?
>>
>> In my example i might have named the method as `whatever`,
>> still there is an explicit value set on a receiver property.
>> I don t feel like i have assumed anything from the method name.
>>
>>
>> On Thursday, May 11, 2017 at 12:17:00 PM UTC+2, Volker Dobler wrote:
>>>
>>> On Thursday, 11 May 2017 11:28:33 UTC+2, mhh...@gmail.com wrote:
>>>>
>>>> //defined
>>>>> var x &T{} // put on heap
>>>>> var x T // put on stack
>>>>>
>>>>> This is definitely a misconception: Allocation on heap vs stack is
>>>>> totaly unrelated to value methods vs pointer methods. Both examples
>>>>> might be allocated on the stack or on the heap and this depends
>>>>> on other factors than methods of T.
>>>>>
>>>>
>>>> what are other factors ? 
>>>>
>>>
>>> Roughly: If the compiler cannot prove that x *can* be safely put on the
>>> stack then it must go to the heap. Values cannot go safely to the stack
>>> if they might outlive the scope of this stack frame / the current 
>>> function.
>>> This can happen if e.g. a pointer to such value leaves the function, e.g.
>>> in a return or a channel send. Search for escape analysis if you are 
>>> interested in the gory details, but I'd urge you not to until the basic 
>>> stuff
>>> is total clear.
>>>  
>>>
>>>> (let s keep it short, optimized code is not a topic for me)
>>>> I understood that the next func call (might be method) 
>>>> will decide how the instance (to not say value here) is passed.
>>>>
>>>> is it ?
>>>>
>>>
>>> Each and every function --- be it a normal function, a function literal,
>>> a closure, a method, whatever --- completely determines its arguments.
>>> This includes the receiver of a method which technical is just a normal
>>> (the first) function argument.
>>> A func f(int) is called with an argument of type int and a func g(*int) 
>>> is
>>> called with a *int. The same is true for receivers. There is *no* magic 
>>> here! 
>>>
>>> The only thing "magical" with methods and their special receiver
>>> argument that the compiler automatically (automagically) takes the
>>> address of a value or dereferences a pointer to match the method
>>> signature. That's all. That's convenience only. A bit less typing, a bit
>>> fewer braces, it reads nicer.
>>>
>>> So: Yes, it is. 
>>>
>>>
>>>>
>>>>> What can i do with `func (x *T)...` i can not do with `func (x T)`,
>>>>>> except checking for T==nil ?
>>>>>>
>>>>>
>>>>> Like explained several times in this thread:
>>>>> func (x *T) lets you modify *x 
>>>>>
>>>>
>>>> yes, i really want not to question
>>>>  the ability to modify a value in place.
>>>>
>>>> its really about its form.
>>>>
>>>> In this code,
>>>> starting at 0,
>>>> is case 1 not an aberration,
>>>> is case 3 is useless
>>>> https://play.golang.org/p/VyOfZyt7rw
>>>>
>>>> Note case 0 is expected to fail and might be detected.
>>>>
>>>> ?
>>>>
>>>
>>> All four cases a perfectly fine and useful.
>>> The problem here is *not* the language construct but probably
>>> your prejudice that a method called "SetName" should
>>> modify the x it is "applied" to in any case as it does e.g.
>>> in Java where there are no (non-primitive) value types.
>>>
>>> Let's use abstract function names and let's add some real
>>> code (as setters and getter in Go are a bit funny).
>>>
>>> type T { s string }
>>> func (t T) M(s string) {
>>>   if t.s == "" { t.s = "GET" }  // default HTTP method used if nothing 
>>> else selected
>>>   foo(t, s)
>>> }
>>>
>>> default := T{}
>>> default.M("bar")
>>> post := T{s: "POST"}
>>> post.M("bar")
>>>
>>> Can you see it? M operates on a copy of the value it is invoked
>>> on. Both default and post will be copied. The copy of default is
>>> modified and this modification is passed foo. This is nice and
>>> useful and there is no reason the disallow this type of code.
>>>
>>> It is really dead simple: If your methods intend to modify the receiver,
>>> the receiver must be a pointer. This is one simple rule, clear and
>>> straightforward, easy to remember and easy to derive in case one
>>> forgets it.
>>>
>>> Again. This all does not depend on what the x in x.M is. it can
>>> be a pointer or a value, the compiler will take the address or 
>>> dereference
>>> as needed, so there are actually just two cases: Method is on
>>> pointer receiver or not. As I said. Dead simple.
>>>  
>>>
>>>>
>>>> Probably i miss some understanding about why i can do that,
>>>> - handle value handling in two places of the program
>>>> - at initialization, at consumption
>>>>
>>>> does it help ?
>>>>
>>>
>>> I'm sorry I do not understand the question.
>>>
>>>
>>> V. 
>>>
>>

-- 
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to