Skip to content

Instantly share code, notes, and snippets.

@sleibrock
Created September 4, 2019 01:07
Show Gist options
  • Save sleibrock/83795d08c1d8a4a02e6de2a46a35cb09 to your computer and use it in GitHub Desktop.
Save sleibrock/83795d08c1d8a4a02e6de2a46a35cb09 to your computer and use it in GitHub Desktop.
Convert a Racket string to a Racket procedure/function
#lang racket/base
#|
String -> Procedure
A way to convert a Racket string into a procedure object.
This is done by hot-code evaluation. Since there's no built-in
method to convert anything to a procedure other than defining
the procedure itself, this lets us check if a string is indeed
a procedure in the current runtime namespace.
This can be used in syntax highlighting beyond the normal
pre-defined keyword/method lists way of highlighting code.
You can check if functions are actually defined in the
Racket namespace and highlight that way.
|#
;; Define a namespace anchor, or really just a reference
;; to the current Racket namespace
(define-namespace-anchor a)
;; Convert a string to a procedure
;; Note: no contracts/type checking provided (very lazy)
;; Returns #f if no procedure can be found/evaluated
(define (string->procedure procstr)
(define cn (namespace-anchor->namespace a))
(define procsym (string->symbol procstr))
(parameterize ([current-namespace cn])
(eval `(cond [procedure? ,procsym]
[else #f]))))
;; Define the id function :: a -> a
(define (id x) x)
;; Test the function/playground
(module+ main
(displayln "Testing string->procedure")
(displayln (format "Should give #<procedure:+> => ~a" (string->procedure "+")))
(define plus (string->procedure "+"))
(displayln (format "Doing addition with it (+ 2 2) => ~a" (plus 2 2)))
(define sid (string->procedure "id"))
(displayln "Testing string->procedure on defined id func")
(displayln (format "Should give #<procedure:id> => ~a" sid))
(displayln (format "Testing (sid 3) = 3 => ~a" (sid 3)))
)
; end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment