Re: [go-nuts] Getting a pointer in a type switch gives a *interface {} if case lists several options

2016-06-22 Thread Marvin Renich
* raidopah...@gmail.com  [160621 18:02]:
> I have encountered some unexpected and inconsistent behavior with type 
> switches. Can someone shed some light as to why Go behaves this way?
> 
> Take a look at https://play.golang.org/p/YPV5YPtWF8
> 
> I would expect both of the switches to behave the same way, but for some 
> reason the one with multiple options in the case ends up with a pointer to 
> an interface and the one with just one option ends up with a pointer to the 
> correct type.

(Aside: reusing the variable t makes it harder to discuss specific
instances of that variable.  I am pasting your code here with variable
name changes.)

package main

import "fmt"
import "reflect"

func main() {
var v uint8 = 0
var t interface{} = v
fmt.Println(fmt.Sprintf("%s %s", reflect.TypeOf(v), reflect.TypeOf()))
switch w := t.(type) {
case uint8:
fmt.Println(fmt.Sprintf("%s %s", reflect.TypeOf(w), 
reflect.TypeOf()))
}
switch x := t.(type) {
case uint8, int8:
fmt.Println(fmt.Sprintf("%s %s", reflect.TypeOf(x), 
reflect.TypeOf()))
}
}

The compiler must know, at compile time, what type w and x are
everywhere except in the switch expression itself.  For w in the "case
uint8" clause, the type of w is known to be uint8.  For x in the "case
uint8, int8" clause, it cannot be determined whether x will be uint8 or
int8, so the compiler must use interface{} so that it can generate a
single block of code that works for both possible case types.

If you use different case clauses for the different types, you will get
what you expected.  (I.e. add a separate "case int8:" to the first
switch statement.)

...Marvin

-- 
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.


Re: [go-nuts] Re: How to create reusable HTML components using default html/template package

2016-08-08 Thread Marvin Renich
* Paulo Janeiro  [160808 11:14]:
> I understand what your point, but I'm just trying to see if this is 
> something easy to do by myself or if I should start looking into a framework
> Nevertheless, I'm using Phoenixframework (Elixir).
> Here we could define a layout that is made of componentes (pre-built 
> templates). Data is passed when you insert templates (components):
> 
> 
> 
> 
> 

Would the html/template package do what you want?

...Marvin

-- 
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.


Re: [go-nuts] Re: is it possible to speed up type assertion?

2017-02-02 Thread Marvin Renich
* T L  [170202 04:20]:
> 
> 
> On Thursday, February 2, 2017 at 4:58:32 PM UTC+8, Axel Wagner wrote:
> >
> > Hi,
> >
> > I can not really reproduce your results. I rewrote your code to use the 
> > builtin benchmarking: http://sprunge.us/IfQc
> > Giving, on my laptop:
> >
> > BenchmarkAssertion-4 10 2.89 ns/op
> > BenchmarkAssertionOK-4   5 2.66 ns/op
> > BenchmarkBare-4   10 2.22 ns/op
> > BenchmarkIface-4 500030.0 ns/op
> > BenchmarkReflect-4   2 9.74 ns/op
> >
> > Note, that a) yes, there is an overhead of the type-assertion, but b) it's 
> > pretty small, especially compared to the other things you're trying and c) 
> > it can be further reduced by using the two-value form (so that there is 
> > never a need to consider stack-unwinding).
> >
> > Overall, this smells like a micro-benchmark. I wouldn't worry too much 
> > about it until you have specific evidence that it's slowing down a real 
> > program.
> >
> 
> The result on my machine for your test:
> BenchmarkAssertion-4 517.9 ns/op
> BenchmarkAssertionOK-4   517.9 ns/op
> BenchmarkBare-4  20 3.93 ns/op
> BenchmarkIface-4 186.7 ns/op
> BenchmarkReflect-4   515.6 ns/op

BenchmarkIface is testing the wrong thing; the value is swamped by the
implicit conversion of d (type T) to the function argument of type I.
Try:

func BenchmarkIface(b *testing.B) {
count := 0
var t T = 1
d := I(t)
for i := 0; i < b.N; i++ {
Iface(, d)
}
}

...Marvin

-- 
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.


Re: [go-nuts] Re: is it possible to speed up type assertion?

2017-02-02 Thread Marvin Renich
* Marvin Renich <m...@renich.org> [170202 09:22]:
> 
> BenchmarkIface is testing the wrong thing; the value is swamped by the
> implicit conversion of d (type T) to the function argument of type I.

Or, maybe it is testing the correct thing.  That is the problem with
microbenchmarking.  Try benchmarking your actual code instead.  :-P

...Marvin

-- 
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.


Re: [go-nuts] Short vs. long variable declarations

2017-01-28 Thread Marvin Renich
* Will Faught  [170127 21:58]:
> Variable shadowing is rarely, if ever, a problem for me too; but what about
> for newcomers?
> 
> I think my copy/paste point stands, though; everyone has those problems, at
> least occasionally.

I agree with you.  See my earlier post for my reasoning:

https://groups.google.com/d/msg/golang-nuts/an7f4o-1cjY/UxexDsuDAwAJ

In short, in the multiple assignment case, «var» instead of «:=» adds
one line of code, but it eliminates ambiguity completely.  In

a, b, c := Foo(d)

what is the cost to every reader of your code to determine which of a,
b, and c are being shadowed?  Look through the entire scope for three
different variable names, at least one of which you are guaranteed to
*not* find, which means you absolutely need to read all the way back to
the beginning of the scope (and hope you don't miss an earlier
declaration which might by var or might be :=).  In

var b SomeType
a, b, c = Foo(d)

what is the cost?  Zero!

In the single assignment case, := saves only three characters.  There
may be no ambiguity about which variables are being shadowed, but for
those of us who have experience with a variety of languages, := has
different meanings in different languages; var a = Foo() is clearly a
declaration, but there is significant cognitive load to recognize that
a := Foo() is a declaration, not a simple assignment or something else.
This cognitive load may not apply equally to everyone, but it does apply
to some people, so if anyone else will read your code, be polite and
make it equally readable for everyone:  use the long declaration (which
really isn't long).

...Marvin

-- 
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.


Re: [go-nuts] Re: Trying to understand := and named return values

2017-02-22 Thread Marvin Renich
On Tue, Feb 21, 2017 at 1:46 PM,   wrote:
> Seems like named returns + if/for/switch initializers = a shadowing
> nightmare. I wish the Go compiler emitted a loud warning on shadowing, as
> this is a dangerously subtle problem out there.

* Ian Lance Taylor [170221 16:13]:
> Yes, named returns may have been a mistake.  Only use them in very
> very short functions.

* John Souvestre  [170221 21:46]:
> I feel the opposite.  I view named returns as documentation of a
> function's parameters.  I'm constantly amazed by the (correct)
> emphasis placed on using appropriate names for calling parameters, but
> not for the return parameters.  The goal is that I shouldn't have to
> read a function's code to use the function, right?

I agree with the John and the others that named return variables are a
good feature.

The confusion is not because of the named returns, but because the :=
notation used with multiple variables on the left combines declaration
and simple assignment without allowing, much less requiring, the
programmer to explicitly identify which variables are being declared and
which are simply being assigned a new value.  This is relevant when :=
is used at the block scope as well as in if/for/switch initializers.

...Marvin

-- 
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.


Re: [go-nuts] Re: Trying to understand := and named return values

2017-02-22 Thread Marvin Renich
* John Souvestre  [170222 11:16]:
> Ø  does it sounds good to disable (in specs) named return vars shadowing ?
> 
> This would help,

I don't think this is a good solution.  It also breaks Go 1 compatibility.

> but the := problem isn’t limited to return variables.
> I think that it’s when there are two (or more) variables, and only one
> is new, that is the real flaw.  I would prefer that it only work when
> both variables are new.

This I agree with 100%.

> I’ve taken to never using := in any multiple variable situation to
> avoid the problem.  This is something that a ver or lint utility can
> check for now, too.  J

Me too.  In fact, I try to only use := in if/for/switch, since I can't
use var there.  As a separate statement, it's easy to use var ... =
instead of ... :=.

...Marvin

-- 
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.


Re: [go-nuts] Understanding go routine heap

2016-08-20 Thread Marvin Renich
* Konstantin Shaposhnikov  [160820 06:34]:
> The code might be race free for the current Go implementation but I don't 
> think this behaviour is documented. 
> 
> https://golang.org/ref/mem doesn't mention sync.WaitGroup at all. So 
> wg.Done() doesn't necessarily happen before wg.Wait() returns and the 
> effect of writing to "result" could be not visible after wg.Wait().

I don't believe that https://golang.org/ref/mem should necessarily be
required to mention every library routine that guarantees a
happens-before relationship.  It should document the lowest-level
language features, and then the documentation for the library routines
should make a claim that their implementations guarantee such a
relationship.

For sync.WaitGroup, the documentation says "A WaitGroup waits for a
collection of goroutines to finish."  For func (*WaitGroup) Wait, the
documentation says "Wait blocks until the WaitGroup counter is zero."
Perhaps the documentation should explicitly mention the Go Memory Model
and state that it is implemented in such a way that a happens-before
relationship exists, but what would be the purpose of WaitGroup if it
didn't guarantee such a relationship?

I believe the happens-before relationship is implied by the current
documentation and the intended use-case for WaitGroup, even if it is not
explicitly stated.

I agree with others in this thread who have stated that there is no race
condition.  I disagree with the implication that WaitGroup, as
documented, could be implemented differently in such a way as to both
conform to the Go 1 compatibility promise and fail to provide an
appropriate happens-before relationship.

...Marvin

-- 
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.


Re: [go-nuts] Re: Understanding go routine heap

2016-08-22 Thread Marvin Renich
* Joubin Houshyar  [160822 09:47]:
> 
> 
> On Saturday, August 20, 2016 at 2:29:41 AM UTC-4, Yulrizka wrote:
> > func process() *foo {
> > var result *foo
> >
> > var wg sync.WaitGroup
> > wg.Add(1)
> > go func() {
> > defer wg.Done()
> > result = {1}
> > }()
> >
> > wg.Wait()
> >
> > return result
> > }
> 
> Your firend is correct that using a WaitGroup here does not in anyway 
> address concurrent access to the heap variable 'result'. 
> 
> This modified example should clear it up:
> 
> func process() *foo {
> var result *foo
> var wg sync.WaitGroup
> 
> wg.Add(1)
> go func() {
> defer wg.Done()
> result = {1}
> }()
> 
> // race condition on result
> result = {8}
> 
> wg.Wait()
> return result
> }
> 
> The issue here is the runtime scheduler and what execution order can occur 
> before the go routine execution 'process' has been stopped at wg.Wait. So 
> process can return a foo initiazed with either 1 or 8. 
> 
> I think the general Go developer intuiton here is that the go routine will 
> not run until the parent go routine has hit the wg.Wait (since there are no 
> explicit IO or blocking instructions between the go func() and wg.Wait. 
> However, using Go(1.7) the main loop will panic after as little as 1000 
> loops.

In the original code given by the OP, there is only one assignment to
result (in the goroutine), and only one read from result (in the return
statement).  The WaitGroup properly orders these statements, so there is
no race condition.

If the OP's friend was trying to say that there easily could be a race
condition if the code was modified to access result in process() after
the go stmt but before the Wait, he would be correct, or if the OP did
not post the full code that his friend was talking about, there might
also be a race condition in the code his friend saw.

But the WaitGroup in the originally posted code does properly order the
two accesses to result.

...Marvin

-- 
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.


Re: [go-nuts] Re: Is uint(v) when v is minus because a huge number supposed behavior?

2017-02-26 Thread Marvin Renich
* peterGo  [170225 22:40]:
> On Saturday, February 25, 2017 at 10:21:49 PM UTC-5, Felix Sun wrote:
> > https://play.golang.org/p/TmxMmltHGH
> >
> > package main
> >
> > import (
> > "fmt"
> > )
> >
> > func main() {
> > var f int = -1
> > fmt.Println("become huge number:", uint(f))
> > fmt.Println("this panic", uint(-1))
> >
> > }
>
> The Go Programming Language Specification https://golang.org/ref/spec
> 
> Conversions https://golang.org/ref/spec#Conversions
> 
> When converting between integer types, if the value is a signed integer, it 
> is sign extended to implicit infinite precision; otherwise it is zero 
> extended. It is then truncated to fit in the result type's size. For 
> example, if v := uint16(0x10F0), then uint32(int8(v)) == 0xFFF0. The 
> conversion always yields a valid value; there is no indication of overflow. 

And the other side (compile error for uint(-1)):

https://golang.org/ref/spec#Constants (in the sixth paragraph)

A constant may be given a type explicitly by a constant declaration or
conversion, or implicitly when used in a variable declaration or an
assignment or as an operand in an expression. It is an error if the
constant value cannot be represented as a value of the respective type.

In this particular case, you can get around the problem like this:

fmt.Println("this works: ", ^uint(^-1))

...Marvin

-- 
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.


Re: [go-nuts] exec.Command

2016-10-05 Thread Marvin Renich
* hadiesmail...@gmail.com  [161005 05:46]:
> hi
> 
> in the second arg in function exec.Command(), what i must put it??
> 
> and any my question is :
> 
> i want run a cmd command.for example : cls
> 
> how can i run this method?

The second argument is a variadic argument, so you can omit it; see [1].
Here is an example of using exec.Command:

var cls = exec.Command("cls")
cls.Stdout = os.Stdout
var err = cls.Run()
if err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
}

[1] https://golang.org/ref/spec#Passing_arguments_to_..._parameters

...Marvin

-- 
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.


Re: [go-nuts] Re: The site at localhost:1234 can't be reached.

2016-09-17 Thread Marvin Renich
* Dave Cheney  [160917 15:58]:
> Move http.ListenAndServe to the top of the main() function, outside the 
> http.HandleFunc call and it will work.

Don't you mean bottom?  At the top, the ListenAndServe will not return,
so the HandleFunc call will never be made, so you will always get 404.

...Marvin

-- 
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.


Re: [go-nuts] differences between pointer and value slice in for-range loop

2016-09-19 Thread Marvin Renich
* Fei Ding  [160918 02:58]:
> Thanks, Marvin, I've learned a lot from your reply. And, I've written more
> code, like:
> 
> a, b, c := 1, 2, 3
> > slice1 := []int{a, b, c}
> > for _, n := range slice1 {
> > go func(n *int) {fmt.Println(*n)}()
> > }
> 
> 
>  It seems that pass *n's address *in the code above will make a data race,
> which you have already explained why. But still, I have another question:
> If the coder do really want the addresses of elements in slice, how to do
> it correctly?

* Marvin Stenger  [160918 07:12]:
> https://play.golang.org/p/9LQMDrDIOv should work.

Marvin Stenger gives two good solutions in the above link.  I will
explain what each does and why you might use one over the other.

for i, _ := range values {
go values[i].print()
}

In this case, the expression values[i].print is evaluated to determine
the function to be scheduled, so the function that is scheduled is the
print method with an implied first argument of [i].  This
expression is evaluated prior to scheduling, so neither the variable
values nor the variable i are referenced in the goroutine.  However, the
value of [i] is a pointer into the backing array for the slice,
which will be important in choosing which solution to use.

for _, v := range values {
w := v
go w.print()
}

In the second case, although the same v is reused for all iterations of
the loop, a new w is created each time through the loop.  The assignment
to v at the beginning of the loop makes a copy of the slice element and
puts it in v.  Then it is copied a second time and stored in w.  (The
compiler may be able to optimize the generated code to avoid making two
copies.)  Now the function call that is scheduled is a call to the print
method with an implied first argument of   Because each iteration of
the loop uses a new variable w, each goroutine has its own copy of the
slice element associated with the iteration of the loop in which the
goroutine was created.

The primary consideration in choosing between these two solutions is
whether or not the goroutine can safely access the slice element in the
backing array.  If it can, use the first solution.  If it cannot, either
because the backing array might be modified or because the element
itself is not safe to reference concurrently, then use the second
solution.  I would probably modify the second solution like this:

for i, _ := range values {
var w = values[i]
go w.print()
}

This doesn't rely on the compiler's ability to optimize copying the
element twice into copying it only once, and it is just as clear to the
next programmer who reads your code.

...Marvin

-- 
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.


Re: [go-nuts] Randomizing contents of a file

2016-09-20 Thread Marvin Renich
* Unknown User  [160920 06:43]:
> Hi All,
> 
> I am trying to print the contents of  a file randomizing the lines.
> The following code works, but does not exit even after all the lines are 
> read.
> What needs to be done to correct it?

Try this 

package main

import(
"fmt"
"bufio"
"os"
"math/rand"
"sync"
"time"
)

func main() {
filename := os.Args[1]
if filename == "" {
panic("No filename")
}
fh,err := os.Open(filename)
if err != nil {
panic(err)
}
scanner := bufio.NewScanner(fh)
c := make(chan string)
var wg sync.WaitGroup
for scanner.Scan() {
line := scanner.Text()
wg.Add(1)
go func(l string){
time.Sleep(time.Duration(rand.Intn(30)) * time.Millisecond)
c <-  l
wg.Done()
}(line)
}
go func() {
wg.Wait()
close(c)
}()
for  {
myline, ok := <-c
if !ok {
return
}
fmt.Println(myline)
}
}

You need a way to determine when all of the spawned goroutines have sent
their line to the channel so you know when to exit the bottom for loop.
A select doesn't help, because the goroutines are sending on the channel
at random intervals, so the default case will cause a busy loop between
sends, not just after all sends have completed.

The WaitGroup keeps track of how many worker goroutines have not yet
finished.  The final goroutine (started below the top for loop) waits
for all the workers to finish, then closes the channel.

The bottom for loop does not use a select statement; it merely reads
from the channel, which will block until the next worker sends its line.
When the final goroutine closes the channel, the channel read will
return "", false, and the bottom for loop will exit.

As a general rule of thumb, use a select only when you have more than
one channel send and/or receive that you want to wait for, and only use
a default case when you have other work that can be done if the channel
operations are all blocked (waiting).  Don't use default in an otherwise
empty for loop around a select.

hth...Marvin

-- 
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.


[go-nuts] playground URL to fetch code only

2016-09-20 Thread Marvin Renich
Is there a way to take a playground URL, such as
https://play.golang.org/p/Vg6f0gSs3l, and modify it (e.g. with a query
string) so that you can retrieve just the code as text without the
surrounding html?  Something like

