25 Tuple Construction
Tuple construction picks several things and combines them to give the set of
attributes output by the frame. The following expression selects course and
department from the university as outputs:
u.(course, department)
Here course and department are both evaluated from the same university u.
Its denotation as a frame is:
course=C:Course, department=D:Department
where
u.course(C)
∧ u.department(D)
The same idea works after navigation. The following expression selects code and
title from each course as outputs:
u.course.(code, title)
The path tails inside the parentheses are evaluated from the same current value.
In this case, both code and title are evaluated from the same course.
The empty tuple () projects away all attributes. The following expression reaches
each course and then returns the empty tuple for each one:
u.course.()
This is the zero-attribute projection. It is useful when only the existence of a matching value matters, rather than any attributes of that value.
Nested tuple expressions
Tuple expressions can be nested:
u.course.((code, title), department.name)
Nesting does not create nested structure in the output frame. The output attributes are flattened:
code=C:String, title=T:String, name=N:String
where
∃K:Course ∃D:Department
u.course(K)
∧ K.code(C)
∧ K.title(T)
∧ K.department(D)
∧ D.name(N)
Empty tuple expressions also disappear when flattened. For example, a.(b,(),(()).())
is equivalent to a.b.
Analogies with unwrapping, projection and Cartesian products
These examples have several relational-model analogies:
u.(course, department)is relational-product-like becausecourseanddepartmentare independent tails evaluated from the same university.u.course.(code, title)is relational-projection-like because it selectscodeandtitleas outputs.u.course.(code, title)is also unwrapping-like because it selects parts of each current course.
Later chapters use the same parentheses with renaming, calculations, folds and nested path expressions.
Path tails inside tuple construction
In general, tuple construction contains path tails. This is powerful because tuple construction composes with navigation, filters, folds and the other forms of path expression.
For example, this expression selects the student's name and the course code from each enrolment as outputs:
u.enrolment.(student.name, course.code)
Both path tails are evaluated from the same enrolment. That is why the student name and course code remain associated with each other.
The path tails can use filters too:
u.course.(code, [advanced].title)
Here code and [advanced].title are both evaluated from the same course. The
second path tail begins with a filter before selecting the course title.
A theta-join-like expression
Tuple construction and filters can be combined in a way that resembles a theta join:
u.(enrolment, session).[enrolment.course = session.course]
The tuple construction forms enrolment-session combinations from the university. The filter keeps the combinations where the enrolment and the session refer to the same course.