Re: [go-nuts] strict type assignability to prevent arbitrary values

2019-11-08 Thread speter
Hi Mohamed,

The memory layout of "string" is the same as that of "struct { string }",
so there is no extra allocation or indirection involved on creation and
access, hence no runtime overhead.

Peter

On Fri, Nov 8, 2019 at 2:01 AM Mohamed Yousif  wrote:

> Hi Speter,
>
> Can you elaborate more on this point please?
> > there is no memory or runtime overhead due to encapsulating the string
> within a struct.
>
>
> On Thu, 7 Nov 2019 at 3:15 PM, speter  wrote:
>
>> Hi bsr,
>>
>> I'd suggest to use a struct type with a single string field. It will
>> prevent conversion from untyped string constant "by mistake".
>> Moreover, if you make the string field unexported, you can limit new
>> instance creation to the declaring package, allowing to enforce predefined
>> values.
>> Unlike with some other languages, there is no memory or runtime overhead
>> due to encapsulating the string within a struct.
>>
>> HTH,
>> Peter
>>
>> On Thu, Nov 7, 2019 at 7:58 PM bsr  wrote:
>>
>>> Hello,
>>>
>>> I am a long time user of go, but I always had the impression that below
>>> code would not work as string and Status are different type.
>>> I thought I need to explicitly convert as ```exec(Status("abc"))``` it
>>> to work.
>>>
>>> I think, this part of the spec may be the reason
>>> https://golang.org/ref/spec#Assignability
>>>
>>>- x is an untyped constant <https://golang.org/ref/spec#Constants>
>>>representable <https://golang.org/ref/spec#Representability> by a
>>>value of type T.
>>>
>>> Is there a way I can prevent this behavior.
>>> I am using Status like an enum, and only predefined status values should
>>> be allowed.
>>>
>>>
>>>
>>>
>>> https://play.golang.org/p/4zsb7KtPBC6
>>>
>>> package main
>>>
>>> import (
>>> "fmt"
>>> )
>>>
>>> type Status string
>>>
>>> func main() {
>>> exec("abc")
>>> }
>>>
>>> func exec(s Status) {
>>> fmt.Printf("Hello, %s", s)
>>> }
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/a20a7034-19c3-410a-bc86-25deff38534f%40googlegroups.com
>>> <https://groups.google.com/d/msgid/golang-nuts/a20a7034-19c3-410a-bc86-25deff38534f%40googlegroups.com?utm_medium=email_source=footer>
>>> .
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/CAK_MaNuSTSGGummC5cOyh%2BbR9VCovrX3xHamDLixDUWbk010Dw%40mail.gmail.com
>> <https://groups.google.com/d/msgid/golang-nuts/CAK_MaNuSTSGGummC5cOyh%2BbR9VCovrX3xHamDLixDUWbk010Dw%40mail.gmail.com?utm_medium=email_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAK_MaNsozfO1_emE4LzkuRYxF9TyBQA1S%2B%2BJh2rN%2B310iv0T%2Bg%40mail.gmail.com.


Re: [go-nuts] strict type assignability to prevent arbitrary values

2019-11-07 Thread speter
Hi bsr,

I'd suggest to use a struct type with a single string field. It will
prevent conversion from untyped string constant "by mistake".
Moreover, if you make the string field unexported, you can limit new
instance creation to the declaring package, allowing to enforce predefined
values.
Unlike with some other languages, there is no memory or runtime overhead
due to encapsulating the string within a struct.

HTH,
Peter

On Thu, Nov 7, 2019 at 7:58 PM bsr  wrote:

> Hello,
>
> I am a long time user of go, but I always had the impression that below
> code would not work as string and Status are different type.
> I thought I need to explicitly convert as ```exec(Status("abc"))``` it to
> work.
>
> I think, this part of the spec may be the reason
> https://golang.org/ref/spec#Assignability
>
>- x is an untyped constant 
>representable  by a
>value of type T.
>
> Is there a way I can prevent this behavior.
> I am using Status like an enum, and only predefined status values should
> be allowed.
>
>
>
>
> https://play.golang.org/p/4zsb7KtPBC6
>
> package main
>
> import (
> "fmt"
> )
>
> type Status string
>
> func main() {
> exec("abc")
> }
>
> func exec(s Status) {
> fmt.Printf("Hello, %s", s)
> }
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/a20a7034-19c3-410a-bc86-25deff38534f%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAK_MaNuSTSGGummC5cOyh%2BbR9VCovrX3xHamDLixDUWbk010Dw%40mail.gmail.com.


