Skip to content

Commit 22b296d

Browse files
authored
Join loop iterations as objects (#580)
* Join loop iterations as objects * Fix dumper
1 parent 29180a0 commit 22b296d

File tree

12 files changed

+83
-52
lines changed

12 files changed

+83
-52
lines changed

docs/tutorial.md

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -421,14 +421,8 @@ This program outputs:
421421
```
422422

423423
To output a number of each line, we can specify which string to use to join the results.
424-
```
425-
description: for loop
426-
for:
427-
i: [1, 2, 3, 4]
428-
repeat:
429-
${ i }
430-
join:
431-
with: "\n"
424+
```yaml
425+
--8<-- "./examples/tutorial/for_with.pdl"
432426
```
433427

434428
```
@@ -440,14 +434,8 @@ join:
440434

441435

442436
To creates an array as a result of iteration, we would write:
443-
```
444-
description: for loop
445-
for:
446-
i: [1, 2, 3, 4]
447-
repeat:
448-
- ${ i }
449-
join:
450-
as: array
437+
```yaml
438+
--8<-- "./examples/tutorial/for_array.pdl"
451439
```
452440

453441
which outputs the following list:
@@ -456,14 +444,8 @@ which outputs the following list:
456444
```
457445

458446
To retain only the result of the last iteration of the loop, we would write:
459-
```
460-
description: for loop
461-
for:
462-
i: [1, 2, 3, 4]
463-
repeat:
464-
- ${ i }
465-
join:
466-
as: lastOf
447+
```yaml
448+
--8<-- "./examples/tutorial/for_lastOf.pdl"
467449
```
468450

469451
which outputs:
@@ -484,20 +466,10 @@ meaning that result of each iteration is stringified and concatenated with that
484466
Note that `join` can be added to any looping construct (`repeat`) not just `for` loops.
485467

486468

487-
The `for` loop constructs also allows iterating over 2 or more lists of the same length simultaneously:
469+
The `for` loop construct also allows iterating over 2 or more lists of the same length simultaneously:
488470

489-
```
490-
description: for loop
491-
defs:
492-
numbers:
493-
data: [1, 2, 3, 4]
494-
names:
495-
data: ["Bob", "Carol", "David", "Ernest"]
496-
for:
497-
number: ${ numbers }
498-
name: ${ names }
499-
repeat:
500-
"${ name }'s number is ${ number }\n"
471+
```yaml
472+
--8<-- "./examples/tutorial/for_multiple_lists.pdl"
501473
```
502474

503475
This results in the following output:
@@ -509,6 +481,18 @@ David's number is 3
509481
Ernest's number is 4
510482
```
511483

484+
The loop constructs also allow to build an object:
485+
```yaml
486+
--8<-- "./examples/tutorial/for_object.pdl"
487+
```
488+
489+
This results in the following output:
490+
491+
```
492+
{"Bob": 1, "Carol": 2, "David": 3, "Ernest": 4}
493+
```
494+
495+
512496
## Roles and Chat Templates
513497

514498
Consider again the chatbot example ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/conditionals_loops.pdl)). By default blocks have role `user`, except for model call blocks, which have role `assistant`.

examples/tutorial/for.pdl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
description: for loop
1+
description: for loop creating a string
22
for:
33
i: [1, 2, 3, 4]
44
repeat:

examples/tutorial/for_array.pdl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
description: for loop
1+
description: array comprehension
22
for:
33
i: [1, 2, 3, 4]
44
repeat:

examples/tutorial/for_lastOf.pdl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
description: loop where the result is the result of the last iteration
2+
for:
3+
i: [1, 2, 3, 4]
4+
repeat:
5+
${ i }
6+
join:
7+
as: lastOf

examples/tutorial/for_multiplie_lists.pdl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
description: for loop
1+
description: for loop over multiple lists
22
defs:
33
numbers:
44
data: [1, 2, 3, 4]

examples/tutorial/for_object.pdl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
description: for loop creating an object
2+
defs:
3+
numbers:
4+
data: [1, 2, 3, 4]
5+
names:
6+
data: ["Bob", "Carol", "David", "Ernest"]
7+
for:
8+
number: ${ numbers }
9+
name: ${ names }
10+
repeat:
11+
data:
12+
${ name }: ${ number }
13+
join:
14+
as: object

examples/tutorial/for_with.pdl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
description: for loop
1+
description: for loop with new lines between iterations
22
for:
33
i: [1, 2, 3, 4]
44
repeat:

src/pdl/pdl-schema.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5245,6 +5245,22 @@
52455245
"title": "JoinLastOf",
52465246
"type": "object"
52475247
},
5248+
"JoinObject": {
5249+
"additionalProperties": false,
5250+
"properties": {
5251+
"as": {
5252+
"const": "object",
5253+
"description": "Return the union of the objects created at each iteration.\n ",
5254+
"title": "As",
5255+
"type": "string"
5256+
}
5257+
},
5258+
"required": [
5259+
"as"
5260+
],
5261+
"title": "JoinObject",
5262+
"type": "object"
5263+
},
52485264
"JoinText": {
52495265
"additionalProperties": false,
52505266
"properties": {
@@ -9439,6 +9455,9 @@
94399455
{
94409456
"$ref": "#/$defs/JoinArray"
94419457
},
9458+
{
9459+
"$ref": "#/$defs/JoinObject"
9460+
},
94429461
{
94439462
"$ref": "#/$defs/JoinLastOf"
94449463
}

src/pdl/pdl_ast.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ class MatchBlock(Block):
477477
class IterationType(StrEnum):
478478
LASTOF = "lastOf"
479479
ARRAY = "array"
480+
OBJECT = "object"
480481
TEXT = "text"
481482

482483

@@ -504,13 +505,19 @@ class JoinArray(JoinConfig):
504505
"""
505506

506507

508+
class JoinObject(JoinConfig):
509+
iteration_type: Literal[IterationType.OBJECT] = Field(alias="as")
510+
"""Return the union of the objects created at each iteration.
511+
"""
512+
513+
507514
class JoinLastOf(JoinConfig):
508515
iteration_type: Literal[IterationType.LASTOF] = Field(alias="as")
509516
"""Return the result of the last iteration.
510517
"""
511518

512519

513-
JoinType: TypeAlias = JoinText | JoinArray | JoinLastOf
520+
JoinType: TypeAlias = JoinText | JoinArray | JoinObject | JoinLastOf
514521

515522

516523
class RepeatBlock(Block):

src/pdl/pdl_dumper.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
IfBlock,
2424
ImportBlock,
2525
IncludeBlock,
26-
JoinArray,
27-
JoinLastOf,
2826
JoinText,
2927
JoinType,
3028
LastOfBlock,
@@ -287,7 +285,7 @@ def join_to_dict(join: JoinType) -> dict[str, Any]:
287285
match join:
288286
case JoinText():
289287
d["with"] = join.join_string
290-
case JoinArray() | JoinLastOf():
288+
case _:
291289
d["as"] = str(join.iteration_type)
292290
return d
293291

0 commit comments

Comments
 (0)