Functions · Default Arguments · Practice Question
Use a Projection to Bake In Defaults
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:
todaysTrades— pre-binds the table totradeand both dates to.z.dtradesFrom— pre-binds the table totradeandstartDtto.z.d - 7(last 7 days), leavingsymsandendDtopen
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 `GOOGKey difference from null-check defaults:
| Approach | When defaults are decided |
|---|---|
Null check ($[null x;...]) | At call time — caller can override per call |
| Projection | At 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]}