Reputation: 39
I want to automatically create a vector containing USDccy and ccyUSD strings for each ccy in ccys below. I can do so in the following way.
ccys: `AUD`CAD`NZD;
ccysvec:`$("USD",/:string ccys), (string ccys),\:"USD";
However, for the each-left part, I note that if remove brackets around string ccys,i.e.
string ccys,\:"USD"
I get the following with USD separated.
Something similar does not happen even if there are no brackets around string ccys for the each-right part.
Could you please help me understand why?
Upvotes: 0
Views: 162
Reputation: 1097
A firm grip on the syntax helps. More precisely, “evaluates right to left” means: a binary function f
with infix syntax has long right scope and short left scope. Without parens, its right argument is everything to its right. Its left argument is the first thing to its left. So as the answers above say, in string ccys,\:"USD"
while the right argument to ,\:
is "USD"
its left argument is ccys
, not string ccys
.
It may help to think of Each Left and Each Right as syntactic sugar. You can replace x f\:y
with f[;y] each x
and x f/:y
with f[x;] each y
. And variants of the same. So your two joins can be written as unary projections of Join: ,["USD";]
and ,[;"USD"]
. Or "USD",
and ,[;"USD"]
if you like.
You can apply both unaries to one currency code:
q)("USD",;,[;"USD"])@\:string `AUD
"USDAUD"
"AUDUSD"
Or, with Each, to all of them.
q)raze`$("USD",;,[;"USD"])@'\:string ccys
`USDAUD`USDCAD`USDNZD`AUDUSD`CADUSD`NZDUSD
And you may want cross-rates from time to time.
q)raze`${(x,;,[;x])@'\:string y}["GBP";ccys]
`GBPAUD`GBPCAD`GBPNZD`AUDGBP`CADGBP`NZDGBP
Upvotes: 1
Reputation: 1593
This is a good example of how the kdb+ ideology of 'bracket free code' can sometimes get you into trouble.
It's important to bear in mind that KDB+ evaluates purely right to left.
In your example ccys is a symbol list whereas "USD" is already a string.
By using brackets in your first code snippet you are converting the symbol list to a list of strings then joining "USD" onto each of these.
In your second example you are first joining "USD" to each symbol (KDB+ happily allows this and creates a new array of mixed lists) then stringing the result.
This will result in a list where each element consists of a string (previously a symbol) joined to the result of string"USD"
- string-ing a string will turn each character into its own char array hence the strange output you are seeing.
Upvotes: 0
Reputation: 2800
kdb executes right to left so without the brackets the each left is joining a list of symbols (ccys
) to a a string which is technically a list of characters.
q)ccys,\:"USD"
`AUD "U" "S" "D"
`CAD "U" "S" "D"
It doesn't happen for the each right because ccys will be converted to strings before the join and in this case a string is being joined to a string.
q)"USD",/:string ccys
"USDAUD"
"USDCAD"
"USDNZD"
Upvotes: 1