# Splicing in syntax

**URL:** <https://racket.discourse.group/t/splicing-in-syntax/2336>\
**Category:** Questions & Answers\
**Tags:** question, macro\
**Created:** [September 23, 2023, 2:41am UTC](https://racket.discourse.group/t/splicing-in-syntax/2336 "2023-09-23T02:41:07Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mem](https://avatars.discourse-cdn.com/v4/letter/m/90ced4/32.png) [@mem](https://racket.discourse.group/u/mem)\
**Post date:** [September 23, 2023, 2:41am UTC](https://racket.discourse.group/t/splicing-in-syntax/2336/1 "2023-09-23T02:41:07Z")

</div>

Be gentle, folks—first time posting here.

I've been interested in DSLs for a long time, and when I get the itch I come back to Racket to fool around a bit and inevitably find myself tangled up in some issue or another. The TL;DR here is that I'm wondering if it's possible to splice syntax into an existing form of the sort:

```scheme
(some-function #:some-keyword-arg some-val
   (generate-n-function-calls arg1 arg2 arg3))

; Expands to:
; (some-function #:some-keyword-arg some-val
; (some-other-function arg1)
; (some-other-function arg2)
; (some-other-function arg3))

```

To make it more concrete, I've been working with slideshow. I wish the following were more entertaining, but it represents basically what I'm looking at:

```scheme
#lang slideshow/widescreen

(slide #:title "Minimal slide"
  (item "One")
  (item "Two")
  (item "Three"))

```

I'm lazy, so I'd rather write:

```scheme
#lang slideshow/widescreen

(define (itemize . lst) (map item lst))

(slide #:title "Minimal slide"
  (itemize "One" "Two" "Three"))

; => slide*: argument sequence contains a bad element: '(#<pict> #<pict> #<pict>)

```

Ahhh, I say, so I presumably need to destructure these and maybe make a set of values? (_Stare at docs a bit_ I don't think I want to use `'alts` even though I can make it work. And why is the error coming from `slide*` and not `slide`? A bit of indirection...)

```scheme
; ...
(define (itemize . lst) (apply values (map item lst)))
; ...

; => result arity mismatch;
; expected number of values not received
; expected: 1
; received: 3

```

Huh, ok. A bit weird. Let me make sure that I haven't completely forgotten how `values` works:

```scheme
$ racket -I slideshow
Welcome to Racket v8.2 [cs]
> (apply values (map item '("1" "2" "3")))
#<pict>
#<pict>
#<pict>

```

Maybe I need to write a syntax transformer that would make this easier? (How naive.)

```scheme
; I know, let's do this the easy way
(define-syntax-rule (itemize str0 ...)
  (begin (item str0) ...)) ; oh macro expansion is so beautiful

(slide #:title "Min slide"
  (itemize "1" "2" "3"))

; => ·3; where did ·1 and ·2 go???
; Ohhhh, right begin evaluates and only returns the last form here

```

So I then reasoned that I needed to splice in the syntax or else write something from the top down, like

```scheme
(define-syntax (itemized-slide stx) 
   ; exercise left to the reader
   #'void)

```

As soon as I started down this path, I thought this would be a terrible choice: I really just want to use an existing API and not try to get too cute. But now I'm thinking hard about this issue of trying to splice in syntax and thought to approach someone, anyone, who could make this a bit more clear for me. Like all of my trials with `define-syntax`, it feels like I immediately hit upon something that will break hygiene and quite possibly the universe.

My intuitions here are usually wrong, and it seems like the sort of simple example where there's a trove of insights waiting to be had.

---

<div class="post-metadata">

**Author:** ![sorawee](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sorawee](https://racket.discourse.group/u/sorawee)\
**Post date:** [September 23, 2023, 3:05am UTC](https://racket.discourse.group/t/splicing-in-syntax/2336/2 "2023-09-23T03:05:45Z")

</div>

You don’t need to use macros. Just need to use `apply` at `slide`. Try

```scheme
(apply slide #:title "Minimal slide"
       (itemize "One" "Two" "Three"))

```

with your original `itemize`.

Re your question about macro (which again is actually not needed here): macro can’t splice into multiple arguments on its own.

---

<div class="post-metadata">

**Author:** ![mem](https://avatars.discourse-cdn.com/v4/letter/m/90ced4/32.png) [@mem](https://racket.discourse.group/u/mem)\
**Post date:** [September 23, 2023, 3:24am UTC](https://racket.discourse.group/t/splicing-in-syntax/2336/3 "2023-09-23T03:24:30Z")

</div>

Thanks—that's lovely and simple and Just Works.

It's also obvious on the face of it, once I think a bit about it—indeed a note I wrote long ago reminds me that `apply` has this effect; I probably was dealing with something similar.

> Re your question about macro (which again is actually not needed here): macro can’t splice into multiple arguments on its own.

Is there a reason for this?

---

<div class="post-metadata">

**Author:** ![usao](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/usao/32/1375_2.png) [@usao](https://racket.discourse.group/u/usao)\
**Post date:** [September 23, 2023, 9:12am UTC](https://racket.discourse.group/t/splicing-in-syntax/2336/4 "2023-09-23T09:12:26Z")

</div>

Syntactic forms are expanded from top to down in a _local_ manner. The enclosing form is a function call form, so each subform is further expanded as an expression. This means that the expanded `begin` form must be an _expression_, which eventually evaluates to the results of the last subexpression.

Certain contexts allow splicing. For example, definition contexts recognize `begin` forms specially and splice the subforms. You can create more such contexts by using Racket’s excellent syntactic extension facilities, but the bottom line is such contexts must be explicitly handled. The default function call (`#%app`) form apparently doesn’t support splicing.

---

<div class="post-metadata">

**Author:** ![mem](https://avatars.discourse-cdn.com/v4/letter/m/90ced4/32.png) [@mem](https://racket.discourse.group/u/mem)\
**Post date:** [September 23, 2023, 12:55pm UTC](https://racket.discourse.group/t/splicing-in-syntax/2336/5 "2023-09-23T12:55:19Z")

</div>

@usao — thanks! The explanation is helpful.

Obviously a bit to ponder on here.
