Back to Default Arguments

Functions · Default Arguments · Practice Question

Use a Projection to Bake In Defaults

Sign in to track your progress

Question

A trading desk uses the following query function throughout their codebase:

fetchTrades:{[tbl; syms; startDt; endDt]
  select from tbl where sym in syms, date within (startDt; endDt)
 }

Most calls query the trade table and only need trades for today. Create two specialised versions using projections:

  1. todaysTrades — pre-binds the table to trade and both dates to .z.d
  2. tradesFrom — pre-binds the table to trade and startDt to .z.d - 7 (last 7 days), leaving syms and endDt open

Solution

To try this out, first create a small trade table with a date column:

trade:([] date:.z.d; sym:`AAPL`MSFT`GOOG`AAPL`MSFT; price:185.5 410.1 142.8 187.0 411.2; qty:100 200 300 150 250)
fetchTrades:{[tbl; syms; startDt; endDt]
  select from tbl where sym in syms, date within (startDt; endDt)
 }

/ Pre-bind table + both dates; only syms remains open
todaysTrades: fetchTrades[trade; ; .z.d; .z.d]

/ Pre-bind table + startDt; syms and endDt remain open
tradesFrom: fetchTrades[trade; ; .z.d - 7; ]

todaysTrades[`AAPL`MSFT]
tradesFrom[`GOOG; .z.d]

Explanation

Projections are a clean alternative to null-checking defaults when a particular combination of arguments is used repeatedly. Rather than writing:

/ Repetitive at every call site
fetchTrades[trade; `AAPL; .z.d; .z.d]
fetchTrades[trade; `MSFT; .z.d; .z.d]
fetchTrades[trade; `GOOG; .z.d; .z.d]

you create the specialisation once and call the simpler form everywhere:

todaysTrades `AAPL
todaysTrades `MSFT
todaysTrades `GOOG

Key difference from null-check defaults:

ApproachWhen defaults are decided
Null check ($[null x;...])At call time — caller can override per call
ProjectionAt definition time — fixed when the projection is created

Use projections when a specific configuration is used in many places and you want a named, documented entry point for it. Use null checks when the default is a fallback that any individual call can override.

Note on .z.d in projections: .z.d is evaluated when the projection is created, not when it is called. If todaysTrades is defined at startup and called the next day, it will still query yesterday's date. For projections that need live values, use a lambda instead:

todaysTrades: {fetchTrades[trade; x; .z.d; .z.d]}