I see.  Okay, thanks for clarifying.

On Sat, Jul 16, 2016 at 8:05 PM, Alex Knauth <alexan...@knauth.org> wrote:
>
>> On Jul 16, 2016, at 7:18 PM, David Storrs <david.sto...@gmail.com> wrote:
>>
>> Wow, that is a lot of problems.  Thanks for taking the time to
>> comment; this was in large part an effort to learn macros, so it's
>> helpful to get this kind of feedback.
>
>> On Sat, Jul 16, 2016 at 2:48 PM, Alex Knauth <alexan...@knauth.org> wrote:
>
>>> A few problems with this.
>>>
>>> One, you shouldn't put extra (lambda () ...)s around the #:when conditions. 
>>> A lambda is a truthy value, since it's not false, so those #:when checks 
>>> weren't checking anything at all.
>>
>> I thought the #:when ran the predicate that it was given and reacted
>> based on the truth value of the response?
>
> The #:when takes a boolean. It works like the #:when clause in match, if 
> you've used that. Or like the condition of an if expression where the 
> then-branch keeps going in the same clause and the else-branch makes it go to 
> the next clause.
>
>> Would (string? pred)  have worked there instead?
>
> I'm not sure what you mean.
>
> #lang racket
> ;; no, I don't want a for-syntax, I'm using it at run-time, as a match-like 
> form
> (require syntax/parse)
> (syntax-parse (syntax ignored)
>   [_
>    #:when (string? "hello")
>    'string])
>
> This tests whether "hello" is a string. But for a pattern-variable like pred 
> it almost can work like that, but not quite.
>
> (syntax-parse (syntax (foo "hello"))
>   [(foo a)
>    #:when (string? a)
>    'string])
>
> This gives the error `a: pattern variable cannot be used outside of a 
> template`. A template means something like the syntax form. However even with 
> that fixed this doesn't work as expected:
>
> (syntax-parse (syntax (foo "hello"))
>   [(foo a)
>    #:when (string? (syntax a)) ; writing (string? #'a) would mean the same 
> thing
>    'string])
>
> The string? predicate returns false, so this fails as well. The problem is 
> that (syntax a) returns a syntax object, but you want the contents inside the 
> syntax object, because that's where the string (or otherwise) will be. To do 
> that you can use syntax-e (one-level-down) or syntax->datum (pure 
> s-expression with no syntax-object sub-expressions).
>
> (syntax-parse (syntax (foo "hello"))
>   [(foo a)
>    #:when (string? (syntax-e (syntax a)))
>    'string])
>
> This succeeds, producing 'string. Using syntax->datum will also work here:
>
> (syntax-parse (syntax (foo "hello"))
>   [(foo a)
>    #:when (string? (syntax->datum (syntax a)))
>    'string])
>
>>> Two, once you remove those lambdas, (procedure? #'pred) will always fail 
>>> because #'pred isn't the actual predicate, it's an expression, which might 
>>> eventually evaluate to predicate, or it might evaluate something else. At 
>>> compile-time, you just don't know yet. What you could do is check that it's 
>>> an identifier, with (identifier? #'pred).
>>
>> Would (procedure? (syntax->datum #'pred)) have worked there?  pred
>> either is or is not a procedure, and that should be known at compile
>> time.
>
> For simple literal data like strings, (string? (syntax->datum #'pred)) will 
> work, since literal data is known at compile-time.
>
> However procedures, although they are values, they only become values at 
> run-time. At compile-time, this pred is only an expression, so (procedure? 
> (syntax->datum #'pred)) will return false.
>
> A procedure given to you by a user in something like
> (throws (boom) exn:fail? "should trigger the proc form")
> Will not be known at compile time. (syntax pred) is an identifier, and 
> (syntax->datum (syntax pred)) will return a symbol, not a procedure.
>
> At compile-time that's all you know. It could be an identifier that happens 
> to be bound to a procedure, or it could be an identifier bound to a number, 
> or it could have no definition at all.
>
> So, for simple literal data like strings, it is known at compile-time, but 
> for more complicated things like procedures, it usually isn't.
>
> Alex Knauth
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to