Re: [go-nuts] Possible issue with math.Floor on Linux

2018-05-04 Thread speter
To file a bug (and have it treated seriously) you would need to demonstrate
that it is causing problems in a program that actually does something
useful, not just a pathological code sample. My expectation would be that
once you start doing some real processing, the difference between
time.Now() invocations becomes non-zero, that is this "issue" doesn't
reproduce with "real" practical programs.


On Fri, May 4, 2018 at 10:26 PM, Andrei Avram <andrei.avram@gmail.com>
wrote:

> But I don't think it is because Windows is so much faster than Linux
>>
>
> Yeah... :) I was exploring all cases.
>
>
>  and/or the way the time package implemented is different between Windows
>> and Linux
>
>
> Could this be considered a possible Go bug and would it worth opening an
> issue on Github?
>
>
> On Friday, May 4, 2018 at 10:57:46 PM UTC+3, speter wrote:
>>
>> So on Linux it's working as expected. In the playground time is
>> "virtual"; the start time is fixed and it doesn't progress unless you
>> explicitly Sleep -- because you don't Sleep in your program, time.Now()
>> returns the same time on both invocation.
>>
>> So the only slightly surprising part is that on Windows, time as measured
>> by time.Now() doesn't progress between the two statements. But I don't
>> think it is because Windows is so much faster than Linux. :) I'd guess this
>> is because the way Windows manages time is different from how Linux manages
>> it, and/or the way the time package implemented is different between
>> Windows and Linux. The result of the cross-platform differences seems to be
>> less precision on Windows -- at least in this specific scenario.
>>
>> Peter
>>
>>
>> On Fri, May 4, 2018 at 9:33 PM, Andrei Avram <andrei.a...@gmail.com>
>> wrote:
>>
>>> Peter and Ian, you are both wright regarding the printing. Still, on
>>> Linux I have different values than on Go Playground.
>>>
>>> Regarding the speed, Peter, do you think that on Windows the two calls
>>> just run faster every time?
>>>
>>> On Friday, May 4, 2018 at 9:07:15 PM UTC+3, speter wrote:
>>>>
>>>> b is slightly less than 3 because there is a bit of time between the
>>>> two calls to time.Now().
>>>>
>>>> If you substitute this:
>>>> fmt.Printf("input: %20.18f\n", b)
>>>>
>>>> you get something like
>>>> input: 2.99965553350911
>>>>
>>>> HTH
>>>> Peter
>>>>
>>>> On Fri, May 4, 2018 at 7:26 PM, Andrei Avram <andrei.a...@gmail.com>
>>>> wrote:
>>>>
>>>>> Hello everyone,
>>>>>
>>>>> Today I ran into a situation that is strange to me. I ran the
>>>>> following code on two Linux machines (go run floor.go), on two Windows
>>>>> ones, and on Go Playground.
>>>>>
>>>>> package main
>>>>>
>>>>> import (
>>>>> "time"
>>>>> "math"
>>>>> )
>>>>>
>>>>> func main() {
>>>>> datetime := time.Now().Add(time.Hour * 24 * 7 * 4 * 12 * 3)
>>>>> seconds := -1 * int(time.Now().Sub(datetime).Seconds())
>>>>> a := 29030400
>>>>> b := float64(seconds) / float64(a)
>>>>>
>>>>> println("input:", b)
>>>>> println("floor:", math.Floor(b))
>>>>> }
>>>>>
>>>>> On Linux the output is:
>>>>>
>>>>> input: +3.00e+000
>>>>> floor: *+2.00e+000*
>>>>>
>>>>> On Windows and Playground:
>>>>>
>>>>> input: +3.00e+000
>>>>> floor: *+3.00e+000*
>>>>>
>>>>> As you can see, on Linux the floor value of float value 3 is rounded
>>>>> down to 2, while on Windows/Playground it's 3.
>>>>>
>>>>> The code was ran with Go 1.10 and 1.10.2.
>>>>>
>>>>> The system details of one of the Linux machines, as reported by "go
>>>>> bug":
>>>>>
>>>>> go version go1.10.2 linux/amd64
>>>>> GOARCH="amd64"
>>>>> GOBIN=""
>>>>> GOCACHE="/home/msd/.cache/go-build"
>>>>> GOEXE=""
>>>>> GOHOSTARCH="amd64"
>>>>> GOHOSTOS="linux"

