Code Monkey home page Code Monkey logo

mo's Introduction

mo - Monads

tag Go Version GoDoc Build Status Go report Coverage License

๐Ÿฆ„ samber/mo brings monads and popular FP abstractions to Go projects. samber/mo uses the recent Go 1.18+ Generics.

Inspired by:

  • Scala
  • Rust
  • FP-TS

See also:

  • samber/lo: A Lodash-style Go library based on Go 1.18+ Generics
  • samber/do: A dependency injection toolkit based on Go 1.18+ Generics

Why this name?

I love short name for such utility library. This name is similar to "Monad Go" and no Go package currently uses this name.

๐Ÿ’ก Features

We currently support the following data types:

  • Option[T] (Maybe)
  • Result[T]
  • Either[A, B]
  • EitherX[T1, ..., TX] (With X between 3 and 5)
  • Future[T]
  • IO[T]
  • IOEither[T]
  • Task[T]
  • TaskEither[T]
  • State[S, A]

๐Ÿš€ Install

go get github.com/samber/mo@v1

This library is v1 and follows SemVer strictly.

No breaking changes will be made to exported APIs before v2.0.0.

This library has no dependencies except the Go std lib.

๐Ÿ’ก Quick start

You can import mo using:

import (
    "github.com/samber/mo"
)

Then use one of the helpers below:

option1 := mo.Some(42)
// Some(42)

option1.
    FlatMap(func (value int) Option[int] {
        return Some(value*2)
    }).
    FlatMap(func (value int) Option[int] {
        return Some(value%2)
    }).
    FlatMap(func (value int) Option[int] {
        return Some(value+21)
    }).
    OrElse(1234)
// 21

option2 := mo.None[int]()
// None

option2.OrElse(1234)
// 1234

option3 := option1.Match(
    func(i int) (int, bool) {
        // when value is present
        return i * 2, true
    },
    func() (int, bool) {
        // when value is absent
        return 0, false
    },
)
// Some(42)

More examples in documentation.

Tips for lazy developers

I cannot recommend it, but in case you are too lazy for repeating mo. everywhere, you can import the entire library into the namespace.

import (
    . "github.com/samber/mo"
)

I take no responsibility on this junk. ๐Ÿ˜ ๐Ÿ’ฉ

๐Ÿค  Documentation and examples

GoDoc: https://godoc.org/github.com/samber/mo

Option[T any]

Option is a container for an optional value of type T. If value exists, Option is of type Some. If the value is absent, Option is of type None.

Constructors:

Methods:

Result[T any]

Result respresent a result of an action having one of the following output: success or failure. An instance of Result is an instance of either Ok or Err. It could be compared to Either[error, T].

Constructors:

Methods:

Either[L any, R any]

Either respresents a value of 2 possible types. An instance of Either is an instance of either A or B.

Constructors:

  • mo.Left() doc
  • mo.Right() doc

Methods:

  • .IsLeft() doc
  • .IsRight() doc
  • .Left() doc
  • .Right() doc
  • .MustLeft() doc
  • .MustRight() doc
  • .Unpack() doc
  • .LeftOrElse() doc
  • .RightOrElse() doc
  • .LeftOrEmpty() doc
  • .RightOrEmpty() doc
  • .Swap() doc
  • .ForEach() doc
  • .Match() doc
  • .MapLeft() doc
  • .MapRight() doc

EitherX[T1, ..., TX] (With X between 3 and 5)

EitherX respresents a value of X possible types. For example, an Either3 value is either T1, T2 or T3.

Constructors:

  • mo.NewEitherXArgY() doc. Eg:
    • mo.NewEither3Arg1[A, B, C](A)
    • mo.NewEither3Arg2[A, B, C](B)
    • mo.NewEither3Arg3[A, B, C](C)
    • mo.NewEither4Arg1[A, B, C, D](A)
    • mo.NewEither4Arg2[A, B, C, D](B)
    • ...

