vaticle / typeql Goto Github PK
View Code? Open in Web Editor NEWTypeQL: the polymorphic query language of TypeDB
Home Page: https://typedb.com
License: Mozilla Public License 2.0
TypeQL: the polymorphic query language of TypeDB
Home Page: https://typedb.com
License: Mozilla Public License 2.0
Previously, Compute had its own independent architecture, separate from the rest of the queries. This feels very "accidental" as it was a consequence of implementing Compute without thinking through a cohesive design that integrates well. However, they should ideally be integrated together.
We need to implement an autocompletion tool to be used by an editor or console, that takes the ANTLR grammar into consideration, rather than string completion of a word. This has been done before, and we can research the best ways to do it. Here's a good start to look at a complete example: https://tomassetti.me/autocompletion-editor-antlr
Currently, rules look like any other schema type (eg. Entity, Attribute, Relation). This leads to confusion because they are defined the same way as these types, eg define newrule sub rule...
, which implies that they may be written in hierarchies themselves. However, we do not have any meaning ascribed to subtyping existing rules.
Core questions:
subtyping
of rules mean semantically? Currently, it is allowed syntacticallyrule
is not a concept type (we have no rule type instances, only exist on the schema level for now). So really should a rule
even exist in the same hierarchy of Thing
that it sits in now?This issue was originally posted by @haikalpribadi on 2018-01-13 18:08.
This issue needs #3763, needs #3809, needs #4005, needs #4062
This issue was originally posted by @haikalpribadi on 2018-04-05 14:23.
This issue was originally posted by @haikalpribadi on 2017-01-18 16:31.
The ability to perform the following basic functions in graql:
This issue was originally posted by @haikalpribadi on 2017-04-24 13:31.
match $a isa cancer; ($a, $b); $b isa mirna; ($b, $c); ($c, $d); $d isa gene; ($d, $e); $d isa drug; offset 0; limit 3;
In the query above, I defined $d
to have two types (that are not an abstraction of one another). This query should not be allowed: a) it should return an error that explains why. b) it should not try to execute the traversal.
This issue was originally posted by Harry Blakiston Huoston on 2018-08-26 09:06.
This is a question at first but may turn into a feature request.
Does grakn support any non-strict attribute requests i.e lets say I am fetching personal information belonging to a person that can either be a phone or an address (both separate child entities of a common entity "property") the two will share a field detail (either +447773078736) or (Flat 70) respectively, then the address may have additional attributes (street, province, city, postalCode and country). A query that allowed me to fetch just the detail if the entity is a "phone" and then the detail, street, province, city, postalCode and country if the entity is an "address".
The naming for asUserDefined
variables is very confusing - it actually means whether or not to retrieve the variable as part of the answer.
Propose renaming var.asUserDefined()
and var.isUserDefinedName()
to var.asRetrievedVar()
and var.isRetrieved()
.
We would like to be able to query directly played/related/owned types, without inheritance.
match $p isa person; $r($t: $p) isa employment; $t plays! employee; get $t;
The exclamation mark raises an error.
It would be nice if this were possible and returned only the directly owned/related/played connections and excluded the inherited ones.
At the moment Graql does not support utf-8 labels like
define Kläger sub entity;
or define übermorgen sub relation;
but it'd be great if it would. This would allow non english "non-techies" a easier interaction when they trying to model with GraKn.
I'd would need to create an extra Layer in my NLP-Lib to change German Words that describe certain entities or relations to replace äöüÄÖÜ
and ß
with another representation. But it would highly decrease readbility and acceptance with my target audience.
Support utf-8 as type labels (or in Graql in general)
This issue was originally posted by @jmsfltchr on 2018-08-31 12:51.
Encountered an unintuitive error message when loading a gql file.
define name sub attribute datatype string;
Given the above, when making the below (incorrect) query, the user should be told more explicitly that they didn't provide a value for attribute name.
>>> insert $n isa name; INVALID_ARGUMENT: GraqlQueryException-missing expected property `` in `$n isa name`. Please check server logs for the stack trace. >>>
Server log:
2018-08-31 12:04:07,885 [grpc-default-executor-46] ERROR a.g.e.r.SessionService$TransactionListener - Runtime Exception in RPC TransactionListener: ai.grakn.exception.GraqlQueryException: missing expected property `` in `$n isa name` at ai.grakn.exception.GraqlQueryException.create(GraqlQueryException.java:89) at ai.grakn.exception.GraqlQueryException.insertNoExpectedProperty(GraqlQueryException.java:211) at ai.grakn.graql.internal.query.executor.ConceptBuilder.useOrDefault(ConceptBuilder.java:339) at ai.grakn.graql.internal.query.executor.ConceptBuilder.use(ConceptBuilder.java:355) at ai.grakn.graql.internal.query.executor.ConceptBuilder.putInstance(ConceptBuilder.java:415) at ai.grakn.graql.internal.query.executor.ConceptBuilder.tryPutConcept(ConceptBuilder.java:247) at ai.grakn.graql.internal.query.executor.ConceptBuilder.build(ConceptBuilder.java:184) at ai.grakn.graql.internal.query.executor.QueryOperationExecutor.buildConcept(QueryOperationExecutor.java:270) at java.util.HashMap.forEach(HashMap.java:1289) at ai.grakn.graql.internal.query.executor.QueryOperationExecutor.insertAll(QueryOperationExecutor.java:256) at ai.grakn.graql.internal.query.executor.QueryOperationExecutor.insertAll(QueryOperationExecutor.java:102) at ai.grakn.graql.internal.query.executor.QueryExecutorImpl.run(QueryExecutorImpl.java:84) at ai.grakn.graql.internal.query.InsertQueryImpl.stream(InsertQueryImpl.java:81) at ai.grakn.engine.rpc.SessionService$TransactionListener.query(SessionService.java:235) at ai.grakn.engine.rpc.SessionService$TransactionListener.handleRequest(SessionService.java:142) at ai.grakn.engine.rpc.SessionService$TransactionListener.lambda$onNext$0(SessionService.java:117) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
Has the GRAKN team ever thought to implement natural language to graql via machine learning models and datasets similar to https://github.com/salesforce/WikiSQL and other efforts using SQL and Neo4j's Cypher?
Given the effort to make GRAKN easy to use, NLP batteries included would be a very compelling feature I think!
This issue was originally posted by @haikalpribadi on 2017-08-30 12:26.
How can we remove a specific roleplayer from a relation? In the Java API, it could be as simple as:
relation.removeRolePlayer(instance);
But how do we do that with Graql? We have two options on the table:
Use a new keyword to flag the role player to be deleted:
match $r (actor NEW-KEYWORD $c: $x); $x isa person; delete $c;
Make the deletion part take in patterns:
match $r (actor: $x); $x isa person; delete $r (actor: $x);
Option 2 makes delete behave a lot like undefine which is nice but it may make get look like the odd one out. Insert and Delete take patterns but get only takes in a list of variables. Not sure how bad that is.
This issue was originally posted by @jmsfltchr on 2018-07-09 20:47.
If you make the mistake of already having a concept defined in your keyspace, but try to load a file that declares that concept to have a different type, you get a slightly cryptic error message, like:
The concept [Base Type [ENTITY_TYPE] - Id [V28736] - Label [led-observation] - Abstract [false] ] is not of type [interface ai.grakn.concept.RelationshipType]
Allegedly, we should be able to distinguish between a duplicate definition in a file and a pre-existing concept in the current schema.
This issue was originally posted by @jmsfltchr on 2018-06-21 11:53.
The following doesn't return all companies that have names:
match $x isa company has name; get;
What works is:
match $x isa company has name $y; get;
This issue was originally posted by @haikalpribadi on 2018-04-09 12:35.
$x plays! $y;
$x sub! $y;
$x relates! $y;as well as java methods playsExplicit
, subExplicit
, relatesExplicit
I'm trying to run the phone_calls
example 2 query (with the negation query as per this PR). It fails to run when negation is used; however when the negation term is not used, the query runs without any issues.
Steps to create the smallest reproducible scenario:
grakn console -k phone_calls -f ./examples/schemas/phone-calls-schema.gql
python3 ./examples/phone_calls/python/migrate_json.py
examples/phone_calls/python/queries.py
)
match
$suspect isa person, has city "London", has age > 50;
$company isa company, has name "Telecom";
(customer: $suspect, provider: $company) isa contract;
$pattern-callee isa person, has age < 20;
(caller: $suspect, callee: $pattern-callee) isa call, has started-at $pattern-call-date;
$target isa person, has phone-number $phone-number;
not { (customer: $target, provider: $company) isa contract; };
(caller: $suspect, callee: $target) isa call, has started-at $target-call-date;
$target-call-date > $pattern-call-date;
get $phone-number;
2019-11-26 17:05:20,805 [grpc-request-handler-13] ERROR g.c.s.r.SessionService$TransactionListener - Runtime Exception in RPC TransactionListener:
io.grpc.StatusRuntimeException: CANCELLED: cancelled before receiving half close
at io.grpc.Status.asRuntimeException(Status.java:517)
at io.grpc.stub.ServerCalls$StreamingServerCallHandler$StreamingServerCallListener.onCancel(ServerCalls.java:272)
at io.grpc.internal.ServerCallImpl$ServerStreamListenerImpl.closed(ServerCallImpl.java:293)
at io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1Closed.runInContext(ServerImpl.java:741)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
2019-11-26 17:05:20,811 [transaction-listener] ERROR g.c.s.r.SessionService$TransactionListener - Runtime Exception in RPC TransactionListener:
java.lang.NullPointerException: null
ERROR:grpc._common:Exception deserializing message!
Traceback (most recent call last):
File "/home/pprao/Desktop/GitHub/graphdb-examples/venv/lib/python3.6/site-packages/grpc/_common.py", line 88, in _transform
return transformer(message)
google.protobuf.message.DecodeError: Error parsing message
Traceback (most recent call last):
File "/home/pprao/Desktop/GitHub/graphdb-examples/venv/lib/python3.6/site-packages/grakn/service/Session/TransactionService.py", line 156, in send
response = next(self._response_iterator)
File "/home/pprao/Desktop/GitHub/graphdb-examples/venv/lib/python3.6/site-packages/grpc/_channel.py", line 364, in __next__
return self._next()
File "/home/pprao/Desktop/GitHub/graphdb-examples/venv/lib/python3.6/site-packages/grpc/_channel.py", line 358, in _next
raise self
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
status = StatusCode.INTERNAL
details = "Exception deserializing response!"
debug_error_string = "None"
We should expect to see 12 phone numbers as the output:
[ '+30 419 575 7546', '+86 892 682 0628', '+1 254 875 4647',
'+351 272 414 6570', '+33 614 339 0298', '+86 922 760 0418',
'+86 825 153 5518', '+48 894 777 5173', '+351 515 605 7915',
'+63 808 497 1769', '+27 117 258 4149', '+86 202 257 8619' ]
ERROR message with the full stack trace shown in the logs (for the workbase example) or in the Python stack trace (for the Python client example).
When I remove the line with the negation term, the query works and I get a result. Looks like the issue is with the way the negation term is being parsed.
Right now, we restrict grammar to disallow statements such as match $x; get
. When building with TypeQL language builders, this is still allowed (TypeQL.match(var("x")).get()
) when it should not be.
Further restrictions are currently built into TypeDB's match clause validation at runtime, but not checked elsewhere - such as match $x != $y; get;
which does a n^2 scan of the database. We could push this into TypeQL and do the check when the Pattern is built.
Graql is still a bit terse for some instances, especially when the rule definitions start becoming more involved. SQL is quite English-like but can become verbose, Graql expresses a lot of the same definitions in shorted constructs but maybe some improvements can be done to meet half-way.
Learn the constructs and get acquainted with the language.
Constructs can be arranged in more like a sentence format: subject-verb-object, subject-verb, a number of improvements can be achieved by just rearranging the constructs or maybe renaming them.
From a technical perspective, it could mean extending or enhancing the parser to understand different formats or maybe extending the vocabulary so it knows more words or similar words. End-users could use the existing format or the new proposed format when writing Graql.
I'm happy to suggest literal improvements if you can point me to a resource which lists the lexicon/constructs of the Graql language and some examples of usages.
By making Graql more English-like we could definitely help this idea: typedb/typedb-studio#153 (I have raised this to help the current idea from the other perspective).
In many cases, TypeQL returns syntax errors that correctly identify the location of the syntax error, but make a generic and incorrect suggestion for how to fix it.
TypeDB version (and platform): Core 1.4 upwards
insert $e isa d-entity, has d-key 1;
, missing a commainsert $e isa d-entity has d-key 1;
Error: syntax error at line 1:
insert $e isa d-entity has d-key 1;
^
mismatched input 'has' expecting {'match', 'define', 'undefine', 'insert', 'compute'}
All uncommitted data is cleared
define my-bool sub attribute, datatype boolean;
define my-bool sub attribute, datatype bool;
Error: syntax error at line 1:
define my-bool sub attribute, datatype bool;
^
mismatched input 'bool' expecting {'match', 'define', 'undefine', 'insert', 'compute'}
All uncommitted data is cleared
insert $m isa my-bool; $m false;
insert $m isa my-bool false;
Error: syntax error at line 1:
insert $m isa my-bool false;
^
mismatched input 'false' expecting {'match', 'define', 'undefine', 'insert', 'compute'}
All uncommitted data is cleared
define $m isa my-entity, has name; name sub attribute, datatype string;
define my-entity, has name; name sub attribute, datatype string;
Error: syntax error at line 1:
define my-entity, has name; name sub attribute, datatype string;
^
no viable alternative at input ','
syntax error at line 1:
define my-entity, has name; name sub attribute, datatype string;
^
mismatched input ',' expecting {'match', 'define', 'undefine', 'insert', 'compute'}
All uncommitted data is cleared
define rel sub relation, relates has;
(uses a keyword as role)define
rel sub relation, relates has;
[TQL03] TypeQL Error: There is a syntax error at line 2:
rel sub relation, relates has;
^
mismatched input 'has' expecting {'get', 'thing', 'entity', 'attribute', 'relation', 'role', 'rule', 'offset', 'limit', 'sort', 'value', 'contains', 'group', 'count', 'max', 'min', 'mean', 'median', 'std', 'sum', VAR_, LABEL_}
In each case, the suggestion expecting {'match', 'define', 'undefine', 'insert', 'compute'}
is misleading. In all of these cases using these options is not valid. Ideally, the user should be prompted with all of the possible options that they could use instead at the point where their syntax is incorrect. At the least, they should be simply told the location of their syntax error, and not misguided.
This issue was originally posted by @haikalpribadi on 2017-04-06 16:59.
This issue was originally posted by @haikalpribadi on 2018-03-27 14:45.
For example:
general-data-link sub relationship,
relates linked-data,
special-data-link sub general-data-link,
relates special-linked-data as linked-data, # overrides super role
relates some-reference, # new role
has special-name;
Will be closed immediately to test the webhook
In conjunction with: typedb/typedb#4946
This issue was originally posted by @haikalpribadi on 2018-09-18 15:06.
This issue was originally posted by @haikalpribadi on 2018-04-10 19:25.
This issue was originally posted by @haikalpribadi on 2016-04-29 13:36.
e.g.
match $x isa person value ~= "James"
This issue was originally posted by @haikalpribadi on 2016-10-12 11:03.
An example of a simple query involving a single relation:
match
(director: $jc, $m);
$jc has name "James Cameron";
$m has title $t;
select $t;
While queries such as the above are clear in their meaning, they take time to type and for users to parse. Experienced users may find it frustrating to repeatedly type these queries out.
This could be resolved by allowing nesting or "inlining" roleplayers, turning this into a one-liner:
match (director: has name "James Cameron", has title $t);
So the above would find titles of movies directed by something with name "James Cameron".
Unfortunately, if we were to allow this nesting of roleplayers then the above becomes ambiguous to parse. It's not clear whether another roleplayer has title $t
, or if James Cameron has title $t
.
This ambiguity is because commas are used to separate roleplayers, but can also optionally be used to separate properties.
Remove optional commas
This can be resolved by not allowing separating properties with commas.
This can lead to ugly one-line statements:
movie ako production plays-role production-with-cast has-resource title;
However, in practice, people are not using the commas anyway. They are instead writing the above like this:
movie ako production
plays-role production-with-cast
has-resource title;
See moogi and pokemon for examples.
Separate roleplayers with a semicolon
Another choice is to use semicolons to separate roleplayers:
match (director: has name "James Cameron"; has title $t);
Semicolons are already being used to separate variable patterns, so it makes total sense here. The only issue is that semicolons inside brackets might look strange.
Strictly speaking, there should be a semicolon after the last roleplayer too, but it looks really, really bad so let's not:
match (director: has name "James Cameron"; has title $t;);
Braces
Another option is to require braces (or similar) around nested properties:
match (director: {has name "James Cameron"}, {$x isa movie});
This is not particularly pretty, but fairly consistent with our use of curly braces to nest queries already. It also allows us to nest variables anywhere. For example, instead of:
match
$x isa $y;
$y plays-role actor;
we can say:
match $x isa {plays-role actor};
Mandatory variable names
Another is to always require a variable name for a roleplayer:
match (director: $y has name "James Cameron", $x isa movie);
select $x;
This eliminates one of the major benefits of the syntax: not requiring a variable name can allow for much shorter queries, by avoiding unused variable names and pointless select statements, such as select $x above.
Comparison example
"titles of movies directed by James Cameron":
Old syntax:
match
(director: $jc, $m);
$jc has name "James Cameron";
$m has title $t;
select $t;
Disallow commas:
match (director: has name "James Cameron", has title $t);
Separate roleplayers with semicolons:
match (director: has name "James Cameron"; has title $t);
Braces:
match (director: {has name "James Cameron"}, {has title $t});
Mandatory variable names:
match
(director: $jc has name "James Cameron", $m has title $t);
select $t;
This issue was originally posted by @jmsfltchr on 2018-05-29 20:46.
It's unlikely TypeQL will be considered mainstream enough, since the criteria is for a language to be used in hundreds of repos. However, at some point down the line we want TypeQL to be highlighted on Github and in GitHub Gists. To do this I believe we need to submit a PR to the linguist repo: https://github.com/github/linguist
Currently, it is not possible to use multiple IDs within the same query (the workaround is to use multiple variables). Ideally, I would like it to be supported similar to other attributes like that:
match $x id $id; {$id V168040;} OR {$id V118888;}; get;
Has the GRAKN team ever thought to implement natural language to graql via machine learning models and datasets similar to https://github.com/salesforce/WikiSQL and other efforts using SQL and Neo4j's Cypher?
Given the effort to make GRAKN easy to use, NLP batteries included would be a very compelling feature I think!
Has the GRAKN team ever thought to implement natural language to graql via machine learning models and datasets similar to https://github.com/salesforce/WikiSQL and other efforts using SQL and Neo4j's Cypher?
Given the effort to make GRAKN easy to use, NLP batteries included would be a very compelling feature I think!
This has been reported by a user, when trying to run 2 insert queries as one
(i.e. one query containing 2 inserts insert $x ...; insert $y....;
)
the user only gets back an empty stack trace
I havent reproduced it, but I see that in Parser
there a few comments about detecting errors, so
maybe it's expected behaviour?
User's query was:
"insert $m1 isa maintainer, has identifier ${m1}, has name 'M1';
insert $m2 isa maintainer, has identifier ${m2}, has name 'M2';"
Meaningful error message
Here errorListener.toString()
seems to return empty.
This issue was originally posted by @haikalpribadi on 2016-10-13 16:22.
define
rel sub relation, relates has;
^
mismatched input 'has' expecting {'get', 'thing', 'entity', 'attribute', 'relation', 'role', 'rule', 'offset', 'limit', 'sort', 'value', 'contains', 'group', 'count', 'max', 'min', 'mean', 'median', 'std', 'sum', VAR_, LABEL_}
A runtime match clause check is being executed on the server which ensures that a query with comparisons that may be n^2 is not allowed without further information, such as match $x != $y
or match $x !== $y
, x
and y
could be considered unbounded outside of comparison here.
Further questions that stem from this:
match $x == "john"
- arguably yes, $x has a precise value, though no type information. Is it bounded though?match $x != "John"
- is this unbounded and allowed (along with other non-equality checks such as > and < ?)This issue was originally posted by @haikalpribadi on 2018-01-05 17:22.
Roles will subclass each other using the new as syntax, and rules will not be subclassable to begin with.
The problem that we need to sort out before implementing this is: how do we query for roles and rules in match queries? Thus, we need to design the new syntax for it.
After this, we should consider removing the meta role and rule.
Grakn version: 1.5 SNAPSHOT
define
title sub attribute,
datatype string;
insert $x isa title; $x "/";
the new instance of attribute title
to be created with value "/"
.
Error: syntax error at line 1:
insert $x isa title; $x "/";
^
token recognition error at: '"/'
syntax error at line 1:
insert $x isa title; $x "/";
^
token recognition error at: '";'
syntax error at line 1:
insert $x isa title; $x "/";
^
no viable alternative at input '$x '
syntax error at line 1:
insert $x isa title; $x "/";
^
extraneous input '$x' expecting {<EOF>, 'match', 'define', 'undefine', 'insert', 'compute'}
All uncommitted data is cleared
Implement TypeQL parsing in languages other than Java. This would for instance allow reading entire files of queries into the python or node client without having to hack some custom delimiters into the files and executing line by line within the user's application code.
Derives from: typedb/typedb-driver-python#41
One can either spread custom delimiters in the file that contains definitions or queries and parse these out in the client's application logic, executing them one by one, or write a wrapper around a small client-java
and typeql
program to do this using parseList()
Extend ANTLR to other languages.
This issue was originally posted by @haikalpribadi on 2018-04-22 22:47.
We want to implement a new feature in Graql syntax: the ability to provide a set of arguments to a given graql statement. For example, the ability to provide the following statement in the schema:
define person sub entity, has email [unique, max=3];
Defining multiple ids:
match $x isa person; $x id [V123, V456]; get;
-> useful for KGlib, set-at-a-time reasoning
Defining multiple values:
match $x has name [Bob, Alice, Stefan]; get
Defining multiple labels:
match $x isa $type; $type label [person, animal]; get;
All these would work as if the multiple elements were defined via a disjunction.
This issue was originally posted by @haikalpribadi on 2016-12-01 16:23.
person sub entity,
has first-name [1,1],
has middle-name [0, *],
has address [1,*];
shopping-transaction sub relationship,
relates buyer [1,1],
relates seller [1,1],
relates product [1,*],
has date [1,1];
...and so on. This might be a demanding extension on some levels, but:
This issue was originally posted by @haikalpribadi on 2018-04-12 13:47.
Improve analytics syntax, pass a match query as subgraph.
e.g. degree:
match
$x isa person;
$y isa movie;
($x, $y) isa has-cast;
compute degree; persist true;
graql.match(
var(“x”).isa(“person”),
var(“y”).isa(“movie”),
var().rel(“y”).rel(“x”).isa(“has-cast”)
).compute().degree().execute();
This can NOT be done with the current version with TinkerPop.
The following table depicts the possible predicates together with their neq and negated versions.
Predicates in brackets are currently not supported.
--- | Predicate | neq Predicate | NOT Predicate |
---|---|---|---|
IdPredicate | $x id '...'; | $x != $y; $y id '...'; | NOT $x id '...'; |
IdPredicate | ($x = $y;) | $x != $y; | (NOT $x = $y;) |
ValuePredicate | $x == '...'; | $x !== '...'; | NOT $x == '...'; |
ValuePredicate | $x == $y; | $x !== $y; | NOT $x == $y; |
The idea is to unify the neq and negated versions where possible (especially for ValuePredicates where we can simply rewrite them).
Caveats:
Related issue: typedb/typedb#4528
At the moment, whenever we want to provide a variable into a Statement
builder, we must construct a full Statement
object that only contains that one Variable
. For example:
type("marriage").relates(var("x"))
In the case above, Graql.var("x")
returns a Statement
object, in which StatementTypeBuilder.relates()
accepts.
This is problematic for various reasons:
Statement
with more information leaked into the query, which may not be semantically correcthas
a type
followed by a default value: type("person").has("age", 0)
has
a var
cannot be followed by anything: type("person").has(var("x"))
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.