T
TypeDBβ€’3mo ago
sevki

Derive Macro for rust

Hey folks, I'm Sevki, I'm new here and I've been working on a typedb macro, I've already posted it to the forums https://forum.typedb.com/t/derive-macro-for-rust/701 , like I said, I'm super new so if anyone wants to help me out I would really apprecitate it
Discussion Forum
Derive Macro for rust
Hi folks, I’m Sevki, I’m new here. I have been searching for a more rustyℒ️ way to generate schemas. something like, #[derive(Relation)] enum Employment { #[role] Employee, #[role] Employer, } // Rust code #[derive(Entity)] #[abs] pub struct Person { #[key] email: String, #[owns] full_name: String, ...
23 Replies
krishnan
krishnanβ€’3mo ago
That's super interesting and similar to what @Joshua (and @dmitrii? ) have been thinking about. We'll be happy to answer any TypeQL questions you may have in this thread. I've struggled to wrap my head around fitting relations into rust. I'm curious why you've not re-used the struct Person for struct PersonAnswer.
sevki
sevkiOPβ€’3mo ago
@krishnan That's very kind of you. I'm currently in a very exploratory state. I don't really have a nice way to map PERA concepts to rust idioms. So I'm trying a bunch of things to see what feels more natural.
sevki
sevkiOPβ€’2mo ago
Hey folks, I've got a poc for this... https://github.com/sevki/typedb-model/blob/main/tests/integration_tests.rs it's not polished or anything of the sort. still very early days and still trying to figure out what the user experience should be.
GitHub
typedb-model/tests/integration_tests.rs at main Β· sevki/typedb-model
TypeDB model generation from with Rust macros. Contribute to sevki/typedb-model development by creating an account on GitHub.
Joshua
Joshuaβ€’2mo ago
ok taking a look @sevki sorry been super busy!
sevki
sevkiOPβ€’2mo ago
@Joshua actually please don't. that implementation is absolute shite. and turns out I was making things super hard for my self. I rewrote the entire thing in a couple of lines of datalog. what an idiot I was two days ago. I literally wrote a couple of fmts for the defineables to make these
attribute id;
id value string;
entity user;
user owns id;
attribute id;
id value string;
entity user;
user owns id;
into these
attributes(id).
attribute_type(id, sting) :- attributes(id), value_types(string).
entities(user).
owns(user, id)
attributes(id).
attribute_type(id, sting) :- attributes(id), value_types(string).
entities(user).
owns(user, id)
and it worked surprisingly well. so now i can do write stuff like this
% prelude
value_types(string).
value_types(double).
value_types(date).
value_types(bool).
value_types(float).
% auto gen starts here
attributes(id).
attribute_type(id,string) :- attributes(id), value_types(string).
attributes(name).
attribute_type(name,string) :- attributes(name), value_types(string).
attributes(description).
attribute_type(description,string) :- attributes(description), value_types(string).
attributes(kid).
attribute_type(kid,string) :- attributes(kid), value_types(string).
attributes(created_at).
attribute_type(created_at,date) :- attributes(created_at), value_types(date).abstract(content).
entities(content).
owns(content, id) :- entities(content), attributes(id).
abstract(account).
entities(account).
owns(account, id) :- entities(account), attributes(id).
abstract(pubkey).
entities(pubkey).
owns(pubkey, kid) :- entities(pubkey), attributes(kid).
abstract(credential).
relations(credential).
relation(credential,key).
relation(credential,subject).
entities(user).
sub(user, account).
owns(user, name) :- entities(user), attributes(name).
entities(service).
sub(service, account).
owns(service, description) :- entities(service), attributes(description).
entities(passkey).
sub(passkey, key).
plays(passkey, key) :- entities(passkey), roles(key).
% my program
sub(?X,?Y) :- sub(?X,?Y).

sub(?X,?Z) :- sub(?X,?Y), sub(?Y,?Z).

owns(?X,?Y) :- owns(?X,?Y).

owns(?X,?Z) :- sub(?X, ?Y), owns(?Y,?Z).

abstract_struct_field_types(?X, ?Y, ?Z) :- abstract(?X), owns(?X, ?Y), attribute_type(?Y, ?Z).
struct_field_types(?X, ?Y, ?Z) :- owns(?X, ?Y), attribute_type(?Y, ?Z).
% prelude
value_types(string).
value_types(double).
value_types(date).
value_types(bool).
value_types(float).
% auto gen starts here
attributes(id).
attribute_type(id,string) :- attributes(id), value_types(string).
attributes(name).
attribute_type(name,string) :- attributes(name), value_types(string).
attributes(description).
attribute_type(description,string) :- attributes(description), value_types(string).
attributes(kid).
attribute_type(kid,string) :- attributes(kid), value_types(string).
attributes(created_at).
attribute_type(created_at,date) :- attributes(created_at), value_types(date).abstract(content).
entities(content).
owns(content, id) :- entities(content), attributes(id).
abstract(account).
entities(account).
owns(account, id) :- entities(account), attributes(id).
abstract(pubkey).
entities(pubkey).
owns(pubkey, kid) :- entities(pubkey), attributes(kid).
abstract(credential).
relations(credential).
relation(credential,key).
relation(credential,subject).
entities(user).
sub(user, account).
owns(user, name) :- entities(user), attributes(name).
entities(service).
sub(service, account).
owns(service, description) :- entities(service), attributes(description).
entities(passkey).
sub(passkey, key).
plays(passkey, key) :- entities(passkey), roles(key).
% my program
sub(?X,?Y) :- sub(?X,?Y).

