Kenny Hegeland | 1 Sep 2011 01:00
Picon
Favicon

Re: New user wanting to know where to go

I dont know much of racket and a lot of stuff on this board goes much over my head(lots of smart people here),
but I would recommend HTdP, it's an excellently written book. I'm thankful for mathias, shriram, Robby,
and mathew, this book is what piqued my interest in computer science. I can't recommend it enough. 

On Aug 31, 2011, at 6:12 PM, Sam Donow <drsam94@...> wrote:

> Hello,
> 
> I have been a part of this list for a while, but until now I have not asked anything.
> I was introduced to Racket recently, and immediately found it intriguing and began writing programs in it
for whatever purposes I saw appropriate (previously I knew only C++ and Java, I am still a high school
student with little in the way of formal computer science education)
> 
> So, I was wondering, other than obviously waiting and taking college courses, what routes anyone would
suggest to learn the language.  So far I have relied on the help of a couple of friends who are CS majors and the
docs online, and looking at the questions on this list most things go over my head.  I have seen a lot about the
book How to Design Programs here, would that be a good option?
> 
> Any advice on how to learn Racket, or programming principles in general which could aid in its learning,
will be much appreciated.
> 
> Sam
> _________________________________________________
>  For list-related administrative tasks:
>  http://lists.racket-lang.org/listinfo/users

Stephen Bloch | 1 Sep 2011 02:03
Favicon

Re: New user wanting to know where to go

> I was introduced to Racket recently, and immediately found it intriguing and began writing programs in it
for whatever purposes I saw appropriate (previously I knew only C++ and Java, I am still a high school
student with little in the way of formal computer science education)
> 
> So, I was wondering, other than obviously waiting and taking college courses, what routes anyone would
suggest to learn the language.  So far I have relied on the help of a couple of friends who are CS majors and the
docs online, and looking at the questions on this list most things go over my head.  I have seen a lot about the
book How to Design Programs here, would that be a good option?

Yes, _How to Design Programs_ changed the way I think about programming (not to mention teaching it).  The
book is, however, 11 years old, and many parts of it no longer represent what most of us actually do in the
classroom.  Most notably, most of us now use a lot more graphics and GUI programming than we did in 2000; we
still use the same design recipe, but have improved the terminology in places.  To get a more modern take on
things, you could look at
(a) _How to Design Programs_ Second Edition, which isn't finished but which is available on-line for free
at http://www.ccs.neu.edu/home/matthias/HtDP2e/
(b) my book _Picturing Programs_, which is available on-line for free at http://www.picturingprograms.org/download/

Both of those are really "how to program" books that happen to use Racket, so some parts of them will be old hat
to you... but you'll probably learn a new take on some things that you _thought_ you had learned in Java or
C++.  Once you've gotten through those, I would suggest looking through various parts of the DrRacket
help: for example, the "universe" teachpack provides a beginner-friendly way to explore client-server
network programming; the "Continue" chapter discusses how to write interactive web apps using
continuations (which make it MUCH easier than web apps in most other languages); macros give you power and
flexibility that isn't available in most other languages; etc. etc.

Stephen Bloch
sbloch@...

(Continue reading)

Hendrik Boom | 1 Sep 2011 02:06

Re: New user wanting to know where to go

On Wed, Aug 31, 2011 at 07:00:45PM -0400, Kenny Hegeland wrote:
> I dont know much of racket and a lot of stuff on this board goes much 
> over my head(lots of smart people here), but I would recommend HTdP, 
> it's an excellently written book. I'm thankful for mathias, shriram, 
> Robby, and mathew, this book is what piqued my interest in computer 
> science. I can't recommend it enough. 

And there's two versions of it -- the original one, and a draft of a new 
one at http://www.ccs.neu.edu/home/matthias/HtDP2e/ .  Use both.

-- hendrik
Sam Donow | 1 Sep 2011 02:41
Picon

Re: New user wanting to know where to go

Thank you very much everyone for the advice - I will make sure to read through HtDP, especially the second edition

Sam


On Wed, Aug 31, 2011 at 8:06 PM, Hendrik Boom <hendrik-e9JHxFxFq/nmOAo1QFYKGQ@public.gmane.org> wrote:
On Wed, Aug 31, 2011 at 07:00:45PM -0400, Kenny Hegeland wrote:
> I dont know much of racket and a lot of stuff on this board goes much
> over my head(lots of smart people here), but I would recommend HTdP,
> it's an excellently written book. I'm thankful for mathias, shriram,
> Robby, and mathew, this book is what piqued my interest in computer
> science. I can't recommend it enough.

