$30 off During Our Annual Pro Sale. View Details »

Developing Your Own Flux Packages (InfluxDays London 2019)

Developing Your Own Flux Packages (InfluxDays London 2019)

Flux is easy to contribute to, and it is easy to share functions and libraries of Flux code with other developers. Although there are many functions in the language, the true power of Flux is its ability to be extended with custom functions. In this session, David will show you how to write your own custom function to perform some new analytics.

David McKay

June 14, 2019
Tweet

More Decks by David McKay

Other Decks in Technology

Transcript

  1. View Slide

  2. View Slide





  3. View Slide

  4. View Slide

  5. // This is a comment

    View Slide

  6. name = “David McKay”
    age = 1.2
    alive = true

    View Slide

  7. name = “David McKay”
    objects = {name, age: 23}

    View Slide

  8. durationLiteral = 1mo7d
    timeLiterals = 2018-08-28T10:20:00Z
    = 2018-08-28
    dateMath = 2019-01-01 + 1mo3d

    View Slide

  9. square = (n) => n * n
    tweet(at: “rawkode”, message: “Sweet!”)

    View Slide

  10. moveIn()
    |> moveOut()
    |> handsUp()
    |> handsDown()
    |> backUp()
    |> backUp()
    |> roll()

    View Slide

  11. > ʭ = () => "I don't know what this symbol is called"
    > ʭ
    () -> string
    > ʭ()
    I don't know what this symbol is called

    View Slide

  12. > hotdog = () => “Armour !”
    > hotdog()
    > Armour !
    > = () => “Armour Hotdog!”
    Error: invalid statement @1:1-1:5:

    View Slide

  13. View Slide

  14. package rawkode
    gitHubHandle = “rawkode”
    hello = () => "Hello"
    awesomeThings = ["BBQ", "Hot Sauce", “”]

    View Slide

  15. package rawkode
    awesomeise = (table=<-) => {
    table |> map(fn: (r) => "Awesome" + r)
    }

    View Slide

  16. rawkode@penguin:~ ./flux repl
    > @rawkode.flux
    > awesomeThings |> awesomeise

    View Slide

  17. View Slide

  18. View Slide









  19. View Slide

  20. import "math"
    math.NaN()
    // Returns NaN

    View Slide

  21. import "math"
    math.sqrt(x: 4.0)
    // Returns 2.0

    View Slide

  22. import "strings"
    strings.title(v: "a flux of foxes")
    // returns "A Flux Of Foxes"

    View Slide

  23. import "csv"
    csv.from(file: "/path/to/data-file.csv")
    // OR
    csv.from(csv: csvData)

    View Slide

  24. import "testing"
    testing.assertEquals(
    name: "streamEquality",
    got: got,
    want: want
    )

    View Slide

  25. View Slide








  26. View Slide




  27. View Slide

  28. View Slide

  29. View Slide

  30. package math
    // builtin constants
    builtin pi
    // builtin functions
    builtin abs

    View Slide

  31. package math
    func init() {
    // constants
    flux.RegisterPackageValue("math", "pi",
    values.NewFloat(math.Pi))
    }

    View Slide

  32. View Slide

  33. "github.com/influxdata/flux/values"

    View Slide

  34. package math
    func init() {
    // constants
    flux.RegisterPackageValue("math", "pi",
    values.NewFloat(math.Pi))
    }

    View Slide

  35. package math
    func init() {
    // rand function
    flux.RegisterPackageValue(
    values.NewFunction(“math”, ???)
    )
    }

    View Slide






  36. View Slide

  37. values.NewFunction(
    "rand",
    ???,
    ???,
    ???
    )

    View Slide

  38. // rand with no params
    semantic.NewFunctionPolyType(semantic.FunctionPolySignature{
    Parameters: map[string]semantic.PolyType{},
    Return: semantic.UInt,
    }),
    // in Go: func rand() uint

    View Slide

  39. // rand with 1 param: max
    semantic.NewFunctionPolyType(semantic.FunctionPolySignature{
    Parameters: map[string]semantic.PolyType{
    "max": semantic.UInt
    },
    Required: semantic.LabelSet{"max"},
    Return: semantic.UInt,
    }),
    // in Go: func rand(max uint) uint

    View Slide

  40. // rand with 2 param: min, max
    semantic.NewFunctionPolyType(semantic.FunctionPolySignature{
    Parameters: map[string]semantic.PolyType{
    "min": semantic.UInt,
    "max": semantic.UInt
    },
    Required: semantic.LabelSet{"min", "max"},
    Return: semantic.UInt,
    }),
    // in Go: func rand(min uint, max uint) uint

    View Slide

  41. values.NewFunction(
    "rand",
    semantic.NewFunctionPolyType( … )
    ???,
    ???
    )

    View Slide

  42. // No Error Checking
    func() (values.Value, error) {
    goRand := rand.New(rand.NewSource(...))
    return values.NewFloat(goRand.Intn(100)), nil
    }

    View Slide

  43. func(args values.Object) (values.Value, error) {
    max, ok := args.Get("max")
    if !ok {
    return nil, errors.New("missing argument max")
    }
    if max.Type().Nature() == semantic.UInt {
    goRand := rand.New(rand.NewSource(time.Now().UnixNano()))
    return values.NewFloat(goRand.Intn(max.UInt())), nil
    }
    return nil, fmt.Errorf(
    "cannot convert argument of type %v to uint",
    v.Type().Nature()
    )
    }

    View Slide

  44. values.NewFunction(
    "rand",
    semantic.NewFunctionPolyType( … )
    func(args values.Object) (values.Value, error){ … },
    ???
    )

    View Slide

  45. View Slide


  46. values.NewFunction(
    "rand",
    semantic.NewFunctionPolyType( … )
    func(args values.Object) (values.Value, error){ … },
    false
    )

    View Slide

  47. View Slide

  48. Compilation !== Unit Test

    View Slide

  49. expected = goRand.Intn(100)

    View Slide

  50. fluxFn = values.NewFunction(...)
    fluxArg := values.NewObjectWithValues(
    map[string]values.Value{
    "max": values.NewFloat(100)
    }
    )
    result, err := fluxFn.Call(fluxArg)

    View Slide

  51. View Slide

  52. View Slide

  53. View Slide

  54. View Slide

  55. View Slide

  56. View Slide

  57. View Slide

  58. View Slide

  59. View Slide

  60. View Slide

  61. View Slide

  62. View Slide

  63. 1.
    2.
    3.

    View Slide

  64. View Slide

  65. Thank You

    View Slide