Back to Projections

Functions · Projections · Practice Question

Project a User-Defined Function

Sign in to track your progress

Question

Given the following function:

between:{[lo; hi; v] (v >= lo) and v <= hi}
  1. Create inWorkingHours — checks whether a time is between 09:30:00 and 16:30:00
  2. Create inPriceRange — checks whether a price is between 100.0 and 200.0
  3. Apply both to a list using each

Solution

between:{[lo; hi; v] (v >= lo) and v <= hi}

inWorkingHours: between[09:30:00; 16:30:00;]
inPriceRange:   between[100.0;    200.0;   ]

times: 08:00:00 10:00:00 12:30:00 17:00:00
inWorkingHours each times
/ 0110b

prices: 50.0 125.5 199.9 250.0
inPriceRange each prices
/ 0110b

Explanation

between[09:30:00; 16:30:00;] fixes the first two arguments of between and leaves the third slot (v) open. The result is a rank-1 function that checks whether a single value falls within that fixed range.

Using each then applies the rank-1 projection to every element of a list, which is cleaner than writing:

/ Without projection — more repetition
{between[09:30:00; 16:30:00; x]} each times

The projection version reads more naturally: "apply inWorkingHours to each time".

Why write projections in full? Always include all semicolons, even when fixing trailing arguments:

between[09:30:00; 16:30:00;]   / preferred — the trailing semicolon shows the slot is open
between[09:30:00; 16:30:00]    / also a projection, but easy to misread as a mistake

Applying a function to fewer arguments than it takes always produces a projection, so both lines create the same function. The trailing semicolon simply makes your intent clear to the reader.

(Because >=, <= and and all work on whole lists, inWorkingHours times without each gives the same result, and q's built-in within does the same job: times within 09:30:00 16:30:00.)