This felt like a big deal last night, but it doesn't seem that important now.
This seems like such a trivial thing, but it drove me crazy when dealing with SAS. There was no apparent organizing principle to parameters; they just showed up in whatever order they were thought of. It was compounded by the fact that nontrivial functionality was in these big monolithic procedures that took half a dozen parameters each. I've managed not to think about it, but I installed Factor yesterday.
Suppose I have a pair of hash tables, and the second table is a mapping from keys to hash tables. I want to think of this pair as a database table, so the first is going to have, for the time being, pairs of column names and default values. Ignoring the test to see whether that name is already present, I have
: extend-schema ( value key table -- ) first set-at ;
The function is named extend-schema, its stack effect is to drop three values, and it does so by taking the first element of the pair and setting the value at the key. Note the strange parameter ordering. Assuming that the key wasn't already present in the schema, I want to update all the entries in the table to have a key with the default value.
The library defines assoc-each ( assoc quot -- )
and the quotation should have the effect ( key value -- )
, although this isn't enforced. The key and the value are in the "wrong" order. This doesn't matter yet, although it would if I wanted to change the values. So let's see what I have to do:
! value key table
second ! value key entries
-rot ! entries value key (I'm going to need to curry these)
extend-member ! entries value key quot (I'll explain shortly)
2curry ! entries quot
therefore needs the type ( name row value key -- )
. It also needs to use set-at
, which had its parameters reversed. I need to use spin
, whose effect is ( x y z -- z y x )
: extend-member ( name row value key ) [ spin set-at drop ] ;
With the resulting function being:
: extend-table ( default-value key table -- )
[ first set-at ]
[ second -rot [ spin set-at drop ] 2curry assoc-each ]
If, on the other hand, set-at were to take its arguments in the opposite order, I could write
: extend-table ( table key default-value -- )
[ [ first ] 2dip set-at ]
[ [ second ] 2dip [ set-at drop ] 2curry assoc-each ]
It doesn't look like I've gained very much, but I've removed an operation from a potentially very long loop. But that price may come back in the new implementation, and the test to see whether the value was already present will be harder.
I guess in this case it isn't worth it.