Abstract
We describe changes to the microKanren implementation that make it more practical to use in a host language without macros. With some modest runtime features common to most languages, we show how an implementer lacking macros can come closer to the expressive power that macros usually provide—with varying degrees of success. The result is a still functional microKanren that invites slightly shorter programs, and is relevant even to implementers that enjoy macro support. For those without it, we address some pragmatic concerns that necessarily occur without macros so they can better weigh their options.
Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, or republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee.
Request permissions from permissions@acm.org.
TFP ’23, January 13–15, 2023, Boston, Massachusetts
© 2023 Association for Computing Machinery. ACM ISBN 978-1-4503-XXXX-X/18/06…$15.00 https://doi.org/XXXXXXX.XXXXXXX
Access this chapter
Tax calculation will be finalised at checkout
Purchases are for personal use only
Similar content being viewed by others
References
Ballantyne, M., King, A., Felleisen, M.: Macros for domain-specific languages. In: Proceedings of the ACM on Programming Languages 4.OOPSLA, pp. 1–29 (2020)
Culpepper, R.: Fortifying macros. J. Funct. Prog. 22(4–5), 439–476 (2012)
Felleisen, M.: Re: Question about tail recursion (2014). https://lists.racket-lang.org/users/archive/2014-August/063844.html
Friedman, D.P., et al.: The Reasoned Schemer, 2nd edn. The MIT Press (2018). ISBN:0-262-53551-3. mitpress.mit.edu/books/reasoned-schemer-0
Griswold, R.E., Griswold, M.T.: The Icon Programming Language, vol. 55. Prentice-Hall, Englewood Cliffs (1983)
Hemann, J., Friedman, D.P.: \(\upmu \)kanren: a minimal functional core for relational programming. In: Scheme 13 (2013). http://schemeworkshop.org/2013/papers/HemannMuKanren2013.pdf
Hemann, J., et al.: A small embedding of logic programming with a simple complete search. In: Proceedings of DLS 2016. ACM (2016). https://doi.org/10.1145/2989225.2989230
Keep, A.W., et al.: A pattern matcher for miniKanren or How to get into trouble with CPS macros. In: Technical Report CPSLO-CSC-09-03, p. 37 (2009)
Kiselyov, O.: The Taste of Logic Programming (2006). http://okmij.org/ftp/Scheme/misc.html#sokuzakanren
Rosenblatt, G., et al.: First-order miniKanren representation: great for tooling and search. In: Proceedings of the miniKanren Workshop, p. 16 (2019)
Acknowledgments
Thanks to Michael Ballantyne, Greg Rosenblatt, Ken Shan, and Jeremy Siek for their helpful discussions and ideas. Our thanks to Yafei Yang and Darshal Shetty for their implementation suggestions. We would also like to thank our anonymous reviewers for their insightful contributions.
Author information
Authors and Affiliations
Corresponding author
Editor information
Editors and Affiliations
Appendices
A conj Derivation
Starting with the variadic function based on the macro in Listing 2, we first \(\upeta \)-expand and split the definition.
We next substitute for the definitions of and .
This definition of sequences the invocations of goal and state in the order they appear. acts like a non-deterministic operator. In each recursive call, we accumulate by mapping, using special delaying implementation of Kanren-language streams, the next goal in the list.
The state does not change in the recursion: only needs to build the stream. Therefore we can assemble the stream on the way in—instead of passing in and separately, we pass in their combination as a stream. The function is tail recursive; we can change the signature in the one and only external call and the recursive call. Adding the trivial base case to , yields the version shown in Listing 3.
B conda Derivation
At this point and in are begging to be passed as a stream ; we oblige them. We lift that local function to a global definition, passing all the parameters it needs. Since the only call to is in , we know that third parameter will always be a non-empty list.
If we also add a line in to dispatch with the trivial case, we arrive at the definition in Listing 6. Most of Listing 6 is a functional implementation of that cascade behavior. knows it has at least one goal; it’s job is to determine if there is precisely one goal, precisely two goals, or more than two goals.
Rights and permissions
Copyright information
© 2023 The Author(s), under exclusive license to Springer Nature Switzerland AG
About this paper
Cite this paper
Hemann, J., Friedman, D.P. (2023). Nearly Macro-free microKanren. In: Chang, S. (eds) Trends in Functional Programming. TFP 2023. Lecture Notes in Computer Science, vol 13868. Springer, Cham. https://doi.org/10.1007/978-3-031-38938-2_5
Download citation
DOI: https://doi.org/10.1007/978-3-031-38938-2_5
Published:
Publisher Name: Springer, Cham
Print ISBN: 978-3-031-38937-5
Online ISBN: 978-3-031-38938-2
eBook Packages: Computer ScienceComputer Science (R0)