Re: [racket-users] splicing conditional results in the surrounding block?
On Fri, Feb 12, 2016 at 10:45 PM, Nota Poinwrote: > > at-exp really is a fascinating language, It's not a language in itself, it's a meta-language, which modifies the actual language with the @-form syntax. > but if a (flatten) isn't any more computationally expensive, you can > just splice all the lists at the end and use the regular racket > language. Either way would work fine, I suspect. This sounds confused. The purpose of the at-exp language is just to make it easier to write code with a lot of text, which is what you do. The scribble/text language that was mentioned is based on the same @-form syntax, and it adds the functionality of outputting strings (and other primitive values), with lists being scanned recursively (so it's essentially flattening everything), and it outputs nothing for #f and void, which makes it easy to embed `and`s and `when`s without the usual gymnastics involved in splicing the results back into a single-level list. -- ((x=>x(x))(x=>x(x))) Eli Barzilay: http://barzilay.org/ Maze is Life! -- 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.
Re: [racket-users] splicing conditional results in the surrounding block?
On Thursday, February 11, 2016 at 12:29:04 PM UTC, Neil Van Dyke wrote: > http://www.neilvandyke.org/racket-html-template/ This does almost exactly what I was thinking about! Looking at the code makes me go cross-eyed, but if you (expand-once #'(html-template ...)) enough, it turns the SXML tree structure into a linear sequence of (write-bytes) statements. It would definitely be possible to instead generate a linear sequence of strings, that could be cached and then possibly written with one single (write-bytes). Certainly not worth the trouble, but possible. And very fascinating! -- 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.
Re: [racket-users] splicing conditional results in the surrounding block?
Nota Poin wrote on 02/12/2016 10:41 PM: This does almost exactly what I was thinking about! Looking at the code makes me go cross-eyed, Yes, I recommend not looking at the code. IIRC, the code is a little icky for a few reasons: 1. It was initially not as clear as I like, just because of the nature of how it worked, and because I was figuring it out. 2. We didn't yet have submodules, which are a godsend for working with Racket's phases, especially how I prefer to work, with one file per package, with inline docs 3. I did a big reworking to facilitate some optimizations for using this with the Racket Web Server specifically, which complicated things and left a lot of placeholders for further changes. But then all my packages stalled around the time of the new package system work, so it's in a half-finished state, and without a cleanup pass (though it should work). Neil V. -- 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.
Re: [racket-users] splicing conditional results in the surrounding block?
On Friday, February 12, 2016 at 1:26:05 AM UTC, Matthew Butterick wrote: > Of course, you can also use the `at-exp` metalanguage from Scribble to > simplify text-heavy constructions like these, with variables interpolated > into strings: > #lang at-exp racket > > (define (query condA condB (limit #f) (offset #f)) > @~a{SELECT something FROM table WHERE @condA AND @condB @(if limit >@~a{LIMIT > @limit @(if offset > >@~a{OFFSET @offset} > >"")} >"")}) I could also do this: (define (query condA condB (limit #f) (offset #f)) (flatten (list "SELECT something FROM table WHERE " condA " AND " condB (if limit (list "LIMIT " limit (if offset (list "OFFSET " offset) '())) '( at-exp really is a fascinating language, but if a (flatten) isn't any more computationally expensive, you can just splice all the lists at the end and use the regular racket language. Either way would work fine, I suspect. -- 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.
[racket-users] splicing conditional results in the surrounding block?
I run into this problem a lot whenever I'm generating some text. I'll be making what amounts to a sequence of strings being appended, and do something like this: (apply string-append (list "" something "")) Compared to un-parsing a representation of a document tree every single time, simplifying document production down to a bunch of string concatenations is pretty efficient. The problem happens when I introduce conditionals, like this: (list "" (if prev (list "Prev") '()) (if next (list "Next") '()) "") Now I no longer have a sequence of strings, but instead a nested list of strings. Then I usually call (apply string-append (flatten list-of-strings)) and don't worry about it, but it'd be even cooler if I could proactively flatten it. (if prev (if next (list "" "Prev" "next" "") (list "" "Prev" "")) (if next (list "" "next" "") (list "" ""))) Obviously that's horrible code, since I don't want to type the surrounding stuff for every possible logic pathway in my code. But it'd be relatively simple to concatenate whatever the result is! I guess what I'm asking is how would I take code like this: (list "" (splicing-if prev (splicing-list "Prev") nada) (splicing-if next (splicing-list "Next") nada) "") ...and have the result inherently be a flat list of strings? Not a complex tree that I then have to walk with (flatten), but genuinely just a list of strings? Something with (reset) and (shift) maybe? Something with (and-let)? To make this happen, would I have to instrument the conditionals like (if)? Would I have to instrument the (list) forms that they result in? Obviously if my conditionals produce simple strings it's easy: (list "things: " (if thing1 thing1 "") (if (and thing1 thing2) " and " "") (if thing2 thing2 "")) Even that is kind of cludgy though, because the "" fallthrough results in lists like (list "things: " thing1 "" "") instead of the ideal: (list "things: " thing1) One possible solution is to use mutable variables and shared state. (ugh) (write "") (when prev (write "Prev")) (when next (write "Next")) (write "") Another thing I've tried is concatenations of concatenations: (apply string-append "" (if prev (string-append "Prev") "") (if next (string-append "Next") "") "") That of course scatters fallthrough "" strings in the calculation, and since it calls string-append multiple times, the implementation can't exactly allocate the result all at once, and must spend more time fooling around with memory. Creating strings, only to destroy them as soon as they've been appended to the larger string. But there's no way I've ever been able to figure to produce generated text that is just a flat list of strings, if I ever want to have conditional decisions about what to go in that list. -- 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.
Re: [racket-users] splicing conditional results in the surrounding block?
On Thursday, February 11, 2016 at 9:08:33 AM UTC-8, Matthew Butterick wrote: > I'm supposing you know that Racket has at least two native representations > (X-expression and SXML) for HTML-like structures, so hacking HTML tags by > hand is unnecessary. Yes, thank you for mentioning them. I was actually thinking of starting with SXML, but then turning it into a list of string fragments (with spaces left for the dynamically generated parts) as a simplification step once I've figured out where everything goes. But there are other languages besides HTML this is relevant for. (define (query condA condB (limit #f) (offset #f)) (list "SELECT something FROM table WHERE " condA " AND " condB (if limit (list "LIMIT " limit (if offset (list "OFFSET " offset) '())) '( for instance. > But if you must, there's a #lang for that: I'll look at scribble/text, but I don't think a whole new language is necessary just to factor if-statements inside out. I suspect it does a (flatten) operation though, after having constructed a complex tree, since this problem seems like a difficult one, and (flatten) really isn't all that much trouble. I was just curious if it was possible to do this, but if I had to get scribble/text ready to release to the masses I'd just throw a (flatten) in there to splice the lists. > Enjoy. No problem! -- 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.
Re: [racket-users] splicing conditional results in the surrounding block?
Nota Poin wrote on 02/11/2016 04:48 AM: But there's no way I've ever been able to figure to produce generated text that is just a flat list of strings, if I ever want to have conditional decisions about what to go in that list. You might like `quasiquote` and `unquote-splicing`: `("a" "b" ,@(if (= 2 (+ 1 1)) `("p" "q") `("x" "y")) "c" "d") ;;=> ("a" "b" "p" "q" "c" "d") BTW, for HTML-writing, maintaining HTML markup in string literals gets to be a headache, and also tends to have bugs. I would use my `html-writing` or `html-template` package. http://www.neilvandyke.org/racket-html-writing/#%28part._.Writing_.H.T.M.L%29 http://www.neilvandyke.org/racket-html-template/ Neil V. -- 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.
Re: [racket-users] splicing conditional results in the surrounding block?
> Yes, thank you for mentioning them. I was actually thinking of starting with > SXML, but then turning it into a list of string fragments (with spaces left > for the dynamically generated parts) as a simplification step once I've > figured out where everything goes. But there are other languages besides HTML > this is relevant for. > > (define (query condA condB (limit #f) (offset #f)) > (list "SELECT something FROM table WHERE " > condA > " AND " > condB > (if limit > (list "LIMIT " limit > (if offset > (list "OFFSET " offset) > '())) > '( > > for instance. Of course, you can also use the `at-exp` metalanguage from Scribble to simplify text-heavy constructions like these, with variables interpolated into strings: #lang at-exp racket (define (query condA condB (limit #f) (offset #f)) @~a{SELECT something FROM table WHERE @condA AND @condB @(if limit @~a{LIMIT @limit @(if offset @~a{OFFSET @offset} "")} "")}) -- 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.
Re: [racket-users] splicing conditional results in the surrounding block?
> Nota Poin wrote on 02/11/2016 04:48 AM: >> But there's no way I've ever been able to figure to produce generated text >> that is just a flat list of strings, if I ever want to have conditional >> decisions about what to go in that list. I'm supposing you know that Racket has at least two native representations (X-expression and SXML) for HTML-like structures, so hacking HTML tags by hand is unnecessary. But if you must, there's a #lang for that: Here's the literal translation of your code in `scribble/text`, which automatically splices all `list`s it finds: #lang scribble/text @(define prev "foo") @(define next "bar") @(if prev @(if next @list{ Prev next } @list{ Prev }) @(if next @list{ next } @list{ })) A more compact refactoring of same: #lang scribble/text @(define prev "foo") @(define next "bar") @(if prev @list{Prev} "") @(if next @list{next} "") And here's the refactored version in `pollen/pre`, which is based on `scribble/text`. It does not splice `list`s by default, but it has a splicing operator `@`, and also a `when/splice` that lets you do single-branch conditionals. #lang pollen/pre ◊(define prev "foo") ◊(define next "bar") ◊when/splice[prev]{Prev} ◊when/splice[next]{next} Here's an HTML-free variant in `pollen/markup` that produces an equivalent X-expression (which can be easily converted to HTML): #lang pollen/markup ◊(define prev "foo") ◊(define next "bar") ◊p[#:id "navigation"]{ ◊when/splice[prev]{◊a[#:href ◊prev]{Prev}} ◊when/splice[next]{◊a[#:href ◊next]{next}}} Finally, we can throw in a macro for fun: #lang pollen/markup ◊(define prev "foo") ◊(define next "bar") ◊(define-syntax-rule (cond-nav id text ...) ◊when/splice[id]{◊a[#:href ◊id text ...]}) ◊p[#:id "navigation"]{ ◊cond-nav[prev]{Prev} ◊cond-nav[next]{next}} Enjoy. -- 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.