Skip to content

Commit 87a1bb8

Browse files
committed
feat: stronger typing for algorithmic function handler
1 parent 6b50cc9 commit 87a1bb8

7 files changed

+21
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2727
### Changed
2828

2929
- The `Root`function now accepts an `Expression` as degree.
30+
- Handler functions passed to `AlgorithmicFunction` can no longer be
31+
dynamically typed.
3032

3133
### Deprecated
3234

lib/src/functions.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1111,7 +1111,7 @@ class AlgorithmicFunction extends DefaultFunction {
11111111
/// method instead it is supported by the parser.
11121112
AlgorithmicFunction(super.name, super.args, this.handler) : super._any();
11131113

1114-
Function handler;
1114+
double Function(List<double>) handler;
11151115

11161116
@override
11171117
dynamic evaluate(EvaluationType type, ContextModel context) {

lib/src/parser.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ abstract class ExpressionParser {
1919
///
2020
/// Throws a [FormatException] if the given [name] is already defined and
2121
/// [replace] is false.
22-
void addFunction(String name, dynamic handler, {bool replace = false});
22+
void addFunction(String name, double Function(List<double>) handler,
23+
{bool replace = false});
2324
}
2425

2526
/// The default parser. This type alias is deprecated, use [GrammarParser]
@@ -175,7 +176,8 @@ class ShuntingYardParser implements ExpressionParser {
175176
}
176177

177178
@override
178-
void addFunction(String name, dynamic handler, {bool replace = false}) {
179+
void addFunction(String name, double Function(List<double>) handler,
180+
{bool replace = false}) {
179181
if (lex.keywords.containsKey(name) && !replace) {
180182
throw FormatException('Cannot redefine existing function $name');
181183
}

lib/src/parser_petit.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class GrammarParser implements ExpressionParser {
5050
};
5151

5252
/// Dynamically defined algorithmic functions.
53-
final functionsC = <String, dynamic>{};
53+
final functionsC = <String, double Function(List<double>)>{};
5454

5555
/// Creates an expression from the given identifier, and list of arguments.
5656
/// May return a constant, function or variable.
@@ -79,7 +79,7 @@ class GrammarParser implements ExpressionParser {
7979
default:
8080
var fun = functionsC[name];
8181
if (fun != null) {
82-
return AlgorithmicFunction(name, arguments, functionsC[name]);
82+
return AlgorithmicFunction(name, arguments, fun);
8383
}
8484
}
8585

@@ -172,7 +172,8 @@ class GrammarParser implements ExpressionParser {
172172
}
173173

174174
@override
175-
void addFunction(String name, dynamic handler, {bool replace = false}) {
175+
void addFunction(String name, double Function(List<double>) handler,
176+
{bool replace = false}) {
176177
if (functionsC.containsKey(name) && !replace) {
177178
throw FormatException('Cannot redefine existing function $name');
178179
}

test/expression_test_set.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,7 @@ class ExpressionTests extends TestSet {
13591359

13601360
/// Tests creation of algorithmic functions.
13611361
void algorithmicFunctionCreation() {
1362-
dynamic handler = (List<double> args) => args.reduce(math.min);
1362+
handler(List<double> args) => args.reduce(math.min);
13631363

13641364
// Generic list minimum (R^2 -> R)
13651365
AlgorithmicFunction f = AlgorithmicFunction('my_min', [n1, -n1], handler);
@@ -1374,7 +1374,7 @@ class ExpressionTests extends TestSet {
13741374
ContextModel cm = ContextModel();
13751375

13761376
Variable x = Variable('x');
1377-
dynamic handler = (List<double> args) => args.reduce(math.min);
1377+
handler(List<double> args) => args.reduce(math.min);
13781378

13791379
// Generic list minimum (R^3 -> R)
13801380
AlgorithmicFunction f =

test/parser_petit_test_set.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,13 +275,13 @@ class PetitParserTests extends TestSet {
275275

276276
void parseAlgorithmicFunctions() {
277277
var cases = {
278-
'myAlgorithmicFunction(1.0)': AlgorithmicFunction(
279-
'myAlgorithmicFunction', [Number(1.0)], () => null),
278+
'myAlgorithmicFunction(1.0)':
279+
AlgorithmicFunction('myAlgorithmicFunction', [Number(1.0)], (_) => 0),
280280
'my_min(1,x,-2)': AlgorithmicFunction('my_min',
281-
[Number(1), Variable('x'), UnaryMinus(Number(2))], () => null),
281+
[Number(1), Variable('x'), UnaryMinus(Number(2))], (_) => 0),
282282
};
283283

284-
parser.addFunction('myAlgorithmicFunction', () => null, replace: true);
284+
parser.addFunction('myAlgorithmicFunction', (_) => 0, replace: true);
285285
parser.addFunction('my_min', (List<double> args) => args.reduce(math.min),
286286
replace: true);
287287

test/parser_test_set.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,13 @@ class ParserTests extends TestSet {
226226

227227
void parseAlgorithmicFunctions() {
228228
var cases = {
229-
'myAlgorithmicFunction(1.0)': AlgorithmicFunction(
230-
'myAlgorithmicFunction', [Number(1.0)], () => null),
229+
'myAlgorithmicFunction(1.0)':
230+
AlgorithmicFunction('myAlgorithmicFunction', [Number(1.0)], (_) => 0),
231231
'my_min(1,x,-2)': AlgorithmicFunction('my_min',
232-
[Number(1), Variable('x'), UnaryMinus(Number(2))], () => null),
232+
[Number(1), Variable('x'), UnaryMinus(Number(2))], (_) => 0),
233233
};
234234

235-
parser.addFunction('myAlgorithmicFunction', () => null, replace: true);
235+
parser.addFunction('myAlgorithmicFunction', (_) => 0, replace: true);
236236
parser.addFunction('my_min', (List<double> args) => args.reduce(math.min),
237237
replace: true);
238238

0 commit comments

Comments
 (0)