Methods:

  • .IsArgX() doc
  • .ArgX() doc
  • .MustArgX() doc
  • .Unpack() doc
  • .ArgXOrElse() doc
  • .ArgXOrEmpty() doc
  • .ForEach() doc
  • .Match() doc
  • .MapArgX() doc

Future[T any]

Future represents a value which may or may not currently be available, but will be available at some point, or an exception if that value could not be made available.

Constructors:

  • mo.NewFuture() doc

Methods:

IO[T any]

IO represents a non-deterministic synchronous computation that can cause side effects, yields a value of type R and never fails.

Constructors:

  • mo.NewIO() doc
  • mo.NewIO1() doc
  • mo.NewIO2() doc
  • mo.NewIO3() doc
  • mo.NewIO4() doc
  • mo.NewIO5() doc

Methods:

IOEither[T any]

IO represents a non-deterministic synchronous computation that can cause side effects, yields a value of type R and can fail.

Constructors:

  • mo.NewIOEither() doc
  • mo.NewIOEither1() doc
  • mo.NewIOEither2() doc
  • mo.NewIOEither3() doc
  • mo.NewIOEither4() doc
  • mo.NewIOEither5() doc

Methods:

Task[T any]

Task represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type R and never fails.

Constructors:

  • mo.NewTask() doc
  • mo.NewTask1() doc
  • mo.NewTask2() doc
  • mo.NewTask3() doc
  • mo.NewTask4() doc
  • mo.NewTask5() doc
  • mo.NewTaskFromIO() doc
  • mo.NewTaskFromIO1() doc
  • mo.NewTaskFromIO2() doc
  • mo.NewTaskFromIO3() doc
  • mo.NewTaskFromIO4() doc
  • mo.NewTaskFromIO5() doc

Methods:

TaskEither[T any]

TaskEither represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type R and can fail.

Constructors:

  • mo.NewTaskEither() doc
  • mo.NewTaskEitherFromIOEither() doc

Methods:

State[S any, A any]

State represents a function (S) -> (A, S), where S is state, A is result.

Constructors:

  • mo.NewState() doc
  • mo.ReturnState() doc

Methods:

๐Ÿ›ฉ Benchmark

// @TODO

This library does not use reflect package. We don't expect overhead.

๐Ÿค Contributing

Don't hesitate ;)

With Docker

docker-compose run --rm dev

Without Docker

# Install some dev dependencies
make tools

# Run tests
make test
# or
make watch-test

๐Ÿ‘ค Contributors

Contributors

๐Ÿ’ซ Show your support

Give a โญ๏ธ if this project helped you!

GitHub Sponsors

๐Ÿ“ License

Copyright ยฉ 2022 Samuel Berthe.

This project is MIT licensed.

mo's People

Contributors

clintrovert avatar corentinclabaut avatar ewenquim avatar gkdr avatar joel-u410 avatar m110 avatar samber avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mo's Issues

Applicative

If m and n are two Option[int], I want to add them up. How can I finish this? I learnt haskell these days and it uses applicative (a special functor) to do this. Maybe an apply method is needed?

Translating types

At this moment we cant use monads to translate between different Result monad types.

Ex
Ok(42).FlatMap(func(int) Result[string] { return Ok("wont work") })
because of the single type constraint introduced in the signature.

It wold be very useful if we can perform translations.

A way to do this is to detach FlatMap from result and make the signature like this

func [T, U any] FlatMap(func(T) Result[U]) Result[U]

Or maybe even

func [T, U any] FlatMap(func(T)(U, error)) Result[U]

I understand why this is not done here, it is because of the go generics restriction not to introduce new types in a struct methods. At the time being all types that are used in the struct methods must be declared in the struct definition.

Also func(T) Result[U] is not a correct functor interface, for go maybe func(t) (U, error) would be more appropriate but tbh returning result feels right. The cons is that it will be hard to define universal interface that will work across all of the monads.

Could we add EitherX ?

