04/12/2020

LotusScript callback functions are possible, sort of...

Using JavaScript more and more, one learns to appreciate the possibilities of callback functions. While developing XPages applications, many complex issues can be dealt with simply by using a standard (library) function and a callback to a function that is your own.

For instance, sorting in JavaScript can be done using a standard sort function in combination with a comparator function.


	var r= [4,5,6,1,2,3];
	r.sort(function(a, b) {
		return b-a;
	});
	console.log(r.join(","))
		
will produce the following output on the console:

	6,5,4,3,2,1
		
Is there a way to do the same in LotusScript? The usual answer to this question is no, it can't be done, but...

There is good news, for there is a way! And, even better news: it's not that difficult. It is of course not possible to use a function parameter, exactly like in JavaScript, but the solution is entirely in LotusScript and fairly easy to understand if you're familiar with simple LotusScript classes and objects.

Let's use the sorting example from above, in combination with a flexible comparator function. The solution below is based on one base class with a derived class. The base class contains the standard methods to fill an array (Variant) with values and to retrieve it again after sorting, plus a standard comparator function. This standard comparator function can be redefined in the derived class.

Maybe it's better to show you the solution:


	Class Sorter
		Private stack As Stack
		
		Sub New
			Set stack= New Stack
		End Sub
		
		Sub addValue(value As Variant)
			Call stack.Push(value)
		End Sub
		
		Function Compare(a, b) As Integer
			If a<b Then 
				Compare= -1
			ElseIf a>b Then
				Compare= 1
			End if
		End Function
		
		Private Function Sort As Variant
			...
		End Function
	End Class
    

Some explanation:

  • Sorter is the base class that simply returns a sorted array,
  • Stack is a class with a variable size array that acts as a stack, with standard push() and pop() operations, and a function that returns the current contents,
  • The Compare function can be redefined in a derived class, the standard function will sort the values in ascending order.
  • Now for the derived class. All we have to do is redefine the Compare function, so that the Sorter sorts the values in descending order:

    
    	Class SortDescending As Sorter
    		Function Compare(a, b) As Integer 
    			If a<b Then 
    				Compare= 1
    			ElseIf a>b Then
    				Compare= -1
    			End If			
    		End Function
    	End Class
        
    Let's put it to the test, in an Agent:
    
    	Sub Initialize
    		Dim sd As New SortDescending
    		Dim v As Variant 
    		
    		v= Split("4,5,6,1,2,3", ",")
    		ForAll p In v
    			Call s.addValue(p)
    		End ForAll
    		v= sd.Sort
    		Print Join(v, ",")
    	End Sub
    	
    I'll leave it to you to guess the output...

    What we achieved is a Sorter class that can be stored in a common library, for everyone to use. If you need a sorting function and you don't want to do the implementation yourself, you can reuse the Sorter class and just redefine the comparator function. The default comparator works for numbers or strings, but you can even write make it work for objects, under the condition that you correctly define the comparator function.

    SorterTest.zip

    © 2020 Sjef Bosman · Consultant HCL Domino/Notes
    SIRET 442 133 252 00019 · tél. +33 475 252 805
    sjef@bosman.fr · sjef.bosman