# Yall lambdas in asserted clauses

**URL:** <https://swi-prolog.discourse.group/t/yall-lambdas-in-asserted-clauses/9374>\
**Category:** General\
**Created:** [November 9, 2025, 1:27pm UTC](https://swi-prolog.discourse.group/t/yall-lambdas-in-asserted-clauses/9374 "2025-11-09T13:27:24Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![patham9](https://avatars.discourse-cdn.com/v4/letter/p/f08c70/32.png) [@patham9](https://swi-prolog.discourse.group/u/patham9)\
**Post date:** [November 9, 2025, 1:27pm UTC](https://swi-prolog.discourse.group/t/yall-lambdas-in-asserted-clauses/9374/1 "2025-11-09T13:27:24Z")

</div>

Hi!

I understand that yall lambdas expand into an efficient form when a Prolog file is consulted, but how about when clauses are asserted at runtime? How can I achieve the same kind of performance with asserted clauses. Unless they are already using the same mechanism, is there a way to trigger the same kind of rewriting / expansion before a clause with an yall lambda in it is asserted?

Best regards,

Patrick

---

<div class="post-metadata">

**Author:** ![patham9](https://avatars.discourse-cdn.com/v4/letter/p/f08c70/32.png) [@patham9](https://swi-prolog.discourse.group/u/patham9)\
**Post date:** [November 10, 2025, 7:11pm UTC](https://swi-prolog.discourse.group/t/yall-lambdas-in-asserted-clauses/9374/3 "2025-11-10T19:11:24Z")

</div>

No. This is for consulted files, my question is about asserted clauses.

Lambdas in them seem very slow so these rewrites do not seem to be applied, so I wonder how one can apply them without writing to a file and consulting them.

Best regards,

Patrick

---

<div class="post-metadata">

**Author:** ![jamesnvc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jamesnvc/32/14_2.png) [@jamesnvc](https://swi-prolog.discourse.group/u/jamesnvc)\
**Post date:** [November 10, 2025, 7:31pm UTC](https://swi-prolog.discourse.group/t/yall-lambdas-in-asserted-clauses/9374/4 "2025-11-10T19:31:34Z")

</div>

Hm, I was thinking that manually calling yall:expand\_lambda/2 and asserting the expansion would do it, but I can’t seem to make that work. Presumably that’s where you’d want to look though.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [November 11, 2025, 8:00am UTC](https://swi-prolog.discourse.group/t/yall-lambdas-in-asserted-clauses/9374/6 "2025-11-11T08:00:23Z")

</div>

> [@jp-diegidio](#):
>
> term/goal expansion applies to any read term/goal, whether read from a file or from the command line

True. Only call/1 and assert/1 do not do goal/term expansion. So, to assert as if read from a file, use expand\_term/2 and assert the result. Note that bot the input and output can be lists.

For library(yall) there is a problem though. The expansion rule says

```prolog
system:goal_expansion(Goal, Head) :-
    lambda_like(Goal),
    prolog_load_context(source, _),
    \+ current_prolog_flag(xref, true),
    expand_lambda(Goal, Head).

```

I.e., we demand that we are reading source code. That has to do with the fact that a lambda goal is expanded to a goal to an auxiliary predicate and this predicate is compiled using compile\_aux\_clauses/1, which demands a “source” context. The problem is that expand\_goal/2 has no way to tell the caller it wants the goal to be expanded some way and specify a helper predicate.

For short, you cannot get this done for library(yall) ☹ Unless you want to refactor library(yall) a bit to make it possible to call expand\_lambda/2 outside a source context and deal with the result. That is doable, but it might be easier to define the required helper by hand and call this without using yall lambdas …

---

<div class="post-metadata">

**Author:** ![patham9](https://avatars.discourse-cdn.com/v4/letter/p/f08c70/32.png) [@patham9](https://swi-prolog.discourse.group/u/patham9)\
**Post date:** [November 11, 2025, 3:23pm UTC](https://swi-prolog.discourse.group/t/yall-lambdas-in-asserted-clauses/9374/7 "2025-11-11T15:23:55Z")

</div>

@anon19431257 Yes, term/goal expansion does not apply to assert.

@jan No worries, in the meanwhile we have our own lambda library that also works for asserted clauses and gives the equal speed as explicitly writing helper predicates does. Maybe we will port it back to yall, but from the discussion it seems yall is not engineered well so probably should be replaced anyways.

Best regards,

Patrick

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [November 11, 2025, 3:40pm UTC](https://swi-prolog.discourse.group/t/yall-lambdas-in-asserted-clauses/9374/8 "2025-11-11T15:40:57Z")

</div>

> [@patham9](#):
>
> Maybe we will port it back to yall, but from the discussion it seems yall is not engineered well so probably should be replaced anyways.

Not sure what you mean. The library has an IMO serious problem that the semantics of the interpreted and compiled versions is not the same. That is a fundamental issue, although SWI-Prolog’s current expansion code could detect that the code is subject to this issue (and thus warn).

I’m still not a big fan of lambdas in Prolog … Seems you have a different experience 🙂 I’m surely interested if you have a better version.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [November 11, 2025, 8:50pm UTC](https://swi-prolog.discourse.group/t/yall-lambdas-in-asserted-clauses/9374/10 "2025-11-11T20:50:07Z")

</div>

> [@jan](#):
>
> o assert as if read from a file, use [expand\_term/2](https://www.swi-prolog.org/pldoc/doc_for?object=expand_term/2) and assert the result.

Note that it’s always safe to call expand\_term/2 even if it’s already been called because term exapansion repeatedly calls term\_expansion/2 and goal\_expansion/2 until it reaches a fixed-point.

(Hmmm … @jan – is this correct? The documentation says that expand\_goal/2 repeatedly calls goal\_expansion/2 until there’s no change but term\_expansion/2 seems to only call expand\_goal/2 once (and then calls the DCG expansion).

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [November 12, 2025, 8:22am UTC](https://swi-prolog.discourse.group/t/yall-lambdas-in-asserted-clauses/9374/12 "2025-11-12T08:22:46Z")

</div>

> [@jp-diegidio](#):
>
> Thanks. Out of interest: is there a reason why that is so? (Could there be a Prolog that expands everything?)

Performance. It is barely every needed and if you need it, just call expand\_goal/2 and call the result. I think SICStus does so by default. Given user hooks, expand\_goal/2 can be arbitrary slow though.

> [@peter.ludemann](#):
>
> (Hmmm … @jan – is this correct? The documentation says that [expand\_goal/2](https://www.swi-prolog.org/pldoc/doc_for?object=expand_goal/2) repeatedly calls [goal\_expansion/2](https://www.swi-prolog.org/pldoc/doc_for?object=goal_expansion/2) until there’s no change but [term\_expansion/2](https://www.swi-prolog.org/pldoc/doc_for?object=term_expansion/2) seems to only call [expand\_goal/2](https://www.swi-prolog.org/pldoc/doc_for?object=expand_goal/2) once (and then calls the DCG expansion).

goal\_expansion/2 is called by expand\_goal/2 until fixed point is reached. expand\_term/2 calls term\_expansion only once. That is AFAIK how it traditionally works. Otherwise there are a lot of variations in how Prolog systems handle the expansion. Would be great if we can synchronize that!
