On Tue, Dec 30, 2014 at 1:01 AM, Alexander D. Knauth <alexan...@knauth.org> wrote: > > On Dec 29, 2014, at 4:53 PM, Eli Barzilay <e...@barzilay.org> wrote: > >> @my-error['x]{blah blah >> blah blah ~v >> @|"something"|} > > Yes this would be bad, but part of the whole point of this is that I > wanted to be able to specify the place-fillers on the same line as the > place-holders while still having multi-line format strings, so I would > never do this, and if I put this into a package or something, I would > be sure to specify that the place-fillers should always be on the same > line as the place-fillers.
(If it's for private use, then this is mostly irrelevant...) > But to help this I just added a parameter that would tell it whether > or not to warn you if one of the place-fillers was the "\n" string. > (the default is to warn you) What about an argument that happens to *be* a "\n"? IIUC, you expect to turn off the warning for that -- but in many cases you don't know what the arguments are... But this was just an example -- it's often useful to abstract code in ways that break the predictability of where you get string breaks for various reasons. I originally had some examples like: @foo{blah blah} as a function that expects two strings separated by a "\n" -- but I quickly concluded that overall, it's a very bad idea, and instead it's best to view any @-form as something that has "a bunch of text" as its input, and avoid relying on some specific string splittage. In cases where you do want "several bunches of texts", you can use currying: (define ((foo . text) . more-text) ...whatever...) @@foo{some text}{some more text} And another alternative which might be more fitting in your case is to use a macro for the structure: @foo[@{some text} @{more text} @{yet more}] but the convenience in that is minor enough that it's usually better to just use another function: @foo[@bar{some text} @bar{more text} @bar{yet more}] >> And you can probably also run into surprises when some argument >> evaluates to a string that has ~s in it. > > No, because it never tries to parse an argument as a format string, > because it knows the number of arguments there should be from the > previous format string. I mean that you can get a mess if you make parsing mistakes, or when format strings change (like the change that added the dotted "~.e" etc forms). There's not too much complications in Racket's format strings, but I wouldn't be surprised if they eventually grow more features. Another way of looking at it is that there are some extensions, like the dot thing, that are mostly backward compatible because they only specify useful stuff for things that used to be invalid -- and the existense of another piece of code that does format-string-parsing mean that now *any* change to format strings is a real bug for you. (So "morally" speaking, if I'd write such code I'd want a whole pile of tests that check all valid and invalid format strings, so I know when they change; or an even better solution would be to expose the Racket format string parser but that makes it a much heavier tool.) >> or even ignore voids >> >> (define (my-print . stuff) >> (for ([thing (in-list stuff)] #:unless (void? thing)) >> ((if (string? thing) display print) thing))) >> >> so you can do something like: >> >> @my-print{blah @some-value blah @write[another-value] blah} > > This is interesting, and solves most of the same "problems," but it > doesn't extend to things like error. I don't see why not... I'm assuming that you have some extension to exceptions that hold the values to show in some way, so you can just as well change it to hold thunks that output stuff instead. Or, if you want to actually hold the values, the add some struct for "printed values" that hold the value and how it should be printed. >> The bottom line is that I'm avoiding the strange mixture of a format >> string and mixed string/values ("interpolation"), which makes it >> easier to use. > > I understand that, but the processing of the format strings first to > find out how many arguments they should take should make sure that > they are never confused with one another, right? (assuming the > place-fillers are on the same line as the place-holders) Yes, assuming no bugs, and ignoring the fact that it's inherently fragile code. But it's still a mix of two different styles. (BTW, yes, there are some points for format strings -- especially when the expressions become bigger and the text become smaller. For example (format "<~a,~a>" (foo-x blah) (foo-y blah)). But mixing them is the bad part, IMO.) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! ____________________ Racket Users list: http://lists.racket-lang.org/users