Re: + Symbol as An Argument not Getting Printed in Output

 new new list compose Reply to this message Top page
Attachments:
+ (text/plain)
+ (text/html)

Delete this message
Author: Kaz Kylheku
Date:  
To: Yves Cloutier
CC: txr-users
Subject: Re: + Symbol as An Argument not Getting Printed in Output

Hi Yves,

Having been up to the elbows in troff recently, I ran into this type of notation, of course:

  .nr foo +1    .\" increase foo by 1

In TXR Lisp, like in many other Lisp-like languages, certain symbol-like tokens, when they are scanned, turn into something else, namely numbers.  That is to say,  although the tokens 1234 and 1E0 are made up of characters that can all be used in a symbol, because they match particular patterns they instead become an integer, and floating-point number, respectively. (Syntax of numbers is covered in the 6.20 Numbers section of the 98 reference manual).

Under evaluation, numbers evaluate to themselves, but symbols (except the keyword symbols and the symbols t and nil)  are treated as variable names under evaluation.

TXR Lisp doesn't have any escape mechanism in symbol tokens, so \+1 is simply the symbol whose name is "\\+1" (backslash plus one).  Since it isn't a keyword, it gets evaluated, and so you get an error about an unbound variable.

Now about this representational issue: basically, I think that you don't want entities like "+12" to be symbols, because symbols are atomic, whereas these entities clearly have two parts: a delta indicator and a number. A string representation can be "sub optimal" in many ways also; if you do that in your model, you will always have to be doing a string type check, and inspecting the first character of every string to check for a leading sign, so that the string can be translated to the proper syntax of the given markup language.

A possible abstract representation for +1 and -2 might be a small compound form with an operator, like say (delta 1) and (delta -2).

If you're processing your syntax by direct evaluation, so that the nodes of the tree are ordinary expressions, then something like (size (delta 2) "text") evaluates (delta 2), which produces the string "2+" for the given target markup language.

I.e.

<size +2<text>   -->  (size (delta 2) "text")   -->  "\*[SIZE +2]text\*"

It so happens that your source language has the +2 notation, and that the target language has the same +2 notation also; but that doesn't mean we have to smuggle +2 as a character string through the entire conversion chain.

It could also be that in some back-end markup language, (size 3 ..) and (size (delta 3) ...) have to produce something completely different. In that case, the delta function can produce an object (not a raw string) which size can detect and act upon ("Hey, I got a delta object as an argument; I have to spit out this kind of syntax intead of the usual"). Alternatively, size can be a macro instead of a function, and then it can recognize the (delta ...) form as special syntax and behave accordingly ("Hmm, my argument form is a delta form; let me generate code which evaluates the argument of that delta and spits out the correct translation.").

For the above target notation where we just want a string, delta can use a format trick:

(defun delta (num) (format nil "~,+a" num))

When the stream designator in format is nil, it means "print to a string and return it".  We use the + character in the precision part of the formatting specifier to say "print a leading sign on numbers".

Without format we could do:

(defun delta (num) `@(if (>= num 0) #\+)@num`) ;; #\+ or "+": either a char or string will do here

Note that both versions put a leading + on zero.

As you can see, you can evaluate expressions in quasi-strings, not only simple variables. 

Also, by the way, in quasi strings there is this notation:

`... @{expression [index-or-range] separator-string} ..`

The index or range in square brackets is optional as is the separator string.

If expression produces a list, then it is catenated using the specified separator string instead of the default one which consists of a single space.

If the index or range is present, then expression must be a sequence (list, vector, string). It is indexed or sliced accordingly. If the result of indexing or slicing is a list, then the separator-string can apply, too.

$ txr -p '(let ((list (quote (1 2 3 4))))
            `a: @{list[1..3]}, b: @{list[0]}, c: @{list[1..:] "-"}`)'

"a: 2 3, b: 1, c: 2-3-4"

Cheers ...

 

On 27.09.2014 08:12, Yves Cloutier wrote:

lol I get what you are trying to say Roman. 

As a numerical value the absence of a + implies a positive numerical value, while a negative one must be preceded by -.

I guess I don't have a choice but to pass this argument as a string since in the markup I want to translate, I want to be able to do the following:

<size 12<text>  => explicit size increase
<size +2<text> => relative size increase (ie: the base font size is 10, and want to increase it by 2 to 12pt)
<size -2<text> => relative size decrease

So I will need to convert the above markup from the input stream into the following Lisp form

(size "12" "text")
(size "+2" "text")
 
passing the first argument as a string for this to work....ok should be easy enough.
 

On Sat, Sep 27, 2014 at 2:26 AM, Roman Mishin <xtradev@yandex.ru> wrote:
> if number is negative

Wow!

Add string "+" if number is positive!