Git Product home page Git Product logo

rangetype's Introduction

Rangetype

Build Status GoDoc License Report Card

A mini-language for defining numeric types by defining ranges.

The idea is to provide a DSL for defining and validating numeric types for implementations of programming languages.

It can also be used for iterating over ranges, generating lists of numbers or slicing a given slice (like slices in Python).

ForEach

Looping over a range can be done by providing a function that takes a float64:

r.New("1..10").ForEach(func(x float64) {
	fmt.Println(int(x))
})

Join

Collecting integers to a comma separated string can be done with Join:

r.New("1..10").Join(", ", 0)

Or for floats, with 2 digits after the period, separated by semicolons:

r.New("1..3 step 0.5").Join(";", 2)

Syntax

Expressions can optionally start with:

  • [ for including the first value in the range, or
  • ( for excluding the first value in the range

And can end with:

  • ] for including the last value in the range, or
  • ) for excluding the last value in the range

Numbers can be suffixed by:

  • ~ for subtracting 1 from the preceding number. Any number of ~ is possible.

The ranges can be Python-style:

[0:10]

Python-style with a step:

[1:20:-1]

Ruby-style:

1..10

Ruby-style with a step:

1..10 step 2

Math-style:

[1,5)

Math-style with a step:

[1,5) step 2

Math-style with negative steps:

(5,1] step -0.1

Here's an expression for specifying the range for a 16-bit unsigned integer:

0..65535

This can also be defined by dropping the initial 0 and using ~ for -1:

..65536~

This can be made clearer (when defining many numbers of many bit-sizes) by using 2**16 instead of 65536:

..2**16~

This can be used for validating if a given number fits a 16-bit unsigned type:

IntType := r.New("..2**16~")     // from 0 up to and including 65536-1
IntType.Valid(42)              // true

Examples

An int with a range from 1 to 3 that includes both 1, 2 and 3:

1,3

A float with a range from 1 to 3 that includes 1.0, 1.1 etc up to 3.0:

1,3 step 0.1

Inclusivity is specified with square brackets:

[1,3]

Exclusivity is specified with parenthesis:

(1,3)

Ranges inspired by Ruby also work:

1..3

These are inclusive, unless parenthesis are used.

Ruby-style range which will exclude 1 and 3 and only keep 2:

(1..3)

Python style ranges are also supported, where the start value is inclusive and the end value is exclusive:

1:3

Adding square brackets makes the range inclusive:

[1:3]

Brackets and parenthesis does not have to be balanced. This works too:

1:3]

Adding an iteration step is also possible:

1..5 step 2

This is a range with the numbers 1, 3 and 5.

The Python-style syntax also supports steps:

[3:1:-1]

This is 3, 2, 1.

Steps does not have to be integers:

[3:1:-0.1]

This steps from 3 (inclusive) down to 1 (inclusive) in step sizes of 0.1.

More Examples

Defining a SmallInt type and checking if a given number is valid

package main

import (
	"fmt"

	r "github.com/xyproto/rangetype"
)

func main() {
	// Define a new type that can hold numbers from 0 up to and including 99
	SmallInt := r.New("0..99")

	// Another way to define a number type from 0 up to and excluding 100
	//SmallInt := r.New("[0,100)")

	// Another way to define a number type from 0 up to and excluding 100
	//SmallInt := r.New("..10**2~")

	// Is 42 a valid SmallInt?
	fmt.Println("0 is a valid SmallInt value:", SmallInt.Valid(0))
	fmt.Println("2 is a valid SmallInt value:", SmallInt.Valid(2))
	fmt.Println("-1 is a valid SmallInt value:", SmallInt.Valid(-1))
	fmt.Println("99 is a valid SmallInt value:", SmallInt.Valid(99))
	fmt.Println("100 is a valid SmallInt value:", SmallInt.Valid(100))

	// How many integers are there room for?
	fmt.Printf("SmallInt can hold %d different numbers.\n", SmallInt.Len())
	fmt.Printf("Storage required for SmallInt: a %d-bit int\n", SmallInt.Bits())

	// All possible SmallInt values, comma separated:
	fmt.Println("All possible values for SmallInt:\n" + SmallInt.Join(",", 0))
}

Example 2

Slicing slices and looping with the ForEach method

package main

import (
	"fmt"

	r "github.com/xyproto/rangetype"
)

func main() {
	// Outputs 1 to 10, with 0 digits after "."
	fmt.Println(r.New("1..10").Join(", ", 0))

	// Outputs 2 and 4
	for _, x := range r.Slice([]float64{1.0, 2.0, 3.0, 4.0}, "1..3 step 2") {
		fmt.Print(x, " ")
	}
	fmt.Println()

	// Also outputs 2 and 4
	r.New("(0:6:2)").ForEach(func(x float64) {
		fmt.Print(x, " ")
	})
	fmt.Println()
}

There are more examples in the range_test.go file.

Features and Limitations

  • Can handle very large ranges without storing the actual numbers in the ranges, but iterating over large ranges may be slow.
  • Only ** and ~ are supported for manipulating numbers in the range expressions.
  • It's not a general language, it's only a DSL for expressing ranges of integers or floating point numbers, with an optional step size.

Error Handling

  • New2 and Slice2 will return both a value and an error (if the expression failed to evaluate) and are the recommended functions to use.
  • New and Slice are fine to use for expressions that are already known to evaluate, but may panic if there are errors in the given expression.

General Info

rangetype's People

Contributors

xyproto avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.