Re: [go-nuts] Possible issue with math.Floor on Linux

2018-05-04 Thread speter
So on Linux it's working as expected. In the playground time is "virtual";
the start time is fixed and it doesn't progress unless you explicitly Sleep
-- because you don't Sleep in your program, time.Now() returns the same
time on both invocation.

So the only slightly surprising part is that on Windows, time as measured
by time.Now() doesn't progress between the two statements. But I don't
think it is because Windows is so much faster than Linux. :) I'd guess this
is because the way Windows manages time is different from how Linux manages
it, and/or the way the time package implemented is different between
Windows and Linux. The result of the cross-platform differences seems to be
less precision on Windows -- at least in this specific scenario.

Peter


On Fri, May 4, 2018 at 9:33 PM, Andrei Avram <andrei.avram@gmail.com>
wrote:

> Peter and Ian, you are both wright regarding the printing. Still, on Linux
> I have different values than on Go Playground.
>
> Regarding the speed, Peter, do you think that on Windows the two calls
> just run faster every time?
>
> On Friday, May 4, 2018 at 9:07:15 PM UTC+3, speter wrote:
>>
>> b is slightly less than 3 because there is a bit of time between the two
>> calls to time.Now().
>>
>> If you substitute this:
>> fmt.Printf("input: %20.18f\n", b)
>>
>> you get something like
>> input: 2.99965553350911
>>
>> HTH
>> Peter
>>
>> On Fri, May 4, 2018 at 7:26 PM, Andrei Avram <andrei.a...@gmail.com>
>> wrote:
>>
>>> Hello everyone,
>>>
>>> Today I ran into a situation that is strange to me. I ran the following
>>> code on two Linux machines (go run floor.go), on two Windows ones, and on
>>> Go Playground.
>>>
>>> package main
>>>
>>> import (
>>> "time"
>>> "math"
>>> )
>>>
>>> func main() {
>>> datetime := time.Now().Add(time.Hour * 24 * 7 * 4 * 12 * 3)
>>> seconds := -1 * int(time.Now().Sub(datetime).Seconds())
>>> a := 29030400
>>> b := float64(seconds) / float64(a)
>>>
>>> println("input:", b)
>>> println("floor:", math.Floor(b))
>>> }
>>>
>>> On Linux the output is:
>>>
>>> input: +3.00e+000
>>> floor: *+2.00e+000*
>>>
>>> On Windows and Playground:
>>>
>>> input: +3.00e+000
>>> floor: *+3.00e+000*
>>>
>>> As you can see, on Linux the floor value of float value 3 is rounded
>>> down to 2, while on Windows/Playground it's 3.
>>>
>>> The code was ran with Go 1.10 and 1.10.2.
>>>
>>> The system details of one of the Linux machines, as reported by "go bug":
>>>
>>> go version go1.10.2 linux/amd64
>>> GOARCH="amd64"
>>> GOBIN=""
>>> GOCACHE="/home/msd/.cache/go-build"
>>> GOEXE=""
>>> GOHOSTARCH="amd64"
>>> GOHOSTOS="linux"
>>> GOOS="linux"
>>> GOPATH="/home/msd/go/"
>>> GORACE=""
>>> GOROOT="/usr/local/go"
>>> GOTMPDIR=""
>>> GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
>>> GCCGO="gccgo"
>>> CC="gcc"
>>> CXX="g++"
>>> CGO_ENABLED="1"
>>> CGO_CFLAGS="-g -O2"
>>> CGO_CPPFLAGS=""
>>> CGO_CXXFLAGS="-g -O2"
>>> CGO_FFLAGS="-g -O2"
>>> CGO_LDFLAGS="-g -O2"
>>> PKG_CONFIG="pkg-config"
>>> GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0
>>> -fdebug-prefix-map=/tmp/go-build304261270=/tmp/go-build
>>> -gno-record-gcc-switches"
>>> GOROOT/bin/go version: go version go1.10.2 linux/amd64
>>> GOROOT/bin/go tool compile -V: compile version go1.10.2
>>> uname -sr: Linux 4.13.0-37-generic
>>> Distributor ID: Ubuntu
>>> Description: Ubuntu 16.04.4 LTS
>>> Release: 16.04
>>> Codename: xenial
>>> /lib/x86_64-linux-gnu/libc.so.6: GNU C Library (Ubuntu GLIBC
>>> 2.23-0ubuntu10) stable release version 2.23, by Roland McGrath et al.
>>> gdb --version: GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
>>>
>>>
>>> Is there something I miss or could this be an issue?
>>>
>>> Thanks,
>>> Andrei
>>>
>>> --
>>> 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...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
> 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.
>

