HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Utility functions for supporting memoization for functions

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
memoizationutilityforsupportingfunctions

Problem

I've got a couple of utility functions to support memoization for functions with anywhere between 0 to 8 arguments:

```
Public Shared Function Mize(Of TResult)(ByVal input_f As System.Func(Of TResult)) As System.Func(Of TResult)
Dim is_new = True
Dim result As TResult
Return Function()
If is_new Then
result = input_f()
is_new = False
End If
Return result
End Function
End Function

Public Shared Function Mize(Of TArg1 As Structure, TResult)(ByVal input_f As System.Func(Of TArg1, TResult)) As System.Func(Of TArg1, TResult)
Dim map = New System.Collections.Generic.Dictionary(Of TArg1, TResult)
Return Function(arg1 As TArg1)
Dim result As TResult
If map.TryGetValue(arg1, result) Then Return result
result = input_f(arg1)
map.Add(arg1, result)
Return result
End Function
End Function

Public Shared Function Mize(Of TArg1 As Structure, TArg2 As Structure, TResult)(ByVal input_f As System.Func(Of TArg1, TArg2, TResult)) As System.Func(Of TArg1, TArg2, TResult)
Dim map = New System.Collections.Generic.Dictionary(Of System.Tuple(Of TArg1, TArg2), TResult)
Return Function(arg1 As TArg1, arg2 As TArg2)
Dim args = System.Tuple.Create(arg1, arg2)
Dim result As TResult
If map.TryGetValue(args, result) Then Return result
result = input_f(arg1, arg2)
map.Add(args, result)
Return result
End Function
End Function

Public Shared Function Mize(Of TArg1 As Structure, TArg2 As Structure, TArg3 As Structure, TResult)(ByVal input_f As System.Func(Of TArg1, TArg2, TArg3, TResult)) As System.Func(Of TArg1, TArg2, TArg3, TResult)
Dim map = New System.Collections.Generic.Dictionary(Of System.Tuple(Of TArg1, TArg2, TArg3), TResult)
Return Function(arg1 As TArg1, arg2 As TArg2, arg3 As

Solution

Unless you want to go with another approach, like code injection (see Anton's comment), you're pretty much stuck with this. I agree it is ugly and repetitive. Basically you've run up against the edges of the type system. Type parameters are a little like method parameters, and type arguments are a little like passing arguments to a method, but methods are much more flexible. Methods permit all sorts of higher-order programming, methods can be variadic, and so on. There are no variadic generic types in the .NET type system, which is really what you want to make this sort of thing work smoothly.

As for violating the DRY principle, don't worry about it. The reason to not repeat yourself is because if you have the same piece of complex business logic in two different places, and one of them needs fixing, they can get out of sync easily when you forget to fix the other. (The C# compiler codebase is littered with comments that say "If you change the reference type convertibility algorithm here, don't forget to also change it here, here and here...") What you're building here is a mechanism: the boring plumbing code that makes the real logic of the program more efficient. DRY is more applicable to business logic than to boring mechanisms.

Context

StackExchange Code Review Q#2478, answer score: 14

Revisions (0)

No revisions yet.