Maplist using a lambda on a lists of dicts doesn't work as expected

Given this:

:- use_module(library(yall)).
:- use_module(library(apply)).
:- use_module(library(apply_macros)).
works(L) :- maplist([A,B]>>(get_dict(b, A, B)), [#{a:1,b:2},#{a:3,b:4}], L).
doesnt(L) :- maplist([A,B]>>(B = A.b), [#{a:1,b:2},#{a:3,b:4}], L).

This works as I expect:

works(L).
L = [2, 4]

But this doesn’t:

doesnt(L).
Arguments are not sufficiently instantiated
In:
   [4] throw(error(instantiation_error,_1920))
   [1] doesnt(_1974) at  line 4

I though the two are supposed to be equivalent, clearly not?

This has come up before and actually just bit me the other day! You can see what’s happening if you try doing listing(doesnt/1):

doesnt(L) :-
    '.'(A, b, C),
    maplist([A, B]>>(B=C),
            [#{a:1, b:2}, #{a:3, b:4}],
            L).

What’s happening here is that the expansion of the dot-syntax to look up the dictionary gets hoisted outside of the lambda, so it happens once at the beginning of the predicate, not each iteration through the lambda.

Ah, thanks! So I’m not losing my marbles then :laughing: The listing hint is useful as well, thank you.

I thought it was pilot error on my part but it looks like it’s is a long-standing issue:

In my case the lambda is more complex than a simple dict value selection, so it is probably better off in a separate predicate anyway.