I guess we could have:

type Either3[T1 any, T2 any, T3 any] struct {
	argId int

	arg1 T1
	arg2 T2
	arg3 T3
}

Constructors:

mo.CreateEither3Arg1()
mo.CreateEither3Arg2()
mo.CreateEither3Arg3()

Methods:

.IsArg(i int)
.Arg1()
.Arg2()
.Arg3()
.MustArg1()
.MustArg2()
.MustArg3()
.Arg1OrElse()
.Arg2OrElse()
.Arg3OrElse()
.Arg1OrEmpty()
.Arg2OrEmpty()
.Arg3OrEmpty()
.ForEach()
.Match()
.MapArg1()
.MapArg2()
.MapArg3()

@samber If you agree that it could be useful I could add Either3/4/5
If this is added I'm wondering if we should then have Either2 instead of the current Either type for consistency?
And maybe mark the current Either as deprecated?

Auto-Boxing in method FlatMap

package main

import "github.com/samber/mo"

func main() {
	var x float64 = 2.0
	op := mo.Some(x)
	square := func(x float64) mo.Option[float64] { return mo.Some(x * x) }
	cubic := func(x float64) mo.Option[float64] { return mo.Some(x * x * x) }
	print(op.FlatMap(square).FlatMap(cubic).OrElse(-1))
}

This is an example of using this package,
but I suppose function square should be

	square := func(x float64) float64 { return x * x }

This declaration of mapping functions is better, I think.

Consider change the FlatMap into

func (o Option[T]) FlatMap(mapper func(T) T) Option[T] {
	if o.isPresent {
		return Some(mapper(o.value))
	}
	return None[T]()
}

Request for Extension of Result Monad to Accommodate Void Functions

Context:

The current implementation of the Result monad in our functional programming library for Golang provides a robust mechanism for handling success and failure scenarios in functions. However, it lacks explicit support for functions that return no result on success, commonly known as "void" functions.

Proposal:

I propose extending the existing Result monad to include explicit support for void functions. This enhancement would enable users to represent and handle successful outcomes where the function does not explicitly return a result.

Requirements:

The extended Result monad should be able to accommodate both functions that return a value on success and functions that don't. This could involve introducing a new type or modifying the existing Result type to support both scenarios.

Use Case:

Consider a scenario where a function is responsible for updating a database record and does not return any value upon success. Currently, users have to resort to using nil or other ad-hoc solutions, which can lead to ambiguity and decreased code readability.

Example:

// Current Usage
func UpdateRecord(data Data) error {
    // perform update
    if err := performUpdate(data); err != nil {
        return err
    } 
    return nil
}

// Proposed Usage
func UpdateRecord(data Data) UnitResult {
    // perform update
    if err := performUpdate(data); err != nil {
        return Err(err)
    }
    return UnitOk() // No result to return on success
}

Benefits:

  • Clarity: Users will have a clear and consistent way to handle functions that don't return a result on success.
  • Readability: Code readability will be improved as the intent of the function will be more explicit.
  • Consistency: The UnitResult monad will maintain consistency with the existing design, making it easier for users to adopt and understand.

I look forward to community feedback and discussions on this proposed enhancement.

Thank you!

swap documentation of functions IsAbsent and IsPresent

struct Option functions IsAbsent and IsPresent has swaped documentation

IsAbsent says: IsAbsent returns true when value is present. - must returns false when value is present
IsPresent says: IsPresent returns true when value is absent - must return true when value is present

version - mo.1.8.0

Decoding BSON values

Hello,

I would like to know if decoding bson values from MongoDB could be a feature of this amazing lib.

type User struct {
	Name  mo.Option[string] `bson:"name"`
}

error decoding key name: cannot decode string into a mo.Option[string]

I would to suggest to decode an empty string or none present key to None.

Thank you in advance.

Result.Map expects new result to be of the same type