-- 
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] Possible issue with math.Floor on Linux

2018-05-04 Thread speter
b is slightly less than 3 because there is a bit of time between the two
calls to time.Now().

If you substitute this:
fmt.Printf("input: %20.18f\n", b)

you get something like
input: 2.99965553350911

HTH
Peter

On Fri, May 4, 2018 at 7:26 PM, Andrei Avram 
wrote:

> Hello everyone,
>
> Today I ran into a situation that is strange to me. I ran the following
> code on two Linux machines (go run floor.go), on two Windows ones, and on
> Go Playground.
>
> package main
>
> import (
> "time"
> "math"
> )
>
> func main() {
> datetime := time.Now().Add(time.Hour * 24 * 7 * 4 * 12 * 3)
> seconds := -1 * int(time.Now().Sub(datetime).Seconds())
> a := 29030400
> b := float64(seconds) / float64(a)
>
> println("input:", b)
> println("floor:", math.Floor(b))
> }
>
> On Linux the output is:
>
> input: +3.00e+000
> floor: *+2.00e+000*
>
> On Windows and Playground:
>
> input: +3.00e+000
> floor: *+3.00e+000*
>
> As you can see, on Linux the floor value of float value 3 is rounded down
> to 2, while on Windows/Playground it's 3.
>
> The code was ran with Go 1.10 and 1.10.2.
>
> The system details of one of the Linux machines, as reported by "go bug":
>
> go version go1.10.2 linux/amd64
> GOARCH="amd64"
> GOBIN=""
> GOCACHE="/home/msd/.cache/go-build"
> GOEXE=""
> GOHOSTARCH="amd64"
> GOHOSTOS="linux"
> GOOS="linux"
> GOPATH="/home/msd/go/"
> GORACE=""
> GOROOT="/usr/local/go"
> GOTMPDIR=""
> GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
> GCCGO="gccgo"
> CC="gcc"
> CXX="g++"
> CGO_ENABLED="1"
> CGO_CFLAGS="-g -O2"
> CGO_CPPFLAGS=""
> CGO_CXXFLAGS="-g -O2"
> CGO_FFLAGS="-g -O2"
> CGO_LDFLAGS="-g -O2"
> PKG_CONFIG="pkg-config"
> GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0
> -fdebug-prefix-map=/tmp/go-build304261270=/tmp/go-build
> -gno-record-gcc-switches"
> GOROOT/bin/go version: go version go1.10.2 linux/amd64
> GOROOT/bin/go tool compile -V: compile version go1.10.2
> uname -sr: Linux 4.13.0-37-generic
> Distributor ID: Ubuntu
> Description: Ubuntu 16.04.4 LTS
> Release: 16.04
> Codename: xenial
> /lib/x86_64-linux-gnu/libc.so.6: GNU C Library (Ubuntu GLIBC
> 2.23-0ubuntu10) stable release version 2.23, by Roland McGrath et al.
> gdb --version: GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
>
>
> Is there something I miss or could this be an issue?
>
> Thanks,
> Andrei
>
> --
> 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.
>

