Re: Static assert

389 views
Skip to first unread message

Martin Angers

unread,
May 9, 2013, 8:16:31 AM5/9/13
to golan...@googlegroups.com, drago....@gmail.com
Well, if you only have to support floats, `convert(text string) float64`. But the gain over calling strconv.ParseFloat directly is minimal. If you want to support multiple types in convert, then you can't. Go doesn't support generics (yet?), so you have to rely on runtime type assertions, like you did, and like the stdlib does in places where it has the same needs as you (encoding/binary comes to mind).

Le jeudi 9 mai 2013 08:10:57 UTC-4, drago....@gmail.com a écrit :
Hi, I have the following code fragment:

package main

import(
    "fmt"
    "strconv"
)

func convert(val interface{}, text string) {
    switch t := val.(type) {
    case *float32:
        v, err := strconv.ParseFloat(text, 32)
        if err == nil {
            *t = float32(v)
        }

    default:
        panic("Unknown type")
    }
}

func main(){
    var f float64
    convert(&f,"345.344")
    fmt.Println(f)
}

I want if I supply wrong type to `convert`, compiler to tell me, instead waiting for runtime panic.
Is there any way?

Dmitry Vyukov

unread,
May 9, 2013, 8:25:41 AM5/9/13
to Martin Angers, golang-nuts, drago....@gmail.com
Another option is
func convertFloat
func convertInt
...
> --
> 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/groups/opt_out.
>
>

Jan Mercl

unread,
May 9, 2013, 9:14:03 AM5/9/13
to drago....@gmail.com, golang-nuts
On Thu, May 9, 2013 at 2:10 PM, <drago....@gmail.com> wrote:
> I want if I supply wrong type to `convert`, compiler to tell me, instead
> waiting for runtime panic.

If you subvert the type system using 'interface{}' typed arguments
then do not ask for them being statically type checked. This is not an
insult, it's a simple fact about how the type system works.

'interface{}' typed entities have static type 'interface{}' and _that_
type _is_ statically checked by the compiler. The _dynamic_ type of
the 'interface{}' payload cannot be statically checked: dynamic vs
static, pick one. As in: you cannot eat the cake and have it.

-j

Martin Angers

unread,
May 9, 2013, 9:19:07 AM5/9/13
to golan...@googlegroups.com, drago....@gmail.com
If your real-case types are custom types, you can always make them implement an interface (not the empty one), and have convert() expect this interface. Then the compiler will make sure only types that satisfy this interface can be passed to convert. But if it is for basic types such as floats and ints, this won't work (unless you define a type MyFloat float64, for example, and make MyFloat satisfy the interface, but then you will have to cast normal floats to MyFloat).


Le jeudi 9 mai 2013 09:10:42 UTC-4, drago....@gmail.com a écrit :
Yes, there will be other types. I used float32 only for simplicity. 
Runtime is not good. It takes away possibilities to catch errors early. 
Does anyone proposed it to Google (I guess at expense of another keyword)?


09 май 2013, четвъртък, 15:10:57 UTC+3, drago....@gmail.com написа:
Hi, I have the following code fragment:

package main

import(
    "fmt"
    "strconv"
)

func convert(val interface{}, text string) {
    switch t := val.(type) {
    case *float32:
        v, err := strconv.ParseFloat(text, 32)
        if err == nil {
            *t = float32(v)
        }

    default:
        panic("Unknown type")
    }
}

func main(){
    var f float64
    convert(&f,"345.344")
    fmt.Println(f)
}

I want if I supply wrong type to `convert`, compiler to tell me, instead waiting for runtime panic.
Is there any way?

Rémy Oudompheng

unread,
May 9, 2013, 10:48:48 AM5/9/13
to drago....@gmail.com, golan...@googlegroups.com
You want to handle a finite number of types and not sharing code
between the handling of the types.
What's the relation with generics?

Rémy.


2013/5/9, drago....@gmail.com <drago....@gmail.com>:
> Yes, you are right. Generics is what I need.
> I hope they add some form of them in the future. They are really handy.
> Thank you.
>
> 09 май 2013, четвъртък, 16:14:03 UTC+3, Jan Mercl написа:
>>
>> On Thu, May 9, 2013 at 2:10 PM, <drago....@gmail.com <javascript:>>

Rémy Oudompheng

unread,
May 9, 2013, 11:33:03 AM5/9/13
to drago....@gmail.com, golan...@googlegroups.com
But why do you want to use the same function for different types?

