Implement map combinator.

This commit is contained in:
Simon Forman 2019-07-21 08:28:56 -07:00
parent 84a2de7790
commit 32d5953f29
2 changed files with 32 additions and 1 deletions

View File

@ -1,9 +1,11 @@
-- == 1 -
++ == 1 +
? == dup bool
++ == 1 +
anamorphism == [pop []] swap [dip swons] genrec
app1 == grba infrst
app2 == [grba swap grba swap] dip [infrst] cons ii
app3 == 3 appN
appN == [grabN] cons dip map disenstacken
at == drop first
average == [sum 1.0 *] [size] cleave /
b == [i] dip i
@ -23,6 +25,7 @@ flatten == [] swap [concat] step
fork == [i] app2
fourth == rest third
gcd == true [tuck mod dup 0 >] loop pop
grabN == [] swap [cons] times
grba == [stack popd] dip
hypot == [sqr] ii + sqrt
ifte == [nullary] dipd swap branch

View File

@ -242,6 +242,34 @@ combo(genrec, [R1, R0, Then, If|S],
Quoted = [If, Then, R0, R1, genrec],
append(R0, [Quoted|R1], Else).
/*
This is a crude but servicable implementation of map combinator.
Obviously it would be nice to take advantage of the implied parallelism.
Instead the quoted program, stack, and each term in the arg list are
transformed to a simple Joy expression that runs the program on a prepared
stack. These expressions are collected in a list and the whole thing is
evaluated with infra on an empty list, so the result is the mapped list.
The chief advantage of doing it this way (as opposed to using Prolog's map)
is that the whole state remains in the continuation expression.
*/
combo(map, [_, []|S], [[]|S], E, E ) :- !.
combo(map, [P, List|S], [Mapped, []|S], E, [infra|E]) :-
prepare_mapping(P, S, List, Mapped).
% Set up a program for each term in ListIn
%
% [term S] [P] infrst
%
% prepare_mapping(P, S, ListIn, ListOut).
prepare_mapping(P, S, In, Out) :- prepare_mapping(P, S, In, [], Out).
prepare_mapping( _, _, [], Out, Out) :- !.
prepare_mapping( P, S, [T|In], Acc, Out) :-
prepare_mapping(P, S, In, [[T|S], P, infrst|Acc], Out).
/*
Compiler