FAQ
Two questions.

I'm interfacing with a few different packages, some C bindings, and between
them their functions take different types of arguments from a given
"family"; one might take a float64, another takes a float32.

I've started defining my own types for units and converting as I pass
values of my types to function calls:

   package unit
   type Meters float32
   type Pixels int
   ...

   ... math.Atan(float64(myMeters))

First, I'm looking for some guidance to supplement my lack of experience.
Doing the conversions everywhere is pretty tedious and I'm wondering if I'm
really buying myself anything by using my own types. In my case I care
about performance but I don't expect memory usage to be an issue. I could
standardize on int64 and whichever of the float types is more performant on
most desktop platforms. I could also try to figure out which type is the
most common for a given unit and standardize on that to minimize the places
I need conversions. I suspect to do this well I'd need to do profiling and
determine which functions are called the most, not the number of call
sites. At that point I've already written the application and I'd have to
go back and change everything.

The second question builds on the first. For my own types I could get
cleaner code by attaching methods to my types to handle the conversions.

   func (m Meters) Float32() float32 { return float(32) }
   func (m Meters) Float64() float64 { return float(64) }
   func (p Pixels) Int() int { return int(p) }
   func (p Pixels) Int64() int64 { return int64(p) }

   ... math.Atan(myMeters.Float64())

This version of the Atan call looks a lot cleaner to me. Assuming that
answers to question 1 indicate that using my own unit types is valuable,
what is the penalty for using conversion methods like this? I'm guessing
that in general when the underlying types match a conversion is basically a
no op. Can I also assume that the returns will be optimized out? Should I
care?

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Kyle Lemons at Aug 15, 2013 at 4:59 am
    There are upsides and downsides to using your own named types for units.
    + You can't accidentally pass a Meters as a Feet.
    - There isn't actually any dimensionality; you can't teach the compiler
    that Meters / time.Duration = MetersPerSecond
    + if Meters is a float64, the conversion in `var m Meters; f := float64(m)`
    is zero-cost.
    - Unless you have methods on them, there often isn't much of a clarity
    benefit.

    On Wed, Aug 14, 2013 at 10:08 AM, wrote:

    Two questions.

    I'm interfacing with a few different packages, some C bindings, and
    between them their functions take different types of arguments from a given
    "family"; one might take a float64, another takes a float32.

    I've started defining my own types for units and converting as I pass
    values of my types to function calls:

    package unit
    type Meters float32
    type Pixels int
    ...

    ... math.Atan(float64(myMeters))

    First, I'm looking for some guidance to supplement my lack of experience.
    Doing the conversions everywhere is pretty tedious and I'm wondering if I'm
    really buying myself anything by using my own types.
    You are buying something, but you're also spending something. Unless you
    do something silly, there is essentially no runtime performance change (the
    compiler treats it precisely as if it were its underlying type), so you
    have to pick: What else would you like to optimize? Clarity of code?
      Idiot-proof-ness of APIs? Fewer keystrokes? Sensible dimensionality?

    In my case I care about performance but I don't expect memory usage to be
    an issue. I could standardize on int64 and whichever of the float types is
    more performant on most desktop platforms. I could also try to figure out
    which type is the most common for a given unit and standardize on that to
    minimize the places I need conversions. I suspect to do this well I'd need
    to do profiling and determine which functions are called the most, not the
    number of call sites. At that point I've already written the application
    and I'd have to go back and change everything.

    The second question builds on the first. For my own types I could get
    cleaner code by attaching methods to my types to handle the conversions.

    func (m Meters) Float32() float32 { return float(32) }
    func (m Meters) Float64() float64 { return float(64) }
    func (p Pixels) Int() int { return int(p) }
    func (p Pixels) Int64() int64 { return int64(p) }

    ... math.Atan(myMeters.Float64())

    This version of the Atan call looks a lot cleaner to me. Assuming that
    answers to question 1 indicate that using my own unit types is valuable,
    what is the penalty for using conversion methods like this? I'm guessing
    that in general when the underlying types match a conversion is basically a
    no op. Can I also assume that the returns will be optimized out? Should I
    care?

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Nico at Aug 15, 2013 at 9:15 am
    I'm not sure if the following meets your requirements, but one could
    take advantage of Go's untyped constants:

    http://play.golang.org/p/ZFregi9L6O

    package main

    import "fmt"

    // Convertion to SI
    const (
      m = 1
      cm = 0.01
      km = 1000
    )

    func main() {
      var distance float64 = 2.54 * cm
      fmt.Printf("distance = %f m\n", distance)
      fmt.Printf("distance = %f km\n", distance/km)
    }

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedAug 15, '13 at 3:46a
activeAug 15, '13 at 9:15a
posts3
users3
websitegolang.org

3 users in discussion

Nico: 1 post Jason: 1 post Kyle Lemons: 1 post

People

Translate

site design / logo © 2021 Grokbase