And there's two versions of it -- the original one, and a draft of a new
one at http://www.ccs.neu.edu/home/matthias/HtDP2e/ .  Use both.

-- hendrik
_________________________________________________
 For list-related administrative tasks:
 http://lists.racket-lang.org/listinfo/users

<div>
<p>Thank you very much everyone for the advice - I will make sure to read through HtDP, especially the second edition<br><br>Sam</p>
<div>
<br><div class="gmail_quote">On Wed, Aug 31, 2011 at 8:06 PM, Hendrik Boom <span dir="ltr">&lt;<a href="mailto:hendrik@...">hendrik@...</a>&gt;</span> wrote:<br><blockquote class="gmail_quote">
<div class="im">On Wed, Aug 31, 2011 at 07:00:45PM -0400, Kenny Hegeland wrote:<br>
&gt; I dont know much of racket and a lot of stuff on this board goes much<br>
&gt; over my head(lots of smart people here), but I would recommend HTdP,<br>
&gt; it's an excellently written book. I'm thankful for mathias, shriram,<br>
&gt; Robby, and mathew, this book is what piqued my interest in computer<br>
&gt; science. I can't recommend it enough.<br><br>
</div>And there's two versions of it -- the original one, and a draft of a new<br>
one at <a href="http://www.ccs.neu.edu/home/matthias/HtDP2e/" target="_blank">http://www.ccs.neu.edu/home/matthias/HtDP2e/</a> . &nbsp;Use both.<br><br>
-- hendrik<br><div>
<div></div>
<div class="h5">_________________________________________________<br>
 &nbsp;For list-related administrative tasks:<br>
 &nbsp;<a href="http://lists.racket-lang.org/listinfo/users" target="_blank">http://lists.racket-lang.org/listinfo/users</a><br>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</div>
Shriram Krishnamurthi | 1 Sep 2011 04:14
Favicon
Gravatar

Re: New user wanting to know where to go

Stephen Bloch mentioned his book Picturing Programs.  I am happy to
recommend it, too, so you don't think only its author likes it:

http://picturingprograms.com/download/

It has many similarities to, but also some real differences from, both
HtDP and HtDP 2/e.  At a *very* coarse level,

HtDP: numbers first
HtDP 2/e: animations first
PP: lots of images first, animations somewhat later

It's great that we have so many different choices available for
readers; pick the one that works best for you.

Shriram
John Clements | 1 Sep 2011 06:03
Gravatar

Racket Badges

I wish you could earn Racket badges and levels for completing exercises, getting +1'ed on the mailing list,
and contributing code and documentation.

Just thinking out loud, I'm afraid.

John

Attachment (smime.p7s): application/pkcs7-signature, 4624 bytes
I wish you could earn Racket badges and levels for completing exercises, getting +1'ed on the mailing list,
and contributing code and documentation.

Just thinking out loud, I'm afraid.

John

Danny Yoo | 1 Sep 2011 06:20
Gravatar

Re: Racket Badges

> I wish you could earn Racket badges and levels for completing exercises, getting +1'ed on the mailing
list, and contributing code and documentation.

+1.  Stack Overflow does this sort of achievement system. It feels
very much like a game.
Neil Van Dyke | 1 Sep 2011 07:00
Picon
Favicon

Re: Racket Badges

Danny Yoo wrote at 09/01/2011 12:20 AM:
I wish you could earn Racket badges and levels for completing exercises, getting +1'ed on the mailing list, and contributing code and documentation.
+1. Stack Overflow does this sort of achievement system. It feels very much like a game.

When someone helps me out here or contributes a good idea to a discussion, I appreciate it, but it's even more appreciated if they're doing it out of higher goals, community, or altruism, without the taint of working towards a merit badge.