curl 'https://play.golang.org/p/Vg6f0gSs3l?text'

If not, would such a feature request be likely to get implemented?

Thanks...Marvin

-- 
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.


Re: [go-nuts] Re: playground URL to fetch code only

2016-09-20 Thread Marvin Renich
* Ivan Anfilatov  [160920 10:36]:
> https://play.golang.org/p/Vg6f0gSs3l.go
> 
> compile - post request to https://play.golang.org/compile in body request - 
> source 
> response - json

Thanks, Ivan!

...Marvin

-- 
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.


Re: [go-nuts] playground URL to fetch code only

2016-09-20 Thread Marvin Renich
* Nicolas Martyanoff  [160920 10:07]:
> curl 'https://play.golang.org/p/Vg6f0gSs3l.go', i.e. just appending '.go' will
> do the trick.

Excellent!  Thank you!

...Marvin

-- 
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.


Re: [go-nuts] differences between pointer and value slice in for-range loop

2016-09-17 Thread Marvin Renich
* Fei Ding  [160916 23:30]:
> Link here: https://play.golang.org/p/cdryPmyWt5
> 
> The code above is going to check the differences between pointers and 
> values in a for loop, while go statement is also used at the same time. For 
> code:
> 
> values := []field{{"one"},{"two"},{"three"}}
> for _, v := range values {
> go v.print()
> }
> 
> we know that the console will print *three three three* as result, because 
> for loop runs into its end before go routines start executing, which write 
> *v* as the last element of the slice. But what about pointers? 
> 
> poniters := []*field{{"one"},{"two"},{"three"}}
> for _, v := range poniters {
> go v.print()
> }
> 
> It seems to print* one two three*, why?

Try running your example with the race detector.  Then try commenting
out, on separate trials, each of the two cases, again running under the
race detector.

The second case runs without a race, but the first does not.

