GithubHelp home page GithubHelp logo

ekmett / bound Goto Github PK

View Code? Open in Web Editor NEW
121.0 121.0 30.0 479 KB

Combinators for manipulating locally-nameless generalized de Bruijn terms

Home Page: https://www.schoolofhaskell.com/user/edwardk/bound

License: Other

Haskell 100.00%

bound's People

Contributors

aloiscochard avatar benjamin-hodgson avatar bixuanzju avatar cartazio avatar ekmett avatar gabriella439 avatar gelisam avatar ggreif avatar glguy avatar hvr avatar icelandjack avatar np avatar ollef avatar phadej avatar polyb avatar ryanglscott avatar saizan avatar sgraf812 avatar shimuuar avatar supki avatar tomjaguarpaw avatar treeowl 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

bound's Issues

Example on how to use Bound.Name

I think I figured out how Bound.Name works, but am unsure which parts of the AST should be decorated with it. The other functions in the module suggest to decorate the first parameter of Scope, but it's weird not to have access to the name when matching on Lam.

Could you drop a really short example? Just the modified basic Exp type + the Lam case of a pretty printing function like here which figures out the right name for the bound variable should be enough.

Minor release for new transformers?

I saw that this repo has had its version requirements for transformers loosened, but not on hackage. Would you mind releasing a new version with the change?

instance Bound Free

Does this make sense

instance Bound Free where
  (>>>=) :: forall m a c. Monad m => Free m a -> (a -> m c) -> Free m c
  Pure a  >>>= ĸ = liftF (ĸ a)
  Free ms >>>= ĸ = liftF (ms >>= retract >>= ĸ)

It looks weird and I don't know if it's useful but it type checks :) I am too undisciplined to dive into it I'm afraid

The `template-haskell` `cabal` flag doesn't do anything

Despite having a template-haskell cabal flag seemingly for the purpose of allowing users to opt out of the template-haskell library dependency:

bound/bound.cabal

Lines 107 to 108 in 6d2ca74

if flag(template-haskell) && impl(ghc)
build-depends: template-haskell >= 2.7 && < 3.0

It turns out that bound also depends on the template-haskell library unconditionally elsewhere in the file, defeating the point of having the cabal flag in the first place:

template-haskell >= 2.7 && < 3,

We should either:

  1. Properly depend on the template-haskell library conditionally, or
  2. Remove the template-haskell cabal flag altogether.

The example use of `Bound.Name` is needed.

The problem is, GHC can't figure out how to fmap the first a out of Scope (Name a ()) Program a.

The >>>= operator will leave the Name a () intact as well.

I can make it Name MyName (), but this kinda defeats the purpose of the Name wrapper.

If the Scope' (bound :: *) (f :: * -> * -> *) (name :: *) (a :: *) is a Bifunctor instead, thus preserving the names by default, this would allow us to keep the oldest names, erase them with lmap (const ()) or do any possible mapping separately from the current name set.

The Monad instance in that case would allow to only work with "latest" names.

makeBound fails when `Exp a` has functor component

λ > data E a = V a | App (E a) (E a) | Lam (Scope () E a) | ND [E a] deriving (Functor)
 > makeBound ''E; deriveEq1 ''E;

<interactive>:1:1: error:
    Exception when trying to run compile-time code:
      This is bad: AppT ListT (AppT (ConT Ghci7.E) (VarT a_1627463734)) False
CallStack (from HasCallStack):
  error, called at src/Bound/TH.hs:256:39 in bound-2-6f91PaWmBSxGss7Mmo1eYD:Bound.TH
    Code: makeBound ''E

is there something I'm doing wrong, Template Haskell error message doesn't help here...

Upload latest version to Hackage

The version of bound on Hackage, 1.0.7, supports only transformers<0.5. This is causing me trouble when installing bound with a fresh install of the latest Haskell Platform, which comes with transformers-0.5.2.0.