2013/5/9, drago....@gmail.com <drago....@gmail.com>:
> I need compile time error, for not handled types.
>
> 09 май 2013, четвъртък, 17:48:48 UTC+3, Rémy Oudompheng написа:
>>
>> You want to handle a finite number of types and not sharing code
>> between the handling of the types.
>> What's the relation with generics?
>>
>> Rémy.
>>
>>
>> 2013/5/9, drago....@gmail.com <javascript:>
>> <drago....@gmail.com<javascript:>>:
>>
>> > Yes, you are right. Generics is what I need.
>> > I hope they add some form of them in the future. They are really handy.
>> >
>> > Thank you.
>> >
>> > 09 май 2013, четвъртък, 16:14:03 UTC+3, Jan Mercl написа:
>> >>
>> >> On Thu, May 9, 2013 at 2:10 PM, <drago....@gmail.com <javascript:>>
>> >> wrote:
>> >> > I want if I supply wrong type to `convert`, compiler to tell me,
>> instead
>> >> >
>> >> > waiting for runtime panic.
>> >>
>> >> If you subvert the type system using 'interface{}' typed arguments
>> >> then do not ask for them being statically type checked. This is not an
>> >>
>> >> insult, it's a simple fact about how the type system works.
>> >>
>> >> 'interface{}' typed entities have static type 'interface{}' and _that_
>> >>
>> >> type _is_ statically checked by the compiler. The _dynamic_ type of
>> >> the 'interface{}' payload cannot be statically checked: dynamic vs
>> >> static, pick one. As in: you cannot eat the cake and have it.
>> >>
>> >> -j
>> >>
>> >
>> > --
>> > 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 <javascript:>.

Rémy Oudompheng

unread,
May 9, 2013, 11:59:01 AM5/9/13
to drago....@gmail.com, golan...@googlegroups.com
It is not more clean nor is it more generic. Go has ruled out function
overloading precisely because it makes things more confusing.

The discussion is not about genericness.

Rémy.


2013/5/9, drago....@gmail.com <drago....@gmail.com>:
> Yes, maybe I wasn't clear on that. I just want more clean implementation. I
>
> just want convert([type],string), not caring actually what [type] is.
> It can be done with distinct functions, but I wanted to try with more
> generic one first.
>
> 09 май 2013, четвъртък, 18:33:03 UTC+3, Rémy Oudompheng написа:
>>
>> But why do you want to use the same function for different types?
>>
>> 2013/5/9, drago....@gmail.com <javascript:>
>> <drago....@gmail.com<javascript:>>:

Steven Blenkinsop

unread,
May 9, 2013, 4:29:03 PM5/9/13
to drago....@gmail.com, golang-nuts
A few days ago, Sean Russell pointed out that defining unexported methods on built-in types wouldn't cause the same problems as defining exported methods on them would[1]. Of course, it doesn't seem all that useful to define unexported methods on types you don't own, since most of the time a function would serve just as well. I find it interesting that 4 days later, a use case popped up. This code would work with built-in types if you could define unexported methods directly on them (or any other named type that isn't declared in your package). Not to say that allowing this would necessarily be a good idea, since it might muddle up people's idea of where methods can be defined.


On Thu, May 9, 2013 at 11:45 AM, <drago....@gmail.com> wrote:
Here is what i come up:

package main

import(
    "fmt"
    "strconv"
)

type Float32 float32
type Float64 float64

type TypeConverter interface {
    typeConvert(text string)
}

func (f *Float32) typeConvert(text string) {
    v, err := strconv.ParseFloat(text, 32)
    if err == nil {
        *f = Float32(v)
    }
}

func convert(val TypeConverter, text string) {
    val.typeConvert(text)
}

func main() {
    {
        var f Float32
        convert(&f,"345.344")
        fmt.Println(f)
    }
}

Changing Float32 for Float64, gives compile time error:

./goplay.go:29: cannot use &f (type *Float64) as type TypeConverter in function argument:

*Float64 does not implement TypeConverter (missing typeConvert method)


09 май 2013, четвъртък, 15:10:57 UTC+3, drago....@gmail.com написа:
Hi, I have the following code fragment:
package main

import(
    "fmt"
    "strconv"
)

func convert(val interface{}, text string) {
    switch t := val.(type) {
    case *float32:
        v, err := strconv.ParseFloat(text, 32)
        if err == nil {
            *t = float32(v)
        }

    default:
        panic("Unknown type")
    }
}

func main(){
    var f float64
    convert(&f,"345.344")
    fmt.Println(f)
}

I want if I supply wrong type to `convert`, compiler to tell me, instead waiting for runtime panic.
Is there any way?

André Moraes

unread,
May 9, 2013, 7:14:46 PM5/9/13
to drago....@gmail.com, golan...@googlegroups.com
>
> type Float32 float32
> type Float64 float64
>
> type TypeConverter interface {
>
> typeConvert(text string)
>
> }
>
>
> func (f *Float32) typeConvert(text string) {
>
> v, err := strconv.ParseFloat(text, 32)
>
> if err == nil {
>
> *f = Float32(v)
>
> }
>
> }
>

You just implemented the Unmarshaler idiom.

http://golang.org/pkg/encoding/json/#Unmarshaler

Check the http://golang.org/pkg/encoding, you could get some inspiration there

--
André Moraes
http://amoraes.info
Reply all
Reply to author
Forward
0 new messages