sub(?X,?Z) :- sub(?X,?Y), sub(?Y,?Z).

owns(?X,?Y) :- owns(?X,?Y).

owns(?X,?Z) :- sub(?X, ?Y), owns(?Y,?Z).

abstract_struct_field_types(?X, ?Y, ?Z) :- abstract(?X), owns(?X, ?Y), attribute_type(?Y, ?Z).
struct_field_types(?X, ?Y, ?Z) :- owns(?X, ?Y), attribute_type(?Y, ?Z).
sevki
sevkiOPβ€’2mo ago
ah nice it even runs on the web https://dub.sh/2dIlb9L
Nemo Rule Engine - Web Browser IDE
Try Nemo online in your Web Browser: Nemo is a datalog-based rule engine for fast and scalable analytic data processing in memory.
Joshua
Joshuaβ€’2mo ago
how does this work with the rus tmacro? super curious to see where you take it @sevki ! I thought i saw a notification you sent about how you did it but i can't find it now @sevki !!
sevki
sevkiOPβ€’2mo ago
Hey @joshua I hadn't. Almost finished my rewrite and I really like this version better. I'll publish it this week πŸ™‚
Joshua
Joshuaβ€’2mo ago
thanks, im excited @sevki !
sevki
sevkiOPβ€’2mo ago
hey @joshua, with apologies to your logo designer, I've written something. https://fistfulofbytes.com/typefrog/
krishnan
krishnanβ€’2mo ago
Ascent looks wild. I wonder if some of our (or a general rust application's) validation logic wouldn't be better off written in ascent. Add a few more lines and you'll have implemented all of TypeQL in ascent πŸ˜… I wonder if this counts as a (possibly unconventional) machine specification as enquired here: https://discord.com/channels/665254494820368395/1097946929079537875/1413241556013416468
sevki
sevkiOPβ€’2mo ago
I don't think it would be unconventional at all, after all these are just a bunch of horn clauses right? perfectly reasonable for someone to write those implications in lean. lots of literature on the subject https://arxiv.org/pdf/1804.11250 https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/nbjorner-yurifest.pdf.
Horn clause
In mathematical logic and logic programming, a Horn clause is a logical formula of a particular rule-like form that gives it useful properties for use in logic programming, formal specification, universal algebra and model theory. Horn clauses are named for the logician Alfred Horn, who first pointed out their significance in 1951.
sevki
sevkiOPβ€’2mo ago
in fact that's apparently what lean already also does
The Lean typeclass resolution procedure can be viewed as a simple Ξ»-Prolog interpreter [8], where the Horn clauses are the user declared instances.
https://lean-lang.org/papers/lean4.pdf @krishnan spot on instincts πŸ™‚ I should probably stick a licence in there πŸ™‚
Joshua
Joshuaβ€’2mo ago
@sevki love the blog post πŸ˜„ awesome logo, please go ahead i would love to allow open source projects to make derivates of our logo officially haha remind me of what your goal is with that project?
sevki
sevkiOPβ€’2mo ago
To write as little code as I possibly can So generating the rust structs from schema and queries πŸ™‚
Joshua
Joshuaβ€’2mo ago
Interesting! Following along to see how you take the next steps πŸ˜„ good inspiration
sevki
sevkiOPβ€’2mo ago
some updates on this front https://fistfulofbytes.com/on-the-next-typefrog-development/ @joshua does this make the goal clearer?
Joshua
Joshuaβ€’2mo ago
right i see it's a compile time build script that connects to typedb and validates the queries you write, am i getting it right? @sevki ? i guess i would like to see: What's the relationship between your build script (and what's in generated.rs) and the typeql! macro
sevki
sevkiOPβ€’2mo ago
so kinda two different paradigms the build script can create these for you https://github.com/sevki/typefrog/blob/879c6e404a2f1d963c6d63bb534574bb37b8f264/src/ir/struct.rs#L126 not just validate. the second one, the tyepql! macro, 1. client side does validate that your query is gramatially correct, so won't compile if it doesn't. then it creates a lazy lock around it https://github.com/sevki/typefrog/blob/879c6e404a2f1d963c6d63bb534574bb37b8f264/src/ir/struct.rs#L126 so you don't parse it over and over again.
GitHub
typefrog/src/ir/struct.rs at 879c6e404a2f1d963c6d63bb534574bb37b8f2...
Contribute to sevki/typefrog development by creating an account on GitHub.
Joshua
Joshuaβ€’2mo ago
On that's cool, you're generating traits per type that encompasses all the definitions like owns and sub and stuff! that is nice πŸ™‚ im curious to see how to integrate it beyond the schema, eg for data! that's the real knot to untie we're also thinking about - returning well-typed responses in local structures. For Typescript it's easy-ish when you have a fetch clause and return JSON. We have a new analyze endpoint which describes the expected output structure of a fetch which you can turn into a TypeScript type. For python it's might have to be something that is actually a mapping layer somewhere
sevki
sevkiOPβ€’2mo ago
ah. hadn't seen that. it's spelled properly and everything https://github.com/typedb/typedb/blob/master/query/analyse.rs in the proper kings english πŸ˜ƒπŸ‡¬πŸ‡§
Joshua
Joshuaβ€’2mo ago
It's only available via HTTP right now but @krishnan is currently adding it to GRPC as well haha our source code uses UK still but our external APIs are using US split personality πŸ˜‚
sevki
sevkiOPβ€’2mo ago
I'm sure @krishnan will do the right thing on the gRPC side πŸ˜ƒ

Did you find this page helpful?