-- 
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] [ANN] gopkg.in/warnings.v0 -- error handling with non-fatal errors (warnings)

2016-08-15 Thread speter . go1
Package warnings implements error handling with non-fatal errors (warnings).

import path:   "gopkg.in/warnings.v0"
package docs:  https://godoc.org/gopkg.in/warnings.v0 
issues:https://github.com/go-warnings/warnings/issues
pull requests: https://github.com/go-warnings/warnings/pulls

A recurring pattern in Go programming is the following:

 func myfunc(params) error {
 if err := doSomething(...); err != nil {
 return err
 }
 if err := doSomethingElse(...); err != nil {
 return err
 }
 if ok := doAnotherThing(...); !ok {
 return errors.New("my error")
 }
 ...
 return nil
 }

This pattern allows interrupting the flow on any received error. But what if
there are errors that should be noted but still not fatal, for which the 
flow
should not be interrupted? Implementing such logic at each if statement 
would
make the code complex and the flow much harder to follow.

Package warnings provides the Collector type and a clean and simple pattern
for achieving such logic. The Collector takes care of deciding when to break
the flow and when to continue, collecting any non-fatal errors (warnings)
along the way. The only requirement is that fatal and non-fatal errors can 
be
distinguished programmatically; that is a function such as

 IsFatal(error) bool

must be implemented. The following is an example of what the above snippet
could look like using the warnings package:

 import "gopkg.in/warnings.v0"

 func isFatal(err error) bool {
 _, ok := err.(WarningType)
 return !ok
 }

 func myfunc(params) error {
 c := warnings.NewCollector(isFatal)
 c.FatalWithWarnings = true
 if err := c.Collect(doSomething()); err != nil {
 return err
 }
 if err := c.Collect(doSomethingElse(...)); err != nil {
 return err
 }
 if ok := doAnotherThing(...); !ok {
 if err := c.Collect(errors.New("my error")); err != nil {
 return err
 }
 }
 ...
 return c.Done()
 }

For an example of a non-trivial code base using this library, see
gopkg.in/gcfg.v1

Rules for using warnings

 - ensure that warnings are programmatically distinguishable from fatal
   errors (i.e. implement an isFatal function and any necessary error types)
 - ensure that there is a single Collector instance for a call of each
   exported function
 - ensure that all errors (fatal or warning) are fed through Collect
 - ensure that every time an error is returned, it is one returned by a
   Collector (from Collect or Done)
 - ensure that Collect is never called after Done

-- 
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] [ANN] gopkg.in/gcfg.v1 : gcfg v1.2.0 released

2016-08-14 Thread speter . go1
Gcfg reads "INI-style" text-based configuration files with "name=value" 
pairs grouped into sections (gcfg files).

A lot has been happening to gcfg since my previous announcement. Most 
notably, the project has moved from Google Code:

gopkg.in/gcfg.v1
https://godoc.org/gopkg.in/gcfg.v1
https://github.com/go-gcfg/gcfg/issues
https://github.com/go-gcfg/gcfg/pulls

New features:

experimental (feature/user_vars branch):
- Sections with user-supplied variables (like in git's [alias] section)

v1.2.0:
- Ability to ignore errors due to extra configuration data. This feature is 
enabled by the new gopkg.in/warnings.v0 package which I intend to announce 
shortly (need some more docs).

v1.1.0:
- Ability to specify default values for subsections

v1.0.0 and earlier:
- Create entries for empty subsections
- "Blank" value for multi-valued vars (slices) resets preset values
- Support pointer to slice (allow distinguishing between no values and 
blank value for slice)
- Support for big.Int
- Configurable parsing of int values (Dec and Hex only by default)
- Support for names starting with unicode letters that are neither upper or 
lower case
- Support for encoding/TextUnmarshaler

Thanks to everyone who has provided feedback!

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