Hi, Racket Discourse.
I guess this is more of a theoretical question than a Racket question, per se, but the audience is well-placed, nonetheless.
I am thinking about how one would implement "sugar" for variadic lambda abstractions, to avoid the need for right-hand wrapping expressions like cons when constructing a list for example, without necessarily resorting to syntactical sugar.
From what I can tell, one needs either:
- a) a counter of some sort, to "allocate" some number of arguments, or
- b) a sentinel value of some sort, to end a sequence of arguments
Considering the first option, as an example, one might define a procedure called FEED, taking a counter and some procedure f which is left-folded over any arguments applied to the continuation, until the counter is exhausted.
;; I am using a little DSL for de bruijn-index notation
(define FEED #λ ;; foldl-like
[ ; _₃ f
[ ; _₂ rec
[ ; _₁ ctr
[ ; _₀ accu
IF (ZERO? _₁) _₀
[_₃ (PRED _₂) (_₄ _₀ _₁)]
]
]
]
]
)
;; which roughly translates to the partially recursive
(lambda (f)
(lambda (rec)
(lambda (ctr)
(lambda (accu)
(if (zero? ctr)
accu
(lambda (x) ((rec (sub1 ctr)) (f x accu))))))))
This can then be used to define LIST:
(define LIST #λ[Y (FEED CONS) _₀ NULL]) ;; recursion using the Y-combinator
(define LIST₄
#λ(LIST FOUR 1 2 3 4)) ;; although this is (list 4 3 2 1) haha
So, my question is, are there any other tactics besides counters and sentinel values to perform this sort of thing, or is it just the way it goes?
I mean, I can't see how you would get around saying, "stop," in this way, but one never knows.