Reflecting on it as an issue of detecting bound identifiers, I've come up with 
a possible approach — could it be this simple, or am I overlooking some 
complication?

bound.rkt:

#lang racket

(provide bound/c (rename-out (top~ #%top)))

(define-syntax-rule (top~ . id)
    (λ x `(id ,@x)))

(define-syntax (bound/c stx)
    (syntax-case stx ()
      [(_ x)
       (if (identifier-binding #'x )
           #'x
           #'(#%top . x))]))


test.rkt:

#lang racket
(require "bound.rkt")
(define foo displayln) ; foo is now bound
(foo "hello")
((bound/c foo) "hello")
(bar "hello") ; bar is unbound
;((bound/c bar) "hello")

This does the right thing:

hello
hello
'(bar "hello")

And then when the last line is uncommented

((bound/c bar) "hello")

It triggers the usual error on compile:

bar: unbound identifier in module in: bar



On Feb 6, 2014, at 8:38 PM, Matthew Butterick <m...@mbtype.com> wrote:

> I'm trying to figure out how to make #%top change behavior based on different 
> kinds of function names, though my experiments keep leading to infinite loops 
> that blow up DrRacket. Oops.
> 
> In my #lang project based on Scribble, I've been using this simple 
> redefinition of #%top for convenience:
> 
> (define-syntax-rule (#%top . id)
>    (λ x `(id ,@x)))
> 
> IOW, if the thing in the function position is undefined, it's treated as the 
> opening tag of an x-expression. This makes it easy to mix undefined and 
> defined names.
> 
> But it can make debugging difficult. Because if you expect a name to be 
> defined as a function and it isn't, then you don't get the syntax error you 
> ordinarily would. The function call silently gets converted an x-expression. 
> Spooky side effects follow.
> 
> I'd like to improve this by making a syntactic prefix that suppresses this 
> behavior and that can be attached to any function name. For instance, def-*. 
> So if I write (def-foobar ..) in the code, this will mean:
> 1) try to invoke a function called (foobar ...); 
> 2) if the function (foobar ...) isn't defined, raise the usual exception + 
> syntax error.
> In other words, the standard #%top behavior.
> 
> Whereas if I just write (foobar ...) without the def-* prefix, this will mean:
> 1) try to invoke the function (foobar ...); 
> 2) if the function (foobar ...) isn't defined, turn it into the x-expression 
> `(foobar ,@ ...). 
> In other words, my special #%top behavior shown above.
> 
> Having explained the logic, I think the flaw in my experiments so far is that 
> this actually requires manipulation of #%app too, because once you hit #%top, 
> you've missed your chance to apply functions. (Right?) But even supposing one 
> creates two evaluation paths under #%app, it's not clear to me how to 
> preserve those paths on the way up to #%top.
> 
> 


____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to