Skip to content

Kiyoshi364/struct-pl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 

Repository files navigation

struct.pl

This is library defines a "macro" (user:term_expansion/2) for defining "struct"s. "Struct"s are like functors with "named fields". They are supposed to remind structs from C.

Basic Usage

To use, add the following to the top of the file:

:- use_module(struct).

and define your "struct" with:

:- struct(struct_name, [field1, field2, ..., fieldN]).

where struct_name is an atom: the name of your struct, and field1, field2, ..., fieldN form a list of fields.

Usually, a field is only an atom telling its name. The library also supports name:type, but THE LIBRARY DOES NO TYPE CHECKING. This feature is for readability purposes.

Then, the library will generate two helper predicates with the same name as your struct: an "view" (struct_name/3) and an "update" (struct_name/5).

struct_name(F, V, S) :- struct_name(F, V, V, S, S).

struct_name(field1, V0, V,
  struct_name(V0, F2, ..., FN),
  struct_name(V , F2, ..., FN)
).
struct_name(field2, V0, V,
  struct_name(F1, V0, ..., FN),
  struct_name(F1, V , ..., FN)
).
% ...
struct_name(fieldN, V0, V,
  struct_name(F1, F2, ..., V0),
  struct_name(F1, F2, ..., V )
).

The "view" predicate struct_name(Field, Value, Struct) is true iff Struct is a "struct" struct_name and Struct has Value at field Field.

The "update" predicate struct_name(Field, Value0, Value, Struct0, Struct) is true iff Struct0 and Struct are "struct"s struct_name, Struct0 has Value0 at field Field, Struct has Value at field Field, and all other fields of Struct0 are the same as the respective fields of Struct.

Virtual/Custom Fields

One can add extra "fields" right after the "struct" declaration.

Here, we are adding a "virtual field" length to vector2d.

:- struct(vector2d, [x, y]).
vector2d(length, Length, Length, Vec2d, Vec2d) :-
  Vec2d = vector2d(X, Y), Length is sqrt(X ** 2 + Y ** 2).

This "virtual field" is "read-only", because it cannot "update" an vector2d object. Observe that it is still possible to access the Length of a Vec2d with the "view" predicate: vector2d(length, Length, Vec2d).

One can also abuse this feature to implement "objects". The virtual field is the message (possibly with arguments), Value0 is some old value related to Struct0, Value is some new value related to Struct (maybe the message response), Struct0 is the old "object" (before the message) and Struct0 is the new "object" (after the message).

About

A prolog library for defining and using struct-like functors

Resources

Stars

Watchers

Forks

Contributors

Languages