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.