I only recently saw this library and it opened the doors to a lot of new stuff for me, i specially liked that it has types like Result and Option which are great for me, since i came from Rust. But what felt weird to me was the type of Result.Map
For a Result, the Map function returns a new Result, this allows me to modify the internal value but im restricted to it being the same type.
On the otherhand in case of rust's Result, Result.Map converts a result of type Result<T, E> to Result<U, E>. I can convert the inner Ok value to a diff type, it can be either the same type or diff. while for mo's case, im bound to having the same type. The following exam fails in mo's case

package main

import (
	"fmt"

	"github.com/samber/mo"
)

func main() {
	ok := mo.Ok([]string{"b"})
	r := ok.Map(func(value []string) (string, error) {
		return value[0], nil
	})
       fmt.Println(r.MustGet())
}

While i could just do ok.MustGet()[0] in this , this is usually not always the case when i'm returning a Result type from a custom function. It would be helpful if the Map function could convert type T to a new type U. Otherwise we explicitly need to unwrap the result, convert it and rewrap it in a result

Reorder fields to save more memory

When size of T is not 8 bytes aligned, put isErr and value before err will save more memory

package main

import (
	"fmt"
	"unsafe"

	"github.com/samber/mo"
)

func Ok[T any](value T) Result[T] {
	return Result[T]{
		value: value,
		isErr: false,
	}
}

type Result[T any] struct {
	isErr bool
	value T
	err   error
}

func main() {
	fmt.Printf("mo(bool): %v\n", unsafe.Sizeof(mo.Ok[bool](false)))
	fmt.Printf("my(bool): %v\n", unsafe.Sizeof(Ok[bool](false)))
	fmt.Printf("mo(int8): %v\n", unsafe.Sizeof(mo.Ok[int8](0)))
	fmt.Printf("my(int8): %v\n", unsafe.Sizeof(Ok[int8](0)))
	fmt.Printf("mo(int16): %v\n", unsafe.Sizeof(mo.Ok[int16](0)))
	fmt.Printf("my(int16): %v\n", unsafe.Sizeof(Ok[int16](0)))
	fmt.Printf("mo(int32): %v\n", unsafe.Sizeof(mo.Ok[int32](0)))
	fmt.Printf("my(int32): %v\n", unsafe.Sizeof(Ok[int32](0)))
	fmt.Printf("mo(int64): %v\n", unsafe.Sizeof(mo.Ok[int64](0)))
	fmt.Printf("my(int64): %v\n", unsafe.Sizeof(Ok[int64](0)))
	fmt.Printf("mo(float32): %v\n", unsafe.Sizeof(mo.Ok[float32](0)))
	fmt.Printf("my(float32): %v\n", unsafe.Sizeof(Ok[float32](0)))
	fmt.Printf("mo(float64): %v\n", unsafe.Sizeof(mo.Ok[float64](0)))
	fmt.Printf("my(float64): %v\n", unsafe.Sizeof(Ok[float64](0)))
	fmt.Printf("mo(complex64): %v\n", unsafe.Sizeof(mo.Ok[complex64](0)))
	fmt.Printf("my(complex64): %v\n", unsafe.Sizeof(Ok[complex64](0)))
	fmt.Printf("mo(complex128): %v\n", unsafe.Sizeof(mo.Ok[complex128](0)))
	fmt.Printf("my(complex128): %v\n", unsafe.Sizeof(Ok[complex128](0)))
	fmt.Printf("mo([12]byte): %v\n", unsafe.Sizeof(mo.Ok[[12]byte]([12]byte{})))
	fmt.Printf("my([12]byte): %v\n", unsafe.Sizeof(Ok[[12]byte]([12]byte{})))
}

mo(bool): 32
my(bool): 24
mo(int8): 32
my(int8): 24
mo(int16): 32
my(int16): 24
mo(int32): 32
my(int32): 24
mo(int64): 32
my(int64): 32
mo(float32): 32
my(float32): 24
mo(float64): 32
my(float64): 32
mo(complex64): 32
my(complex64): 32
mo(complex128): 40
my(complex128): 40
mo([12]byte): 40
my([12]byte): 32

