Skip to content

V0.4.0/dsl foundation#122

Merged
thanos merged 4 commits into
mainfrom
v0.4.0/DSL_Foundation
Jun 21, 2026
Merged

V0.4.0/dsl foundation#122
thanos merged 4 commits into
mainfrom
v0.4.0/DSL_Foundation

Conversation

@thanos

@thanos thanos commented Jun 21, 2026

Copy link
Copy Markdown
Owner

v0.4.0: Schema DSL for declaring Datalog programs

Add Ecto-inspired macro DSL (use ExDatalog.Schema) with relation,
fact, facts, rule, query, and wildcard macros that compile into the
existing Program/Rule/Fact/Constraint/Knowledge builder APIs.

Generated functions: program/0, materialize/0,1, queries/0, query/2

New modules:

  • ExDatalog.Schema — macro module with before_compile
  • ExDatalog.DSL.CompileError — readable compile-time errors
  • ExDatalog.UnsupportedFeature — forward-compatible aggregate stub

DSL features:

  • relation/2: typed field schemas (:atom, :integer, :string, :any)
  • fact/1, facts/2: single and bulk fact declaration
  • rule/2: lowercase vars, :atom constants, /wildcard(), not negation,
    16 named constraint predicates (gt, eq, add, member, etc.)
  • query/2: post-materialization queries with find/where and projection
  • Compile-time validation: undefined relations, unsafe variables,
    arity mismatches with descriptive error messages
  • Aggregate syntax parsed but not executable (returns UnsupportedFeature)

Documentation:

  • README updated with DSL quickstart
  • docs/migration_dsl.md — builder API → DSL migration guide
  • docs/articles/ — 5 educational articles
  • livebooks/ex_datalog_dsl.livemd — interactive tutorial
  • CHANGELOG.md — v0.4.0 entry
  • mix.exs — extras for livebooks, articles, migration guide; DSL module group

Tests: 786 total (718 existing + 68 new), 93.5% coverage, 0 failures.
Quality: mix format, compile --warnings-as-errors, credo --strict,
dialyzer, mix docs all clean. No breaking changes

thanos added 4 commits June 20, 2026 18:04
New files:
- lib/ex_datalog/schema.ex — ExDatalog.Schema macro module + ExDatalog.UnsupportedFeature struct
- test/ex_datalog/schema_test.exs — 23 integration tests
Key features implemented:
- relation/2 macro — declare typed relations
- fact/1 and facts/2 macros — declare ground facts
- rule/2 macro — declare rules with lowercase vars, not_ negation, named constraints (gt, eq, add, etc.)
- query/2 macro — declare named post-materialization queries with find/where
- __before_compile__ generates program/0, materialize/0,1, queries/0, query/2
- Aggregate syntax (agg) parsed but returns %UnsupportedFeature{feature: :aggregates}
Convention: Uppercase identifiers (X, Y) in rule/query bodies are logic variables. Lowercase atoms and atoms starting with : are constants. _ is wildcard.
Results: 741 tests (718 existing + 23 new), 0 failures, credo clean.
Add Ecto-inspired macro DSL (use ExDatalog.Schema) with relation,
fact, facts, rule, query, and wildcard macros that compile into the
existing Program/Rule/Fact/Constraint/Knowledge builder APIs.

Generated functions: program/0, materialize/0,1, queries/0, query/2

New modules:
- ExDatalog.Schema — macro module with __before_compile__
- ExDatalog.DSL.CompileError — readable compile-time errors
- ExDatalog.UnsupportedFeature — forward-compatible aggregate stub

DSL features:
- relation/2: typed field schemas (:atom, :integer, :string, :any)
- fact/1, facts/2: single and bulk fact declaration
- rule/2: lowercase vars, :atom constants, _/wildcard(), not_ negation,
  16 named constraint predicates (gt, eq, add, member, etc.)
- query/2: post-materialization queries with find/where and projection
- Compile-time validation: undefined relations, unsafe variables,
  arity mismatches with descriptive error messages
- Aggregate syntax parsed but not executable (returns UnsupportedFeature)

Documentation:
- README updated with DSL quickstart
- docs/migration_dsl.md — builder API → DSL migration guide
- docs/articles/ — 5 educational articles
- livebooks/ex_datalog_dsl.livemd — interactive tutorial
- CHANGELOG.md — v0.4.0 entry
- mix.exs — extras for livebooks, articles, migration guide; DSL module group
…e before the Enum.each(constraint_ops, ...) expansion, since Elixir matches function clauses in definition order and the expanded constraint ops all match {atom(), _, list()} which would shadow {:agg, _, list}.
@thanos
thanos merged commit 1d6b299 into main Jun 21, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant