xexpr cond failing

25 views
Skip to first unread message

liendolucas84

unread,
Mar 1, 2020, 3:31:16 AM3/1/20
to Racket Users
Hi everyone! Just joined the Racket User's group. I'm trying to conditionally render a paragraph element using a cond and an xexpr but I can't make the "xexpr?" function return a #t value and of course the response/xexpr function call fails as well. I've kind of fix this by always returning a paragraph element regardless is needed or not (of course this is not what I want). Here's the working code:

(define (login-template (login-error ""))
 
`(html
     (head
       (link ((rel "icon") (href "data:,")))
       (title "Please login"))
     (body
       (form ((action "") (method "post"))
             (label ((for "username")) "Username:")
             (input ((type "text") (name "username") (maxlength "64")))
             (label ((for "password")) "Password:")
             (input ((type "password") (name "password") (maxlength "64")))
             (button ((type "submit") (value "Login")) "Login"))
       ,(cond
          ((not (eq? login-error "")) `
(p, login-error))
         
(else '(p "Enter your username/password."))))))

However I don't want to display at all the "else" clause as is not needed at all, here's the failing code:

(define (login-template (login-error ""))
 
`(html
     (head
       (link ((rel "icon") (href "data:,")))
       (title "Please login"))
     (body
       (form ((action "") (method "post"))
             (label ((for "username")) "Username:")
             (input ((type "text") (name "username") (maxlength "64")))
             (label ((for "password")) "Password:")
             (input ((type "password") (name "password") (maxlength "64")))
             (button ((type "submit") (value "Login")) "Login"))
       ,(cond
          ((not (eq? login-error "")) `
(p, login-error))))))

The last example fails if the login-error is indeed "" (an empty string). Am I missing something like a "null xexpr" usage for the "else" clause or something different that needs to be used in these situations? Of the all examples out there that I could find and read none of them shows how to do something like this. Is there a doc page where can I read about caveats using xexprs (if any) or situations like the one I've described?

Thanks for your time,
Lucas.

Sorawee Porncharoenwase

unread,
Mar 1, 2020, 3:43:20 AM3/1/20
to liendolucas84, Racket Users

One possible way is to have the first case returns a list of one element, and the else case returns an empty list. You then splice this list into body via ,@.

`(body
  (form ((action "") (method "post"))
        (label ((for "username")) "Username:")
        (input ((type "text") (name "username") (maxlength "64")))
        (label ((for "password")) "Password:")
        (input ((type "password") (name "password") (maxlength "64")))
        (button ((type "submit") (value "Login")) "Login"))
  ,@(cond
      [(not (eq? login-error "")) `((p ,login-error))]
      [else '()]))

If the then branch is taken, the value will be:

`(body
  (form ((action "") (method "post"))
        (label ((for "username")) "Username:")
        (input ((type "text") (name "username") (maxlength "64")))
        (label ((for "password")) "Password:")
        (input ((type "password") (name "password") (maxlength "64")))
        (button ((type "submit") (value "Login")) "Login"))
  (p ,login-error))

On the other hand, if the else branch is taken, the value will be:

`(body
  (form ((action "") (method "post"))
        (label ((for "username")) "Username:")
        (input ((type "text") (name "username") (maxlength "64")))
        (label ((for "password")) "Password:")
        (input ((type "password") (name "password") (maxlength "64")))
        (button ((type "submit") (value "Login")) "Login")))

--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/48f5b3c7-3ec2-43cc-8f01-60e36acb1e74%40googlegroups.com.

liendolucas84

unread,
Mar 1, 2020, 3:50:47 AM3/1/20
to Racket Users
Thank you very much for your reply Sorawee. I'll go with your proposed solution for the time being. However it feels like I'm adding unnecessary code to make the xexpr valid which can be really annoying if having nested cases or other more complex situations. Thanks again for your fast reply!
To unsubscribe from this group and stop receiving emails from it, send an email to racket...@googlegroups.com.

Sorawee Porncharoenwase

unread,
Mar 1, 2020, 6:26:49 AM3/1/20
to liendolucas84, Racket Users

Well, you can always use macro!

(define-syntax-rule (when/splice test body ...)
  (if test (list (begin body ...) '()))) `(body (form ((action "") (method "post")) (label ((for "username")) "Username:") (input ((type "text") (name "username") (maxlength "64"))) (label ((for "password")) "Password:") (input ((type "password") (name "password") (maxlength "64"))) (button ((type "submit") (value "Login")) "Login")) ,@(when/splice (not (eq? login-error "")) `(p ,login-error)))


To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/1286c435-bbff-4b0a-8a3a-eb1ccf731b27%40googlegroups.com.

Sorawee Porncharoenwase

unread,
Mar 1, 2020, 5:06:32 PM3/1/20
to liendolucas84, Racket Users

Actually you might want to use (list (let () body ...)) rather than (list (begin body ...)) so that you can use define inside when/splice, just like how you can do that in when.

Reply all
Reply to author
Forward
0 new messages