I see from the Cabal file in this repo that the dependency has already been updated - could you please upload the latest version to Hackage?

Thanks!

Remove or explain mention of "ideal monad" from package introduction.

The first thing the user reads after clicking on this library is

We represent the target language itself as an ideal monad supplied by the user

I find this a bit confusing because "ideal monad" doesn't seem to be a widely known concept in Haskell (unlike, say, "free monad"). The references I have found give more general category-theoretic explanations and are a bit hard to grasp. In Haskell terms, it seems that ideal monads have a "pure" constructor, but I'm not sure if there are other conditions.

If the conditions are easy to state, perhaps they should be used instead of the term "ideal monad".

makeBound chokes on types containing tuples of constants

The following makeBound invocation chokes:

{-# LANGUAGE DeriveFunctor, TemplateHaskell #-}

import Bound
import Bound.Name
import Data.Text

type Named b = Name Text b

data Term v
  = EVar v
  | EApp (Term v) (Term v)
  | EAbs (Named ()) (Scope (Named ()) Term v)
  deriving (Functor)

makeBound ''Term
boundbug.hs:1:1: error:
    Exception when trying to run compile-time code:
      This is bad: AppT (ConT Main.Named) (TupleT 0) False
CallStack (from HasCallStack):
  error, called at src/Bound/TH.hs:269:35 in bound-2.0.1-13f2bf83f03b2fd0ec7401893dd97861fab71a8bfa55e6a9cf9d765f1a520a4f:Bound.TH
    Code: makeBound ''Term

But the following works fine:

data MyUnit = MyUnit deriving (Eq)

data Term v
  = EVar v
  | EApp (Term v) (Term v)
  | EAbs (Named MyUnit) (Scope (Named ()) Term v)
  deriving (Functor)

makeBound ''Term

The problem is that makeBound doesn't recognize () as a constant because it parses as an empty tuple, and isKonst is missing a rule for tuples. The other, remaining occurrence of Named () is okay because it gets handled by boundInstance rather than isKonst.

Mutually recursive expression types?

I'm thinking about implementing the System DC language (from this paper, essentially "dependent GHC Core", to save you a click) using Bound.

The problem is that it has mutually recursive types for terms and coercions, like so:

data Tm a 
  = TmVar a | TmConv (Tm a) (Co a) 
  | TmPi (Tm a) (Scope () Tm a) | TmCoAbs (Tm a) (Scope () Co a) | ...
data Co a = CoVar a | CoRefl (Tm a) | CoSym (Co a) | CoPiFst (Scope () Co a) ...

so I don't think Monad instances are happening for either.

Some points:

  • Co nodes appear in the Tm type, and vice versa, as noted
  • Scope b Co a appears in both types
  • Scope b Tm a only appears in the first (as far as I can tell)

How would I modify these types to support something akin to @gelisam's "sideways" imperative example?

The semantics I want are captured by the simple-minded types I wrote above; unlike in the Imperative example, I have no need for bound variables being unavailable in certain parts of the ASTs or anything of the sort.

Edit: also see this comment below, it appears I need two kinds of binders

Split bound to offer a lightweight version

bound depends on profunctors to allow it to offer a few trivial bits of lensy glue. Would it be possible to get a bound-core package or similar that just doesn't bother? Even playing around with bound is annoying because of the dependency.

`Scope`s with `Control.Lens.Plated` lead to infinite loop and space leak

Using Bound with Lens breaks Control.Lens.Plated as traverse and rewrite loop infinitely and leak memory. Removing the Lam alternative (and thereby also the Scope resolves the issue. Attached is a (somewhat) minimal working example, profiterole and heap profiling results.

I am using GHC version 8.0.2, all packages with exception of bound-2 are part of stack lts-8.17. The program is compiled as ghc test.hs. Enabling or disabling optimizations doesn't affect the problem.

(Potentially) see this SO question for more information/discussion.

This issue might be in the wrong project, feel free to ping me and I'll sumbit it to lens instead.


{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable, DeriveDataTypeable #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell    #-}

module Main (main) where
import           Bound
import           Control.Lens hiding (List)
import           Control.Lens.Plated
import           Data.Deriving (deriveShow1, deriveEq1)
import           Data.Data
import           Data.Data.Lens (uniplate)

data Expr a   = Var   a
              | List  [Expr a]
              | Apply (Expr a) (Expr a)
              | Lam   (Scope () Expr a)
              | Nop
              deriving (Functor, Foldable, Traversable, Data)

main = do
         print ex
         print $ transform removeTest ex

ex :: Expr String
ex = List [ Apply (Var "test") $ List [Var "arg1", Var "arg2"]
          , Apply (Var "two") (Var "three")]

removeTest :: Expr String -> Expr String
removeTest = \expr -> case expr of
                        Apply (Var "test") _ -> Nop
                        _ -> expr

instance Data a => Plated (Expr a) where
  plate = uniplate

makeLenses  ''Expr
makeBound   ''Expr
deriveEq1   ''Expr
deriveShow1 ''Expr
deriving instance Show a => Show (Expr a)
deriving instance Eq   a => Eq   (Expr a)

Output:

List [Apply (Var "test") (List [Var "arg1",Var "arg2"])
     ,Apply (Var "two") (Var "three")]
^CList [Nop,Apply (Var "two") (Var "three")]

 -- profiterole stats
 TOT   INH   IND
99.9  99.9    .1  MAIN MAIN (0)

99.9  99.9    .1  MAIN MAIN (0)
99.9  99.9  34.0    Main CAF (0)
65.9  65.9     -      Data.Data.Lens fromOracle (35)
65.9  65.9     -        Data.Data.Lens hitTest (0)
65.9  65.9     -          Data.Data.Lens hitTest.\ (35)
65.9  65.9     -            Data.Data.Lens readCacheFollower (30)
65.9  65.9     -              Data.Data.Lens readCacheFollower.\ (30)
65.9  65.9     -                Data.Data.Lens insertHitMap (1)
65.9  65.9     -                  Data.Data.Lens insertHitMap.populate (1)
65.9  65.9  56.4                    Data.Data.Lens insertHitMap.populate.f (1824891)
 2.3   2.3   2.3                      Data.HashMap.Base clone16 (2682671)
 2.1   2.1   2.1                      Data.HashMap.Base hash (6204631)
 1.7   1.7    .4                      Data.HashMap.Array copy (1620382)
 1.3   1.3   1.3                        Data.HashMap.Array copy.\ (1620382)
 1.1   1.1   1.1                      Data.Data.Lens insertHitMap.populate.fs (2189870)
  .9    .9    .9                      Bound.Var gfoldl (364976)
  .5    .5    .5                      Data.HashMap.Array new_ (810191)
  .5    .5    .5                      Bound.Var gunfold (364976)
  .3    .3    .3                      Data.HashMap.Base sparseIndex (3620621)
  .2    .2    .2                      Bound.Scope gfoldl (182489)

Heap profile:

heap profile

Add predicate to substitute functions

substitute :: Monad f => Eq a => a -> f a -> f a -> f a
substitute = substituteOf . (==)

substituteBy :: Monad m => (a -> Bool) -> m a -> m a -> m a
substituteBy old new as = do
  a <- as
  if old a
    then new
    else pure a
substituteVar :: Functor f => Eq a => a -> a -> f a -> f a
substituteVar = substituteVarOf . (==)

substituteVarBy :: Functor f => (a -> Bool) -> a -> f a -> f a
substituteVarBy old new as = do
  a <- as
  pure
    if old a
      then new
      else a

Is there a use for this?

bound + recursion schemes

Is it possible to use bound with recursion-schemes library?
i.e. to define the names in an AST using bound and doing AST transformations (optimisations, inlining, etc) with recursion-schemes

Add another abstract variant

abstractE :: Monad f => (a -> Either a' b) -> f a -> Scope b f a'
abstractE f e = Scope (liftM k e) where
  k y = case f y of
    Right z  -> B z
    Left q -> F (return q)

The idea is that the free variable type can change to reflect the fact that some of its values are gone. I don't know if this is practically important, but a nice side effect is that the type of abstractE expresses/constrains what it does much more thoroughly than the type of abstract does.

Eq1, Ord1, Show1, Read1 with ghc8

The following example works fine for me with ghc7.10.3, but not with ghc8. It is complaining

src/Exp.hs:56:22: error:
    • No instance for (Data.Functor.Classes.Show1 (Exp t))
        arising from the second field of ‘Lam’ (type ‘Scope () (Exp t) a’)
      Possible fix:
        use a standalone 'deriving instance' declaration,
          so you can specify the instance context yourself
    • When deriving the instance for (Show (Exp t a))

and similar for Eq1, Ord1, Read1

Sorry, if I am asking the obvious, but I would appreciate some help of how to
derive Eq1, Ord1, Show1, Read1 for (Exp t)

Note that the use of two type variables: t, a makes my expressions: Exp t a a little more
complicated than most of the Bound examples I usually see (with just Exp a), an idea I got by
cheating at Terms in the ermine code originally:

https://github.com/ermine-language/ermine/blob/master/src/Ermine/Syntax/Term.hs

but they have worked fine for me so far (and I have come to rely on them).

Not sure if I have a chance to apply a simple/automatic solution like

import Data.Eq.Deriving (deriveEq1)
import Text.Show.Deriving (deriveShow1)

from deriving-compat relying on Template Haskell, as in the example at
https://github.com/ekmett/bound

at all, given my two expressions of t and a, but I would be happy already
if I just got my code compiled with ghc8

I have tried deriving instance Show t => Show1 (Exp t) as well, with no luck so far.

Im am using the latest version of Bound from github (not the slighly older version on hackage),
cf. https://github.com/ekmett/bound/issues/32, ie. Bound itself compiles fine for me
under ghc8 from debian sid/unstable.

Thanks in advance,
Andreas

{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveTraversable #-}


{-# LANGUAGE StandaloneDeriving #-}

{-# LANGUAGE CPP #-}


module Exp where


import Control.Monad



import Prelude.Extras

import Bound


infixl 9 :@


data Exp t a =

  V a

  | (Exp t a) :@ (Exp t a)

  | Lam  t       (Scope () (Exp t) a)



#if MIN_VERSION_GLASGOW_HASKELL(8,0,1,0)

-- what to do here for ghc8 ? 


-- these lines just copied, but don't work
  deriving (Eq, Ord, Show, Read, Functor, Foldable, Traversable)

instance Eq t => Eq1 (Exp t)
instance (Ord t) => Ord1 (Exp t)
instance Show t => Show1 (Exp t)
instance Read t => Read1 (Exp t)



#else
-- works fine in ghc 7.10.3

  deriving (Eq, Ord, Show, Read, Functor, Foldable, Traversable)

instance Eq t => Eq1 (Exp t)
instance (Ord t) => Ord1 (Exp t)
instance Show t => Show1 (Exp t)
instance Read t => Read1 (Exp t)

#endif



instance Applicative (Exp t) where
  pure = V
  (<*>) = ap



instance Monad (Exp t) where

  return = V

  
  V a        >>= f = f a

  (x :@ y)   >>= f = (x >>= f) :@ (y >>= f)

  Lam n s    >>= f = Lam n (s >>>= f)



-- | 
-- >>> lam "a" $ V "a" :@ V "b"
-- Lam "a" (Scope (V (B ()) :@ V (F (V "b"))))



lam v b = Lam v (abstract1 v b)

`Imperative` example fails to compile

In particular, a file containing:

{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable, RankNTypes, ScopedTypeVariables #-}
module Lib where

import Bound

data Prog operand a
  = Ret (operand a)
  | Add (operand a) (operand a)
        (Prog (Scope () operand) a)
  deriving (Eq,Ord,Show,Read,Functor,Foldable,Traversable)

pAbstract1 :: forall operand a. (Applicative operand, Monad operand, Eq a)
           => a
           -> Prog operand a
           -> Prog (Scope () operand) a
pAbstract1 = go abstract1
  where
    go :: forall o o' u. Eq u
       => (forall v. Eq v => v -> o v -> o' v)
       -> u -> Prog o u -> Prog o' u
    go f x (Ret o)        = Ret (f x o)
    go f x (Add o1 o2 cc) = Add (f x o1) (f x o2)
                          $ go f' x cc
      where
        f' :: forall v. Eq v => v -> Scope () o v -> Scope () o' v
        f' v = Scope . f (F v) . unscope

gives the following error:

    • Occurs check: cannot construct the infinite type: v ~ o v
      Expected type: Scope () o v -> o (Var () v)
        Actual type: Scope () o v -> o (Var () (o v))
    • In the second argument of ‘(.)’, namely ‘unscope’
      In the second argument of ‘(.)’, namely ‘f (F v) . unscope’
      In the expression: Scope . f (F v) . unscope
   |
44 |         f' v = Scope . f (F v) . unscope
   |

despite being in the examples/ folder of this repo.

Remembering the binder name when there is no occurrence

Hey, I've been using bound for quite a while for a personal project, and it satisfies almost all of my needs, except for one issue.

The family of abstractName allows remembering names of binder occurrences after abstraction as a forgettable property, and that's pretty neat. But when a binder does not occur in a term, abtracting over it forgets it entirely.

I have been wondering whether it would be feasible / worth it to remember this as a forgettable property stored in the Scope itself, rather than in B, so that one could re-instantiate the scoped variables with the same name.

I'm not sure whether this is clearly explained. In my use case, I have some dependent types like:

∀ (A : Type) (v : A) , Type

And, when representing them using bound, the binder v gets completely forgotten (which makes sense, since it has no occurrence). But for debugging purposes, it'd be nice to be able to have the Scope remember it.

Let me know what people think about this. Is this unwanted/unfeasible for some reason I'm not thinking about?

bound-2 won't build with current `stack`

[1 of 2] Compiling Main             ( /tmp/stack11223/bound-2/Setup.lhs,
/tmp/stack11223/bound-2/.stack-work/dist/x86_64-linux-ncurses6/Cabal-
1.24.2.0/setup/Main.o )

/tmp/stack11223/bound-2/Setup.lhs:24:1: error:
    Failed to load interface for ‘Warning’
    Use -v to see a list of the files searched for.

I checked the source tarball and it seems like Warning.hs is missing entirely.

Edward mentioned to tag you @phadej to fix it.

Trouble implementing `Monad` instance when scoping more than one term

Sorry to post this as a GitHub issue, this might not be the best venue for such questions.

I used to have a type like:

data Term v
= Constructor (Scope N Term v)

which easily satisfied all the good things we could care about (like Monad).

Now, I would like to have a pair of two terms sharing the exact same scope. My initial approach is the following:

data Paired f v = Paired (f v, f v)

data Term v
= Constructor (Scope N (Paired Term) v)

Unfortunately, the Paired type is not a Monad, because it makes no sense to substitute variables for pairs of terms. It is, however, an instance of Bound, as it supports Paired f a -> (a -> f c) -> Paired f c. I cannot figure out how to write the Monad instance for Term though.

The easy way out is to instead define:

data Term v
= Constructor (Scope N f v) (Scope N f v)

and manually enforce that the scopes are the same.

But I wonder whether the former approach is doomed, or whether I'm just missing something.

Do all the Scope methods that have a requirement Monad f really need this requirement, or is it required because it is expected that f would be a Monad?

ListT instance smells funny

ListT from transformers isn't really a monad transformer, so it seems most unlikely to be a valid Bound instance with the default definition.

Scope doesn't allow the outer constructor to differ from the constructor we abstract over

I tried using bound for extracting equality constraint on meta variables for type reconstruction in a lambda calculus:

data Type b
  = MetaVar b
  | Arrow (Type b) (Type b)
  | TyNat

data ConstraintScheme b
  = Poly (Scope () f b) -- What's f?
  | Mono (Constraints b)

newtype Constraints b
  = Constraints [(Type b, Type b)]

Note that where I mentioned Scope, I want it to unwrap to ConstraintScheme (Var () (Type b)). I think that would only be possible by separating the two occurences of f in Scope, e.g.

newtype Scope g b f a = Scope { unscope :: g (Var b (f a)) }

Is there another way to use bound for tracking unification variables?

two wrongs make a right?

In the example I recently contributed, I made two mistakes which happen to cancel each other out: pInstantiate1 and pAbstract1 both recur over the wrong variable, and as a result bound variables behave like De Bruijn indices instead of De Bruijn levels.

Despite this, the example works fine, because it only manipulates variables via those two functions and they both use the same numbering convention. Since the fix is a bit hairy, maybe it would be better to keep the example as is?

Details after the cut.


the problem

The easiest way to see why this is a mistake is to generalize the signature of pInstantiate so that it accepts a Scope b operand instead of just Scope () operand, just like the original instantiate1 does. The given Prog (Scope b operand) a contains a bunch of Scope b operand a sub-terms, which in turn contain variables of type Var b a, and pInstantiate is supposed to instantiate all the variables of type b with the term x ("instantiate b with x" for short).

pInstantiate1 :: Monad operand
              => operand a
              -> Prog (Scope b operand) a
              -> Prog operand a
pInstantiate1 x (Add ... cc) = Add ... (pInstantiate1 (lift x) cc)

Since cc has type Prog (Scope () (Scope b operand)) a, the recursive call instantiates () with x instead of instantiating b with x. Oops!

the complicated solution

To recur on b instead, I'd need a more general type accepting a Scope b regardless of the number of nested Scope () wrappers under which it is hidden:

pInstantiate1 :: Monad operand
              => operand a
              -> Prog (Scope () (Scope () ... (Scope b operand))) a
              -> Prog (Scope () (Scope () ... operand)) a
pInstantiate1 x (Add ... cc) = Add ... (pInstantiate1 x cc)

I can implement this and pAbstract1 using about 50 lines of type-level machinery, but doing so makes the example a lot less appealing.

the slow solution

To keep the types simple, I can temporarily hide the Scope () within the a, leaving only the Scope b on which we can safely recur, after which I'd recreate the Scope ().

pInstantiate1 :: forall operand a. (Monad operand, Eq a)
              => operand a
              -> Prog (Scope () operand) a
              -> Prog operand a
pInstantiate1 x (Ret o)        = Ret (instantiate1 x o)
pInstantiate1 x (Add o1 o2 cc) = Add (instantiate1 x o1)
                                     (instantiate1 x o2)
                                     cc'
  where
    cc' :: Prog (Scope () operand) a
    cc' = fmap fromJust
        $ pAbstract1 Nothing
        $ pInstantiate1 (fmap Just x)
        $ pInstantiate1 (pure Nothing)
        $ fmap Just cc

This works, but since pAbstract1 is implemented the same way, the complexity for n nested binders is O(3^n), quite steep!


So, what should we do? Keep the morally-wrong-but-working solution, implement the correct-but-complicated solution, or implement the correct-but-slow solution? Or maybe there's a better solution I'm not seeing?

documentation bug in Bound.Scope

traverseBound docs say it works on both bound and free variables, but it clearly is only for bound variables, unlike traverseScope, which does both

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.