Functional Basic Code
Status: Beta
Brought to you by:
non_apparent
FunctionalBasic Introduction FunctionalBasic is a library for Visual Basic 6.0 that provides the higher-order functions map, filter, fold(l/r), compose and bind in addition to anonymous 'lambda' functions. It can be used to concisely express operations on list types (arrays, ListBoxes, ComboBoxes and Collections). It provides an interface (IFunction) that can be used if it is difficult to express the functionality you require in terms of lambda, compose and bind. Unfortunately it only supports functions with up to 9 parameters, but that should be enough for most purposes. Map Map takes a list type and a function type and returns a new list where each element corresponds to the result of applying the function to each element in the original list. Map can be called with a string as the list in which case it returns a new string where the function was applied to each character in turn. In pseudo-code: Function Map(List() As T, Func As T(T)) As T() For Each Element In List NewList.Add Func(Element) Map = NewList End Function Filter Filter takes a list type and a function type and returns a new list containing only the elements where the function returned True when applied to them. Filter can be called with a string as the list in which case it returns a new string containing only the characters for which the function returned True. In pseudo-code: Function Filter(List() As T, Func As Bool(T)) As T() For Each Element In List If Func(Element) NewList.Add Element Filter = NewList End Function Note that Filter is already used as a function name in VB6 so you must either use HigherOrder.Filter or its alias RemoveIf. Foldl/r Foldl takes a list type and a function type, and optionally an initial value and returns the value obtained by applying the function to each pair of elements from left to right. If an initial value if specified it is treated as the leftmost element of the list. Foldr functions similarly but it applies the function from right to left and the initial value is treated as the rightmost element of the list. In pseudo-code: Function Foldl(List() As T, Func As T(T, T), Optional Initial As T) As T If Initial Then Initial = Func(Initial, List(0)) Else Initial = List(0) For Each Element In List(1 ..) Initial = Func(Initial, Element) Foldl = Initial End Function Compose Compose takes two function types and returns a new function which when evaluated calls the first function with the result of the second. In pseudo-code: Function Compose(F As Any(T), G As T(Any...)) As Any(Any...) Compose(Params) = F(G(Params) End Function Bind Bind takes a function type and a list of parameters and returns a new function which calls the function with the new parameters. It also supports specifying parameters to be supplied when the new function is called via the Param(1 - 9) syntax. In pseudo-code: Function Bind(F As Any(Any...), Params...) Bind(Params) = F(Params) End Function Lambda Lambda takes a string and returns a new function that evaluates the expression in the string. The syntax of the expression is as close to VB6 syntax as possible. (params) => expression where params is a comma separated list of parameter names and expression is a normal VB6 expression using those parameters. You may use ' instead of " for string literals inside the expression. The following VB6 functions are supported inside expressions: Abs, Asc, Atn, CBool, CDbl, CLng, Chr, CInt, Cos, CSng, CStr, Exp, Fix, Hex, IIf, InStr, InStrRev, Int, IsArray, IsEmpty, IsNull, IsNumeric, IsObject, LBound, LCase, Left, Len, Log, LTrim, Mid, Oct, RGB, Right, Rnd, RTrim, Sgn, Sin, Sqr, String, Tan, Trim, TypeName, UBound, UCase, Val Examples Stripping non-alphabetic characters from a string: RemoveIf("L33t", _ Lambda("(C) => (C >= 'a' And C <= 'z') Or (C >= 'A' And C <= 'Z')")) = "Lt" Building a comma-separated list of names: Foldl(Array("John", "Steve", "Bruce"), _ Lambda("(N1, N2) => N1 & ', ' & N2")) = "John, Steve, Bruce" Rot13 encoding a string: Map("HELLOURYYB", _ Lambda("(C) => IIf(UCase(C) > 'M', Chr(Asc(C)-13), Chr(Asc(C)+13))")) = "URYYBHELLO"