deliveredtechnologies / rulebook Goto Github PK
View Code? Open in Web Editor NEW100% Java, Lambda Enabled, Lightweight Rules Engine with a Simple and Intuitive DSL
Home Page: http://www.deliveredtechnologies.com
License: Apache License 2.0
100% Java, Lambda Enabled, Lightweight Rules Engine with a Simple and Intuitive DSL
Home Page: http://www.deliveredtechnologies.com
License: Apache License 2.0
You have lots of features and if you could document everything clearly, it will be really useful.
Hi Clayton,
Usage of Java8 features (especially Optional) can be improved.
I suggest you to put an eye on this article :
https://dzone.com/articles/optional-ispresent-is-bad-for-you
Also you should consider returning Optional in your API when the attribute can be null (like next rule).
Again, great work !
If you are using POJO Rules, this is a non-issue. But if you are using the Java DSL, then mixing types of Facts is cumbersome since generics suppose all Facts are of the same type.
This should be an easier thing to do. I'm thinking that a RuleBook can be of an unspecified type and then Rules of any type can be added. Facts of all types would be chained across Rules. But only Facts of the type of the Rule would be available in the When and Predicate, still keeping the lambda syntax pretty streamlined.
When using POJO-Rules with Spring, is there any way to configure a Rule as last Rule, like in the DSL-examples: addRule(RuleBuilder.create().....stop().build());
? Im looking for a way to create a rulebook with different rules that can be executed exclusively (like "only execute the first matching rule"), so i could have a default rule with low order to be executed if there has been no more specific matching rule before.
Don't know if i just haven't found the correct way or there's no way to do this at the moment. And if there's no way to do this at the moment, would it make sense to add this feature or is this a strange use case?
Hi. This is an awesome library!
Suppose the following:
then
method on a rule evaluation.In my use case, is it possible to configure RuleBook
or each individual rule in such a way that any unhandled Exceptions stop the rule book evaluation and have the Exception bubble up back to the caller? Is there a better way to handle this scenario?
Thanks again!
Thread safety in POJO RuleBooks requires different instances of RuleBooks per thread since state is stored in the Rules. This allows the interface to very intuitive. But unfortunately, it also means that each thread needs its own POJO RuleBook. I think the solution is to have Facts injected as parameters instead of instance variables.
Hi,
I'm trying to use RuleBook version 0.5 in my Spring-application. It seems like the when-part will never be evaluated, so I access for each rule the then-part.
First there comes my code, then the issue is explained with a little bit more details.
My Pom contains:
<dependency>
<groupId>com.deliveredtechnologies</groupId>
<artifactId>rulebook-core</artifactId>
<version>0.5</version>
</dependency>
<dependency>
<groupId>com.deliveredtechnologies</groupId>
<artifactId>rulebook-spring</artifactId>
<version>0.5</version>
</dependency>
Like in the wiki/readme told I created a @Configuration-bean:
@Configuration
public class RuleBookSpringConfig {
@Bean
public RuleBookFactoryBean ruleBook() throws InvalidClassException {
return new RuleBookFactoryBean("my.package.rulebook.myRules");
}
}
I defined one rule in the package:
@Rule(order =1)
public class MyRule {
public MyRule() {}
@Given("field")
private myClass field;
@When
public boolean when() {
System.out.println("Evaluate condition");
return field.isPropertySet();
}
@Then
public RuleState then() {
System.out.println("Rule is correct");
return RuleState.NEXT;
}
}
This rule is used here:
NameValueReferableMap<FieldMetaElement> facts = new FactMap<>();
facts.setValue("field", instanceOfMyClass);
this.ruleBook.run(facts);
If I run the code, my output is every time Rule is correct
, wether the property is set or not. The output Evaluate condition
is never displayed. So I changed the when-part to:
@When
public boolean when() {
return false;
}
The output is every time Rule is correct
again. If I set a breakpoint to when()
it does not stop there. So the when-part is not executed at every time.
If I set a breakpoint at com.deliveredtechnologies.rulebook.model.runner.RuleAdapter.class
line 126 - public Predicate<NameValueReferableMap> getCondition()
the application does not stop there. Same at com.deliveredtechnologies.rulebook.runner.RuleAdapter.class
line 121 - public Predicate getWhen()
.
I tried to use a manually instance of RuleBook without spring and have exactly the same situation.
Same situation comes if I use a rule with a Result or more rules.
The imports at the rule-class are:
The imports at the rule-usage-class are:
The import at Spring-configuration is:
Hi Clayton, I have a question. Is it possible to re-use a RuleBook instance? So, is it possible to call run method in a cycle for example ? Thanks.
I understand one can apply multiple rules to any value on the facts map.
But what if I have a List of objects that I want to have evaluated by the same rule pipeline?
Imagine I have something like:
List<Person> people = new ArrayList<Person>();
people.add(new Person("Steve", 30));
people.add(new Person("Eddie", 42));
people.add(new Person("Mary", 32));
RuleBook ruleBook = ruleBookBuilder.addRule(RuleBuilder.create().withFactType(JsonObject.class)
.when(person -> person.age < 40)
.then(person -> person.getName())
.build()).build();
ruleBook.run(people);
-------OUTPUT------
Steve
Mary
It seems that if I want to put a List/Set of objects through a rule pipeline at the moment I always need to recreate a new Rulebook, is this right?
hellowordrule.txt
example4.1.txt
Hi Clayton,
Running the Hello World example using bogus facts the rulebook.getResults().isPresent() is true. Should the results be false? I was expecting a Null value.
Running the Hello World example using RuleBookBuilder using bogus facts the rulebook.getResults().isPresent() is false. Which is what I expected.
Love the RuleBook. Keep up the good work.
cheers,
Kent
There are some formatting things that should be cleaned up before the first official release.
Hi
If I want to add a bunch of rules, where I want the result to contain success ONLY if all rules are successful, is this possible currently. So, lets say that I have two rules, the first one checks if a user is Male, the second checks whether the users age is less than 40. If the user happens to be female, then the first rule will return false, but the second rule will still process. If the second rule returns true (the user is less than 40), then the rulebook result is true, even though I actually want it to be false. Essentially I'd like to be able to stop the chain should a rule fail, but this doesn't look possible. Is there another way of doing this possibly ?
Thanks
Darrell
Practically, this shouldn't be a huge issue since RuleBooks are likely instantiated each time they are to be used (Spring does this with prototype) and therefore run() would likely only be called once per RuleBook instance. However, if a developer wanted to create a single instantiation of a RuleBook class and re-run it then there could be an issue with rules running multiple times unintentionally. This should be corrected in a minor release.
Can you explain what the expected behavior would be for setting RuleState to next/break vs setting the RuleChainActionType to continue/stop on failure? I noticed setting STOP_ON_FAILURE automatically sets the rule to RuleState.NEXT. Just looking for some clarity on these values.
I'm thinking that it would be cool to be able to have rules stored outside of the application (and the JVM) and have RuleBook be able to point to those rules and use them.
Supported languages and format is currently TBD. Maybe Groovy?
Hi, I tried to do the simple Hello World example to see how the library generally work, but the result is a little bit funky.
Here is the code I wrote:
import com.deliveredtechnologies.rulebook.FactMap;
import com.deliveredtechnologies.rulebook.NameValueReferableMap;
import com.deliveredtechnologies.rulebook.Result;
import com.deliveredtechnologies.rulebook.lang.RuleBookBuilder;
import com.deliveredtechnologies.rulebook.model.RuleBook;
import com.deliveredtechnologies.rulebook.lang.RuleBuilder;
import com.deliveredtechnologies.rulebook.Rule;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.lang.String;
class ruletest{
public static void main(String [] arg){
NameValueReferableMap factMap = new FactMap();
factMap.setValue("hello", "Hello");
factMap.setValue("world", " World");
RuleBook ruleBook = RuleBookBuilder.create().withResultType(Integer.class)
.addRule(rule -> rule.withFactType(FactMap.class)
.when(f -> f.containsKey("hello") )
.using("hello").then(t -> System.out.println(1) ))
.addRule(rule -> rule.withFactType(FactMap.class)
.when(f -> !f.containsKey("hello_2"))
.then(t -> System.out.println(2) ))
.build();
ruleBook.run(factMap); //return 2. However it should be 1
System.out.println(factMap.containsKey("hello")); //Return true
}
}
When I run the code, it seems that it is not working. the expected result should be 1 instead of 2.
Thank you for the help.
Wish you have a good day
Hi,
I have several rules, each having to be triggered (when is true) and so each one should return the name of the winner (some String value). I have been wondering if you have an advice to give me to achieve that. I thought about creating a RuleBook instance per rule, but this is quite tedious and messy. Also, I am using Spring and the Rule logic is quite long, so either I'd have to create a package per Rule (quite messy!) or I'd have to use addRule() on each Rule instance and instanciate them manually.
Thanks!
Valentin
Specialized Spring support for RuleBook isn't really needed anymore. RuleBook can now be easily used with Spring.
Also, there's some old RuleBook code left over from the early days of RuleBook that's only kept there for backwards compatibility purposes. v1.0 should see that old code removed.
I think the time has come to include complete working project examples in the GitHub source. Suggestions are welcome. Contributions are encouraged.
Hi,
I'm trying to integrate RuleBook in an enterprise project, because it seems to be really interesting.
I'm using version 0.5 and found that first run returns a default value because headRule is not correctly valued in CoRRuleBook.run method. These are the steps I did:
public class AutoEvaluationRuleBook extends CoRRuleBook<MyBean> {
@Override
public void defineRules() {
// here I define all my business rules
}
}
RuleBook<AutoEvaluationResult> autoEvaluationRuleBook = RuleBookBuilder.create(AutoEvaluationRuleBook.class)
.withResultType(AutoEvaluationResult.class)
.withDefaultResult(new AutoEvaluationResult(null, false, false, null))
.build();
List<NameValueReferableMap<MyBean>> factsList = testCases();
factsList.forEach(x -> {
count++;
autoEvaluationRuleBook.run(x);
autoEvaluationRuleBook.getResult().ifPresent(result -> {
MyBean ref = result.getValue().getRef();
System.out.println(String.format("%s. Item: %s, Autoevaluated: %s, Suspect: %s, Reason: %s", count,
null != ref ? "item" : "NULL", result.getValue().isAutoEvaluated(),
result.getValue().isSuspect(), null != result.getValue().getReason() ? result.getValue().getReason().name() : "NULL"));
});
});
In this way, the first run returns an unexpected result because I noticed in the run method inside the CoRRuleBook class the object headRule is not valued.
The original code:
@Override
@SuppressWarnings("unchecked")
public void run(NameValueReferableMap facts) {
// here an Optional obj wraps the class property _headRule
Optional<Handler<Rule>> headRule = Optional.ofNullable(_headRule);
if (!headRule.isPresent()) {
// if not present (first run), you call defineRules()
defineRules();
}
// here headRule Optional value is still null, is it wanted ?
headRule.ifPresent(ruleHandler -> {
ruleHandler.getDelegate().setFacts(facts);
getResult().ifPresent(result -> ruleHandler.getDelegate().setResult(result));
});
headRule.ifPresent(Handler::handleRequest);
}
In the original code if the headRule is not present, it calls the defineRules, defining the book rules, but after that the method isPresent is called on the Optional<Handler> headRule object which will return false. Is this wanted ?
I modified this code in this way:
@Override
@SuppressWarnings("unchecked")
public void run(NameValueReferableMap facts) {
Optional<Handler<Rule>> headRule = Optional.ofNullable(_headRule);
if (!headRule.isPresent()) {
defineRules();
// new added line below, rules are defined but object is still not present
headRule = Optional.ofNullable(_headRule);
}
headRule.ifPresent(ruleHandler -> {
ruleHandler.getDelegate().setFacts(facts);
getResult().ifPresent(result -> ruleHandler.getDelegate().setResult(result));
});
headRule.ifPresent(Handler::handleRequest);
}
In this way I have all the objects valued correctly (also the first one).
Let me know.
Thanks and best regards,
Alessandro Torrisi.
I don't think the MegaBank Example With POJO Rules are documented properly and even its working ?
I tried to simulated MegaBank Example With POJO Rules but the rules are not getting invoked.
Result is simply coming null.
Applicant qualified for the following rate: null null
Is it possible to use a Java interface and/or a general class (instead of the concrete type) as the generic type passed to Facts and FactMap and the @given List? I replaced references to ApplicantBean with an interface (IApplicant which declares the expected methods) e.g. FactMap and in the rule:
@given private List applicants
I end up with no objects in the applicants list. I've tried this with a generalized class as well (where concrete classes are specializations of ApplicantBean).
Is there any way we can get the addRule functionality added to the RulebookFactoryBean? Had a setup like below where we created rulebookbeans (at prototype scope) and were able to use the same rules from the same package within different rulebooks. After updating the version I noticed the RuleBookBean is deprecated and you now only have package scanning available for spring created rulebooks.
`@Configuration
public class RulesEngines {
@bean(name="defaultRule")
@scope("prototype")
public RuleBookBean inRuleBook(FilterItemRateMapRule filterItemRateMapRule, InterstateRule interstateRule, IntrastateRule intrastateRule, CountryRule countryRule) throws InvalidClassException {
return getRuleBook(filterItemRateMapRule, interstateRule, intrastateRule,countryRule);
}
@bean(name="indiaRuleMTR")
@scope("prototype")
public RuleBookBean inRuleBookMTR(FilterItemRateMapRule filterItemRateMapRule, InterstateRule interstateRule, IntrastateRuleMTR intrastateRule,CountryRule countryRule) throws InvalidClassException {
return getRuleBook(filterItemRateMapRule, interstateRule, intrastateRule,countryRule);
}
private RuleBookBean getRuleBook(FilterItemRateMapRule filterItemRateMapRule, InterstateRule interstateRule, ApplicableTaxRule intrastateRule, CountryRule countryRule) throws InvalidClassException {
RuleBookBean inRuleBook = new RuleBookBean();
inRuleBook.addRule(filterItemRateMapRule);
inRuleBook.addRule(countryRule);
inRuleBook.addRule(interstateRule);
inRuleBook.addRule(intrastateRule);
return inRuleBook;
}
}
`
Arrays in POJO rules can only be injected with String Facts. This is clearly a bug that should be resolved.
Hello again.
Is it possible to include multiple object types in one FactMap, after setting the FactType in the ruleBuilder? Example:
I'm first building the rule with a FactType of Deduction.class:
private RuleBuilder<Deduction,Boolean> getDeductionRuleBuilder(){ return RuleBuilder.create().withFactType(Deduction.class).withResultType(Boolean.class); }
When I setup my FactMap, I have a Deduction and String object I want to pass in:
private NameValueReferableMap getFactMap(Deduction deduction, String state) { NameValueReferableMap facts = new FactMap<>(); facts.setValue("deduction", deduction); facts.setValue("state", state); return facts; }
Here's an example rule I have defined:
addRule(getDeductionRuleBuilder() .when(facts -> facts.getOne().getType().equals(SOME_EQUALITY_CHECK)) .then((factMap, booleanResult) -> { System.out.println(factMap.getStrVal("state")); booleanResult.setValue(Constants.SOME_OTHER_CHECK.contains(factMap.getStrVal("state"))); }).stop().build());
So, when I execute the Rule, obviously the Deduction fact is retained, however the String object seems to get cut out of the factmap, and it returns false because it can't evaluate the "state" Fact. I realize I could easily create a container object to hold the Deduction and String object. However, I wanted to make sure there was no other way to create a FactMap of various object types to be used in a RuleBook.
Rules and Decisions can be very nicely wired up with lambda. But [eventually] there should be support for wiring rules up without lambda and without the DSL (even though, this is very cool :).
What if given(), when() and then() methods could take in Facts, Predicates and Functions, respectively, but also be defined in a Rule class (by the developer)? That might be pretty cool. So, it could be an either/or situation. And thenRules or Decisions could then be added to a Book or mixed with other Rule types.
RuleBook can already be used easily with Spring. But there are a few things the developer has to be aware of: the Rules, Decisions and Books must be prototypes because they persist state which may be interrupted and changed if they were singletons.
There might be some other useful stuff that can be streamlined for Spring support, too.
There are a couple of things in the new DSL that are a bit cumbersome. Retrieving results is one of those things. Maybe it could be cleaned up a bit.
Defining rules in Java using Lambda is awesome. But Groovy doesn't currently support Lambda; it uses Groovy closures.
Given how much I personally love Groovy and that Groovy scripting could be used to externalize (and version) RuleBooks, I think RuleBook needs to be Groovy too!
Separate the interface (flow) from the API.
Rules Engine uses CoR for sequential rules evaluation. It works! And for many situations, it's serves the need. However, for more ambitious applications, it would be nice to have other algorithms for rules evaluation available. The catch is that other algorithms should have a sequential dependency component to provide predictable execution between dependent rules. In addition, rules evaluation algorithms should be pluggable - the library certainly allows for it.
This is not pressing. On the 1. Make it work 2. Make it good 3. Make it fast hierarchy, it's definitely in the 3rd category. And there are other things (like versioning and BDSL) that should take precedence. But this is something that will be needed at some point down the line.
The MegaBank example won't work correctly with POJOs since POJOs cannot currently be injected with a grouping of objects stored in different facts. Right now, it only injects based on the name. However, in the MegaBank example, the name might not be known ahead of time, nor would the number of Facts.
This should probably be fixed before the next minor release.
currently spelled with Deafult Result
It comes to mind that it might be useful to have an audit of rules available. Say, for example, I have a RuleBook that contains many different rules. When I run that RuleBook, some rules might fire, some rules might not. It might be nice to know which rules executed.
I'm thinking rules could be audited by name. That means, each rule should have a name. By default, it could be the classname of the Rule. But if a String name is specified, then it would be the name specified.
As I understand it, the ApplicantNumberRule only allows loan applications with 3 or fewer applicants to be processed, i.e. if greater than three applicants then processing is halted. In my main method I supplied 4 applicants:
RuleBookRunner ruleBook = new RuleBookRunner("rules");
NameValueReferableMap<ApplicantBean> facts = new FactMap<ApplicantBean>();
ApplicantBean applicant1 = new ApplicantBean(650, 20000, true);
ApplicantBean applicant2 = new ApplicantBean(620, 30000, true);
ApplicantBean applicant3 = new ApplicantBean(620, 30000, true);//same as applicant2
ApplicantBean applicant4 = new ApplicantBean(900, 30000, true);
facts.put(new Fact<>(applicant1));
facts.put(new Fact<>(applicant2));
facts.put(new Fact<>(applicant3));
facts.put(new Fact<>(applicant4));
ruleBook.setDefaultResult(4.5);
ruleBook.run(facts);
ruleBook.getResult().ifPresent(result -> System.out.println("Applicant qualified for the following rate: " + result));
output:
Applicants count:3
Applicant qualified for the following rate: 3.3
Because two of the applicants have the same facts.
If I change one of the repeated applicants so that all the applicants are unique the rule fires as expected (4 applicants).
Is this a bug or a feature?
P.S. also the code copied and pasted from the readme did not compile with some missing ")"s
A default result is required when a RuleBook has a result. However, the DSL does not enforce setting a default result before a RuleBook is built. This can be misleading. The DSL should be updated to make it clear that when a result type is specified, a default result must also be specified.
Execution order was included in POJO rules, but it was not verified. It should be verified to ensure that facts and/or results are used & modified in the order specified.
A Boolean and BigDecimal conversion should also be included.
Hi, is there some way to have like an "else" for a rule? I have to run a set of rules, but I need to know which one "passed" and which ones not, so I was thinking about having a Result consisting on a list of "states" for each rule ran.
The problem is, I have no access to the "result" in the "when" rule part, and the "then" is never ran if the rule result is false. Is there any way to achieve this with Rulebook? Thanks in advance!.
Hello,
Was trying to run through your HomeLoan example and it doesn't appear to be returning any result. I have the ApplicantBean and the Main classes copied verbatim. However instantiating the HomeLoanRateRuleBook object gives me a compile error because the following is incompatible:
HomeLoanRateRuleBook homeLoanRateRuleBook = RuleBookBuilder.create(HomeLoanRateRuleBook).withResultType(Double.class) .build();
Results in "Incompatible types". Required HomeLoanRateRuleBook, found RuleBook
If I try casting as HomeLoanRateRuleBook or even setting the variable as:
RuleBook<Double> homeLoanRateRuleBook = RuleBookBuilder.create(HomeLoanRateRuleBook).withResultType(Double.class) .build();
It does not work. Any time I run through the steps the RuleBook result (_result) is coming back null. Only when I specify a defaultResult does it return a value back. Any ideas?
You can tell me if I'm just not using it correctly, but --
If I pass a single POJO as Given, I retrieve the List in my rule and process it as normal, as your documentation states. However, trying to pass a collection seems to result in the object either being swallowed up and spit out as null, or as an empty List. I can provide an example if needed.
I like where this library is going so I am giving it a shot. The main problem I've encountered that I don't seem to find a workaround for is this FileSystemNotFoundException
that occurs when I run the RuleBook standalone (I am using the annotated classes not the Java DSL). Everything works fine in IntelliJ but if I try to just java -jar target/long-jar-name.jar
from the command line it fails. I am running this in a standard Spring Boot app.
It appears that the problem could be how the Paths are created using NIO: https://stackoverflow.com/questions/22605666/java-access-files-in-jar-causes-java-nio-file-filesystemnotfoundexception
I am using version 0.8 pulled from Maven Central. Here is what the exception looks like:
2017-09-12 23:18:22 [http-nio-8080-exec-3] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.nio.file.FileSystemNotFoundException] with root cause
java.nio.file.FileSystemNotFoundException: null
at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
at java.nio.file.Paths.get(Paths.java:143)
at com.deliveredtechnologies.rulebook.model.runner.RuleBookRunner.findRuleClassesInPackage(RuleBookRunner.java:120)
at com.deliveredtechnologies.rulebook.model.runner.RuleBookRunner.run(RuleBookRunner.java:68)
Is RuleBook thread safe for multithreading environment?
Should I create an instance for each thread for rule evaluation?
In the below example where using is used(highlighted in bold):
RuleBook ruleBook = RuleBookBuilder.create().withResultType(String.class)
.withDefaultResult("Unknown!")
.addRule(rule->rule.withFactType(String.class)
.when(f->f.containsKey("hello") && f.containsKey("world"))
.using("hello").then(System.out::print)
.using("world").then(System.out::println))
.build();
The outcome is actually object reference like:
com.deliveredtechnologies.rulebook.TypeConvertibleFactMap@5f4da5c3com.deliveredtechnologies.rulebook.TypeConvertibleFactMap@443b7951
Instead of "Hello World"
Rules should be able to be versioned independently of the application code. When a new version of rules is published, the application should load the newly published rules and start running the new rules version in place of the old one.
A couple of things to consider:
Initially, repositories for rules could be Maven. Maybe later, Git could be supported.
Hello, just moved to 0.8 from 0.7. Prior to and after the update, I'm getting these debug statements in my output when trying to build rules. However, the rules are being loaded and executed properly as all my testing is passing successfully. I've tried different variations of below and still end up with the log statements. Any ideas?
14:30:59.143 [main] DEBUG c.d.rulebook.lang.RuleBuilder - Unable to create an instance of the specified Rule class 'class com.deliveredtechnologies.rulebook.model.GoldenRule' with fact and result types specified
`public class CanadaRules extends CoRRuleBook{
Override
protected void defineRules() {
addRule(getCalculatorRuleBuilder()
.when(fact -> isRequestTypeDonation(fact.getOne()))
.then((fact, result) -> {
Map<Item,List> appliedItemRateMap = getAppliedItemRateMap(fact.getOne());
result.setValue(createResult(appliedItemRateMap));
}).stop().build());
private RuleBuilder<CalculatorFact, BusinessRulesResult> getCalculatorRuleBuilder() {
return RuleBuilder.create().withFactType(CalculatorFact.class).withResultType(BusinessRulesResult.class);
}
}`
Unit Tests for StandardRule need to be completed
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.