To understand why, you must carefully analyze what is happening
according to the Go specification
(https://golang.org/ref/spec#Go_statements).

In the both cases, the variable v is reused for all iterations of the
for loop; that is, every iteration of the loop uses the same variable v,
but with a different value for each iteration.

Now, in the first case, v is of type field.  The go statement evaluates
the function value and parameters.  Evaluating the function value means,
essentially, getting a pointer to the function to be called (this is a
simplification, but is accurate enough for this analysis); it does not
yet call the function.

A method call can be thought of as a function call with the receiver as
an implied first argument.  So the first, implied, argument is evaluated
as  (because, according to the spec, x.m() is shorthand for ().m()
in this scenario).  The go statement creates a new goroutine with this
particular function call, with the address of v as the first argument,
to be executed at the go scheduler's discretion.

Next, the for loop assigns the next element from the slice values to the
variable v.  This is the data race.  There is no guarantee that the
scheduler will wait for the sleep statement after the loop to start
executing the first goroutine, and in fact it didn't on one run on my
system; I got a result of two three three.  There is no synchronization
between the assignment to v by the for loop and the reference of v.name
in v.print, so you have a data race.

In the second case, v is of type *field.  The go statement evaluates the
first, implied, argument as the current value of v (the first pointer in
the slice).  The go statement creates a goroutine with a call to the
print method with that value as the argument.

When the for loop assigns the next element from the slice to v, it is
not changing anything that is being referenced by the go routine, so
there is no data race (and the values printed are taken from successive
slice elements).

...Marvin

-- 
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.


Re: [go-nuts] Re: Understanding go routine heap

2016-08-22 Thread Marvin Renich
* Joubin Houshyar <jhoush...@gmail.com> [160822 12:36]:
> On Monday, August 22, 2016 at 10:27:06 AM UTC-4, Marvin Renich wrote:
> > * Joubin Houshyar <jhou...@gmail.com > [160822 09:47]: 
> > > 
> > > Your firend is correct that using a WaitGroup here does not in anyway 
> > > address concurrent access to the heap variable 'result'. 

I obviously (still) misunderstand what you are saying here.  Taking the
OP's question at face value, and assuming that important details were
not left out, the OP's friend is simply wrong, and using the WaitGroup
does, indeed, address the concurrent access to the variable 'result'.

> > In the original code given by the OP, there is only one assignment to 
> > result (in the goroutine), and only one read from result (in the return 
> > statement).  The WaitGroup properly orders these statements, so there is 
> > no race condition. 
> 
> Didn't say there was.
> 
> > If the OP's friend was trying to say that there easily could be a race 
> > condition if the code was modified to access result in process() after 
> > the go stmt but before the Wait, he would be correct, or if the OP did 
> > not post the full code that his friend was talking about, there might 
> > also be a race condition in the code his friend saw. 
> 
> That's my assumption here. 
> 
> > But the WaitGroup in the originally posted code does properly order the 
> > two accesses to result. 
> 
> Didn't say it didn't. 

...Marvin

-- 
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.


Re: [go-nuts] How to define two identical named types?

2016-10-02 Thread Marvin Renich
* Matt Harden  [161001 23:34]:
> I do think that T L has a point. The spec defines the syntax of the
> language, and TypeSpec refers to a syntactical construct. It is not
> possible in the syntax of the language to create two named types that
> originate in the same TypeSpec. We seem to be saying that uint8 and byte
> originate in the same "TypeSpec", but the "TypeSpec" referred to there is
> an implementation detail of the compiler, not the syntactical construct
> defined in the Language Specification.

Does anyone remember if there was a time when TypeSpec was defined as

  TypeSpec = IdentifierList Type .

instead of the current

  TypeSpec = identifier Type .

This would give a clear reason why the wording under type identity is
the way it is.  I don't remember such a definition, and I've been
following Go since before Version 1, but not since the beginning, so
this is at least conceivable.  It's also possible that the Go authors
were considering such a definition, and part of the spec was written,
but the idea was thrown out as unnecessary and adding extra complexity,
accidentally leaving an artifact of a considered, but discarded, design
detail.

...Marvin

-- 
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.


Re: [go-nuts] why "iota"?

2016-11-09 Thread Marvin Renich
* liyu1...@gmail.com  [161109 08:26]:
> I don`t know how to speak 'iota' too,I have to say "i---o---t---a" when I 
> talk with somebody. 
> 
> 在 2013年4月28日星期日 UTC+8上午8:52:36,mb0写道:
> >
> > > Wikipedia says it's a greek alphabet that looks like i, and I am seeing 
> > > APL used iota for something like range() in python, which makes 
> > > go-lang's use of iota a bit different from that in APL. 
> > > 
> > > iota sounds cool, and I like it, but I wonder if that coolness was the 
> > > primary reason behind the name of an important language construct, or 
> > > there are some relevant legacy behind the character. 
> >
> > from http://en.wiktionary.org/wiki/iota#Noun 
> > ... 2. A jot; a very small, inconsiderable quantity. 
> >
> > hope that helps to clarifies it 

Speaking as a former APL language implementer, I think the Go use of
iota is very much in line with the APL definition:  it produces
successive integers.  APL, being an array oriented language, produces
them all at once, but the basic idea is the same.

In APL, ⍳7 produces the vector (one-dimensional array) 1 2 3 4 5 6 7.

Iota is pronounced eye-OH-tuh.

...Marvin

-- 
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.


Re: [go-nuts] Are short variable declarations necessary?

2016-11-09 Thread Marvin Renich
* T L  [161109 05:18]:
> On Friday, October 21, 2016 at 11:26:46 PM UTC+8, T L wrote:
> > Thanks, gri, this is almost the answer I want.
> >
> > I still have two small questions about the short form.
> > 1. would it be good to allow all identifiers in a short form are old ones 
> > (assume there is only one code block)?
> > 2. would it be good/better to let identifiers in a short form not shadow 
> > outer block identifiers?
> > I know the second one will break compatibility. It is not a feature 
> > request. It is just a plain question. 
> >
> 
> how about adding a ::= operator to satisfy above two rules?

The first one would definitely not be a good design.  The problem with
the short variable declaration is that you cannot tell by looking just
at that one line of code which variables are being redeclared and which
continue to refer to a previously existing variable.

Implementing the second one would only be good if it were part of fixing
the real problem, that is adding a new syntax that allows a single
combined assignment/declaration which requires each variable on the left
side to be individually identified as either a new (possibly shadowing)
variable or an existing variable that is not to be shadowed.

This has been discussed before, and does not seem likely to ever happen.

I go out of my way to avoid := when I can, to the point of writing

var x int
x, err = foo()

instead of

x, err := foo()

when err has been declared earlier in that block.  There is no ambiguity
in the code on top; in the bottom statement, you have to look through
the source to find (or not find, which is more of an issue) both x and
err.

In the single variable case, where there is no ambiguity,

var x = foo()

is only three more characters than

x := foo()

and is _much_ easier to distinguish as a declaration rather than
assignment, especially for those of us who have experience in many
languages, where := can mean different things in different languages.
It is simply an issue of cognitive load.

...Marvin

-- 
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.


Re: [go-nuts] Are short variable declarations necessary?

2016-11-09 Thread Marvin Renich
* T L  [161109 11:57]:
> yes, := can be avoided totally.
> but := really has some benefits.
> 
> The contradiction is the short form is 80% good with 20% bad side effects.

I disagree.  I saves three characters and in doing so adds much more
cognitive load to distinguish declaration from assignment.  It is useful
in the condition expressions in if and for statements, but in many cases
it is easy to avoid.  I say it is 20% good and 80% bad.

...Marvin

-- 
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.


[go-nuts] html/template modifies template outside of actions

2016-11-11 Thread Marvin Renich
In this code (at https://play.golang.org/p/HVxzsn0_eC)

package main

import (
"fmt"
"html/template"
"os"
)

var tmpl = `
{{range .}}
  {{.}}{{end}}

`

var items = []string{"one", "two", "three"}

func main() {
var t, err = template.New("").Parse(tmpl)
if err == nil {
err = t.Execute(os.Stdout, items)
}
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
}
}

the Execute method escapes the first character ('<' in "https://groups.google.com/d/optout.


Re: [go-nuts] html/template modifies template outside of actions

2016-11-11 Thread Marvin Renich
* Ian Davis <m...@iandavis.com> [16 06:04]:
> On Fri, Nov 11, 2016, at 09:21 AM, Marvin Renich wrote:
> 
> > the Execute method escapes the first character ('<' in " > "".  This seems wrong to me, both logically and according to the
> > documentation, which states in the fourth paragraph under Overview for
> > text/template:
> > 
> >   all text outside actions is copied to the output unchanged.
> > 
> > Templates are assumed to be written by trusted authors, and don't need
> > sanitizing; only the substitution data needs escaping.
> > 
> > I don't have a github account.  If nobody disagrees that this is a bug,
> > will someone please file an issue?
> 
> 
> html/template is only designed for use with html output. It understands
> the html model and sanitizes the template according to the those rules.
> You'll need to use text/template for xml.

While I understand that the html/template package is intended for html,
much of the escaping it does is appropriate for certain classes of xml
(including rss.xml, which is my particular use case atm).

My issue is that the documentation explicitly says that text outside of
actions are copied verbatim, and this is the only reasonable behavior, in
my opinion.  The template author has control of, and is responsible for,
the content of the template.  Trying to "fix" his/her mistakes is wrong.
Only the contents of the data should have any sanitizing performed on
it.

The current behavior contradicts the explicitly stated security model:

  This package assumes that template authors are trusted, that Execute's
  data parameter is not, and seeks to preserve the properties below in
  the face of untrusted data

and two paragraphs later:

  "... only code specified by the template author should run as a result
  of injecting the template output into a page and all code specified by
   ^^^
  the template author should run as a result of the same."

With the data, the program author can explicitly override the
sanitization by casting a string to template.HTML.  Neither the program
author nor the template author can prevent Execute from changing the
text outside of actions when it shouldn't (without significant extra
kludges).

...Marvin

-- 
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.


Re: [go-nuts] What is called reference values in Golang?

2016-10-21 Thread Marvin Renich
* T L  [161021 01:47]:
> This faq, "Why are maps, slices, and channels references while arrays are 
> values?", https://golang.org/doc/faq#references.
> thinks maps, slices, and channels are references. I think the "references" 
> here means "reference values".

That's not the way I read it.  The question is contrasting references
and values, as if they are two distinct things.  Nowhere does it use the
phrase "reference value".  Note that maps, slices, and channels are all
types, adding further evidence that "reference type" would fit better
than "reference value".  Also, in that paragraph, it says "changing
these types to act as references"  The word value does not occur in
that sentence, but type does.

...Marvin

-- 
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.


Re: [go-nuts] Re: converting slice of items into nested array

2016-12-08 Thread Marvin Renich
* Mikael Gustavsson  [161208 03:55]:
> There's no need to use maps, you want to follow this pattern:
> 
> for i := range items {
>   if i==0 || !grouped(i-1, i) {
> appendToResult
>   }
>   appendToGroup
> }
> 
> Here's the full example: https://play.golang.org/p/1e0rDDmq7b

Note that this only works if the input slice is sorted, which it is in
the example data given by the OP, but that constraint was not explicitly
stated.  If the input is not sorted, you must either sort it first, use
a map, or perform a search in each iteration.

If the input data is not guaranteed to be sorted, minimal changes to the
above would work: https://play.golang.org/p/4GsVUV_fBs

The map is only used to perform the search efficiently, and is no longer
used after the for loop.

...Marvin

-- 
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.


Re: [go-nuts] Golang text template - time.Format epoch

2016-12-08 Thread Marvin Renich
* 'Sergey Krutsko' via golang-nuts  [161208 
02:12]:
> Thanks Marvin!
> 
> that's exactly what i need
> 
> bwt, is there any way to get current timestamp inside the template (without 
> referencing to the data structure) ?
> 
> something like that:
> "timestamp: {{time.Now.Unix}}"

You can use a template.FuncMap.

If, by "without referencing to the data structure", you mean without
adding anything additional to the data structure, then you will have to
use a FuncMap.   If you mean "without adding the current time as a value
to the data structure", but will allow adding functions to the data
structure, then there is another way.  Add a field (or map element) to
the data of some func type (e.g. func() time.Time) and use call inside
the template.

The playground link https://play.golang.org/p/9rsVDBPzy2 demonstrates
both methods.

When using a FuncMap, it must be defined on the template (with a call to
Funcs) before parsing any template that uses it.  If you are using
ParseFiles or ParseGlob, rather than Parse, this is a little tricky, and
the template documentation could be improved significantly to address
the issue.

The helper functions ParseFiles and ParseGlob (at the package level,
rather than the methods on *Template) cannot be used because there is no
way to pass a FuncMap before parsing.

If you try something like

var t, err = template.New("").Funcs(fm).ParseFiles(file)
// handle error, then...
err = t.Execute(os.Stdout, data)

you will get an error containing

... "" is an incomplete or empty template;...

The problem is that t is an empty template with name "", and the
template(s) resulting from ParseFiles is only an associated template
with a name derived from the file name.  So t.Execute() attempts to
execute the empty template.  There are at least two ways to make it
work.  One way is to replace the first line above with

var t, err = template.New(filepath.Base(file)).Funcs(fm).ParseFles(file)

and the other is to replace the Execute line above with

err = t.ExecuteTemplate(os.Stdout, t.Templates()[0].Name(), data)

A third way would be to use ioutil.ReadFile to read the whole file and
then call t.Parse on the string obtained from that.  Using this method,
the result of Parse is used as the template t, not as an associated
template with a different name.

...Marvin

-- 
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.


Re: [go-nuts] Reset Slice with Make Every Time?

2017-01-10 Thread Marvin Renich
* Tomi Häsä  [170110 02:23]:
> On Tuesday, January 10, 2017 at 1:49:37 AM UTC+2, kortschak wrote:
> > On Mon, 2017-01-09 at 15:12 -0800, Tomi Häsä wrote: 
> > > Is this the correct way of resetting a slice? I mean do I always
> > > need to  use make to reset a slice? 
> > > 
> > > // initialize slice 
> > > onearea Area = Area{} 
> > > group []Area = make( []Area, 0, MAX ) 
> > > 
> > > // add stuff to slice 
> > > group = append( group, onearea ) 
> > > 
> > > // reset slice 
> > > group = make( []Area, 0, MAX ) 
> >
> > group = group[:0] 
> >
> > > Using nil to reset a slice doesn't seem to be wise as the capacity
> > > does not stay with MAX, but it will decrease to 2 in my program. 
> > > 
> > > group = nil 
> > > 
> > > Full code here: https://github.com/tomihasa/unicodetest 
> 
> By the way, what happens to the old data I used with the previous make 
> command?

I'm not sure if these were mentioned earlier in the thread, but both
https://blog.golang.org/slices and
https://blog.golang.org/go-slices-usage-and-internals give some really
good info on this.

The abbreviated answer is to think of a slice as a view into its backing
array.  As long as a slice (or other variable) refers to the backing
array or one of its elements, the garbage collector will not reclaim any
of the backing array.  So, even doing
group = group[1:]
will not allow the GC to reclaim the memory for the old group[0].

If the elements of the slice (and therefore of the backing array) are
simple values, such as ints, or structs of simple values, doing
group = group[:0]
will reset the slice to empty without changing its current capacity and
without reallocating the memory for its backing array.

If, however, the slice elements contain pointers, maps, channels, or
other slices, then the memory referred to by those items will not be
reclaimed, even though group appears to not refer to them.  As you
append to group the second time around, those elements will be
overwritten, and the memory referred to by the old values will be able
to be reclaimed by the GC.  Example:

type LargeStruct struct { /* lots of fields */ }
func NewLargeStruct(i int) (ls *LargeStruct) { /* does what's needed */ }
type SmallStruct struct { ls *LargeStruct }
var small []SmallStruct = make([]SmallStruct, 0, 50)
for i := 0; i < 10; i++ {
small = append(small, SmallStruct{NewLargeStruct(i)})
}
small[:0]

small is now an empty slice with capacity 50, but none of the memory
allocated for the ten instances of LargeStruct is able to be reclaimed
by the GC.  This is because the backing array still contains the
pointers to all of the LargeStruct's allocated in the loop.  Now do

small = append(small, SmallStruct{NewLargeStruct(41)})
small = append(small, SmallStruct{NewLargeStruct(42)})

and the memory allocated by NewLargeStruct(0) and NewLargeStruct(1) in
the earlier loop can be reclaimed (assuming they are not referenced
elsewhere).

On the other hand, replacing
small[:0]
in the above code by
small = make([]SmallStruct, 0, 50)
will allocate a new backing array and will allow the old backing array
as well as all of the LargeStruct's to be reclaimed.  Which is better
will depend on your application.

...Marvin

-- 
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.


Re: [go-nuts] Golang text template - time.Format epoch

2016-12-07 Thread Marvin Renich
* skrutsko via golang-nuts  [161207 08:30]:
> Hello
> 
> I have a field in my text template: "start":"{{.Start.Format "Jan 02, 2006 
> 15:04:05 UTC"}}"
> 
> But, I want to have output as epoch time. E.g. 148110633400 
> 
> Could you please explain how to do this ? Thanks

Do you mean Unix time (seconds since Jan 1, 1970 UTC)?  Try

"{{.Start.Unix}}"

Note that in your Format above, UTC should probably be MST to print the
time zone associated with Start.  Also, I presume your code has the
double quotes properly escaped for their context, which does not appear
to be done above (though the context is not clear; a more complete
example would be more helpful).

...Marvin

-- 
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.


Re: [go-nuts] Re: Building with "go install" vs "go build"

2017-04-18 Thread Marvin Renich
* Dave Cheney  [170418 09:57]:
> > Apparently Dave Cheney says to prefer "go install" over "go build"[3], 
> except when cross-compiling [4]. However, many of these posts are older, 
> and Golang moves at such a rapid clip that it's difficult to keep track of 
> what everybody is doing.
> 
> This information is still correct.
> 
> On Friday, 10 February 2017 02:55:25 UTC+11, Jonathan Yu wrote:
> >
> > Hello Gophers!
> >
> > There's a fair amount of documentation available[0] about how "go install" 
> > works, particularly in contrast to "go build,"[1,2] but not a lot about 
> > which one is more idiomatic/preferred.  Using the standard toolchain, it 
> > seems there's three ways to build your applications:

I use "go build" in the "edit, build, test, repeat" cycle, and only use
go install when I have what I consider to be a working program.  Often,
this involves incrementing the version and adding a version tag to the
repo.

If I used go install during edit-test, I would often have a non-working
executable in my path, so I would not be able to use the program for
"real" work while I am knee-deep in a bug fix or implementing a new
feature.

Dave's mileage obviously varies from mine, which is fine.  However, I
believe my use case and reasoning is common enough that I believe it is
counterproductive to try to declare one way or the other to be "The
Idiomatic Way".  This just boils down to personal preference and work
flow, and trying to tell others that one way is the "preferred" way is
wrong.

...Marvin

-- 
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.


Re: [go-nuts] memory gc when slice shortcut

2017-03-09 Thread Marvin Renich
* 代君  [170309 05:45]:
> I have a []*Struct, at some times it length grow to 1000, after that, the 
> slice be shortcut to length of 10, and never grow to 1000 again.
> 
> dose the memory of *Struct at slice's tail will never be gc?

What Jan says is correct, but if your program logic can determine when
the slice has shrunk and you want to allocate a smaller backing array to
allow the larger array to be garbage collected, you can do something
like this:

var sl []*Struct
// ... Lots of stuff is appended to sl.
// ... Later, most of sl is unused (resliced with sl = sl[a:b]).

// Allow large sl backing array to be gc'ed.
sl = append([]*Struct(nil), sl...)

This last line allocates a new array that is large enough to hold the
current contents of sl, copies those elements to the new array, and
assigns sl to be a slice pointing to the new array.  The old, presumably
much larger, array can then be collected by the GC when it is ready to
do so.

...Marvin

-- 
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.


Re: [go-nuts] does Go memory model guarantee this program always prints 1?

2017-07-09 Thread Marvin Renich
* T L <tapir@gmail.com> [170709 04:56]:
> On Friday, July 7, 2017 at 8:42:28 PM UTC+8, Marvin Renich wrote:
> > Yes, the go routine establishes a happens-before relationship such that 
> > x is incremented before y, and the atomic Add of y and Load of y ensure 
> > that the Load either happens before or after, but not during, the Add. 
> 
> But I remember that the "happens-before relationship" is never written down 
> in any official Go documentation.

Actually, I believe the documentation is specific enough, at least if
you accept a reasonable definition of "atomic" as it is used in the
documentation of the atomic package.

Without atomic operations, a write to memory in one go routine and a
read from the same memory in another (without other synchronization)
cannot be guaranteed to have any specific behavior at all.
Specifically, the read may return garbage that has nothing to do with
either the value that was originally in the memory or the value that is
being written to the memory.

If you are performing atomic writes and reads, this guarantees that the
read must either observe the original value or the value placed by the
write; no other value may be observed.  So, if the initial value of
variable X is 0, and the only code that changes variable X is in go
routine A, which changes it atomically (exactly one time) to have a
value 1, then go routine B, which atomically reads variable X, must
either get a value of 0, which implies that the read MUST happen-before
the write in go routine A, or it must get a value of 1, which implies
that the write in go routine A MUST happen-before the read in go routine
B.  So, the value read by go routine B can be used to determine which of
the read and write happens before the other.

In other words, if we take the existing description under "Happens
Before" it the memory model documentation, specifically:

  Also, if e1 does not happen before e2 and does not happen after e2,
  then we say that e1 and e2 happen concurrently.

And we add the following definition, which currently is implicit in the
atomic documentation:

  An atomic read and an atomic write of the same variable cannot happen
  concurrently [for the definition of "concurrently" above].

Then an atomic read and an atomic write on the same variable establish a
happens before relationship between the two, but it is up to the code to
be able to prove which one happens first.

This is slightly different than most of the other happens-before
relationships, such as channel writes and reads, where the operation
determines which one happens first, but it is still good enough to
establish a happens-before relationship based on the result of the read.

...Marvin

-- 
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.


Re: [go-nuts] does Go memory model guarantee this program always prints 1?

2017-07-10 Thread Marvin Renich
* T L  [170710 12:32]:
> so this is guaranteed by go memory model?
> 
> package main
> 
> import "fmt"
> import "sync/atomic"
> 
> func main() {
> var x, y int32
> 
> atomic.AddInt32(, 1)
> atomic.AddInt32(, 1)
>
> if atomic.LoadInt32() == 1 {
> fmt.Println("x =", atomic.LoadInt32()) // always 1 if it is 
> printed?
> }
> } 

No concurrency here.  Order is as written.

...Marvin

-- 
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.


Re: [go-nuts] does Go memory model guarantee this program always prints 1?

2017-07-10 Thread Marvin Renich
* T L  [170710 12:35]:
> so this is guaranteed by Go memory model?
> 
> package main
> 
> import "fmt"
> import "sync/atomic"
> import "unsafe"
> 
> func main() {
> var x, y int32
> 
> var p = unsafe.Pointer()
> 
> atomic.AddInt32(, 1)
> atomic.AddInt32(, 1)
>
> if atomic.LoadInt32() == 1 {
> fmt.Println("x =", *(*int32)(p)) // always 1 if it is printed?
> }
> } 

Again, no concurrency.  Order is as written.

I've only used unsafe.Pointer once and in a way that was specifically
documented to work, and I have not otherwise researched it, so I may be
wrong here, but assuming the GC is guaranteed to update p if x moves,
then I believe this will always print "x = 1".

...Marvin

-- 
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.


Re: [go-nuts] does Go memory model guarantee this program always prints 1?

2017-07-10 Thread Marvin Renich
[Reply-To set; I don't need two copies of replies.]

* T L  [170710 12:31]:
> so this is guaranteed by Go memory model?
> 
> package main
> 
> import "fmt"
> import "sync/atomic"
> 
> func main() {
> var x, y int32
> go func() {
> atomic.AddInt32(, 1)
> atomic.AddInt32(, 1)
> }()
>
> if atomic.LoadInt32() == 1 {
> fmt.Println("x =", atomic.LoadInt32()) // always 1 if it is 
> printed?
> }
> } 

Asked and answered in your previous msg.  Yes, assuming the Go authors
agree that atomic operations guarantee non-concurrency.  Can we have
someone authoritative weigh in here?

...Marvin

-- 
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.


Re: [go-nuts] does Go memory model guarantee this program always prints 1?

2017-07-07 Thread Marvin Renich
* T L  [170707 01:32]:
> Then how about this?
> 
> package main
> 
> import "fmt"
> import "sync/atomic"
> 
> func main() {
> var x, y int32
> go func() {
> atomic.AddInt32(, 1)
> atomic.AddInt32(, 1)
> }()
> 
> if atomic.LoadInt32() == 1 {
> fmt.Println("x =", atomic.LoadInt32()) // always 1 if it is printed?
> }

Yes, the go routine establishes a happens-before relationship such that
x is incremented before y, and the atomic Add of y and Load of y ensure
that the Load either happens before or after, but not during, the Add.

> if atomic.LoadInt32() == 0 {
> fmt.Println("y =", atomic.LoadInt32()) // always 0 if it is printed?
> }

No.  If the Load of x returns 0, it must happen before the Add of 1 to x.
But after the test and before the Load of y, the main go routine and the
func go routine are both runnable and there is nothing to establish a
happens-before relationship between the Load of y and the Add of 1 to y.

> }

...Marvin

-- 
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.


Re: [go-nuts] Slice capacity changes

2017-08-08 Thread Marvin Renich
* sno  [170808 20:57]:
> package main
> 
> import (
> "fmt"
> "reflect"
> "unsafe"
> )
> 
> func main() {
> a := []byte("1234567")
> printSliceDetails(a)
> }
> 
> func printSliceDetails(a []byte) {
> sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer())
> fmt.Printf("Backing array location: %v, data: %s, len: %d, cap: %d\n",
> sliceHeader.Data, string(a), len(a), cap(a))
> 
> // fmt.Printf("Backing array location: %v, data: %s, len: %d, cap: %d\n",
> // sliceHeader, string(a), len(a), cap(a))
> }
> 
> In the above code, the capacity prints 32. However, if you comment the 
> first print statement and remove the commenting on the second and run the 
> program again the capacity will only be 8. What is happening with 
> sliceHeader.Data to make its capacity grow like that?

I'm not an expert, but my guess is that the compiler is doing escape
analysis and allocating a on the heap in the first case and on the stack
in the second case (with different minimum allocation sizes).

Hopefully someone else can give a more authoritative answer.

...Marvin

-- 
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.


Re: [go-nuts] Slice capacity changes

2017-08-09 Thread Marvin Renich
[I'm subscribed; reply-to set.]

* sno  [170808 21:34]:
> Hmm, interesting. However, wouldn't that mean that if I removed the 
> function and did the following: https://play.golang.org/p/enI6UmYoFJ the 
> escape analysis wouldn't happen?

Why would escape analysis not happen for main just like for any other
function?  (main is just a function.)  By passing the value of
sliceHeader.Data to fmt.Printf, the address of the backing array
allocated for the slice escapes, so it is allocated on the heap.

And, as Jan Mercl says in another reply, the size of the backing array
allocated for a slice created from a literal is an implementation detail
that is not specified in the language spec, and so the size can vary
between invocations, including between different invocations of the
slice initialization code within the same invocation of the program
(e.g. if the slice is initialized within the body of a for loop).

...Marvin

-- 
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.


Re: [go-nuts] Re: use of builtin print for debug

2017-05-09 Thread Marvin Renich
* mhhc...@gmail.com  [170509 07:10]:
> Also i think go has already several patchers that you might get
> inspiration from, not sure where they are located. Sorry : x

Try man gofmt and look at -r.

...Marvin

-- 
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.



Re: [go-nuts] Re: use of builtin print for debug

2017-05-09 Thread Marvin Renich
[I set an explicit Reply-To header because I do not want duplicate
emails.  Please do not CC me; I read this list.]

* mhhc...@gmail.com  [170509 07:40]:
> : ( thanks
> 
> $ man gofmt
> Aucune entrée de manuel pour gofmt
> /no such entry/

One of many advantages of the Debian distribution is that policy
mandates that any command which the end user is expected to use must
have a man page.  Many thanks go to the Debian maintainers of the Go
packages for their hard work, including, but not limited to, converting
Go package documentation into proper man pages.  This is not busy work;
rather it is very, very helpful!

> *$ gofmt -husage: gofmt [flags] [path ...]  -r stringrewrite rule 
> (e.g., 'a[b:len(a)] -> a[b:]')*
> 
> https://golang.org/cmd/gofmt/#hdr-Examples

Indeed, this is the right place to find the official Go documentation
for this tool.

> How to take advantage of it ?
> He needs to add new func, probably.
> And maybe to rename expr.Call.Name.

If I were trying to extricate myself from the OP's position, my first
attempt would be

  gofmt -r 'print -> debug.Print'

and then add a debug package where I could make that function empty if I
wanted.  If you want to get fancy, use build tags so that

  go build -tags debug

will build with debugging turned on, but without the tag, the debug
functions are empty.

...Marvin

-- 
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.


Re: [go-nuts] Handling errors in functions

2017-06-21 Thread Marvin Renich
* suburb4nfi...@gmail.com  [170621 08:44]:
> Is it possible to give a default nil value to an error at the beginning of 
> a function and then just assign to it in case of need ? What I want to do 
> is something like the following : 
> 
> func GetSummonerByName(name string, server string) *SummonerProfile err  {

I think you mean

func GetSummonerByName(name string, server string) (profile *SummonerProfile, 
err error) {

The named return values are initialized with the zero values for their
specific types, which for error is nil.  (Be careful not to shadow
profile or err in the function.)  A bare return without arguments will
return with the current values of the named return variables.

This playground example might be helpful :

package main

import (
"fmt"
)

func Calc(a int) (r int, err error) {
if a == 0 {
err = fmt.Errorf("Bad argument")
return
}
r = 72 / a
return
}

func main() {
fmt.Println(Calc(3))
fmt.Println(Calc(0))
}

...Marvin

-- 
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.


Re: [go-nuts] Handling errors in functions

2017-06-21 Thread Marvin Renich
* Marvin Renich <m...@renich.org> [170621 09:48]:
> package main
> 
> import (
>   "fmt"
> )
> 
> func Calc(a int) (r int, err error) {
>   if a == 0 {
>   err = fmt.Errorf("Bad argument")
>   return
>   }
>   r = 72 / a
>   return
> }
> 
> func main() {
>   fmt.Println(Calc(3))
>   fmt.Println(Calc(0))
> }

I have to add, however, that stylistically, I usually prefer to use
explicit return values, like this:

func Calc(a int) (r int, err error) {
if a == 0 {
return 0, fmt.Errorf("Bad argument")
}
r = 72 / a // I am assuming that calculating r is much more complex
return r, nil
}

This makes my intention clear about when a return value is a "default"
and when it is the result of a calculation.  It also avoids accidentally
returning a non-nil err when I keep re-using err throughout a function
to hold the error returns from function calls made from within my
function.

...Marvin

-- 
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.


Re: [go-nuts] Re: issues about struct align

2017-05-23 Thread Marvin Renich
* Marvin Renich <m...@renich.org> [170523 08:58]:
> Looking more closely at the MSDN docs for FwpmFilterAdd0 and
> FWPM_FILTER0, if I were doing this, I might use «RawContext uint64»
> instead of «ProviderContextKey GUID», which would be properly aligned
> without manual padding.  I would then convert this value manually to a
> GUID if the appropriate flag were set in Flags.  This would, of course,
> depend on my expected use of that context field.

Of course, that would have to be a struct with two uint64 fields so that
it would be the correct size and have the full GUID.

...Marvin

-- 
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.


Re: [go-nuts] Save file handle into struct

2017-06-07 Thread Marvin Renich
* Tong Sun  [170607 15:53]:
> So, Here is the update version. 
> 
> 1. https://play.golang.org/p/txOIO1riwd
> 2. https://play.golang.org/p/_Qk9n0mZPM
> 
> The two version only differ on line 26 & 29. However, the second one will 
> get the following while trying to do *gofmt*:
> 
> 29:2: expected identifier on left side of :=
> 
> 
> And get this when trying to *run*:
> 
> main.go:29: non-name ft.f on left side of :=

Note that := is "short variable declaration" and must have an identifier
or list of identifiers on the left.  It cannot, by definition, have a
member of a struct on the left.

...Marvin

-- 
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.


Re: [go-nuts] os.Args[0] for program executed by go

2017-06-01 Thread Marvin Renich
* Santhosh Ram Manohar  [170601 14:03]:
> 
> 
> On Thursday, June 1, 2017 at 10:45:56 AM UTC-7, Jan Mercl wrote:
> >
> > On Thu, Jun 1, 2017 at 7:41 PM Santhosh Ram Manohar  > > wrote:
> >
> > > Args: []string{"self", "selftest"},
> >
> > Here you explicitly pass arsg[0] == "self" and that's what the program 
> > gets.
> >
> 
> Yes, because I already have the program name in "Path". When Run() calls 
> exec syscall i would expect Args[0] to be program name because from the 
> exec point of view its no different from how shell would invoke it, no ?

The documentation for Args says:

// Args holds command line arguments, including the command as Args[0].
// If the Args field is empty or nil, Run uses {Path}.
//
// In typical use, both Path and Args are set by calling Command.

If you use Command, and then print the Args field, you see the proper
setup for Args.  Try https://play.golang.org/p/phIbvlwa8s

Run is using Path as the command to execute and Args as the argv
argument to the underlying execve call (or corresponding Windows API).
The documentation for execve explicitly says that by _convention_ the
first string in argv (argv[0]) should contain the filename associated
with the file being executed.  However, this is just convention, and the
caller of execve is not required to do so.  Not setting argv[0] (i.e.
Args[0]) to the name of the command will normally get undesired results,
since all well-written programs expect argv[0] to be the command name,
not the first command argument.

...Marvin

-- 
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.


Re: [go-nuts] Timestamp issues

2017-09-15 Thread Marvin Renich
* xana...@gmail.com  [170915 03:16]:
> No the clients are connected to this app through websockets, they are using 
> javascript, following snippet is used to make the countdown:
> let timeLeft = Math.ceil(((timestamp * 1000) - new Date().getTime()) / 1e3)

Okay, so the clients are on different machines, with no guarantee that
the clocks on the server and client machines are synchronized.  Also, I
am guessing (since you did not answer that part of my question), that
you believe the time is off by 3 sec because the client sees a timeLeft
that is 93 sec, when timestamp was generated on the server machine.

Hopefully, the reason the client sees a countdown starting at 93 instead
of 90 (and, perhaps, ending at 3 instead of 0) should now be obvious to
you:  the client and server clocks have a 3-second difference, and you
are taking a time value created on the server and then using it on the
client.

Does this answer your question?

...Marvin

-- 
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.


Re: [go-nuts] "html/dom" alternative to html/template for true separation of concerns?

2017-09-14 Thread Marvin Renich
* Karv Prime  [170913 22:01]:
> It = html/template
> "The purpose" = the one I thought I could use it for and described above.

I'm still not sure you understand the capabilities of html/template.
This playground snippet might help you:

https://play.golang.org/p/_1KSiZbwh-

package main

import (
"fmt"
"html/template"
"os"
)

var Trusted = `This Is Bold`
var Untrusted = `pwnd`

var MyHtml = `
{{.systemContent}}
{{.userContent}}
`

func main() {
var tmpl, err = template.New("").Parse(MyHtml)
if err != nil {
fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err)
os.Exit(1)
}
var data = make(map[string]interface{})
data["systemContent"] = template.HTML(Trusted)
data["userContent"] = Untrusted
err = tmpl.Execute(os.Stdout, data)
if err != nil {
fmt.Fprintf(os.Stderr, "error executing template: %s\n", err)
os.Exit(1)
}
}

You as the programmer get to decide which sources are trusted and which
are not.

If you are happy with goquery, as someone else suggested, that's fine.
But the template package may be simpler to work with and do what you
want.  Note that with template, you can put some, or even most, of your
logic in the template, or you can go the other way around and have only
simple {{.foo}} tags in the template that get replaced with large chunks
of HTML that you generate in your program (which seems to be very close
to what the Template Animation link encourages), or somewhere in
between.

...Marvin

-- 
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.


Re: [go-nuts] Timestamp issues

2017-09-14 Thread Marvin Renich
* dr.ink  [170914 10:26]:
> Hello, I have an issue with generating timestamps in golang, this is how my 
> app works. First the app generates the timestamp like this
> 
> timestamp := time.Now().UTC().Add(time.Second * 
> time.Duration(settings.TimeToLive)).Unix()
> 
> this value is then added to struct and sent to clients, clients then start 
> a countdown to that date.
> 
> Now, the issue is that *sometimes* the generated timestamps do not have the 
> given duration. For example variable *settings.TimeToLive* is set to 90, so 
> the generated timestamp should have +90 seconds to now, but it has +93 
> seconds for example.

The scenario is unclear.  Is the client on the same machine?  In the
same program in a different go routine?

How do you know the generated timestamp is now+93?  Do you have debug
statements to show that the Add() added 93?  At the site where timestamp
is generated or in the client where it is being used?  Do the server and
client have synchronized clocks (or mis-synchronized clocks)?

You are not giving enough detail to get a useful answer.

Also note that a time.Time value (as returned by time.Now) represents an
instant in time; the location (UTC, Local, etc.) only tells how the
value should be presented when formatting it.  time.Now().UTC().Unix()
is identical to time.Now().Unix() and time.Now().Local().Unix(); the
UTC() does not change the instant that the value represents.  Try

var t = time.Now()
fmt.Println(t.Unix(), t.UTC().Unix(), t.Local().Unix())

...Marvin

-- 
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.


Re: [go-nuts] Re: "html/dom" alternative to html/template for true separation of concerns?

2017-09-14 Thread Marvin Renich
* Karv Prime  [170914 11:14]:
> ... - yet 
> there's the disadvantage of the need to put artifacts into the markup which 
> then get replaced by the wanted content

You have to do that anyway, you just use different artifacts.  Each
location where a substitution will occur must be uniquely identified,
whether it is  or
{{.summaryData}}.

If summaryData has any HTML at all, then the programmer and the designer
must coordinate on styles (at least style names) anyway (the Template
Animation post glosses over this point), so there is not even a need for
the  wrapper; just put {{.summaryData}} and let the program supply
any necessary style or class attributes.  The resulting HTML will have
one less unnecessary wrapper element.

I'm not saying the  wrapper can't be in the template if it is
useful for other purposes, but that it is not needed for the template
substitution, whereas it is needed as a placeholder when doing DOM
manipulation.

...Marvin

-- 
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.


Re: [go-nuts] Timestamp issues

2017-09-15 Thread Marvin Renich
* xana...@gmail.com  [170915 12:33]:
> Yes, I have also tried this on separate devices and some were off and some 
> were exact to the second so this is definitely a frontend therefore 
> javascript issue and not an issue with golang. Not sure how to fix it but 
> this is not a question for golang-nuts forum now. Thank you for your time.

I would not say this is a javascript issue; it is really a general
programming issue about how to deal with networked machines having
different clocks.

The simplest, and most likely best, solution is to make sure the server
and all clients synchronize their clocks with an established time
standard, using software such as ntp.

If this is not possible, the problem starts to get hard very quickly,
and depends on many factors, including how important it is for the
client display to be accurate and the range of network latency between
the various clients.

If network latency is typically small, and you don't mind the display
being off by the current network latency, you can have the server send
its idea of the current time, and have the client store the delta and
use that to adjust the displayed value (details left as exercise for the
reader!).

...Marvin

-- 
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.


Re: [go-nuts] Re: "html/dom" alternative to html/template for true separation of concerns?

2017-09-14 Thread Marvin Renich
* Karv Prime  [170914 13:16]:
> I wouldn't agree on "there is not even a need for the  wrapper" part. 
> If the HTML tags are produced entirely by code, it comes with its own 
> issues - suddenly there is a thing that wasn't in the markup - it would 
> probably reduce maintainability. If there's already a file with  class="summaryData">[...] it can be reused as the designer sees fit. 
> Let's, for example, assume 2 cases.

As I said in my previous post, if the  element is useful for the
designers, e.g. to position or align the whole replacement summaryData
(which I am assuming is significantly more complicated than some
unformatted text), then by all means put it in.

The point about not needing the  tags was really more directed at
use cases where you are inserting some simple replacement in the middle
of the content of a larger element, e.g.

  Hello, {{.Name}}, you last logged in on {{.PrevLogin}}.

Doing this with DOM manipulation requires extra  elements around
the items to be replaced.  The snippet above is much easier to read and
maintain than the corresponding HTML with  elements, and produces
smaller, more readable HTML to send over the wire.

The  tag also _may_ not be needed in cases where the replacement
content is significantly larger, contains multiple elements, and a
container is not needed to separate the replacement from elements before
and after it.

> Case 1: Main file has '[...][...]', the module is the 
> aforementioned div with summary data. The coder has to know where to put 
> it. Does it belong directly in main? Is it inside another element? The 
> backend dev doesn't know without input from the frontend devs - so backend 
> devs are involved deeper into the frontend design as they should be.

No, the main file has

  {{.summaryData}}

The program is told where to put it by the designer.

My point was that the designer must use something to identify the
location for the replacement, and there is little difference to the
designer whether the file has

  
or
  {{.summaryData}}

I posit that the second is much easier to recognize as a placeholder for
data that will be supplied later; easier for the designers, easier for
the programmers, easier for outside consultants unfamiliar with the
project, easier for new hires, and easier for management.

...Marvin

-- 
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.


Re: [go-nuts] concurrent write-only to map ok?

2017-10-13 Thread Marvin Renich
* Alex Buchanan  [171013 14:06]:
> Basically, I want to spawn a goroutine per object, objects have unique IDs, 
> and I want each routine to write its results to a shared map. Nothing will 
> be reading from the map while the goroutines are running.

You didn't give much detail, but if the map is map[ID]sometype and each
goroutine is only writing to its own element of the map, you could make
it a map[ID]*sometype.  Assuming the goroutines are all spawned by a
single "main" goroutine, that main goroutine can create the sometype,
assign its address to the map, and pass the *sometype to the goroutine.
Now, only the main goroutine accesses the map.  Accessing the individual
sometype instances does not interfere with any other goroutine, and no
explicit synchronization is needed.

...Marvin

-- 
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.


Re: [go-nuts] Scope of variables with closures

2017-10-11 Thread Marvin Renich
* Marvin Renich <m...@renich.org> [171011 08:19]:
> > >> > //func fibo2() func() (x int) { 
>   ^
> 
> Here, x is a placeholder name within a type literal; it is not within
> the scope of fibo.
   ^

Typo; should be fibo2.

...Marvin

-- 
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.


Re: [go-nuts] Scope of variables with closures

2017-10-11 Thread Marvin Renich
* etienne.da...@gmail.com  [171011 03:14]:
> I was thinking of your answer, and I don't understand when you say:
> 
> > within a func type literal such as `func() (x int)`, the scope of the 
> > parameters and results is restricted to the type literal itself.
> >
> Because the following code works, so the scope of a parameter is different 
> than the scope of a result.
> 
> const N = 10
> 
> func main() {
> f := fibo(0)
> for i := 0; i < N; i++ {
> fmt.Println(f())
> }
> }
> 
> func fibo(x int) func() int {
^

Here, x is in the scope of fibo and during execution of fibo exists as a
variable with that name.  Within fibo it can be bound in a closure
created by fibo.

> y := 1
> return func() int {
> defer func() { x, y = y, x+y }()
> return x
> }
> }
> 
> On Tuesday, 10 October 2017 17:08:49 UTC+2, Etienne Daspe wrote:
> > On Tuesday, 10 October 2017 16:58:43 UTC+2, Ian Lance Taylor wrote:
> >> On Tue, Oct 10, 2017 at 7:22 AM,   wrote: 
> >> > // fibo2 doesn't compile because x is undefined in the function 
> >> returned. 
> >> > //func fibo2() func() (x int) { 
  ^

Here, x is a placeholder name within a type literal; it is not within
the scope of fibo.  This could be rewritten as:

type result func() (x int)
func fibo2() result {

Note that x is neither an argument nor a result of fibo2 (either way the
code is written).  The name x in fibo2 is part of the description of the
type of the result of fibo2, it is not the name of an argument or result
of fibo2.  This is what Ian was saying below.

> >> > //y := 1 
> >> > //return func() int { 
> >> > //defer func() { x, y = y, x+y }() 
> >> > //return x 
> >> > //} 
> >> > //} 
> >>
> >> In the commented out code, x is a result variable, but only for 
> >> `func() (x int)`.  x is not a result variable for fibo2. 
> >>
> >> To put it differently, within a func type literal such as `func() (x 
> >> int)`, the scope of the parameters and results is restricted to the 
> >> type literal itself. 
> >>
> >> Ian 

...Marvin

-- 
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.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-08 Thread Marvin Renich
* Dorival Pedroso  [170908 02:08]:
> The "watch" strategy would, of course, allow us to do the important steps 
> you've mentioned (e.g. clean up and so on).
> 
> For instance:
> watch err != nil {
> // do the important things
> return err
> }

Except that "do the important things" often depends on which step
produced the error.  Now you have a switch statement inside the watch
statement to handle the different "early exit" cases.  Instead of having
individual "do step1; clean up after step1" in a linear sequence, you
have "do step1; do step2..." with all of the separate "clean up after
stepN" in a switch statement in a different place.  You also have
additional code within the "do step1; do step2..." section to allow the
watch statement to determine which switch case to invoke.This is
much easier to get wrong, harder to modify (especially if you have
nested watch statements), and harder to debug.

I believe that the Go devs want to encourage suggestions like yours for
Go 2, but this particular one has already been discussed more than once
on this list.  You have numerous experienced programmers who have all
used languages with similar constructs telling you that it looks good at
the start, but ends up producing much less maintainable code.  Listen to
experience.

In this particular case, it is not the details that are inconsistent
with the basic philosophy behind the design of the Go language, it is
the entire concept of separating "error" handling from "non-error"
handling.  Both are "handling the results" and both belong in the
relative vicinity of the code that produced the results, whether the
results are considered "errors" or "non-errors".

...Marvin

-- 
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.


Re: [go-nuts] Defer with anon func and func literal

2017-09-28 Thread Marvin Renich
* Karan Chaudhary  [170928 08:50]:
> I'm trying to find rationale for this:  why is "defer foo(x)" treated 
> differently than "defer func() { foo(x) }" by the language designers?

Here is what the language spec says:

  Each time a "defer" statement executes, the function value and
  parameters to the call are evaluated as usual and saved anew but the
  actual function is not invoked.

So, in the first case, the address of foo is saved along with the
current value of x.  The variable x is not part of a closure involving
foo.

In the second case, the address of a closure, the anonymous func, is
saved; it has no function arguments to evaluate.  This closure includes
the variable x from the surrounding scope.  So when the deferred closure
is executed, the value of x at this later time is used.

Does this explain it?

...Marvin

-- 
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.


Re: [go-nuts] Errors out of syscall

2017-10-02 Thread Marvin Renich
* Chris Hopkins  [171002 10:52]:
>   out, err := os.Create(potential_file_name)
>   switch t := err.(type) {
>   case *os.PathError:
> switch t.Err {
> case os.ErrNotExist:
>   log.Fatal("Invalid filename", potential_file_name)
> case os.ErrInvalid:
>   log.Fatal("Invalid argument", potential_file_name)
> default :

I think what you are missing is that t.Err is almost certainly a
syscall.Errno, which you can type-switch and then use directly:

switch en := t.Err.(type) {
case syscall.Errno:
switch en {
case syscall.EISDIR:
...
}
default:
... // I don't think os.Create will ever return an error that
// isn't syscall.Errno wrapped as an os.PathError.
}

Of course, this is OS dependent.  However, I think EISDIR is defined for
all supported architectures.

> switch t.Err.Error(){
> case "is a directory":
>   // Case we are trying to catch
>   return
> default:
>   log.Fatalf("Unknown 
> os.PathError\n\"%s\"\n%v\n,Type:%t\nDir:%s\nUrl:%s\n", potential_file_name, 
> t.Err, t.Err, dir_str, fetch_url)
>   }
> }
>   case nil:
> // nothing to see here
>   default:
> log.Fataf("Error is of type %T,n", err)
>   }

...Marvin

-- 
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.


Re: [go-nuts] Errors out of syscall

2017-10-02 Thread Marvin Renich
* Marvin Renich <m...@renich.org> [171002 11:31]:
> * Chris Hopkins <cbehopk...@gmail.com> [171002 10:52]:
> >   out, err := os.Create(potential_file_name)
> >   switch t := err.(type) {
> >   case *os.PathError:
> > switch t.Err {
> > case os.ErrNotExist:
> >   log.Fatal("Invalid filename", potential_file_name)
> > case os.ErrInvalid:
> >   log.Fatal("Invalid argument", potential_file_name)
> > default :

Additionally, os.Create, os.Open, and os.OpenFile all guarantee (via
their documentation and the Go 1 Compatibility Guarantee) that if they
return a non-nil error, it will be of type *os.PathError, so you could,
if you wish, replace the "switch t := err.(type)" with
t = err.(*os.PathError) and if it panics, you can file a bug.
Furthermore, because the current implementation is extremely unlikely to
change, you can simplify even more.  I would write this as:

var out, err = os.Create(potential_file_name)
if err != nil {
var pe = err.(*os.PathError) // let it panic or use the ,ok trick as 
below
var en, ok = pe.Err.(syscall.Errno) // not a Go 1 Compat guarantee, so 
handle failed type assertion
if !ok {
log.Fatalf("Unexpected error from os.Create: %s\n", pe)
}
switch en {
case syscall.EEXIST:
...
case syscall.EISDIR:
...
case syscall.EINVAL:
...
}
}

This code is much more readable than the nested type switch that you are
using.  Note that os.ErrNotExist and os.ErrInvalid are not of type
*os.PathError and os.Create will never return either of them (promised
by Go 1 Compat).

If the !ok test ever succeeds, you know that the implementation of
os.OpenFile has changed.

...Marvin

-- 
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.


Re: [go-nuts] Problems with JSON Marshal/UnmarshalText aand maps

2017-11-28 Thread Marvin Renich
* Henrik Johansson  [171128 07:43]:
> But wouldn't unmarshal just overwrite in case of more trivial keys?
> 
> So pointer receivers on the marshaling methods is better.
> I think I tried it but something else blew up.

While MarshalText can use a value or pointer receiver, it makes no sense
to use a value receiver with UnmarshalText.  The UnmarshalText method
must be able to change the caller's copy of the variable that is to hold
the unmarshalled data.

As for time.Time, if you read its documentation, it says that it holds
both a wall clock time and a monotonic time.  time.Now() returns a
structure that has both values, but some operations (e.g. time.Parse and
time.Time.UnmarshalJSON) return a time.Time that only has a wall clock
time.  t.Round(0) is the canonical way to strip the monotonic time from
a time.Time value t.

So after t := time.Now(); t2 := t.Round(0), t and t2 represent the same
wall clock time, but compare as different, because the t has both wall
clock and monotonic times, whereas t2 only has wall clock time.

So your map with key time.Now() has a key with both times.  When you
marshal it, the marshalled value only has wall clock time.  When you
unmarshal it back to the same map, the unmarshalled time is different
(but represents the same wall clock time) from the existing map key, so
it creates an additional map element with the new key.

If you create your map with keys that only have wall clock times with
UTC location, as in https://play.golang.org/p/BCB3TAZADB, the
unmarshalled key will match the existing key and overwrite it.  If you
remove either .UTC() or .Round(0) or both from that code, you will
notice that the map keys are different, and you end up with two values
in the map after unmarshalling.

...Marvin

-- 
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.


Re: [go-nuts] Surprise About How Method Receivers Work

2017-12-18 Thread Marvin Renich
* jlforr...@berkeley.edu  [171217 15:33]:
> Here's what I believe is the explanation. The book says (slightly
> edited) "If the receiver p is a variable of type Path but the method
> requires a *Path receiver, we can use this shorthand:
> 
> p.pr1()
> 
> and the compiler will perform an implicit  on the variable.". This
> explains what happens when pr1() is called.
> 
> I'm surprised that Go would include this implicit behavior because type
> conversions are generally required to be explicit.
> 
> type Path []byte
> 
> func (p *Path) pr1() {
>  fmt.Printf("%s\n", *p)
> }
> 
> func (p Path) pr2() {
>  fmt.Printf("%s\n", p)
> }
> 
> func main() {
>  var p Path
> 
>  p = Path("abc")
>  p.pr1()
> 
>  p = Path("abc")
>  p.pr2()
> }

I think you are looking for this statement in the Go spec:

  A method call x.m() is valid if the method set of (the type of) x
  contains m and the argument list can be assigned to the parameter list
  of m. If x is addressable and 's method set contains m, x.m() is
  shorthand for ().m()

This can be found at https://golang.org/ref/spec#Calls near the bottom
of that section.  This was clearly an intentional design decision.

...Marvin

-- 
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.


Re: [go-nuts] Re: Learning Go: suggestions for code review?

2017-12-13 Thread Marvin Renich
* Ben Hoyt  [171213 09:45]:
> > One minor thing may be that instead of using os.Args, I would use the 
> > flag's package.
> 
> Good call.

If you like the Plan 9 convention of -short style options, the standard
library's flag package is good and simple.  If you want the GNU
-l/--long-option convention, you will need to search for one of the many
other third-party flag packages, as the standard library flag package
doesn't support this.

For projects that only require simple argument parsing, but you want to
be able to use --long-option style, there is nothing wrong with ignoring
the existing packages and writing your own ParseArgs function.  For
simple cases with a few options, a robust implementation that allows
-l value, --long-option=value, and --long-option value is only about
30-40 lines of code.  For me, the trade-off between 40 loc and reliance
on a third-party package leans heavily toward the 40 loc.

...Marvin

-- 
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.


Re: [go-nuts] What are Parse Html token methods for email templates in golang?

2017-11-10 Thread Marvin Renich
* Josh Kamau  [171110 03:47]:
> You can use 'with'  to achieve what you want.
> Take a look at this example
> 
> https://play.golang.org/p/incDGEmUJK
> 
> On Wed, Nov 8, 2017 at 12:03 PM,  wrote:
> > I could not found such token system in golang or any library supporting
> > such format. Can anyone please tell how can I achieve to create such
> > tokens. There should be no dot before the attribue. either it should be
^^
> > only the attribute like {{Name}} or like {{ test.name }}.

This is not how the template package works.  You must use the dot to
signify that the name comes from the data supplied to the Execute method
(e.g. a field, key, or method of the data).  An identifier without a
preceding dot is either a keyword used to specify an action (e.g. if,
range, or with), or a function name.

You can use {{.test.name}}, or you can use {{with .test}} and then
{{.name}} as Josh shows above.

It is unclear if you have found the correct documentation, where this is
described.  In the documentation at [1], which describes things specific
to html/template, the second paragraph in the Overview directs you to
[2], which describes the text/template package, which is the basis for
the html/template package.

In the text/template documentation, see Actions[3] and Arguments[4] for
more details about what items require a preceding dot.

If you want a much simpler templating system, which only allows simple
substitutions and does not require the dot, it would be a fairly easy
package to write.

...Marvin

[1] https://golang.org/pkg/html/template/
[2] https://golang.org/pkg/text/template/
[3] https://golang.org/pkg/text/template/#hdr-Actions
[4] https://golang.org/pkg/text/template/#hdr-Arguments

-- 
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.


Re: [go-nuts] Puzzle: make a sync.Once fire more than once

2017-11-20 Thread Marvin Renich
* roger peppe  [171120 09:35]:
> This trick is used in the standard library (see net.http.envOnce.reset), and 
> for
> testing purposes it's just about OK (though still dubious IMHO) but you should
> never use it in production code, as you're writing atomic state with 
> non-atomic
> operations.

When I read this, I was afraid something might be wrong in the net.http
code.  But by looking at the code, it is clear that what you meant by
"this trick" was replacing an existing instance of sync.Once with a new
instance, as opposed to copying an already-used instance of sync.Once
and using both the copy and the original.

The latter is completely broken.  The former might be safe as long as
the assignment to the variable containing the Once is properly
synchronized with any other assignments or reads.  It is not clear from
the code in transport.go whether any synchronization is necessary; there
is none in envOnce.

...Marvin

-- 
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.


Re: [go-nuts] Puzzle: make a sync.Once fire more than once

2017-11-20 Thread Marvin Renich
* Carl Mastrangelo  [171119 19:25]:
> I was playing around with a puzzle trying to break the sync package and 
> found something cool.   Can you think of a definition for f that causes 
> once.Do to execute the argument more than once?
> 
> package main
> 
> import (
> "sync"
> )
> 
> func main() {
> var once sync.Once
> var f = // ...
> 
> once.Do(f)
> }
> 
> HIGHLIGHT BELOW FOR ANSWER
> 
> package main
> 
> import (
> "fmt"
> "sync"
> )
> 
> func main() {
> var once sync.Once
> var f func()
> times := 9
> f = func() {
> if times == 0 {
> return
> }
> times--
> fmt.Println("Called")
> oldonce := once
> * = sync.Once{}
> once.Do(f)
> once = oldonce
> 
> }
> once.Do(f)
> }

The call to «once.Do(f)» inside f is on an explicitly new instance of
Once that is completely independent of the original, as well as
independent of the other instances of Once in the recursive calls to f.

I do not understand why you believe that this shows once.Do invoking its
argument more than once.

The implementation of Once uses a uint32 and a sync.Mutex.  A Mutex is
not safe to copy after it has been used (this is explicitly stated in
the Mutex documentation), thus Once is not safe to copy after it has
been used.  This was clear to me, but perhaps this should be added to
the sync.Once documentation.

You are creating new instances of Once which are copies of other
instances both at «oldonce := once» and «once = oldonce».  This makes
calling once.Do(f) more than once outside of f a violation of the
sync.Mutex contract.  The correct way to use Once is to pass around a
pointer to an instance, which ensures all invocations of Do use the same
underlying uint32 and Mutex.

I believe, though I haven't proved it to myself, that if multiple go
routines use the same instance of Once, but one of the go routines makes
a copy of that instance, the copy could start out with its Mutex in a
locked state with nothing to unlock it.

...Marvin

-- 
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.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-10-31 Thread Marvin Renich
* oju...@gmail.com  [171031 12:34]:
> Ian, with all due respect, I beg to differ.
> 
> Let's look at that example posted 5 years back:
> 
> http://play.golang.org/p/Isoo0CcAvr
> 
> Yes, that is the proper behavior according to the rules, we have a FAQ 
> entry, fine, but ... put simply: that makes no sense. Why? Because we, the 
> users, expect the code to work the other way. That is a big surprise and we 
> don't need the tool creating surprises for us, much to the contrary.

I beg to differ.  I, a user, very much expect the current behavior and
would be very surprised if it worked the way you are suggesting.

Ian's msg gives good reasons why it would be wrong to change the
behavior, even if we could go back in time to before the release of Go
1 and the Compatibility Guarantee.

...Marvin

-- 
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.


Re: [go-nuts] float accuracy when calculating Fibonacci numbers

2018-04-30 Thread Marvin Renich
* Michael Jones  [180430 13:54]:
> Andrey, that's great!
> 
> On the Fibonacci series evaluation, let's make sure that we're all doing
> the same calculation. For completeness and safety, let's skip all library
> values and derived values. Here are more-than-sufficient versions of the
> three constants in Yuval's code:

I think both of you missed the point of my message.  This has nothing to
do specifically with Fibonacci numbers.  The problem is simply that
math.Pow does not give as precise answers as the C++ std lib.  Look at
https://play.golang.org/p/_gVbAWjeoyW and notice that the result from
math.Pow is off in the 15th decimal digit.  Both the bigPow and the C++
pow library function are good until the 17th digit, which is what is
expected.  (Actually, I thought bigPow might do better, with the
specified precision of 300.)  I trust the Mathematica answer to be
correct to the number of digits printed (last digit rounded).

There is no math.Phi involved here, except that the hand-typed constant
happens to be as close as you can get to Phi in a float64 (but this is
not relevant to the test).

...Marvin

-- 
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.


Re: [go-nuts] float accuracy when calculating Fibonacci numbers

2018-05-01 Thread Marvin Renich
* andrey mirtchovski  [180430 17:41]:
> > math.Pow does not give as precise answers as the C++ std lib.
> 
> math pow doesn't just multiply X by itself Y times, it uses a
> different algorithm:
> 
> https://golang.org/src/math/pow.go#L40

Sure, I understand that.  However, the current algorithm used by
math.Pow produces results that are far enough from the true value that
it is worth opening an issue.

> it would perhaps make sense to quantify the error margins that this
> algorithm introduces.

As far as the OP's question about why he needs to round in Go but
truncate in C++, I am not convinced that the error in math.Pow is
significant.

Binet's formula, given exact (non-computer limited) values and
calculations, will give exact integral values for the Fibonacci numbers.
If you start with the assumption that using Binet's formula with IEEE
floating point arithmetic will give results that are close enough to the
correct value that you will have no trouble determining which integer is
the right one, then the assumption that the error is between -0.5 and
+0.5 is much more reasonable than the assumption that the error is in
the range [0, 1).

It is certainly plausible that one could prove that the error will
always be positive, given known characteristics of the computer
program's implementation of pow, among other things, but without such
analysis, assuming that truncating the result will always give the
correct answer is naive.

I posit that the OP's C++ implementation only works because of specific
characteristics of C++ library pow function, the last-mantissa-bit
rounding of the value used for phi, and other aspects of the
implementation that have not be adequately analyzed to be certain that
the error is always positive.

In short, the OP's assumption that the algorithm in his C++ program is
correct is wrong; it just happens to work for the values tested.  Both
the C++ and the Go program should round the floating point result to get
the correct integer.

...Marvin

-- 
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.


Re: [go-nuts] float accuracy when calculating Fibonacci numbers

2018-04-30 Thread Marvin Renich
* Yuval Lifshitz  [180430 02:02]:
> It seems like go and C++ are doing something different regarding floating 
> point arithmetic, but I cannot say one is better than the other. It is just 
> the that C++ consistently overshoots (hence truncation work), and go 
> consistently undershoots (this is why rounding is needed). For example, in 
> C++:
> 
> F(59) = 956722026041.002
> 
> And in go, it is:
> 
> F(59) = 956722026040.999878

/* aside - this doesn't seem relevant to this problem except perhaps
 * the implementation of math.Pow, but...

The 8087 and successor FPUs (e.g. amd64 class processors) have an 80-bit
extended precision format which is used for all calculations.  More than
a couple decades ago, when I was working on implementation of floating
point in an APL interpreter (written in C, C++, asm), the IEEE 754
standard did not specify how compilers should handle precision of
intermediate results, and the compiler we were using would only convert
from 80-bit to 64-bit when it needed to store a result back into memory.
This could easily give different results depending on how the floating
point expression was broken up.  E.g. a = (b + c) - d could give a
different result than a = b + c; a = a - d.

The standard has, since then, attempted to address this, but I have not
studied this at all, so I don't know what is expected of C or Go.

*/

Back to your specific problem:

Go:  psi = -0.61803398874989490
C++: psi = -0.61803398874989479

Go:  math.Pow(math.Phi, float64(33)) = 7.8811960012666e+06
C++:pow(phi, 33) = 7.8811960013597e+06

And using hand-typed constants:

Go:  math.Pow(1.61803398874989490, 33.0) = 7.8811960012666e+06
C++:  pow(1.61803398874989490, 33.0) = 7.8811960013597e+06

So indeed there is a difference between math.Pow in Go and pow in C++.
I would say to file an issue.  I have no idea which answer is closer to
correct, but using math/big and multiplying 1.61803398874989490 by
itself 33 times with a result precision of 80, I get
7.8811960013562e+06.

Note:  in Go, math.Phi is an untyped constant with precision greater
than float64.  Adding  var phi float64 = math.Phi  and replacing
math.Phi everywhere else with phi did not change anything except the
value of psi (which then matched the C++ value).  The C++ version of psi
is definitely farther from the "true" value, but as Michael said, the
error in pow(psi, n) is swamped by the value of pow(phi, n).

...Marvin

-- 
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.


Re: [go-nuts] Re: Nil Channels and Case Evaluation

2018-01-24 Thread Marvin Renich
* dc0d  [180124 14:44]:
> 
> >
> > If the channel is nil, there's nothing to lock. But also, there's no 
> > sending happening.
> >
> 
> So first the payload is computed and then the nil check happens?

To add to what Axel said, it would be inconsistent to only evaluate the
LHS if the RHS was non-nil.  Just like in the select case.  Consider

foo_returns_channel() <- goo()

It should be determinable at the time the code is written (rather than
when it is executed) whether goo() will be evaluated or not.

...Marvin

-- 
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.


Re: [go-nuts] why can't change map when in for range statements?

2018-01-16 Thread Marvin Renich
* sheepbao  [180115 21:24]:
> I wrote this code, and why `map=nil` don't stop the loop?
> 
> func mapTest() {
> for k, v := range m {
> println(k, v)
> m = nil
> }
> }
> 
> output:
> 
> 1 1
> 
> 2 2
> 
> I don't understand when I set  `m = nil`, the loop is not stop. m doesn't 
> seem to be affected.

While Go does not have any "reference" types, maps have something
similar to reference semantics.  What is stored in a map variable can be
thought of as a pointer to the map data (I believe it is really several
pointers in a struct, but we don't need that level of detail for this
explanation).  The value of variable m is evaluated once, giving a value
that represents a map.  Changing the variable m in the loop (by
assigning it a completely new value) does not change the map being used
by the loop.  This is what «m = nil» is doing; m no longer refers to the
same map data being held by the loop.

However, using the original variable m to change the map value (because
m and the value held by the loop refer to the same data) can change the
keys and values which are seen by the loop.  «delete(m, 2)» modifies the
same map data that the loop is using.

Note at https://golang.org/ref/spec#For_statements under "For statements
with range clause" it says:

  3. The iteration order over maps is not specified and is not
 guaranteed to be the same from one iteration to the next. If a map
 entry that has not yet been reached is removed during iteration,
 the corresponding iteration value will not be produced. If a map
 entry is created during iteration, that entry may be produced
 during the iteration or may be skipped. The choice may vary for
 each entry created and from one iteration to the next. If the map
 is nil, the number of iterations is 0. 

So, adding new map elements within the for statement may or may not
include those elements in a subsequent iteration of the for statement.

The key point is whether you are changing the contents of the variable
in the range expression or the value obtained from that variable.

...Marvin

-- 
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.


Re: [go-nuts] how to add items to an array without append function.

2018-01-12 Thread Marvin Renich
* pradam  [180112 01:45]:
> I'm Newbie to golang,

Welcome to Go!  Many newbies often use "golang" rather than "Go" as the
language name, and most old-timers usually ignore this incorrect usage,
but golang is an artifact of the web site's hostname, golang.org.  Also,
using golang in web searches for Go language information can help make
the results more specific to the computer language rather than other
uses of "go".  However, in normal conversation, it is correct to use
"Go" for the name of the language.

A very good introduction to Go can be found at the Go Tour
«https://tour.golang.org/».

> var m []int   //array declaration

First, m is a slice of int, not an array of int.  An array is a type
that has a fixed number of elements.  A slice is a view into an array
that can vary in size.  An array would be declared with an explicit
size, as

var a [3]int

A very good explanation of slices and arrays can be found at
«https://blog.golang.org/go-slices-usage-and-internals».

> m = {1,2,3,4,5,6,7} // this throws error

The left side of the assignment above is an attempt to specify a
composite literal.  The correct syntax is

m = []int{1, 2, 3, 4, 5, 6, 7}

In other words, you must specify both the literal's type, []int, and its
value, {1, 2, 3, 4, 5, 6, 7}.  You could do the same for the array a
declared above (note the explicit size in the type; it must match the
size in the original declaration):

a = [3]int{23, 29, 31}

This is described in the language specification at
«https://golang.org/ref/spec#Composite_literals».

The complete language spec is extremely short compared to the specs for
most other computer languages.  Once you have completed the Go Tour and
have played with Go for a little bit, it is probably worth your time to
read the entire spec.

> so I have declared an array which takes only int items,
> 
> so I can append items to it with append function.:
> 
> m = append(m, 1,2,3,4,5,6,7,8,9)
> 
> but I want to insert items without using append function.

Again, the above blog entry about slices should help you understand how
to use slices and arrays more effectively.  The Go language is designed
to make it easier to reason about when memory is being allocated for a
new value than in dynamically typed languages such as Python or
JavaScript.  Because of this, an explicit function call to append is
necessary when appending to a slice might need to allocate a larger
backing array.

I hope this explanation and the above links help you to better
understand this terrific language!

...Marvin

-- 
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.


Re: [go-nuts] Re: Is my understanding on numeric literals right?

2018-01-12 Thread Marvin Renich
* 'Axel Wagner' via golang-nuts  [180112 05:11]:
> Hm, this thread has actually opened up a question I don't have a good
> answer to.
> 
> On Fri, Jan 12, 2018 at 9:47 AM,  wrote:
> > an untyped interger literal/constant is representable float64 type for
> > sure.
> > an untyped floating-point literal/constant is representable complex128
> > type for sure.
> >
> 
> Now, this is where I don't have a good answer. The answer to both of these
> is actually "no", but the compiler still allows it.
> 
> For example, the integer constant (1<<54)+1 is not representable as a
> float64, contradicting the first statement.
> Also, the floating-point constant math.Pi is not representable as a float64
> and thus can't be represented by a complex128 either (as that has a float64
> real part).
> In both cases, the compiler rounds to the nearest representable value, but
> does not complain. I tried reading in the spec why exactly, but so far I
> couldn't.

Perhaps the following explains the intent (found at
https://golang.org/ref/spec#Constants):

  Implementation restriction: Although numeric constants have arbitrary
  precision in the language, a compiler may implement them using an
  internal representation with limited precision. That said, every
  implementation must:

∙ Represent integer constants with at least 256 bits.
∙ Represent floating-point constants, including the parts of a
  complex constant, with a mantissa of at least 256 bits and a
  signed binary exponent of at least 16 bits.
∙ Give an error if unable to represent an integer constant
  precisely.
∙ Give an error if unable to represent a floating-point or complex
  constant due to overflow.
∙ Round to the nearest representable constant if unable to represent
  a floating-point or complex constant due to limits on precision.

  These requirements apply both to literal constants and to the result
  of evaluating constant expressions. 

It seems that by "representable", when converting to a floating point
type, the spec means "can be rounded to, but must not overflow".  I
think the last bullet makes this explicit (i.e. every implementation
"must"...round to the nearest...).

...Marvin

-- 
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.


Re: [go-nuts] strings.Split behavior

2018-02-20 Thread Marvin Renich
* buc...@gmail.com  [180220 15:51]:
> package main
> 
> import (
>   "fmt"
>   "strings"
> )
> 
> func main() {
>   s := "this/that there/here that/this"
>   tmp := strings.Split(s, "/")
>   fmt.Println(tmp)
>   for _, s1 := range tmp {
> if strings.Contains(s1, "that") {
>   fmt.Println(s1)
> }
>   }
> }

Look at https://play.golang.org/p/2tz2asuZcGc where I have changed

fmt.Println(tmp)
to
fmt.Printf("%#v\n", tmp)

and I think you will understand that tmp does not contain what you
thought it did.  Split splits the string at "/", not at "/" and " ", so
tmp contains four strings, "this", "that there", "here that", and
"this".

...Marvin

-- 
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.


Re: [go-nuts] Type "slicing"

2018-08-01 Thread Marvin Renich
* Paul J. Lucas  [180728 14:43]:
> First, please forgive the length of the example code.  It's as small a
> distillation of my original code as I could manage that still
> illustrates the issue.  The code is here:
> 
>   https://play.golang.org/p/MjyFize1iOW
>
> [trimmed]
> 
> The problem is that root's activeChild 'C' is of type:
> 
>   *struct { main.CoreParent; S main.CoreState }
> 
> When the code calls CoreParent.Enter() that calls CoreState.Enter(),
> the type of the receiver 's' is converted into:
> 
>   *main.CoreState
> 
> Then 's' is passed as an argument to switchActiveChildTo() that gets
> assigned back to root's activeChild (which is 'C').  The type of
> activeChild changes even though it's the same object!  It's as if its
> type was "sliced" down to its "base" type.
> 
> When Exit() is eventually called on 'C', only CoreState.Exit() is
> called since it's type is now *main.CoreState rather than the original
> struct.
> 
> Is such type "slicing" expected behavior?  (This was a most annoying
> bug to track down.)

I haven't seen any replies to your question, so I will try to help you
understand what is happening.  Indeed, your analysis that passing the
receiver of the CoreState.Enter method to parent.switchActiveChildTo
causes root.activeChild to change from one concrete type to another is
correct.

It appears that you are trying to use interfaces and embedding to
achieve inheritance and virtual methods, but Go does not have
inheritance or virtual methods.  Calling a method of an embedded field
on the containing struct is the same as calling the method on the
embedded field; the receiver is that of the embedded field not of the
containing struct.  E.g.

type E struct { }

func (e E) Foo() { }

type T struct {
E
a int
}

var t T

Calling t.Foo() is identical to calling t.E.Foo(), and either way, Foo
has no intrinsic ability to access t.a.

Note that a Parent is a State with an additional method.  If a Parent
has State independent of its children, implement ParentState and
LeafState, each with their own implementation of the State interface,
giving ParentState the additional method required by Parent.

On the other hand, if a Parent does not have State of its own, but
merely exposes the State of its active child, don't include CoreState
(from your code, or CommonState from my code below) as a field of the
concrete type implementing Parent, but implement the State interface as
covers that call their counterparts on the active child.

If there is a large set of common data that all concrete types
implementing State will have, you can use embedding for the data, but
not for methods that would, in a language like C++, be virtual.  E.g.

type CommonState struct {
name   string
parent Parent
}

func (c *CommonState) Name() string {
return c.name
}

func (c *CommonState) Parent() Parent {
return c.parent
}

type LeafState struct {
CommonState
}

func (l *LeafState) Enter(msg string) {
// implementation for LeafState
}

func (l *LeafState) Exit(msg string) {
// implementation for LeafState
}

type ParentState struct {
CommonState
children[]State
activeChild State
}

func (p *ParentState) Enter(msg string) {
// implementation for ParentState
}

func (p *ParentState) Exit(msg string) {
// implementation for ParentState
}

func (p *ParentState) switchActiveChildTo() {
// implementation for ParentState
}

Because the Name and Parent methods of a type implementing State do not
need to have access to anything except fields in CommonState, these
methods can be safely defined on CommonState which can be embedded,
promoting these methods.

Note that CommonState does not implement all of the State interface, but
when embedded, its methods can be used by the containing struct as part
of the State interface.

One further comment:  you have CoreMachine embedding Machine.  This is
extraneous.  CoreMachine implements Machine by virtue of having all the
necessary methods.  Embedding Machine causes CoreMachine to reserve
memory for a field holding a Machine interface variable which is never
used.

...Marvin

-- 
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.


Re: [go-nuts] Re: looking for a flexible file path resolver

2018-08-07 Thread Marvin Renich
* DrGo  [180806 18:37]:
> There are situations where you need to check (and report back to the user) 
> for file existence no matter how you do that (using Stat or by attempting 
> to open or create it). 

I agree completely.  However, doesn't os.Stat do what you want here
simply and portably?  If not, what would you like from such a function?
Note that path canonicalization is orthogonal to this.

> There are several issues with the approach you described, which is 
> essentially what fileapth.Abs() does, some are discussed here 
> https://github.com/golang/go/issues/17084
>  and here 

The discussion in the first appears to come to the conclusion that in
some cases it is not possible to get a unique canonical name.  Two
different Windows UNC or network paths can point to the same file in a
way that it is not possible for the local machine to be able to
determine this.  The same is true for remotely mounted file systems on
Linux (e.g. NFS or CIFS mounts).

Hard links (both Windows and Linux) are problematic at best.  You could
arbitrarily say that the alphabetically first name was the canonical one
(or use other criteria), but in order to determine all possible names
still requires (worst case) traversing the entire file system directory
structure; from a performance POV, I would not want to do this.

The second link really just describes Java's getCanonicalPath and
related functions, but doesn't really say much else.  The Java doc for
this claims to return a "unique" name, but says nothing about how that
is done for either of the two cases described above.  This is not the
only place where the Java documentation left me wondering how it handled
edge conditions.

A simple test shows that it fails to recognize that a single file with
two hard links in the same directory are the same file.  This is not any
different from failing to replace symbolic links.

So the real question is what are you trying to accomplish with a
canonicalization function?  Are you simply looking for
Abs(EvalSymlinks(path)) except with a guarantee in the documentation for
EvalSymlinks that says both the 8.3 and long file names for the same
file will give identical results?  What transformations do you want it
to perform and what transformations are acceptable to ignore?

* DrGo  [180806 02:00]:
> Thanks,
> filepath.Abs does some of what I want, but as far as I could tell, it does
> not handle resolving relative paths

Can you give an example of how it does not handle relative paths the way
you would like?

I'm having trouble identifying what you believe are the shortcomings of
the simple solutions provided in this thread and the link you gave
above.

...Marvin

-- 
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.


Re: [go-nuts] why my program will panic?

2018-08-14 Thread Marvin Renich
* sheepbao  [180814 10:53]:
> Thank you for your detailed answer.
> I thought it would crash in this line (b.Z = "zz") of code. But it dose not 
> happen and the program print "zz".
> I don't understand why this program crash in return, not in b.Z = "zz". 
> Because I agree with your opinion,  The field Z of (*b) is beyond the 
> memory that was allocated 
> on the heap or reserved on the stack for a.

It does not crash when assigning to b.Z because b.Z references valid,
writable memory.  It overwrites what some other part of the code wrote
there for a different purpose.  It is not until the incorrect value is
read and used for the original intended purpose that incorrect behavior
can be noticed.  If nothing ever reads from that location afterwards,
than no incorrect behavior can be observed.

It might crash when assigning to b.Z if that memory location is not
writable or is not within the program's address space.  This could
happen, for instance, if the memory allocated for a were at the very end
of the program's address space.  This is extremely unlikely under most
circumstances.

Once you use unsafe to convert a pointer from one type to another, you
become responsible for ensuring that your use is appropriate; the
compiler no longer attempts to keep track of the memory to which the
unsafe pointer points.

...Marvin

-- 
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.


Re: [go-nuts] Re: go/format ouputs spurious newlines

2018-08-14 Thread Marvin Renich
* n...@mit.edu  [180814 11:43]:
> The documentation can be interpreted as you say.

I do not see how you can interpret it otherwise.

> If the resulting AST is subsequently inserted into a larger AST and then 
> serialized, the source that is output can be syntactically invalid.
> 
> It is unexpected (and I believe unreasonable) that serializing an AST can 
> produce code that can't be parsed.

If you insert an ast.Expr that was given to you with documented
deficiencies, I do not see why you would expect otherwise.

This sounds like a difference between what you want and what the package
is documented to do.  I.e. a feature request.

> There is no API for invalidating the Pos information of an AST.  In order 
> to make my application work, I needed to implement a function which copied 
> an entire AST except for its Pos information 
> (https://raw.githubusercontent.com/MarkNahabedian/Goshua/master/rete/rule_compiler/nopos.go).
> 
> 
> Issue filed:
> https://github.com/golang/go/issues/26986

This seems like the correct approach to me, though I still think your
wording implies something wrong with the documentation and/or
implementation, as opposed to requesting an improvement to the design (I
do believe what you are asking for would be an improvement).

...Marvin

-- 
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.


Re: [go-nuts] Re: looking for a flexible file path resolver

2018-08-06 Thread Marvin Renich
* DrGo  [180806 02:00]:
> Thanks,
> filepath.Abs does some of what I want, but as far as I could tell, it does 
> not handle resolving relative paths

Does this code help out?

if filepath.IsAbs(somepath) {
somepath = filepath.Clean(somepath)
} else {
var wd, err = os.Getwd()
if err != nil {
// Handle error
}
somepath = filepath.Join(wd, somepath)
}

It isn't much more code to handle an optionally provided default
directory in place of the current working directory.

You mentioned checking if a file must or must not exist.  Usually, doing
so before attempting to actually open or create the file is at best
redundant and at worst the wrong thing to do.  The correct way to do
this is almost always to use os.OpenFile with the appropriate flag (e.g.
os.O_CREATE and/or os.O_EXCL), and handle the error.

The reason is that between checking for existence and actually opening
or creating the file, the file may be created or deleted.  OpenFile will
give you an error if your desired condition fails and an open file if it
succeeds, and it will be atomic (at least to the best of the
capabilities of your OS/filesystem combination).

...Marvin

-- 
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.


Re: [go-nuts] Re: go/format ouputs spurious newlines

2018-08-14 Thread Marvin Renich
* n...@mit.edu  [180814 09:47]:
> The documentation for parser.ParseExpr says that the position information 
> in the AST it returns "is undefined".  I opserved the result as having 
> position information.  This looks like a bug.
> 
> https://play.golang.org/p/tpzqDF3EZ_S
> 
> demonstrates this bug.

Why would you say this is a bug?  The documentation explicitly says the
position information is "undefined".  Undefined means that you might get
a value, but the value will be nonsense.  The value might coincidentally
be relevant, but you cannot rely on it because you will not be able to
determine whether it is nonsense, coincidentally relevant and correct,
or coincidentally relevant and incorrect.

Obtaining a coincidentally relevant and correct value for something that
is defined to be "undefined" is not a bug; it just happens sometimes.

"Undefined" may also be used when the current code returns something
correct, but the authors wish to reserve the right (i.e. not break Go 1
Compatibility) to change the implementation in a way that does not give
a meaningful value.

...Marvin

-- 
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.


Re: [go-nuts] why my program will panic?

2018-08-14 Thread Marvin Renich
* sheepbao  [180813 23:45]:
> go version
> go version go1.10.2 darwin/amd64
> 
> test code:
> 
> func TestPoint(t *testing.T) {
> type A struct {
> X int
> Y string
> }
> type B struct {
> X int
> Y string
> Z string
> }
> 
> a := A{X: 2, Y: "yy"}
> b := (*B)(unsafe.Pointer())
> b.Z = "zz"
> 
> fmt.Printf(" z: %v\n", b.Z)
> return
> }

Enough bytes are allocated for a (of type A).  It doesn't matter whether
they are on the stack or on the heap.  Now you use unsafe to make b a
pointer to type B that points to the same memory location where a was
allocated.  The field Z of (*b) is beyond the memory that was allocated
on the heap or reserved on the stack for a.  Neither the compiler (for
stack-reserved a) nor the runtime (for heap-allocated a) has made any
provision for ensuring that the memory immediately beyond a is not used
for anything else.  Writing to b.Z overwrites memory to which b has no
claim.

Both this code and the change in your subsequent message are simply
wrong.  Whether it crashes or not depends on the legitimate "owner" of
the memory at b.Z.  If it is a return address on the stack, a crash is
almost certain.  If it is memory on the heap that has not been allocated
yet, and will never be allocated in such a simple program, you might not
see any evidence that the code was written incorrectly.

...Marvin

-- 
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.


Re: [go-nuts] Character Replacement/Algorithm for Replacement

2018-08-30 Thread Marvin Renich
* Michael Jones  [180830 11:44]:
> The task to "translate a string through a table" is common. It is a single
> computer instruction (TR) in the IBM 360 and was extended over time with
> related instructions for conversion in and out of UTF-8, testing before and
> after translation, and expanded character sizes. Tamás Gulácsi's approach
> would be mine too.

Wow, that brings back memories!  The x86 has xlat as well, which can be
used with lodsb and stosb for efficient string translation.  The
question is whether the go compiler will produce optimized code using
these instructions.

I was not disagreeing with Tamás.  My point was simply that without
benchmarking, or prior in-depth knowledge of both how the Go compiler
translates these constructs to assembly and the characteristics of the
processor/motherboard/memory bus, it is hard to say which Go algorithm
is the fastest for the OP's data.

...Marvin

-- 
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.


Re: [go-nuts] Re: Nil Channels and Case Evaluation

2018-01-23 Thread Marvin Renich
* dc0d  [180123 08:45]:
> Can anybody help me understand the reason? (It's in the spec. That's not 
> the reason)
> 
> On Sunday, December 31, 2017 at 10:14:31 AM UTC+3:30, dc0d wrote:
> >
> > Assume there is this select statement:
> >
> > for {
> > select {
> > // ...
> > // ...
> >
> > case rcvd <- first():
> > }
> > }
> >
> >
> > The rcvd channel will be set to nil or a chan value, by it's own case or 
> > other cases.
> >
> > If the rcvd channel is nil, that case should have no effect. But even 
> > when rcvd channel is nil, the first() function will be called.
> >
> > I did not expect that. Why is that so?

There are several candidate designs for this.  Here is my analysis of
the choices that I think are most worthy of consideration:

1.  (The current spec)  Evaluate all channel operands (send and receive)
and all expressions for values to be sent.  Choose one of the
communication operations that is ready to proceed and do it.

2.  Evaluate all channel operands.  For all non-nil send channels,
evaluate all expressions for values to be sent.  Choose one of the
communication operations that is ready to proceed and do it.

3.  Evaluate all channel operands.  Choose one of the communication
operations that is ready to proceed.  If it is a send operation, now
evaluate its value expression.  Perform the operation.

It is unclear to me whether you were expecting (2) or (3), but I don't
like either of these.

I do not like (2) because it is not determinable until execution of the
select statement which expressions for send operations will be executed.
Some values that will not be sent may be evaluated even though they will
not be used, while others might not be evaluated.  This can vary from
one execution of the select statement to another within the same
invocation of the program.

I do not like (3) because, in order to ensure that the communication
operation that was chosen is still ready to proceed after evaluating its
value to be sent, the channel must be locked during evaluation of the
value, blocking other go routines that try to use the channel.  This
might take any amount of time (e.g. tens of minutes, or even hours).
This goes completely against the design principles and goals of
channels.

Thus (1) is the clear winner.  Did I miss the design that you were
expecting?

...Marvin

-- 
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.


Re: [go-nuts] How to bufio.Write with a length specified?

2018-01-18 Thread Marvin Renich
* Peng Yu  [180118 18:37]:
> Dan & Bruno,
> 
> I didn't realize that it is as simple as that :) Thanks.
> 
> Does it involve any extra copy of the byte slice? Or f.Write literally
> access the memory of d and only access 2 bytes of data for writing to
> the buffer?

The blog entry https://blog.golang.org/go-slices-usage-and-internals
will give you some good info about this.

...Marvin

-- 
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.


Re: [go-nuts] Re: panic propagation can be blocked by blocking defer function

2018-04-02 Thread Marvin Renich
* 'Bryan Mills' via golang-nuts  [180402 15:10]:
> This is indeed a subtle pattern, but it's not clear to me how often it 
> comes up in practice, and preventing deferred function calls from blocking 
> could result in all kinds of other unwanted side effects.

I'd like to point out that the problem is not specific to defer during
panic; the exact same problem can occur when executing deferred code
during a normal return.  It is also the same as putting an infinite loop
somewhere else that you did not intend (i.e. not in a defer).

I don't think the language spec (or implementation) needs to have any
special safeguard for an unintended infinite loop just because it
happens during deferred code while panicking.

...Marvin

-- 
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.


Re: [go-nuts] Re: About a channel detail, bug, defect, or intended?

2018-03-26 Thread Marvin Renich
It seems that you understand why you are seeing the behavior you
reported, but you are questioning whether the spec either does or should
guarantee that reading from a channel with a goroutine waiting to send
on that channel will fill the buffer as an atomic part of the read.

As others have said, the spec does not guarantee this.  I would like to
add that I believe it shouldn't.  Suppose goroutine A is currently
blocked waiting to send on a channel.  Now goroutine B reads from that
channel.  If the refill of the channel must happen atomically with the
read from that channel, now goroutine B must be put in a blocked state
waiting for goroutine A to finish its send.  This contradicts the spec
at [1] which states

  ...communication succeeds without blocking if the buffer is not full
  (sends) or not empty (receives).

If you think about how this is likely to be implemented (including
considerations for GOMAXPROC and multicore vs single core systems), you
should realize that, while it would be possible to implement
atomic-refill, it would give no (or very little) benefit and might have
undesirable performance effects.

As an aside, I think the reason Jake is seeing 100 lines of output and
you only see 1 is likely to be the difference between GOMAXPROC=1 and
greater than 1.  If GOMAXPROC=1, the scheduler may force a running
goroutine to yield after receiving, but before returning from the
receive operation.  In other words, the receive happens without
blocking, but the scheduler thinks that is a convenient point for giving
another goroutine an opportunity to run.

...Marvin

[1] https://golang.org/ref/spec#Channel_types

-- 
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.


Re: [go-nuts] Is this a bug?

2018-02-25 Thread Marvin Renich
The point to remember is that each value of a concrete type has exactly
that one concrete type, while each value of an interface type has
exactly one interface type and one concrete type.

It is also important to note that there is a distinction between
"assignability" and "type-assertiblity".

* Bakul Shah  [180225 03:48]:
> https://play.golang.org/p/IMWd3cvgfsU
> 
> // also replicated below
> 
> package main
> 
> import (
>   "fmt"
> )
> 
> type (
>   T1 interface{ f1()int; f2()int }
>   T2 interface{ f2()int; f3()int }
> )
> type C int
> func (c C)f1()int {return 1}
> func (c C)f2()int {return 2}
> func (c C)f3()int {return 3}
> 
> func main() {
>   var (x1 T1; x2 T2; c C; o interface{})
>   fmt.Printf("%T, %T, %T, %T\n", x1, x2, o, c)
>   p(x1);p(x2);p(o);p(c)
>
>   x1 = c; x2 = c; o = c
>   fmt.Printf("%T, %T, %T, %T\n", x1, x2, o, c)
>   p(x1);p(x2);p(o);p(c)
^

x2 (type T2) is assignable to the argument of p (type interface{}), but
when the assignment happens, the value loses the information that it
came from a value with interface type T2.  The o argument to p has
interface type interface{} and concrete type C, even though it came from
a value with interface type T2.

> }
>   
> func p(o interface{}) {
>   switch o.(type) {

A type switch uses the first case that can match (i.e.
type-assertibility, not assignability).  For the x2 case above, o still
only has interface type interface{} and concrete type C.  However C is
type-assertible to type T1, so the first case matches (and so do all the
others, except default, but the first matching case wins).

>   case T1: fmt.Println("T1")
>   case T2: fmt.Println("T2")
>   case C: fmt.Println("C")
>   case interface{}: fmt.Println("interface{}")
>   default: fmt.Println("?")
>   }
> }

It is also worth emphasizing that if you changed the argument to p from
interface{} to T2, the following snippet would still print "T1":

func main() {
var x2 T2
var c C
x2 = c
p(x2)
}

func p(o T2) {
// remainder of function as above
...
}

...Marvin

-- 
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.


Re: [go-nuts] Is there some kind of memory write protection mechanism?

2018-02-25 Thread Marvin Renich
* d...@veryhaha.com  [180225 11:37]:
> I think I get it.
> Because the above program tries to modify the constant (or program) zone, 
> which is not allowed.
> The following program works:

But, note that the language spec does not guarantee it to work.  The
compiler is free to recognize what that first line is doing and optimize
the assignment into a string in a R/O memory segment.  The optimization
is legal because the compiler does not have to recognize the use of
unsafe to determine the programmer's intent to subvert the type system.

> package main
> 
> import "fmt"
> import "unsafe"
> import "reflect"
> 
> func main() {
> s := string([]byte{'k', 'e', 'e', 'p'})
> hdr := (*reflect.StringHeader)(unsafe.Pointer())
> byteSequence := (*byte)(unsafe.Pointer(hdr.Data))
> fmt.Println(string(*byteSequence)) // k
> *byteSequence = 'j' // crash here
> fmt.Println(s) // expect: jeep
> }

...Marvin

-- 
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.


Re: [go-nuts] Regarding contracts

2018-10-22 Thread Marvin Renich
> Ian Denhardt :
> > But I think fundamentally folks have to
> > make choice: do we want to be able to write `<` for user defined types, or 
> > do
> > we want to be able to look at the `<` operator and know for certain that 
> > it's
> > not calling a method? You can't have both.

You can have almost both by using one of these syntaxes in
parametrically typed functions:

a (<) b
or
a <() b

This syntax would only be necessary in parametrically typed functions
and probably should be prohibited in non-parametrically typed functions.
You end up with explicitly-marked overloaded operators.

* Eric S. Raymond  [181019 12:38]:
> This is why I confidently predict that nobody will find a simpler way
> to approximate contracts than "implements".  Ever.

My declarative contracts are almost as simple, but require
parametrically typed functions, and are much more flexible and
expressive.

I do like your idea, but I don't think it is the correct approach to
adding generic programming features to Go.

> Of course "implements" is not an entire generic system; we need syntax
> and semantics for parametric polymorphism and parametric types, too.
> But it's a *good thing* that "implements" can be described without any
> reference to these concerns; it means we have *orthogonality*.

No, you have conflated two ideas that have corresponding features, but
are orthogonal to each other (interfaces and operator overloading).  If
you don't also implement parametrically typed functions, you have lost
much of the flexibility that has been requested with generics.  If you
do, than operator overloading belongs with contracts not with
interfaces.

The general paradigm of interfaces is that they represent boxed values.
Interface values are represented in memory as boxed values, and the code
generated by the compiler handles them as boxed values.

If generic programming in Go uses boxed values, we have gained very
little over interfaces.  This means we should not use interfaces as the
language basis for generic programming.  If we do, we either end up with
generic programming with boxed values or we end up with interfaces that
sometimes use boxed values and sometimes do not, depending on what is
in the interface.

For generic programming, the Go compiler should produce specialized code
for each type combination that is used, except where more than one type
produces the same machine code.

I personally believe that parametrically typed functions without
operator overloading will satisfy about 80% of the use cases and is much
more important than operator overloading.  However, I realize that there
is a large segment of Go programmers that would like to use familiar
operators with user-defined types.  I like the explicitly marked
overloaded operators for reasons of cognitive load when maintaining
code, and I hope that they will satisfy this segment of the programmer
population.

...Marvin

-- 
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.


Re: [go-nuts] Regarding contracts

2018-10-22 Thread Marvin Renich
* Burak Serdar  [181018 15:08]:
> tbh, I am not trying to avoid operator overloading, I am trying to
> avoid the contracts. With operator overloading, you can write:
> 
> func F(a,b type T like(int,X)) {
>if a  ...
>}
> }
> 
> provided X is a type that supports <.

Are you trying to avoid the concept of contracts or the specific syntax
proposed in the design draft?

The more I read through this thread, the more convinced I am that
interfaces and contracts are, and should be, separate entities.  While
the "implements" proposal is simple and rather elegant, it has a few
limitations that have been pointed out elsewhere.  My objection to it is
that it conflates the concept of a common set of methods on a type and a
common set of attributes of a function type parameter.

The current implementation of interfaces uses (exactly one layer of)
boxing of a non-interface type.

The intended implementation of generics provides zero layers of boxing
around a non-interface or interface type.

If you shoehorn generics into an extension of interfaces, you are
conflating two completely different implementation goals, and now we
cannot think of interfaces as a simple box.

By using contracts (hopefully _not_ with the syntax proposed in the
design draft) and function type parameters, the programmer can clearly
distinguish from the code how the compiler is going to treat both
interface arguments and generic function type parameters.

I contend that the "implements" design, while being slightly (and only
slightly) simpler syntactically, is a subset of my suggested declarative
contract syntax.

It also has the disadvantage that every method that "implements" an
operator must explicitly declare it.  Declarative contracts allow taking
an existing type written elsewhere that has a method with appropriate
signature and semantics, and using it with a newly created contract
without modifying the original type.  This is analogous to a newly
created interface that is automatically implemented by a previously
defined type without modifying the type.

For the type

type MySortable struct {
name string
sortkey id
}

Using implements:

type Sortable interface { 
implements <
}

func (r MySortable) LessThan (s MySortable) bool implements < {
return r.sortkey < s.sortkey
}

Using declarative contracts:

contract Sortable(U) {
U: LessMethod(LessThan)
}

func (r MySortable) LessThan (s MySortable) bool {
return r.sortkey < s.sortkey
}

Actually, I think I would define it like this:

contract Sortable(U) {
U: Operator(<, LessThan)
}

Note that my earlier message was not a full blown proposal, just a
suggested syntax without any attempt to specify semantics of specific
contract keywords.

Because contract keywords are in their own namespace and do not conflict
in any way with any language keywords or user identifiers, extending the
attributes that can be declared by a contract can be done at any time
without any backwards incompatibility.  The list of contract keywords
can initially be very short and sweet, and can then be extended as
desired features are identified.

So, interfaces are to method sets on a type as contracts are to the type
parameters on a generic function or type.  Don't try to shoehorn
generics into interfaces.

The contract paradigm allows specifying interaction of multiple types in
a way that implements does not.  Also, it specifies in a single place a
set of attributes that can be used in multiple functions and types
spread out over multiple packages in the same way that interfaces allow
defining in one package a set of methods that can be used to describe
variables in multiple packages.

One package can define a contract, that contract can be used in multiple
packages to define type-parametric functions and types, and then any
type defined elsewhere that satisfies the contract can be used with the
aforementioned functions and types.

Finally, using a named contract can give meaning to a set of type
parameter attributes in the same way that we can now define "type Widget
int" and "type Color int" and refer to them in code to express the
intended use of the int.  The implements proposal lacks this ability to
identify the programmer's intent.

...Marvin

-- 
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.


Re: [go-nuts] Generics: an unwelcome conclusion and a proposal

2018-10-17 Thread Marvin Renich
* Ian Lance Taylor  [181016 17:59]:
> The contract system in the generics design draft does not have this
> problem.  It may have other problems, but it doesn't have this one.

I haven't finished reading the draft (I got to the beginning of the
Contract Details section when it was first mentioned on this list, but
then got sidetracked) nor have I read any of the counter proposals,
which is why I have not responded before now.

I very much like the idea of contracts, but I do not like the specific
design.  Programming by example is a cool idea, but it is simply a bad
practice when you want to clearly and unambiguously express the intended
behavior.  While the draft design allows the compiler to unambiguously
determine the correct behavior, as has been pointed out many times in
the various discussions on this list, the specific code which the
programmer must use to convey his/her intent to the compiler is
extremely ambiguous to the programmer, and the meaning conveyed by a
previously written contract to a different programmer reading the code
is at least equally ambiguous.  The example in the draft document
concerning value method vs. pointer method clearly demonstrates this.
This is contrary to the stated goals of the Go language with respect to
simplicity, scalability and maintainability.

On the other hand, if you replace the body of the contract with a simple
declarative syntax, you regain these core attributes of the Go language.

contract Readable(T) {
T: Implements(io.Reader)
}

contract ComparableInt(U) {
U: EqualMethod(IsSame), ConvertableTo(int), ConvertableFrom(int)
}

contract SortableRecord(V, W) {
V: IsSliceOf(W), Implements(sort.Interface)
W: Implements(Record)
}

Each constraint that a programmer might want to use in a contract must
be specified by the language as a contract keyword.  These keywords are
only special inside a contract body, so they do not interact in any way
with other Go code (e.g. there can be a method Implements on a type).
The contract syntax is such that it is unambiguous what tokens are
contract keywords and what are other language identifiers, such as
interfaces and types; e.g. in Implements(Implements) the first
Implements is a contract keyword and the second is the name of an
interface in the current package.

Some contract keywords may not have any arguments.  Comparable might
mean that the type is comparable using the primitive == operator.

contract Comparable(X) {
X: Comparable
}

Whether to require, allow, or forbid the empty parentheses is a detail
for later discussion.  I.e. the constraint might be X: Comparable().

There would be no ambiguity between the above contract name Comparable
and the contract keyword Comparable, since the contract keyword has no
relevance outside the contract body.

A contract keyword might have more than one argument, such as
M: IsMapOf(K, V).

In the above examples, the contract keyword Implements declares that
type T must implement interface io.Reader.  The keyword EqualMethod
declares that type U must have a method IsSame that has an argument and
result signature appropriate for overloading the == operator.

I see no technical or readability reason to require, or even allow, the
extra names on contract arguments, such as in the draft example contract
convertible(_ To, f From).  It is just as expressive to write contract
convertible(To, From).  The form in the draft was necessary to allow
writing Go expressions that used both values and types to describe what
was permissible.  My declarative syntax does not need this.

It might be convenient to have a predefined contract for each contract
keyword that can be used without explicitly declaring the contract.  The
predefined contract would be shadowed by an explicit contract with the
same name.  The predefined contract will have an additional argument
preceding the arguments required by the keyword.  E.g.

func Massage(type T ConvertableTo(T, int))(item T) error {...}

would use the predefined ConvertableTo contract that is equivalent to a
contract with one constraint, T: ConvertableTo(int).

To switch gears to operator overloading, I would like to start by saying
that one of the fundamental beauties of Go is that looking at a small
piece of code out of context, a programmer can still glean a substantial
amount of information about what the code does, _especially_ about when
external code is called.  I would very much dislike for the language to
be changed such that looking at «a == b» would leave me wondering if
some method of a or b would be called to evaluate that expression.

I had thought of «a ==() b» as a possible syntax for "if the type of a
has a method that overloads ==, use it, otherwise if the primitive ==
operator can be applied, use it, otherwise fail to compile."  Someone
else (was it Michael Jones?) suggested «a (==) b».  I kind of like my
syntax better because it has a "function call" look to it, but either
works for me.

The point is that possibly 

Re: [go-nuts] Regarding contracts

2018-10-25 Thread Marvin Renich
* Andy Balholm  [181024 17:52]:
> What I’m doing with structural contracts is basically the same as what
> you’re doing with struct and interface types as contracts, except that
> (I hope) the syntax is a little clearer. 
> 
> I added the support for operators basically to avoid having the
> supportsEqual contract as a special case that needs to be built in.
> Most other operators could be handled just as well with an enumerated
> contract, so maybe it would be better to just have supportsEqual or
> comparable as a built-in contract.
> 
> The equivalent to your StrNum example in my syntax would be:
> 
> contract num int, int8, int16…
> 
> contract StrNum {
>   num
>   String() string
> }

The most powerful feature of the contracts described in the original
design draft is the ability to describe interactions between two types
in a type specification.  Your proposal doesn't seem to allow this.

Also, you seem to be trying to use "familiar" Go constructs for your
contract body, but you mix types, fields, and operators at the same
syntactical level.  This is bound to be a source of significant
cognitive load both when writing and reading contracts.

My mini-proposal, given earlier in one of these threads (all the
different partially-related threads have become rather jumbled!), is a
change to the contract body syntax from the original design draft.

It has the following features:

  ∙ The syntax is extremely simple and consistent.  It is trivial for
the compiler to parse and trivial for the programmer to both write
and read.
  ∙ It adds zero keywords outside of a contract body, regardless of how
many contract keywords are added and at what time (absolute
extensibility).
  ∙ The keywords can and should be descriptive enough that once you have
used a keyword one time, you will rarely need to return to the
documentation to remember what it does.
  ∙ A keyword can have any number of arguments, as needed for its
particular semantics (see next point).  Each argument can
conceivably have any syntax that is not ambiguous with parens and
commas to enclose and separate the arguments, though I would
encourage limiting it to a very small set of possible choices, such
as an identifier, a type, an operator, and possibly a string
constant.
  ∙ A keyword can have any semantic meaning desired.
  It can identify another type that must be, at some recursive
level, an underlying type.
  It can identify a list of types, one of which must be
(recursively) an underlying type.
  It can identify an operator along with the method that must
implement that operator for the type.
  It can name an interface that the type must implement.
  It can specify that the type must be a slice of another type
(perhaps another type in the type specification, linking the two
types).
  It can specify that it is a map whose keys and or values are
particular types.
  It can specify that the type has a particular size on (or based
on) the current architecture.

As a ridiculous example just to show the flexibility, it could
specify that the type is a struct with a public field whose name
ends in a vowel, that does not satisfy a particular interface, and
that has an import path matching a specific regular expression.

This last point, along with the absolute extensibility means that we can
start with a small number of contract keywords, and add new ones as we
determine the need.  There will never be a need to change the contract
syntax just because a new desirable feature might have a conflicting Go
syntax or namespace with an existing contract specification.  E.g. a
type and a field name have separate namespaces, yet your syntax uses
both names at the same syntactic level; with my syntax these would be
used as arguments to different contract keywords, so there would be no
ambiguity.

I think the primary goal of adding generics to Go is to allow writing
code once that can be used with multiple types with compile-time type
safety.  There are two mutually independent, specific features that
appear to be desired by a significant number of Go programmers:
parametrically-specified types for functions and/or types, and operator
overloading.

I am wholly in favor of parametric types if it can be done without
falling down the C++ rabbit-hole.  I like the idea of operator
overloading, but only if it can be done in a way that visually
distinguishes native operators from user operators (see a previous
post).  However, I could easily do without operator overloading if
necessary.

Andy, if your proposal is just taking the design draft and replacing the
contract syntax, then I like it, but I believe my syntax is
significantly better.

While I like the idea and simplicity of the "implements" proposal, I
think it falls way short of what most people want (or subconsciously
expect) with generics.  Furthermore, I am not 

Re: [go-nuts] Traverse directory without infinite loops while following links

2018-10-04 Thread Marvin Renich
* EricR  [181004 13:33]:
> Hi! I'm new to Go and need to do something with each file in directories. 
> Symlinks need to be followed. I've tried filepath and a few popular 
> libraries and they either crash with segfaults on my system, do not follow 
> symlinks or do not prevent infinite loops.
> 
> Is there a directory walking library that follow symlinks but detects 
> cylces as you would expect? It needs to work on all platforms.

I would use filepath.Walk with a WalkFunc that checked FileInfo.Mode()
for a symlink, used os.Stat() to determine if the symlink points to a
directory, and if it does, calls Walk with the symlink target.

Preventing loops is as simple as making the WalkFunc a closure with a
map[string]struct{} that keeps track of every directory already walked.
If the current path is a directory and is in your map, exit, otherwise
(for directories) add the directory to the map and continue.

It is not a lot of work on top of Walk to get what you want.  If you
need more help, let me know.

...Marvin

-- 
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.


Re: [go-nuts] Casting Back from nested Struct

2018-10-10 Thread Marvin Renich
* Chris Hopkins  [181010 12:04]:
> Hi,
> I appreciate this is not possible, but realised I never understood why (so 
> have just been working around it).
> Example code at:
> https://play.golang.org/p/BgFL9T0KiC7
> 
> I can create a struct with other structs as a member. I then get all the 
> fields and methods associated with that member.
> But you can't cast from that master struct back to the member struct. 
> i.e. I can create a type T with subtype S and operate on the members and 
> data within S, but can't cast T to S.
> I guessed that when you define type S, it exists as effectively a pointer 
> to a struct, and then members within that struct are an indexed offset from 
> that pointer. The act of creating S within T is simply extending that 
> definition so that T's new fields start where S's finished. Casting back 
> from T should therefore be trivial, but clearly it isn't :-)
> 
> I'm sure there's a good reason, but it escapes me at the moment. Any ideas?

While my answer below is correct and more technical, I think the answer
Burak Serdar gave, that embedding is composition not inheritance, may be
more helpful in understanding why you might have believed that it should
work when it doesn't.

However, in the interest of clearer communication between gophers, I am
going to wax pedantic.  Go does not have any syntactic construct called
a cast.  It has conversions and type assertions.

Type assertions are used to change a value from a concrete type to an
interface type which it implements, an interface type to the concrete
type currently held by that value, or an interface type to another
interface type which the concrete type also implements.

Some type assertions can be determined to be illegal at compile time,
others can produce a runtime panic (if the v, ok = x.(T) assignment form
is not used).

Conversions come in two flavors:  those that change the underlying
representation of the value and those that don't.  The ones that do
either convert from one numeric type to another (e.g. uint to float64),
or convert to or from a string type (e.g. []byte to string).

For all other conversions, the underlying types of the value being
converted and the type to which it is being converted must be identical
(a little extra verbiage is necessary for pointers, but the idea is the
same).

Conversions can always be type-checked at compile time and never produce
a runtime panic (out-of-memory notwithstanding).

In your example, c = Bob(f), you are attempting a conversion of f (type
Fred) to type Bob.  But Bob and Fred do not have identical underlying
types so you cannot convert f to type Bob.

You can, however, say c = f.Bob, since embedding Bob (the type) creates
a field named Bob.

...Marvin

-- 
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.


Re: [go-nuts] Traverse directory without infinite loops while following symlinks

2018-10-07 Thread Marvin Renich
[I've set reply-to to include you (per your reply-to) but to exclude me; I
prefer to read my list mail on the list rather than in my personal inbox.]

* rob solomon  [181006 15:17]:
> I've been trying to do something simple like this, but I'm not interested in
> following symlinks.  Here I just am interested in summing all subdirectories
> from my start directory.  But I'm not geting consistent sums, especially if
> I start from my home directory.
> 
> I guess I'm not handling errors, but I don't know how to handle them in a
> way that allows continuing w/ all directories until all non-error-producing
> directories are walked and summed.
> 
> I don't want to follow symlinks.
> 
> I use this on Ubuntu amd64 16.04, 18.04 and Win10.
> 
> Compiled w/ 1.11.1 (and earlier, but that doesn't matter now).
> 
> I don't know how to post code without bombing this list.

This list likes to use The Go Playground at https://play.golang.org to
share code that is not exceedingly large.  I have taken your program,
repaired line breaks added by the email handling programs, fixed a typo,
run gofmt, and pasted it into play.golang.org.  Clicking on the "Share"
button gives the following link:
.

Many simple programs run on the Playground, but when I attempted to run
yours, I discovered that the playground passes an empty first command
line argument (os.Args[1] == ""), so your program just gives the usage
message.  I'm not sure whether or not this Playground behavior is
intentional.

Note that programs that are already running and which modify the
directory being scanned (e.g.  Firefox may be frequently updating a
cache subdirectory of your home directory) may cause the program to give
different results for each run.  However, I think your problems lie
elsewhere.

One problem is that you use fi.Name() in DirAlreadyWalked, but fi.Name()
is only the file name without the directory (e.g. filepath.Base(fpath)).
You want to use fpath.

The filepath.Walk function does not follow symlinks, and a normal file
system will not have any cycles, so you do not need any of the logic
associated with DirAlreadyWalked.  This would remove your problem with
fi.Name as well.

The documentation for WalkFunc is not clear on what errors might be
passed in as the err argument, but I suspect things like errors from the
underlying syscalls for stat or lstat.  However, it is clear that if err
is not nil on entry, the Walk function will already skip that directory
without you needing to return SkipDir.  You should return nil in this
case unless you want to abort the walk completely.

Also in your WalkFunc, you return SkipDir for non-regular files that are
not directories (e.g. device or pipe).  You probably want to return nil
in this case as well.

When I first started writing this, I took "not getting consistent sums"
to mean that you were getting different results from successive runs.
Now I realize you may mean results that are not close to the output of
du.  Being more specific about what your program produced and what you
expected it to produce would help here.

The *nix program du specifically gives you space taken on disk, unless
you pass an appropriate option to return the sum of apparent file sizes.
Your program sums file sizes, not disk space used.  It also ignores
sizes of directories (which can be large for directories with many files
and subdirectories).

When you start producing output, you create an output file on disk, and
then write to Stdout if dirList is small, leaving the empty disk file,
or write to the disk file otherwise.  It would be better to do something
like this:

var isFileOutput = len(dirList) >= 30
var w io.Writer
if !isFileOutput {
w = os.Stdout
} else {
var outfile, err = os.Create(outfilename)
if err != nil {
// print a message to os.Stderr and exit
...
}
defer outfile.Close()
var bufoutfile = bufio.NewWriter(outfile)
defer bufoutfile.Flush()
w = bufoutfile
}

I would put this code after filepath.Walk, but before any output.  You
can then use isFileOutput to ensure that the summary info is written to
both Stdout and the output file, but only have to generate it once.

var b0 = []byte(fmt.Sprintf("start dir is %s, found %d files in this tree.  
GrandTotal is %s, or %s, and number of directories is %d\n", startDirectory, 
TotalOfFiles, GrandTotalString, s2, len(DirMap)))
if isFileOutput {
// Display summary info to Stdout as well.
os.Stdout.Write(b0)
}
_, err = w.Write(b0)
if err != nil {
// print a message to os.Stderr and exit
...
}

And then your main output loop would look like this:

for _, d := range dirList {
var str = strconv.FormatInt(d.subtotal, 10)
str = AddCommas(str)
var _, err = fmt.Fprintf(w, "%s size is %s", d.name, str)
if err != nil {
// print a message to 

Re: [go-nuts] Character Replacement/Algorithm for Replacement

2018-08-30 Thread Marvin Renich
* Tamás Gulácsi  [180830 01:17]:
> An even faster lookup is creating a [256]byte array for the replacements, 
> having the 9 replacements candidates _position_ having the replacements, 
> all others the identity:
> 
> // prepare the lookup table
> var a [256]byte
> for i := 0; i<256; i++ {
>   a[i] = i
> }
> a[37] = '-'
> a[129] = '-'
> ...
> 
> // replace the bytes, in-place operation
> func replace(p []byte) {
>   for i, b := range p {
> p[i] = a[b]
>   }
> }
> 
> Although map lookup is O(1), array lookup is O(1) with a smaller constant 
> factor, I'm sure.
> And this has no branching, so should be even faster.

I'm not convinced, and only benchmarking will tell.  If len(p) == 100
and only six of those are in the set to be replaced, doing 100 memory
writes instead of branching and doing six memory writes might very well
be slower.

Today's hardware has all sorts of optimizations that help with both
cases.  Predictive branching and caching will each help with one of the
two approaches.  You can't be sure until you have benched with realistic
data.

I would, however, replace the map in the previous suggestion with a
[256]int16 with -1 meaning "don't replace".  This is really just a
special-case optimized map.  If 0 is not a valid replacement byte, use
[256]byte with 0 meaning "don't replace".

...Marvin

-- 
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.


Re: [go-nuts] Re: Are Go floats smarter?

2018-08-30 Thread Marvin Renich
* José Colón  [180830 06:53]:
> Very interesting. So would it be a good idea to use these types of untyped 
> constant calculations for financial applications, or instances where one 
> would use the math.big package?

Not likely.  You would have to know at compile time the exact values you
wanted to calculate, so you might as well not even write the program!

If you are writing financial applications or other applications where
rounding and/or precision are important, you must have a much more
thorough understanding of how the computer stores floating point values,
how calculations are performed, how results are represented in the
precision available, and how (and why) those results differ from the
exact values.

Simply learning that Java and Python have rounding errors and that using
Go's untyped constants give you the "human expected" results for some
simple examples is woefully insufficient to write correct floating point
code when such details are important.

On the other hand, there is a wide variety of programs that use floating
point values that don't need to worry about the rounding error in the
least significant bits.

As an example, if you had a set of coordinates, stored as floating point
numbers, representing a graphical figure, it is highly probable that you
could translate and scale those coordinates for display on the screen
without worrying about, or having a deep understanding of, rounding
errors.

...Marvin

-- 
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.


Re: [go-nuts] "All types implement the empty interface"

2019-01-23 Thread Marvin Renich
* 伊藤和也  [190123 00:27]:
> I found the explanation "All types implement the empty interface".
> https://golang.org/ref/spec#Interface_types
> So an empty interface also implements an empty interface? and again the 
> empty interface implements an empty interface and the empty inter...
> What I imagine is like this below.
>   :
>   :
>   :
>empty interface
>   |
>empty interface
>   |
>empty interface
>  ||  |  
>int  float64  bool
> 
> In java, Object class is the top.
>   
> Object
>  |
> Creture
>  ||
>   Animal   Human
>|   |
> Dog  Cat

Francisco's answer is very good, but I think there is a lot of confusion
over variables of an interface type containing values of another
interface type.  This does not happen.  When assigning a value X of an
interface type A to a variable Y of another interface type B, only the
dynamic type of X is retained in Y.  The variable Y contains no
information that the value assigned to it was previously held in a
variable of type A (i.e. had a different interface type).

The dynamic type of an interface value is NEVER an interface type.

Repeat the above statement over and over until it sinks in.

At https://golang.org/ref/spec#Variables the spec defines the dynamic
type of an interface variable as "the concrete type of the value
assigned to the variable at run time", but it never defines the term
"concrete type".  The approximate definition of "concrete type" (and
thus "dynamic type") is the underlying non-interface type of the value.

This definition is implied by the fact that there is no way to create a
value of an interface type (other than nil, which is given as an
explicit exception in the definition of "dynamic type") except by
assignment from a type that implements the interface.  The type of the
value being assigned is either an interface type or a non-interface
type.

If it is an interface type, this is a recursive definition, so the
dynamic type of the result of the assignment must be the dynamic type of
the value being assigned.  Keep recursing on this until the value being
assigned is not an interface type, and you end up with the implication
that the dynamic type must be a non-interface type.

To be pedantic, Jan's answer is wrong.  Instances do not implement
interfaces, types do (both interface and concrete types).

Note under https://golang.org/ref/spec#Interface_types the statement
"Such a type is said to implement the interface".  Also note that the
assignability rules only make sense if you are talking about the type of
a value.

The following would not be legal if an interface type could not
implement another interface type (because the instance of «a» cannot be
known at compile time, at least not easily in a more complicated example
where the value of a is the result of invoking a function from another
package):

https://play.golang.org/p/DBj6Jczj3OM

type A interface {
foo()
goo()
}

type B interface {
foo()
}

type X struct {}
func (x X) foo() {}
func (x X) goo() {}

var a A = X{}
var b B = a

...Marvin

-- 
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.


Re: [go-nuts] errgroup example without channels

2018-12-03 Thread Marvin Renich
* Mu11  [181203 11:47]:
> I saw the example 
>  of 
> errgroup in godoc, and it makes me confused that it simply assigns the 
> result to global results instead of using channels in each search routines. 
> Heres the code:
> 
> Google := func(ctx context.Context, query string) ([]Result, error) {
> g, ctx := errgroup.WithContext(ctx)
> 
> searches := []Search{Web, Image, Video}
> results := make([]Result, len(searches))
> for i, search := range searches {
> i, search := i, search // 
> https://golang.org/doc/faq#closures_and_goroutines
> g.Go(func() error {
> result, err := search(ctx, query)
> if err == nil {
> results[i] = result
> }
> return err
> })
> }
> if err := g.Wait(); err != nil {
> return nil, err
> }
> return results, nil
> }
> 
> 
> I'm wondering is there any mechanism or implied rules that makes the *write 
> *in sub goroutines a happens before of *read *in main goroutine? Thanks for 
> your time.

Note that each go routine only accesses its own element of the result
slice, so there is no overlap and thus no race condition.  The g.Wait()
ensures that all go routines have completed before the "results"
variable is returned (i.e. before any element is referenced by any code
other than the single go routine which has been given "control" of that
element).

...Marvin

-- 
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.


Re: [go-nuts] When set time.Location, will be detected Data Race

2018-11-30 Thread Marvin Renich
* Ian Lance Taylor  [181130 01:01]:
> On Thu, Nov 29, 2018 at 9:47 PM  wrote:
> > The feature of golang is goroutine, and it is a normal situation that get 
> > time in different goroutine.
> > But only can set time.Location in one goroutine. So the Data Race is 
> > inevitable.
> >
> > And there is the replay from agnivade 3
> >
> > “It is not a bug. Please synchronize access to time.Location using 
> > synchronization primitives in the sync andsync/atomic packages.”
> >
> > But there are lots of place that time.Location used by time package of 
> > golang. For example: time.Now(), time.locabs()
> > I can’t change them.
> >
> > So, What should I do ? Please help me.
> 
> You said time.Location.  Do you mean time.Local?  It's true that you
> should never change time.Local.  Why  do you want to?  If you want to
> change the location of a specific time.Time value, call the In method.

For the OP's clarification, I believe he is trying to take the result of
t.Location(), which is a *time.Location, and happens to be the time.loc
private member of the Time struct (unless that is nil, in which case the
result is time.UTC), and assign to it.

However, your answer still stands.

...Marvin

-- 
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.


  1   2   3   >