Saturday, April 6, 2024

Iterators in ALGOL 68, using Currying.


#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #

MODE GEN = VOID; # hint/flag generator contructs #

MODE YIELDINT = PROC(INT)GEN;
MODE GENINT = PROC(YIELDINT)GEN;

PROC is perfect square = (INT n)BOOL:
ENTIER (sqrt(n)+0.5) ** 2 = n; # Round to nearest integer #

PROC gen int = (YIELDINT yield)GEN:
FOR i DO yield(i) OD;

PROC gen square = (GENINT gen, YIELDINT yield)GEN:
gen((INT value)VOID: yield(value*value));

PROC gen sum = (GENINT gen, YIELDINT yield)GEN:
BEGIN
INT sum := 0;
gen((INT value)VOID: yield(sum +:= value))
END;

PROC gen perfect square = (GENINT gen, YIELDINT yield)GEN:
BEGIN
gen((INT value)VOID:
IF is perfect square(value) AND value NE 1 THEN
yield(value) # Yield the perfect square sum #
FI
)
END;

PROC head = (GENINT gen)INT:
BEGIN
INT return;
gen((INT i)VOID: ( return := i; GOTO done ));
done: return
END;

MODE PIPEINT = PROC(GENINT, YIELDINT)GEN;
MODE SINKINT = PROC(GENINT)INT;

OP AND = (GENINT source, PIPEINT pipe)GENINT: pipe(source,##);
OP AND = (GENINT source, SINKINT sink)INT: sink(source);

BEGIN
# INT result := head(gen perfect square(gen sum(gen square(gen int,##),##),##)); #
INT result := gen int AND gen square AND gen sum AND gen perfect square AND head;
printf(($"This sum is a perfect square: "gl$, result))
END

No comments:

Post a Comment