Stack Overflow's game is probably benign, but there's a context of the last several years of connected society.  Online sites are conditioning us in various ways to accept ubiquitous buzz marketing, and to parody social processes and fritter away social capital to promote products in exchange for some consideration ("like us on Facebook for a discount"), and this all being socially acceptable to the extent that people care or realize it's going on.  This isn't new -- we've enjoyed entertainment industry generated 'news' and disingenuous performances for TV talk show for decades -- but it's only the last decade or so that everyone can see themselves acting a role and playing the game on a large scale.  I hope that individuals of the new generation somehow manage to value being genuine and to have genuine connections, despite an environment that's trying to push them otherwise.  In this context, do you *really* want to bring more of this game into a relative oasis?

<div>
Danny Yoo wrote at 09/01/2011 12:20 AM:
<blockquote cite="mid:CAGZAPF64-Y3Sn7yf6-ozXH4FOQThZHSJnLpH4rZSdPy94jLMsA@..." type="cite">
  <blockquote type="cite">
    I wish you could earn Racket badges and levels for completing exercises, getting +1'ed on the mailing list, and contributing code and documentation.

  </blockquote>

+1.  Stack Overflow does this sort of achievement system. It feels
very much like a game.
</blockquote>
<br>
When someone helps me out here or contributes a good idea to a
discussion, I appreciate it, but it's even more appreciated if they're
doing it out of higher goals, community, or altruism, without the taint
of working towards a merit badge.<br><br>
Stack Overflow's game is probably benign, but there's a context of the
last several years of connected society.&nbsp; Online sites are conditioning
us in various ways to accept ubiquitous buzz marketing, and to parody
social processes and fritter away social capital to promote products in
exchange for some consideration ("like us on Facebook for a discount"),
and this all being socially acceptable to the extent that people care
or realize it's going on.&nbsp; This isn't new -- we've enjoyed
entertainment industry generated 'news' and disingenuous performances
for TV talk show for decades -- but it's only the last decade or so
that everyone can see themselves acting a role and playing the game on
a large scale.&nbsp; I hope that individuals of the new generation somehow
manage to value being genuine and to have genuine connections, despite
an environment that's trying to push them otherwise.&nbsp; In this context,
do you *really* want to bring more of this game into a relative oasis?<br><br><div class="moz-signature">-- <br><a class="moz-txt-link-freetext" href="http://www.neilvandyke.org/">http://www.neilvandyke.org/</a>
</div>
</div>
Stephen De Gabrielle | 1 Sep 2011 09:25
Picon
Favicon

Re: Racket Badges

It's based on the xbox badges.

S.

On Thursday, September 1, 2011, Danny Yoo <dyoo-kCM0ysTr5uA3uPMLIKxrzw@public.gmane.org> wrote:
>> I wish you could earn Racket badges and levels for completing exercises, getting +1'ed on the mailing list, and contributing code and documentation.
>
>
> +1.  Stack Overflow does this sort of achievement system. It feels
> very much like a game.
> _________________________________________________
>  For list-related administrative tasks:
>  http://lists.racket-lang.org/listinfo/users
>

--

--
Stephen De Gabrielle
stephen.degabrielle-HInyCGIudOg@public.gmane.org
Telephone +44 (0)20 85670911
Mobile        +44 (0)79 85189045
http://www.degabrielle.name/stephen

<div><p>It's based on the xbox badges.<br><br>S.<br><br>On Thursday, September 1, 2011, Danny Yoo &lt;<a href="mailto:dyoo@...">dyoo@...</a>&gt; wrote:<br>&gt;&gt; I wish you could earn Racket badges and levels for completing exercises, getting +1'ed on the mailing list, and contributing code and documentation.<br>
&gt;<br>&gt;<br>&gt; +1. &nbsp;Stack Overflow does this sort of achievement system. It feels<br>&gt; very much like a game.<br>&gt; _________________________________________________<br>&gt; &nbsp;For list-related administrative tasks:<br>
&gt; &nbsp;<a href="http://lists.racket-lang.org/listinfo/users">http://lists.racket-lang.org/listinfo/users</a><br>&gt;<br><br>-- <br><br>--<br>Stephen De Gabrielle<br><a href="mailto:stephen.degabrielle@...">stephen.degabrielle@...</a><br>
Telephone +44 (0)20 85670911<br>Mobile&nbsp; &nbsp; &nbsp; &nbsp; +44 (0)79 85189045<br><a href="http://www.degabrielle.name/stephen">http://www.degabrielle.name/stephen</a><br><br></p></div>
Marco Maggi | 1 Sep 2011 11:23
Picon
Favicon
Gravatar