Weird function signature on `(mo.Option).Map`

Firstly I just want to say that I love this library and has allowed to me to largely remove my own custom implementation of a lot of these types. However I was wondering what the reasoning behind the signature and behaviour of (mo.Option).Map?

func (o Option[T]) Map(mapper func(value T) (T, bool)) Option[T] {
	if o.isPresent {
		return TupleToOption(mapper(o.value))
	}

	return None[T]()
}

Generally speaking Map called on a Some should always return a Some which is a sentiment you also shared here. The ability to return false within the mapper makes Map behave more like FlatMap. It also makes passing point-free functions a little awkward as you have to "lift" the mapper into that signature. e.g.

// Error function signature requires returning an additional boolean
mo.Some("ExampleString").Map(strings.ToLower)

func lift[A any](fn func(A) A) func(A) (A, bool) {
  return func(a A) (A, bool) {
    return fn(a), true
  }
}

mo.Some("ExampleString").Map(lift(strings.ToLower))

I propose that (mo.Option).Map's signature should be changed to remove the boolean argument, if someone wants the old behaviour they can use FlatMap and TupleToOption.

Create a MapTrue on option

Hi,

Most of the times we returns a constant for the Map method on the Option receiver. For example, we might have something like :

mo.Some("foobar").Map(func(value string) (string, bool) { return strings.ToUpper(value), true }).MustGet()

Maybe we can get a little better with something like:

mo.Some("foobar").MapTrue(func(value string) string { return strings.ToUpper(value) }).MustGet()

What's your opinion about that ?

Regards,
Patrick

Option wrappers for slices and maps?

Something like:

var s OptionSlice[[]int]
var m OptionMap[map[string]int]
fmt.Println(s.IsPresent(10), s.OrEmpty(10))
fmt.Println(m.IsPresent("key"), m.OrEmpty("key"))

Misuse of resolve/reject causes "close of closed channel" panic

Hello,

If I run:

mo.NewFuture(func(resolve func(struct{}), reject func(error)) {
	resolve(struct{}{})
	reject(errors.New("oh no..."))
})

I get panic: close of closed channel.

This makes me write defensive code (e.g. return after each call to reject / resolve).
I would suggest to recover from panics and reflect it as an error as part of Result[T]'s error.

Irritating lack of type inference on Option for None and Result for Err

I realize this is a limitation of the compiler's type inference mechanism but it looks bad to have to explicitly state a type parameter for the None and Err variants. Can anything be done to avoid this and clean up the use of Option and Result?

Here's what I mean for Result, for instance:
Screenshot 2023-08-15 at 11 56 56

Here's what would be cooler:
Screenshot 2023-08-15 at 11 56 42

Ok, and here's what would be really nice, with options for wrapping this:
Screenshot 2023-08-15 at 11 56 04

Add .Unpack() to Result and friends to mirror lo Tuple family OR add .Get() to lo Tuple family to mirror mo Result/Option

I would like to be able to do this:

type myUnpack[T any, U any] interface {
  Unpack() (T, U)
}

func MyFunc() <-chan myUnpack[int, error] {
  c := make(chan myUnpack[int, error])
  go func(){
    defer close(c)
    time.Sleep(200 * time.Milliseconds)
    // c <- mo.Option
    // c <- lo.Tuple2
    // c <- mo.Result
    // c <- whatever
  }()
  return c
}

so that my users downstream don't have to really care whether they got a Result or a Tuple2 or what; they just do this in their code and it works:

import "github.com/jcbhmr/thelib"

func main() {
  v, err := (<-thelib.MyFunc()).Unpack()
  if err != nil {
    log.Fatal(err)
  }
  log.Printf("The result is %d", v)
}

