Domain-Specific and Data-Oriented Programming

A DSL provides notation tailored to a particular problem domain.

16.1 Domain-specific languages (DSLs)

A DSL provides notation tailored to a particular problem domain. Examples include SQL for queries, regular expressions for pattern matching, CSS for styling, and build/configuration languages.

Internal DSL: embedded in a general-purpose host language.

External DSL: has its own syntax and parser/tooling.

DSLs can make domain rules expressive, but their grammar, error messages, validation, versioning, and security need maintenance.

16.2 Designing a small DSL

A rule might look like:

This is illustrative pseudolanguage, not a standard syntax. A real implementation should parse a constrained grammar into an abstract syntax tree, validate identifiers and types, and evaluate rules without arbitrary code execution.

WHEN course.status == "published"
AND user.role IN ["student", "instructor"]
ALLOW course.read

16.3 Data-oriented design

Data-oriented design organizes data and processing around actual access patterns, memory layout, and workload. It often matters in game engines, simulations, high-performance analytics, and embedded systems.

16.4 Array of Structures versus Structure of Arrays

Conceptual C-like representation:

AoS groups each particle's fields together; SoA groups each field across particles. SoA can improve contiguous access and vectorization when processing one field across many particles, while AoS can be convenient when operating on whole individual records. Measure using the actual workload.

/* Array of structures (AoS) */
struct Particle { float x, y, z; };
struct Particle particles[COUNT];

/* Structure of arrays (SoA) */
float x[COUNT];
float y[COUNT];
float z[COUNT];

16.5 Entity-component-system (ECS)

ECS separates:

Entity: identity for an item.

Component: data associated with an entity.

System: logic processing entities with selected components.

ECS is common in simulation and game development because it can improve composition and data locality. It is not inherently faster for every workload and introduces its own complexity.

16.6 Vectorization and SIMD

SIMD executes one instruction over multiple data elements. Compilers may auto-vectorize loops when they can prove safe transformations; programmers can use vector libraries or intrinsics where necessary. Alignment, aliasing, numeric precision, and target hardware affect results.

16.7 Memory locality

Cache lines, access patterns, allocation, pointer chasing, and data size influence performance. Data-oriented optimization should be based on profiling and measurements rather than assumptions.

Exercise

Represent a set of sensor readings as AoS and SoA. Benchmark filtering and averaging a single field. Document hardware, data size, compiler/runtime, and measurement variability.

Quiz

? When can Structure of Arrays (SoA) be faster than Array of Structures (AoS)?
+ When processing one field across many records, because the data is contiguous and easier to vectorise. :: That is the typical win; measure on the real workload.
- Always. :: AoS can be better when whole records are processed together.
- Never; layout does not matter. :: Memory layout affects cache behaviour.
- Only in interpreted languages. :: The effect is strongest in compiled code.

? What is the difference between an internal and an external DSL?
+ Internal: embedded in a host language. External: its own syntax, parser and tooling. :: That is the definition.
- Internal DSLs are private; external ones are public. :: It is about syntax and tooling, not visibility.
- External DSLs cannot be validated. :: They should be parsed and validated.
- There is no difference. :: They differ in how they are implemented.

? Which are required to evaluate a small rule DSL safely? (select all that apply)
+ Parse a constrained grammar into an AST. :: Never execute the raw text.
+ Validate identifiers, operators and types. :: Reject unknown fields early.
- Pass the rule text to `eval`. :: That allows arbitrary code e
…