Re: Basic Questions Regarding Macros

Todd Bittner wrote:
> In  regards  to   syntax-rules  and  syntax-id-rules  there  is
> 'literal-id' parameter that I don't understand.

There was a thread on this subject recently:

<http://www.mail-archive.com/users-GvBox1K3Ixw1Q5oZIJT9Xw <at> public.gmane.org/msg07145.html>

in which I tried to give an explanation with examples:

<http://www.mail-archive.com/users-GvBox1K3Ixw1Q5oZIJT9Xw <at> public.gmane.org/msg07147.html>

at  then I  turned it  into an  annotation to  the  R6RS standard
(scroll  down  to  the  section  entitled  "How  to  use  literal
arguments"):

<http://marcomaggi.github.com/docs/nausicaa.html/baselib-transformers.html>

> Finally, reading  through the reference, #'  serves, I believe,
> as shorthand for (syntax),

From now on I will use  a Scheme language compliant with the R6RS
standard.  Yes, the following two forms are equivalent:

   (syntax (a b c))
   #'(a b c)

in the same way as the following two forms are equivalent:

   (quote (a b c))
   '(a b c)

  Notice  that it  is the  source  code *reader*  (the lexer  and
parser) which builds the symbolic expression:

   (quote (a b c))

from the sequence of characters:

   '(a b c)

and this happens before any library is loaded, so the source code
expander only sees the  symbolic expression with the QUOTE symbol
in  it.  While the  following program  works because  the library
(rnrs) exports the QUOTE identifier:

   #!r6rs
   (import (rnrs))
   (write '(a b c))

the following program will fail:

   #!r6rs
   (import (except (rnrs) quote))
   (write '(a b c))

in exactly the same way as the following program will fail:

   #!r6rs
   (import (except (rnrs) quote))
   (write (quote (a b c)))

because we  have explicitly excluded  QUOTE from the  import set,
showing:

  $ racket proof.sps
  proof.sps:8:0: compile: unbound identifier in module in: quote

  The same happens with the SYNTAX identifier:

   #!r6rs
   (import (except (rnrs) syntax))
   #'(a b c)

showing:

  $ racket proof.sps
  proof.sps:6:0: compile: unbound identifier in module in: syntax

  Summary: once  our eyes have adapted  to use '---  and #'--- as
abbreviations for (quote ---) and (syntax ---), and it may take a
while, they  are of  friendly usage; but  we have to  remember to
import libraries exporting the QUOTE and SYNTAX identifiers.

> but in what practical situations would I then call it?

The  SYNTAX identifier  is bound  to a  special, very  low level,
macro  integrated  in the  source  code  expander  (which is  the
"preprocessor").

  It is  impossible to fully understand  its implementation using
the mental model of a Scheme program being executed at run-time.

  In  particular: such  a  syntax *cannot*  be implemented  using
DEFINE-SYNTAX  and  it  does  *not*  expand  to  code  using,  at
run-time,  some technique involving  the dynamic  environment and
the DYNAMIC-WIND function.  Rather, when the expander walking the
code finds a form like:

   (syntax . stuff)

it  invokes an internal  function having  access to  its internal
data structures (or something to that effect).

  The gist of  it is: we must use the SYNTAX  macro every time we
hand-write  the  transformer  function  for a  macro,  whose  use
expands into  a form containing identifiers.  Example:  we do not
need  SYNTAX if  the macro  use expands  into a  datum,  like the
string "ciao":

   #!r6rs
   (import (rnrs))

   (define-syntax ciao
     (lambda (stx)
       "ciao"))

   (write (ciao))
   (newline)

but  we  need  SYNTAX if  we  want  to  use  the binding  of  the
identifier NEWLINE in the output form:

   #!r6rs
   (import (rnrs))

   (define-syntax return
     (lambda (stx)
       (syntax (newline))))

   (display "first line")
   (return)
   (display "second line\n")

  Notice that we can use the SYNTAX macro to return a datum, too:

   #!r6rs
   (import (rnrs))

   (define-syntax ciao
     (lambda (stx)
       (syntax "ciao")))

   (write (ciao))
   (newline)

we can think of:

   (syntax "ciao")

as equivalent to "ciao" by itself.

  In what follows, I will  try to describe the basic mechanics of
SYNTAX omitting  a lot  about what the  expander needs to  do its
thing (which  is: to conduct the "expansion  process").  There is
so much  I have to omit that  I hope the result  still makes some
sense. :)

  The  expander  walks  a  symbolic expression  representing  the
source  code recursively  (somewhat)  as shown  by the  following
program you can run using "racket":

   #!r6rs
   (import (rnrs))

   (define (%log which sexp)
     (display which)
     (display ": ")
     (display sexp)
     (newline))

   (define (%log-enter sexp)
     (%log "Enter" sexp))

   (define (%log-exit sexp)
     (%log "Exit" sexp))

   (define (%log-processing sexp)
     (%log "Processing" sexp))

   (define (simulate-expand-recursion sexp)
     (cond ((list? sexp)
            (%log-enter sexp)
            (simulate-expand-recursion (car sexp))
            (unless (null? (cdr sexp))
              (simulate-expand-recursion (cdr sexp)))
            (%log-exit sexp))
           ((symbol? sexp)
            (%log-processing sexp))
           (else
            (%log-processing sexp))))

   (simulate-expand-recursion
      '(let ((a 1))
         (let ((b 2))
           (write a)
           (write b))))

as  you can see  from the  output it  "enters" and  "exits" every
subexpression.

  From now on I will use pseudo-code, unless otherwise specified.

  Internally, the expander constructs a collection data structure
handled somewhat  like a stack, let's call  it "lexical context";
record values are  pushed on this stack.  The  lexical context is
initialised as follows:

   (define-record-type mark
     (fields (immutable name)))

   (define top-mark
     (make-mark "top"))

   (define lexical-context
     (list top-mark))

   (define (push! obj)
     (set! lexical-context (cons obj lexical-context)))

   (define (pop!)
     (set! lexical-context (cdr lexical-context)))

  With reference to the symbolic expression:

   (let ((a 1))
     (let ((b 2))
       (write a)
       (write b)))

when the  expander enters the outer  LET it pushes a  new mark on
the stack:

  (push! (make-mark "outer-let"))

and  then it  pushes a  record representing  the binding  for the
variable A:

  (define-record-type binding
    (fields (immutable name)
            #| other fields here |#))

  (push! (make-binding 'a))

so that the lexical context looks like:

   lexical-context => (#<binding name=a>
                       #<mark name="outer-let">
                       #<mark name="top">)

  When the expander enters the inner  LET it pushes a new mark on
the stack, followed  by a record representing the  binding for B,
so that the lexical context looks like:

   lexical-context => (#<binding name=b>
                       #<mark name="inner-let">
                       #<binding name=a>
                       #<mark name="outer-let">
                       #<mark name="top">)

  When the expander finds the reference to A in the form:

   (write a)

it  searches  the lexical  context  left-to-right  for a  BINDING
record whose name  is A and it finds it: we  say that the binding
"captures" the reference.

  When the expander  exits the inner LET it  removes its bindings
and its mark:

   lexical-context => (#<binding name=a>
                       #<mark name="outer-let">
                       #<mark name="top">)

and when it  exits the outer LET it removes  its bindings and its
mark:

   lexical-context => (#<mark name="top">)

  You get the picture: every binding form like LAMBDA, LET, LET*,
... causes the expander to push on the lexical context a new MARK
record followed by BINDING records; these records stay there only
while  the  expander  is  processing the  corresponding  symbolic
expression.

  Now enter the SYNTAX macro.  It can inspect the lexical context
in  search of  bindings and  other  records.  Let's  look at  the
following program:

   #!r6rs
   (import (rnrs))

   (let ((a 1))

     (define-syntax reference-to-a
       (lambda (stx)
         (syntax a)))

     (write (reference-to-a))
     (newline))

when the expander  processes the LET form it pushes  a MARK and a
BINDING on the lexical context:

   lexical-context => '(#<binding name=a>
                        #<mark name="let-form">
                        #<mark name="top">)

let's omit what  it does to process the  DEFINE-SYNTAX form, what
matters here is that when the macro use:

   (reference-to-a)

is expanded, the transformer function:

   (lambda (stx)         ;STX is ignored here
     (syntax a))

is called and the SYNTAX macro searches left-to-right the lexical
context for a BINDING record whose  name is A, it finds it and so
it  returns what  is needed  to cause  the macro  to expand  to a
reference to A.

  Let's step back because we  have omitted an important fact.  To
write a program  we have to start the source  code with an IMPORT
form  listing  imported  libraries,   else  we  can  do  nothing.
Whenever the expander processes an  import set (a set of bindings
exported from imported libraries),  it pushes all the bindings on
the lexical context; for example:

   #!r6rs
   (import (only (rnrs)
                 write
                 newline))

causes the  bindings for  WRITE and NEWLINE  to be pushed  on the
stack:

   lexical-context => (#<binding name=write>
                       #<binding name=newline>
                       #<mark name="top">)

and:

   #!r6rs
   (import (rnrs))

causes all  the bindings exported by  (rnrs) to be  pushed on the
stack:

   lexical-context => (#<binding name=display>
                       #<binding name=write>
                       #<binding name=newline>
                       ...
                       #<binding name=sin>
                       #<binding name=cos>
                       #<binding name=tan>
                       ...
                       #<mark name="top">)

too many  to be  listed.  This is  why the following  program can
work:

   #!r6rs
   (import (rnrs))

   (define-syntax return
     (lambda (stx)
       (syntax (newline))))

   (return)

whenever the expander processes the macro use:

   (return)

it calls the transformer function:

   (lambda (stx)
     (syntax (newline)))

and the  SYNTAX macro visits the  lexical context in  search of a
BINDING  record whose  name is  NEWLINE, it  finds it  and  so it
returns what is needed to cause  the macro to expand to a call to
NEWLINE.

  Now we can understand why the following program fails:

   #!r6rs
   (import (rnrs))

   (define-syntax hurt-me
     (lambda (stx)
       (syntax sword)))

   (write (hurt-me))

while expanding the macro use:

   (hurt-me)

the  SYNTAX macro  searches  the lexical  context  for a  BINDING
record whose name is SWORD, it  does not find it and so it causes
the program to abort with:

   $ racket proof.sps
   proof.sps:9:12: compile: unbound identifier in module in: sword

  Now enter  the SYNTAX-CASE  macro; we have  to step  back again
because  we  have omitted  another  important fact.   SYNTAX-CASE
provides two main features:

* It deconstructs  the input  form of a  macro use  using pattern
  matching.  I am not going to describe it here in detail.

* It  pushes  records of  type  PATTERN-VARIABLE  on the  lexical
  context, which later  can be searched by the  SYNTAX macro.  We
  want to understand this.

  Let's look at this program:

   #!r6rs
   (import (rnrs))

   (define-syntax the-second-among
     (lambda (stx)
       (syntax-case stx ()
         ((_ ?a ?b ?c)
          (syntax ?b)))))

   (write (the-second-among 1 2 3))
   (newline)

let's fast forward to when the expander processes the macro use:

   (the-second-among 1 2 3)

the transformer function:

   (define transformer
     (lambda (stx)
       (syntax-case stx ()
         ((_ ?a ?b ?c)
          (syntax ?b)))))

is applied to a record instance of type SYNTAX-OBJECT:

   (define-record-type syntax-object
     (fields (immutable sexp)
             (immutable current-lexical-context)
             #| other fields here |#))

   (define stx
     (make-syntax-object '(the-second-among 1 2 3)
                         lexical-context))

   (transformer stx)

the use of SYNTAX-CASE:

   (syntax-case stx ()
     ((_ ?a ?b ?c)
      (syntax ?b)))

decomposes the symbolic expression:

   (the-second-among 1 2 3)

and  pushes on  the lexical  context PATTERN-VARIABLE  records as
follows:

   (define-record-type pattern-variable
     (fields (immutable name)
             (immutable sexp)))

   (push! (make-pattern-variable '?a 1))
   (push! (make-pattern-variable '?b 2))
   (push! (make-pattern-variable '?c 3))

so that:

   lexical-context => (#<pattern-variable name=?c sexp=3>
                       #<pattern-variable name=?b sexp=2>
                       #<pattern-variable name=?a sexp=1>
                       ...
                       #<mark name="top">)

later  the  SYNTAX macro  visits  the  lexical context  searching
left-to-right for a BINDING record *or* a PATTERN-VARIABLE record
whose name is ?A, it finds it and so it returns what is needed to
cause the macro to expand to the symbolic expression 1.

  Got it?
--

-- 
Marco Maggi

Gmane