Open ccamel opened 5 days ago
That's an important I agree.
I also think it is easier to implement it in Prolog directly than as a custom Go predicate:
foldl(Goal, [H|T], Result) :-
foldl(Goal, T, H, Result).
foldl(Goal, [H|T], Acc, Result) :-
call(Goal, Acc, H, NewAcc),
foldl(Goal, T, NewAcc, Result).
foldl(_Goal, [], Result, Result).
I'd like to propose to allow implementing new predicates directly in prolog, which would be added to the bootstrap.pl
when loading the VM.
I recall for example that we've implemented the source_files/1
predicate this way, but I'm not comfortable editing the bootstrapping program directly as we don't benefit from autogenerated documentation, tests, etc.. I'd like instead to propose an alternative way of registering predicates by providing its related Prolog code the registry would load after the bootstrap program.
What do you think @ccamel ? We may lose in performance though, maybe some benchmarks could help us on that
Hey! I agree. IMHO, native predicate implementations should be reserved for:
Regarding foldl/n
, you're right, this is a typical predicate that can be implemented in pure Prolog. And that's exactly what swi-prolog does, afais: implemented it in apply.pl as follows:
foldl(Goal, List, V0, V) :-
foldl_(List, Goal, V0, V).
foldl_([], _, V, V).
foldl_([H|T], Goal, V0, V) :-
call(Goal, H, V0, V1),
foldl_(T, Goal, V1, V).
Further considerations.
Note: bootstrap.pl
will be deprecated once module implementation is available in ichiban/prolog
(see PR https://github.com/ichiban/prolog/pull/307), and we can leverage it to treat our modules as first-class Prolog citizens, enabling dynamic module loading at runtime and proper module scoping and visibility rules...
Documentation:
Performance considerations:
If you want to move forward on these topics, we should create tickets to address the different steps. Also, some topics need to be addressed in axone-protocol/prolog.
📝 Purpose
Implement the
foldl/4
Prolog predicate. This predicate performs a fold (left-fold) over a list, applying a goal to each element in the list, starting with an initial accumulator value and producing a final value after all elements are processed.Rationale
This predicate is quite common and can facilitate the expression of certain governance rules, especially in scenarios where an aggregate decision or value must be derived from a list of inputs by applying a consistent operation across them...
🧪 Expected behavior
foldl/4
folds a list head-to-tail (“fold-left”), applying each element to the specified Goal.V0
serves as the initial accumulator value, andV
is the final result of the folding operation.Where:
Goal
: A predicate that is applied to the elements of List and the accumulator. It should accept three arguments: an element of List, the current accumulator, and the new accumulator.List
: A list of elements to be folded over.V0
: The initial accumulator value.V
: The final value of the accumulator after folding the entire list.🎯 Example
✅ Acceptance Criteria
🔗 References and linked predicate