basically I want to have a nice "this is the way you do it" pattern to pass through 2x tuple of values in a chan. i sometimes use a lo.Tuple[int, bool] and sometimes a mo.Result[int] and sometimes an mo.Option[int] all to represent basically the same thing; I want the user to just .Unpack() the chan result and not worry about any additional .map() or other magic this-library-specific details. just unpack it into idiomatic go multivalues lol. does that make sense? i don't want the user to even need to be aware that I'm using lo or mo; they should just .Unpack() to get the plain go-like multireturn (T, bool) or (T, error) or (T, U) pair.

my suggesting to achieve this utopia of .Unpack() meaning "make into go-like multireturn" is to add a .Unpack() to Result in this package and any other related unpackable types like maybe Option -> (T, bool) or something

NEED TO MENTION that this COULD work with .Get() too! Result and Option in this package already implement .Get() idiomatically; its just that the sister package lo doesnt implement Tuple2.Get() https://pkg.go.dev/github.com/samber/lo#Tuple2

type myGet[T any, U any] interface {
  Get() (T, U)
}

func MyFunc() <-chan myGet[int, error] {
  c := make(chan myGet[int, error])
  go func(){
    defer close(c)
    time.Sleep(200 * time.Milliseconds)
    // c <- mo.Option
    // c <- lo.Tuple2
    // c <- mo.Result
    // c <- whatever
  }()
  return c
}
import "github.com/jcbhmr/thelib"

func main() {
  v, err := (<-thelib.MyFunc()).Get()
  if err != nil {
    log.Fatal(err)
  }
  log.Printf("The result is %d", v)
}

tldr is either .Unpack() or .Get() would be nice to have on all these Option Result Tuple types to convert them back to go-idiomatic multivalues that are not lib-specific Option/Result/Tuple types

Type transformations in Map

Scala: def map[B](f: (A) ? B): Traversable[B]

Golang: func (r Result[T]) Map(mapper func(value T) (T, error)) Result[T] 

Generally the map function supports type transformations from T[A] => T[B] which is used the most in all practical use cases.
While the library supports mapping, but its applicability is very limited due to this limitations.

I believe this is majorly because Golang does not support type arguments on methods.

Any means to bypass this and get a more practical mappers?

Is there a good way to define a Future of nothing?

Hi, this might be a noob question.

When doing an async computation, there are cases where we don't have a resolve value, but we might have an error.
Future requires to define a resolve type, since there is no non-generic definition.

Is that an unusual case for Future usage? Is there another construct that I should use?

Failed scanning row for mysql with Option

For example

CREATE TABLE t (optional VARCHAR(64));

rows, err := db.Query("SELECT optional FROM t  LIMIT 1?")
for rows.Next() {
  var o mo.Option[string]
  if err := rows.Scan(&o); err != nil {
	  t.Errorf("Failed scanning row: %s", err.Error())
	  continue
  }
}

then will got Failed scanning row: sql: Scan error on column index 1, name "optional": failed to scan Option[T], and the reason is
that type of arg src of Scan is []uint8, and failed here when assert type is string, refer to sql.NullString, we can use the function sql.convertAssign to replace the driver.DefaultParameterConverter.ConvertValue to resolve it, but the convertAssign is private, and maybe won't be public(refer to golang/go#24258), so we can copy out the convertAssign and make some modification or write a new convert function? what do you think? Or have some other solution?

Future[T] implementation discussion

If we call (*Future[T]).Then after Future[T] has completed, the Than-callback will never been called. And if we try to Collect a completed Future[T], it could cause deadlock.

for example:

func Test_Future(t *testing.T) {
	completed := make(chan struct{})
	fut := mo.NewFuture(func(resolve func(int), reject func(error)) {
		resolve(1)
		close(completed)
	})

	<-completed
	fut.Then(func(in int) (int, error) {
            fmt.Println(in) // will never been print
	    return in, nil
	}).Collect() // deadlock
}

Futures call next future once they have finished, so if we chain a callback on a finished future, the call chain would be broken.

And here is my commit to fix this commit.

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.