Current section
Files
Jump to
Current section
Files
lib/enhanced_adt.ex
defmodule EnhancedADT do
@moduledoc """
Enhanced Algebraic Data Types with automatic IsLabDB integration.
This module provides mathematical ADT definitions that automatically translate
to optimized IsLabDB operations with physics intelligence. Domain models become
pure mathematical expressions while transparently leveraging quantum entanglement,
wormhole routing, and spacetime optimization.
## Core Concepts
- **defproduct**: Define product types (records) with physics annotations
- **defsum**: Define sum types (unions) with automatic topology generation
- **fold**: Pattern match with automatic IsLabDB translation
- **bend**: Generate structures with automatic wormhole network creation
## Physics Integration
ADT structures automatically:
- Create quantum entanglement relationships
- Generate wormhole networks for cross-references
- Configure gravitational routing based on access patterns
- Optimize temporal placement based on data lifecycle
## Example Usage
```elixir
use EnhancedADT
defproduct User do
id :: String.t()
name :: String.t()
preferences :: UserPreferences.t(), physics: :quantum_entanglement_group
activity_score :: float(), physics: :gravitational_mass
end
defsum UserNetwork do
IsolatedUser(User.t())
ConnectedUsers(primary :: User.t(), connections :: [rec(UserNetwork)])
end
# Mathematical operations automatically become IsLabDB commands
fold user do
User(id, name, preferences, score) ->
# Automatically translates to IsLabDB.cosmic_put with physics configuration
store_user_with_physics(id, name, preferences, score)
end
```
"""
@doc """
Initialize Enhanced ADT system with IsLabDB integration.
This macro sets up the mathematical ADT environment and imports all
necessary functions for domain modeling.
"""
defmacro __using__(_opts) do
quote do
import EnhancedADT.ProductType
import EnhancedADT.SumType
import EnhancedADT.Fold
import EnhancedADT.Bend
import EnhancedADT.Physics
# Import elegant variant and field syntax
import EnhancedADT.VariantSyntax
import EnhancedADT.FieldSyntax
# Enable compile-time ADT analysis for optimization
@before_compile EnhancedADT.Optimizer
end
end
@doc """
Create recursive type reference for sum types.
Used within sum type definitions to create cyclic references that enable
recursive data structures with automatic wormhole network optimization.
## Example
```elixir
defsum Tree do
Leaf(value :: any())
Branch(left :: rec(Tree), right :: rec(Tree), value :: any())
end
```
"""
def rec(type_name) do
{:recursive_reference, type_name}
end
end
defmodule EnhancedADT.ProductType do
@moduledoc """
Product type definitions with physics annotations.
Product types represent record-like structures where all fields are present.
Physics annotations allow automatic configuration of IsLabDB behavior.
"""
@doc """
Define a product type with optional physics annotations.
Physics annotations control how the data interacts with IsLabDB:
- `:gravitational_mass` - Affects shard placement and routing
- `:quantum_entanglement_group` - Creates automatic entanglements
- `:temporal_weight` - Influences data lifecycle management
- `:spacetime_shard_hint` - Suggests optimal shard placement
## Example
```elixir
defproduct Customer do
id :: String.t()
loyalty_score :: float(), physics: :gravitational_mass
preferences :: CustomerPreferences.t(), physics: :quantum_entanglement_group
created_at :: DateTime.t(), physics: :temporal_weight
end
```
"""
defmacro defproduct(name, do: fields) do
# Transform elegant physics syntax first, then extract field definitions
transformed_fields = transform_physics_field_syntax(fields)
field_specs = extract_field_specifications(transformed_fields)
physics_config = extract_physics_annotations(field_specs)
quote do
defmodule unquote(name) do
@moduledoc "Enhanced ADT Product Type: #{unquote(name)}"
# Store physics configuration for compile-time optimization
@adt_type :product
@adt_physics_config unquote(Macro.escape(physics_config))
@adt_fields unquote(Macro.escape(field_specs))
# Generate struct definition
unquote(generate_struct_definition(field_specs))
# Generate constructor functions
unquote(generate_constructor_functions(name, field_specs))
# Generate physics integration functions
unquote(generate_physics_integration(name, field_specs, physics_config))
# Generate pattern matching helpers
unquote(generate_pattern_helpers(name, field_specs))
end
end
end
# Transform elegant physics field syntax to parseable format
defp transform_physics_field_syntax(fields) do
case fields do
{:__block__, meta, field_list} ->
{:__block__, meta, Enum.map(field_list, &transform_single_physics_field/1)}
single_field ->
transform_single_physics_field(single_field)
end
end
defp transform_single_physics_field({:"::", meta1, [field_name, {:"::", meta2, [type_spec, [physics: physics_annotation]]}]}) do
# Transform: field_name :: Type.t() :: physics: :annotation
# This handles syntax errors from Elixir parser attempting to parse physics annotations
{field_name, type_spec, physics_annotation}
end
defp transform_single_physics_field({{:"::", meta, [field_name, type_spec]}, [physics: physics_annotation]}) do
# Transform: {field_name :: Type.t(), physics: :annotation}
{field_name, type_spec, physics_annotation}
end
defp transform_single_physics_field({:"::", _meta, [field_name, type_spec]}) do
# Regular field: field_name :: Type.t()
field_name_atom = extract_field_name(field_name)
{field_name_atom, type_spec, nil}
end
defp transform_single_physics_field(field_name) when is_atom(field_name) do
# Just field name
{field_name, :any, nil}
end
defp transform_single_physics_field(other) do
# Pass through other syntax
other
end
# Helper functions for macro expansion
defp extract_field_specifications(fields) do
case fields do
{:__block__, _, field_list} -> Enum.map(field_list, &parse_field_spec/1)
single_field -> [parse_field_spec(single_field)]
end
end
# Parse field specifications with optional physics annotations
defp parse_field_spec({:field, _, [field_spec]}) do
# field macro call without physics: field name :: Type.t()
parse_field_macro_call(field_spec, nil)
end
defp parse_field_spec({:field, _, [field_spec, [physics: physics_annotation]]}) do
# field macro call with physics: field name :: Type.t(), physics: :annotation
parse_field_macro_call(field_spec, physics_annotation)
end
defp parse_field_spec({field_name, field_type, physics_annotation}) when is_atom(field_name) do
# Result from field macro: {field_name, field_type, physics_annotation}
%{name: field_name, type: field_type, physics: physics_annotation}
end
defp parse_field_spec({:"::", _meta, [field_name_ast, type_spec]}) do
# Simple field: name :: Type.t()
field_name = extract_field_name(field_name_ast)
%{name: field_name, type: type_spec, physics: nil}
end
defp parse_field_spec(field_name) when is_atom(field_name) do
# Just a field name without type specification
%{name: field_name, type: :any, physics: nil}
end
defp parse_field_spec(other) do
raise "Invalid field specification: #{inspect(other)}"
end
defp parse_field_macro_call({:"::", _, [field_name_ast, type_spec]}, physics_annotation) do
# Parse field macro call: name :: Type.t()
field_name = extract_field_name(field_name_ast)
%{name: field_name, type: type_spec, physics: physics_annotation}
end
# Extract field name from different AST formats
defp extract_field_name(field_name) when is_atom(field_name), do: field_name
defp extract_field_name({field_name, _meta, _context}) when is_atom(field_name), do: field_name
defp extract_field_name({"::", _, [field_name, _type]}) when is_atom(field_name), do: field_name
defp extract_field_name({"::", _, [{field_name, _, _}, _type]}) when is_atom(field_name), do: field_name
defp extract_field_name(other), do: raise "Invalid field name: #{inspect(other)}"
# Extract variant name from AST
defp extract_variant_name({:__aliases__, _, [variant_name]}) when is_atom(variant_name), do: variant_name
defp extract_variant_name(variant_name) when is_atom(variant_name), do: variant_name
defp extract_variant_name(other), do: raise "Invalid variant name: #{inspect(other)}"
defp extract_physics_annotations(field_specs) do
Enum.reduce(field_specs, %{}, fn field, acc ->
case field.physics do
nil -> acc
physics_type -> Map.put(acc, field.name, physics_type)
end
end)
end
defp generate_struct_definition(field_specs) do
field_atoms = Enum.map(field_specs, & &1.name)
quote do
@enforce_keys unquote(field_atoms)
defstruct unquote(field_atoms)
end
end
defp generate_constructor_functions(name, field_specs) do
field_names = Enum.map(field_specs, & &1.name)
field_vars = Enum.map(field_names, fn name -> Macro.var(name, nil) end)
field_assignments = Enum.map(field_names, fn name ->
{name, Macro.var(name, nil)}
end)
quote do
@doc "Create new #{unquote(name)} with all required fields"
def new(unquote_splicing(field_vars)) do
%__MODULE__{unquote_splicing(field_assignments)}
end
@doc "Create new #{unquote(name)} from keyword list"
def new(fields) when is_list(fields) do
struct(__MODULE__, fields)
end
end
end
defp generate_physics_integration(_name, field_specs, physics_config) do
quote do
@doc "Get physics configuration for IsLabDB integration"
def __adt_physics_config__, do: unquote(Macro.escape(physics_config))
@doc "Get field specifications for IsLabDB optimization"
def __adt_field_specs__, do: unquote(Macro.escape(field_specs))
@doc "Extract physics parameters for IsLabDB cosmic_put operation"
def extract_physics_context(data) do
physics_config = __adt_physics_config__()
Enum.reduce(physics_config, %{}, fn {field_name, physics_type}, acc ->
field_value = Map.get(data, field_name)
physics_parameter = convert_to_physics_parameter(physics_type, field_value)
Map.put(acc, physics_type, physics_parameter)
end)
end
defp convert_to_physics_parameter(:gravitational_mass, value) when is_number(value), do: value
defp convert_to_physics_parameter(:gravitational_mass, _), do: 1.0
defp convert_to_physics_parameter(:quantum_entanglement_potential, value) when is_number(value), do: min(1.0, max(0.0, value))
defp convert_to_physics_parameter(:quantum_entanglement_potential, _), do: 0.5
defp convert_to_physics_parameter(:temporal_weight, value) when is_number(value), do: value
defp convert_to_physics_parameter(:temporal_weight, %DateTime{}), do: 1.0
defp convert_to_physics_parameter(:temporal_weight, _), do: 1.0
defp convert_to_physics_parameter(:spacetime_shard_hint, :hot), do: :hot
defp convert_to_physics_parameter(:spacetime_shard_hint, :warm), do: :warm
defp convert_to_physics_parameter(:spacetime_shard_hint, :cold), do: :cold
defp convert_to_physics_parameter(:spacetime_shard_hint, _), do: :warm
defp convert_to_physics_parameter(_, value), do: value
end
end
defp generate_pattern_helpers(_name, field_specs) do
field_names = Enum.map(field_specs, & &1.name)
field_vars = Enum.map(field_names, fn name -> Macro.var(name, nil) end)
field_assignments = Enum.map(field_names, fn name ->
{name, Macro.var(name, nil)}
end)
quote do
@doc "Pattern match helper for fold operations"
def __adt_pattern_match__(unquote_splicing(field_vars)) do
%__MODULE__{unquote_splicing(field_assignments)}
end
@doc "Destructure instance into field tuple for fold operations"
def __adt_destructure__(%__MODULE__{} = instance) do
{unquote_splicing(Enum.map(field_names, fn name ->
quote do: Map.get(instance, unquote(name))
end))}
end
end
end
end
defmodule EnhancedADT.SumType do
@moduledoc """
Sum type definitions with automatic wormhole topology generation.
Sum types represent union-like structures where exactly one variant is present.
These automatically create wormhole networks for efficient traversal between variants.
"""
@doc """
Define a sum type with automatic wormhole network generation.
Sum types create branching structures that automatically establish wormhole
connections between related variants for optimized traversal.
## Recursive Types
Use `rec(TypeName)` for recursive references that create cyclic wormhole networks.
## Example
```elixir
defsum UserTree do
UserLeaf(User.t())
UserBranch(user :: User.t(), connections :: [rec(UserTree)])
QuantumSuperposition(users :: [User.t()], coherence :: float())
end
```
"""
defmacro defsum(name, do: variants) do
# Transform elegant design doc syntax before processing
transformed_variants = transform_elegant_defsum_syntax(variants)
# Extract variant specifications from transformed syntax
variant_specs = extract_variant_specifications(transformed_variants)
quote do
defmodule unquote(name) do
@moduledoc "Enhanced ADT Sum Type: #{unquote(name)}"
# Store ADT metadata
@adt_type :sum
@adt_variants unquote(Macro.escape(variant_specs))
# Generate variant modules and functions
unquote_splicing(generate_variant_modules(variant_specs))
# Generate pattern matching infrastructure
unquote(generate_sum_pattern_helpers(name, variant_specs))
# Generate wormhole network topology functions
unquote(generate_wormhole_topology_functions(name, variant_specs))
end
end
end
defp extract_variant_specifications(variants) do
case variants do
{:__block__, _, variant_list} -> parse_elegant_variant_list(variant_list)
single_variant -> parse_elegant_variant_list([single_variant])
end
end
defp transform_elegant_defsum_syntax(variants) do
# The variant macro has already transformed the syntax, so just pass through
variants
end
defp parse_elegant_variant_list(variant_list) do
# Parse variant macro calls and other variant definitions
Enum.map(variant_list, fn
# variant macro call: {:variant, _, [VariantName, field1, field2, ...]}
{:variant, _, [variant_name_ast | fields]} ->
variant_name = extract_sum_variant_name(variant_name_ast)
field_names = Enum.map(fields, &extract_sum_field_name/1)
%{name: variant_name, fields: Enum.map(field_names, &%{name: &1, type: :any})}
# Result from variant macro: {VariantName, [field1, field2]}
{variant_name, field_list} when is_atom(variant_name) and is_list(field_list) ->
%{name: variant_name, fields: parse_variant_field_list(field_list)}
# Tuple pair: {:VariantName, [:field1, :field2]} (backward compatibility)
{:{}, _, [variant_name, field_list]} when is_atom(variant_name) and is_list(field_list) ->
%{name: variant_name, fields: parse_variant_field_list(field_list)}
# Simple atom: VariantName
variant_name when is_atom(variant_name) ->
%{name: variant_name, fields: []}
# Error case
other ->
raise "Invalid variant specification: #{inspect(other)}. Expected variant macro call or simple variant"
end)
end
# Helper functions for sum type parsing
defp extract_sum_variant_name({:__aliases__, _, [variant_name]}) when is_atom(variant_name), do: variant_name
defp extract_sum_variant_name(variant_name) when is_atom(variant_name), do: variant_name
defp extract_sum_variant_name(other), do: raise "Invalid variant name: #{inspect(other)}"
defp extract_sum_field_name(field_name) when is_atom(field_name), do: field_name
defp extract_sum_field_name({field_name, _meta, _context}) when is_atom(field_name), do: field_name
defp extract_sum_field_name({"::", _, [field_name, _type]}) when is_atom(field_name), do: field_name
defp extract_sum_field_name({"::", _, [{field_name, _, _}, _type]}) when is_atom(field_name), do: field_name
defp extract_sum_field_name(other), do: raise "Invalid field name: #{inspect(other)}"
defp parse_elegant_variant_fields(args) do
# Parse elegant design doc variant field definitions
Enum.with_index(args) |> Enum.map(fn {field_spec, index} ->
case field_spec do
# Named field with type: field :: Type.t()
{"::", _, [field_name, type_spec]} when is_atom(field_name) ->
%{name: field_name, type: type_spec}
# Named field without type annotation: field_name
field_name when is_atom(field_name) ->
%{name: field_name, type: :any}
# Just a type without field name: Type.t()
type_spec ->
# Generate field name from position if no name provided
field_name = String.to_atom("field_#{index}")
%{name: field_name, type: type_spec}
end
end)
end
defp parse_variant_field_list(field_list) do
Enum.map(field_list, fn field_name when is_atom(field_name) ->
%{name: field_name, type: :any}
end)
end
defp generate_variant_modules(variant_specs) do
Enum.map(variant_specs, fn variant ->
generate_variant_module(variant)
end)
end
defp generate_variant_module(%{name: variant_name, fields: fields}) do
if Enum.empty?(fields) do
# Simple variant without fields - create as nested module
quote do
defmodule unquote(variant_name) do
defstruct [:__variant__]
def new(), do: %__MODULE__{__variant__: unquote(variant_name)}
end
# Create a convenience constructor function at the sum type level
def unquote(variant_name)(), do: __MODULE__.unquote(variant_name).new()
end
else
# Variant with fields - create as nested module
field_atoms = Enum.map(fields, & &1.name)
quote do
defmodule unquote(variant_name) do
defstruct [:__variant__ | unquote(field_atoms)]
def new(unquote_splicing(Enum.map(field_atoms, fn atom -> Macro.var(atom, nil) end))) do
args = unquote(Enum.map(field_atoms, fn atom ->
quote do: {unquote(atom), unquote(Macro.var(atom, nil))}
end))
struct(__MODULE__, [{:__variant__, unquote(variant_name)} | args])
end
end
# Create a convenience constructor function at the sum type level
def unquote(variant_name)(unquote_splicing(Enum.map(field_atoms, fn atom -> Macro.var(atom, nil) end))) do
__MODULE__.unquote(variant_name).new(unquote_splicing(Enum.map(field_atoms, fn atom -> Macro.var(atom, nil) end)))
end
end
end
end
defp generate_sum_pattern_helpers(_sum_name, variant_specs) do
quote do
@doc "Get all variant specifications for pattern matching"
def __adt_variants__, do: unquote(Macro.escape(variant_specs))
@doc "Check if value is instance of this sum type"
def is_variant?(%{__variant__: variant_name}) do
variant_name in unquote(Enum.map(variant_specs, & &1.name))
end
def is_variant?(_), do: false
@doc "Get variant name from instance"
def get_variant(%{__variant__: variant_name}), do: variant_name
def get_variant(_), do: nil
end
end
defp generate_wormhole_topology_functions(_sum_name, variant_specs) do
quote do
@doc "Generate wormhole network topology for this sum type"
def __adt_wormhole_topology__() do
variants = unquote(Macro.escape(variant_specs))
# Create wormhole connections between variants that reference each other
connections = Enum.flat_map(variants, fn variant ->
variant_connections = analyze_variant_connections(variant, variants)
Enum.map(variant_connections, fn target_variant ->
%{
source: variant.name,
target: target_variant,
connection_type: :variant_transition,
strength: calculate_variant_connection_strength(variant, target_variant)
}
end)
end)
%{
sum_type: __MODULE__,
variant_count: length(variants),
wormhole_connections: connections,
topology_type: :sum_type_network
}
end
defp analyze_variant_connections(variant, all_variants) do
# Find other variants that this variant might connect to
# Based on field types and recursive references
Enum.filter(all_variants, fn other_variant ->
variant.name != other_variant.name and
variants_have_connection?(variant, other_variant)
end) |> Enum.map(& &1.name)
end
defp variants_have_connection?(%{fields: fields1}, %{fields: fields2}) do
# Check if variants share common field types or have recursive references
has_recursive_reference?(fields1) or
has_recursive_reference?(fields2) or
have_common_field_types?(fields1, fields2)
end
defp has_recursive_reference?(fields) do
Enum.any?(fields, fn field ->
case field.type do
{:recursive, _} -> true
_ -> false
end
end)
end
defp have_common_field_types?(fields1, fields2) do
types1 = Enum.map(fields1, & &1.type) |> MapSet.new()
types2 = Enum.map(fields2, & &1.type) |> MapSet.new()
not MapSet.disjoint?(types1, types2)
end
defp calculate_variant_connection_strength(_variant1, _variant2) do
# Default connection strength - can be enhanced with usage pattern analysis
0.5
end
end
end
end
defmodule EnhancedADT.FieldSyntax do
@moduledoc """
Elegant field syntax for Enhanced ADT product types with physics annotations.
Provides the `field` macro for beautiful mathematical field definitions:
```elixir
defproduct Person do
field :id, String.t()
field :influence_score, float(), physics: :gravitational_mass
field :activity, float(), physics: :quantum_entanglement_potential
end
```
"""
@doc """
Define a product type field with optional physics annotation.
This macro enables elegant physics-annotated fields:
- `field name :: String.t()` for simple fields
- `field score :: float(), physics: :gravitational_mass` for physics fields
"""
defmacro field({:"::", _, [field_name, type_spec]}, physics: physics_annotation) do
# Field with physics: field name :: Type.t(), physics: :annotation
field_name_atom = extract_field_name_from_ast(field_name)
quote do
{unquote(field_name_atom), unquote(type_spec), unquote(physics_annotation)}
end
end
defmacro field({:"::", _, [field_name, type_spec]}) do
# Simple field: field name :: Type.t()
field_name_atom = extract_field_name_from_ast(field_name)
quote do
{unquote(field_name_atom), unquote(type_spec), nil}
end
end
# Helper for extracting field names in macros
defp extract_field_name_from_ast(field_name) when is_atom(field_name), do: field_name
defp extract_field_name_from_ast({field_name, _, _}) when is_atom(field_name), do: field_name
end
defmodule EnhancedADT.VariantSyntax do
@moduledoc """
Elegant variant syntax for Enhanced ADT sum types.
Provides the `variant` macro for beautiful mathematical ADT definitions:
```elixir
defsum Result do
variant Success(value)
variant Error(message)
variant Pending
end
```
"""
@doc """
Define a sum type variant with elegant mathematical syntax.
This macro enables beautiful ADT syntax:
- `variant Success, value` for single field
- `variant Transform, input, output` for multiple fields
- `variant Empty` for no fields
"""
defmacro variant(variant_name, field1) when is_atom(variant_name) do
# Single field variant: variant Success, value
{variant_name, [field1]}
end
defmacro variant(variant_name, field1, field2) when is_atom(variant_name) do
# Two field variant: variant Transform, input, output
{variant_name, [field1, field2]}
end
defmacro variant(variant_name, field1, field2, field3) when is_atom(variant_name) do
# Three field variant: variant Connection, person, friends, strength
{variant_name, [field1, field2, field3]}
end
defmacro variant(variant_name, field1, field2, field3, field4) when is_atom(variant_name) do
# Four field variant
{variant_name, [field1, field2, field3, field4]}
end
defmacro variant(variant_name) when is_atom(variant_name) do
# No field variant: variant Empty
{variant_name, []}
end
end
defmodule EnhancedADT.Optimizer do
@moduledoc """
Compile-time optimizer for Enhanced ADT definitions.
This module provides compile-time analysis and optimization of Enhanced ADT
structures to generate optimal configurations and recommendations.
"""
defmacro __before_compile__(_env) do
quote do
@doc """
Get compile-time optimization metadata for this module.
Returns information about the optimizations applied during compilation
and recommendations for runtime optimization.
"""
def __adt_optimization_metadata__ do
%{
optimization_level: :standard,
physics_optimizations: [],
wormhole_optimizations: [],
quantum_optimizations: [],
compile_time: :os.system_time(:millisecond),
recommendations: []
}
end
end
end
end