sancarn / stdVBA

VBA Standard Library - A Collection of libraries to form a common standard layer for modern VBA applications.
MIT License
294 stars 58 forks source link

[Feature] stdICallable::bind() #7

Closed sancarn closed 4 years ago

sancarn commented 4 years ago

FEATURES

Added the stdICallable::Bind(...) function to stdLambda, stdCallback and stdICallable.

The bind() method creates a new ICallable that, when called, supplies the given sequence of arguments preceding any provided when the new function is called.

Dim cb as stdLambda: set cb = stdLambda.Create("$1 + $2").Bind(5)
Debug.Print cb(1) '6 
Debug.Print cb(2) '7
Debug.Print cb(3) '8
'...

This is exceptionally useful to prevent recursive recompiles in stdArray loops.

For example, imagine you are trying to filter an array, with items less than a value. Typically with previous versions of stdLambda you would do the following:

Dim arr as stdArray: set arr = stdArray.Create(1,2,3,4,5,6,7,8,9,10)

set filtered = arr.filter(stdLambda.Create("$1 <= 5"))
set filtered = arr.filter(stdLambda.Create("$1 <= 10"))

This is fine, however in this case 2 lambda expressions are created. We compile first for $1 <= 5 and again for $1 <= 10. In reality this means we do signficantly more load for what seems to be a trivial set of calculations.

We can increase the performance of this using Bind to restrict the number of calls to compile:

Dim arr as stdArray: set arr = stdArray.Create(1,2,3,4,5,6,7,8,9,10)

set filtered = arr.filter(stdLambda.Create("$2 <= $1").Bind(5)) 'get elements <= 5
set filtered = arr.filter(stdLambda.Create("$2 <= $1").Bind(10)) 'get elements <= 10

Though this looks like more work, it also allows us to setup more optimal API functions:

Public records as stdArray

Function GetRecordsByDate(ByVal dt as Date) as stdArray
    set GetRecordsByDate = records.filter(stdLambda.Create("$2.Date = $1").bind(dt))
End Function

Ultimately, the use of bind is to restrict compilations of expressions and thus optimise their repeated usage on large datasets.