unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* macro like "my" in Perl
@ 2002-06-25 22:19 Paul Jarc
  2002-06-25 23:16 ` Robert Uhl <ruhl@4dv.net>
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Paul Jarc @ 2002-06-25 22:19 UTC (permalink / raw)


I'm looking for something like Perl's "my": something that adds a
binding to the current environment (like internal defines), gives an
error for multiple uses of the same symbol in a single scope (like
internal defines and let), and lets previously-defined variables be
used in values for later bindings (like let*).  I expect I'll have to
wrap the whole scope with a special macro, but I'd like to avoid
having each definition wrap everything that comes after it.  Is there
anything like this already out there?
(new-scope
  (my-define foo #t)
  (do-random-stuff-with foo)
  (my-define bar foo)
  (do-other-stuff-with bar))


paul

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-06-25 22:19 macro like "my" in Perl Paul Jarc
@ 2002-06-25 23:16 ` Robert Uhl <ruhl@4dv.net>
  2002-06-26  2:25 ` Alex Shinn
  2002-07-12 20:43 ` Paul Jarc
  2 siblings, 0 replies; 13+ messages in thread
From: Robert Uhl <ruhl@4dv.net> @ 2002-06-25 23:16 UTC (permalink / raw)


prj@po.cwru.edu (Paul Jarc) writes:
>
> I'm looking for something like Perl's "my": something that adds a
> binding to the current environment (like internal defines), gives an
> error for multiple uses of the same symbol in a single scope (like
> internal defines and let), and lets previously-defined variables be
> used in values for later bindings (like let*).  I expect I'll have to
> wrap the whole scope with a special macro, but I'd like to avoid
> having each definition wrap everything that comes after it.  Is there
> anything like this already out there?

Sounds like yet another job for bound?.  Essentially, one could simply
write a little macro which checks if something is bound, erroring if
so, otherwise defining it and then doing something else.

-- 
Robert Uhl <ruhl@4dv.net>
The power of Satan is as nothing before the might of the Lord, so don't
go getting any ideas.                             --I Abyssinians 20:20

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-06-25 22:19 macro like "my" in Perl Paul Jarc
  2002-06-25 23:16 ` Robert Uhl <ruhl@4dv.net>
@ 2002-06-26  2:25 ` Alex Shinn
  2002-06-26 13:15   ` Ken Anderson
  2002-06-26 14:44   ` Lynn Winebarger
  2002-07-12 20:43 ` Paul Jarc
  2 siblings, 2 replies; 13+ messages in thread
From: Alex Shinn @ 2002-06-26  2:25 UTC (permalink / raw)


>>>>> "Paul" == Paul Jarc <prj@po.cwru.edu> writes:

    Paul> I'm looking for something like Perl's "my":

    [...]

    Paul>  (new-scope
    Paul>    (my-define foo #t)
    Paul>    (do-random-stuff-with foo)
    Paul>    (my-define bar foo)
    Paul>    (do-other-stuff-with bar))

let* can do this if you want:

  (let* ((foo #t)
         (dummy (do-random-stuff-with foo))
         (bar foo))
    (do-other-stuff-with bar))

but that's rather poor style.  If you just want bar to be some function
of foo, you can do

  (let* ((foo #t)
         (bar (some-random-function-of foo)))
    (do-other-stuff-with bar))

or you can declare all the variables you need up front

  (let* ((foo #t) (bar #f))
    (do-random-stuff-with foo)
    (set! bar foo)
    (do-other-stuff-with bar))

or nest let

  (let ((foo #t))
    (do-random-stuff-with foo)
    (let ((bar foo))
      (do-other-stuff-with bar)))

I guess that's the real complaint... nested lets indent the code too
much, but for some straight but very long procedural algorithms it's
less clear to make all the variable decls up front when their use is
localized.

You can write new-scope as a low-level macro that walks the code,
turning my-define into set! and accumulating all the variable names used
into one top-level let.  Something like

(define-macro (new-scope . code)
  (let ((vars (map cadr (filter (lambda (x) (eq? (car x) 'my-define))
                                code))))
    `(let (,@(map (lambda (x) (list x #f)) vars))
       ,@(map (lambda (x) (if (and (pair? x) (eq? (car x) 'my-define))
                              (cons 'set! (cdr x))
                              x))
              code))))

but make it recurse (this only works if all the my-define's are at the
top level).

-- 
Alex

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-06-26  2:25 ` Alex Shinn
@ 2002-06-26 13:15   ` Ken Anderson
  2002-06-26 14:45     ` Lynn Winebarger
  2002-06-26 14:44   ` Lynn Winebarger
  1 sibling, 1 reply; 13+ messages in thread
From: Ken Anderson @ 2002-06-26 13:15 UTC (permalink / raw)
  Cc: Timothy Hickey

In Jscheme, not guile, i recently redefined (define) so that groups of 
internal defines are turned into let* or letrec as appropriate, so you can 
write code without additional indenting:

  (define (graph)
   (define objRoot (BranchGroup.))
   (define objTrans (TransformGroup.))
   (define (addToRoot obj) (.addChild objRoot obj))
   (.setCapability objTrans TransformGroup.ALLOW_TRANSFORM_WRITE$)
   (.addToRoot objTrans)
   (.addChild objTrans (ColorCube. 0.4))
   (define yAxis (Transform3D.))
   (define rotationAlpha (Alpha. -1 4000L))
   (define rotator
     (RotationInterpolator. rotationAlpha objTrans yAxis
                            0.0f
                            (* 2.0F (.floatValue Math.PI$))))
   (define bounds (BoundingSphere. (Point3d. 0.0 0.0 0.0) 100.0))
   (.setSchedulingBounds rotator bounds)
   (addToRoot rotator)
   (.compile objRoot)
   objRoot)


At 10:25 PM 6/25/2002, Alex Shinn wrote:
> >>>>> "Paul" == Paul Jarc <prj@po.cwru.edu> writes:
>
>     Paul> I'm looking for something like Perl's "my":
>
>     [...]
>
>     Paul>  (new-scope
>     Paul>    (my-define foo #t)
>     Paul>    (do-random-stuff-with foo)
>     Paul>    (my-define bar foo)
>     Paul>    (do-other-stuff-with bar))
>
>let* can do this if you want:
>
>   (let* ((foo #t)
>          (dummy (do-random-stuff-with foo))
>          (bar foo))
>     (do-other-stuff-with bar))
>
>but that's rather poor style.  If you just want bar to be some function
>of foo, you can do
>
>   (let* ((foo #t)
>          (bar (some-random-function-of foo)))
>     (do-other-stuff-with bar))
>
>or you can declare all the variables you need up front
>
>   (let* ((foo #t) (bar #f))
>     (do-random-stuff-with foo)
>     (set! bar foo)
>     (do-other-stuff-with bar))
>
>or nest let
>
>   (let ((foo #t))
>     (do-random-stuff-with foo)
>     (let ((bar foo))
>       (do-other-stuff-with bar)))
>
>I guess that's the real complaint... nested lets indent the code too
>much, but for some straight but very long procedural algorithms it's
>less clear to make all the variable decls up front when their use is
>localized.
>
>You can write new-scope as a low-level macro that walks the code,
>turning my-define into set! and accumulating all the variable names used
>into one top-level let.  Something like
>
>(define-macro (new-scope . code)
>   (let ((vars (map cadr (filter (lambda (x) (eq? (car x) 'my-define))
>                                 code))))
>     `(let (,@(map (lambda (x) (list x #f)) vars))
>        ,@(map (lambda (x) (if (and (pair? x) (eq? (car x) 'my-define))
>                               (cons 'set! (cdr x))
>                               x))
>               code))))
>
>but make it recurse (this only works if all the my-define's are at the
>top level).
>
>--
>Alex
>
>_______________________________________________
>Guile-user mailing list
>Guile-user@gnu.org
>http://mail.gnu.org/mailman/listinfo/guile-user


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-06-26  2:25 ` Alex Shinn
  2002-06-26 13:15   ` Ken Anderson
@ 2002-06-26 14:44   ` Lynn Winebarger
  2002-06-27  1:28     ` Alex Shinn
  1 sibling, 1 reply; 13+ messages in thread
From: Lynn Winebarger @ 2002-06-26 14:44 UTC (permalink / raw)


On Tuesday 25 June 2002 21:25, Alex Shinn wrote:
> I guess that's the real complaint... nested lets indent the code too
> much, but for some straight but very long procedural algorithms it's
> less clear to make all the variable decls up front when their use is
> localized.
        
     If it's very procedural, why is it indented so far that nested lets will
indent the code "too much"?   And how is not indenting new scopes
going to clarify where "localized" definitions come from?  (Where 
"localized" is visual only, as the declaration extends to the end of
the enclosing block).
      Of course, he can do whatever he wants.
        
> You can write new-scope as a low-level macro that walks the code,
> turning my-define into set! and accumulating all the variable names used
> into one top-level let.  Something like
> 
> (define-macro (new-scope . code)
>   (let ((vars (map cadr (filter (lambda (x) (eq? (car x) 'my-define))
>                                 code))))
>     `(let (,@(map (lambda (x) (list x #f)) vars))
>        ,@(map (lambda (x) (if (and (pair? x) (eq? (car x) 'my-define))
>                               (cons 'set! (cdr x))
>                               x))
>               code))))
> 
> but make it recurse (this only works if all the my-define's are at the
> top level).

   If you must, why not call it "perl-scope" and introduce "my" as a syntax 
keyword (as is "(my x 'initial-value-here)").
   And I would suggest not fully recursing - you do (presumably) still want the
various let forms to introduce new scopes.  Recursing over begins and ifs 
should be sufficient.  Although perl has it's own rules for how my variables 
scope (like introducing them as the iteration variable in a loop), you might 
want to imitate those as well.  
   Also, what happens if the variable is used before declared?  Will that be an
error?  That _would_ require full recursion.

Lynn

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-06-26 13:15   ` Ken Anderson
@ 2002-06-26 14:45     ` Lynn Winebarger
  2002-07-02 15:34       ` Ken Anderson
  0 siblings, 1 reply; 13+ messages in thread
From: Lynn Winebarger @ 2002-06-26 14:45 UTC (permalink / raw)


On Wednesday 26 June 2002 08:15, Ken Anderson wrote:
> In Jscheme, not guile, i recently redefined (define) so that groups of 
> internal defines are turned into let* or letrec as appropriate, so you can 
> write code without additional indenting:

How do you handle
(let ()
   (define (even? x) (if (= x 0) #t (not (odd? (- x 1)))))
   (define foo (even? 7))
   (define (odd? x) (if (= x 1) #t (not (even? (- x 1))))))

Lynn

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-06-26 14:44   ` Lynn Winebarger
@ 2002-06-27  1:28     ` Alex Shinn
  0 siblings, 0 replies; 13+ messages in thread
From: Alex Shinn @ 2002-06-27  1:28 UTC (permalink / raw)
  Cc: guile-user

>>>>> "Lynn" == Lynn Winebarger <owinebar@free-expression.org> writes:

    Lynn> On Tuesday 25 June 2002 21:25, Alex Shinn wrote:
    >> I guess that's the real complaint... nested lets indent the code
    >> too much, but for some straight but very long procedural
    >> algorithms it's less clear to make all the variable decls up
    >> front when their use is localized.
        
    Lynn> If it's very procedural, why is it indented so far that nested
    Lynn> lets will indent the code "too much"?

Procedural code doesn't imply you don't need new variables... in fact in
procedural code you tend to use variables and state much more than
functional code.  The notion that lots of indentation shows good code is
vastly over-simplified.

I don't know what the OP's use for this was, but I have seen code where
Perl style variable declarations right before their use is more
readable.  Consider a quick and dirty CGI script, which in Perl may
follow a form like:

  my $foo = computeFoo();
  print funcOfFoo1($foo);
  ...
  print funcOfFooN($foo);

  my $bar = computeBar($foo);
  print funcOfBar1($bar);
  ...
  print funcOfBarN($bar);

This is, of course, a matter of style, but I find in these cases it
helps to define bar and initialize it right before the section it's used
in, rather than at the top where foo is initialized.  Each block is thus
isolated and easier to read.  Some people will say this is ugly,
unfactored code, and it would be better to pull out all the funcOfFoo's
together and funcOfBar's into an enclosing function, but that's just
blindly following principles without understanding them.  Why break up
code that only gets used in one place?  It just causes more to read and
more moving back and forth between source code.

And I'm not alone in this, a lot of Perl gets written in this style.
Then again, a lot of Perl is used for things like quick and dirty CGI
scripts :)

    Lynn> And how is not indenting new scopes going to clarify where
    Lynn> "localized" definitions come from?  (Where "localized" is
    Lynn> visual only, as the declaration extends to the end of the
    Lynn> enclosing block).

Extra lines between each block, as above, helps.  Also using the more
readable define-my or some such that will stand out with syntax
highlighting would be good.

-- 
Alex

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-06-26 14:45     ` Lynn Winebarger
@ 2002-07-02 15:34       ` Ken Anderson
  0 siblings, 0 replies; 13+ messages in thread
From: Ken Anderson @ 2002-07-02 15:34 UTC (permalink / raw)
  Cc: Timothy Hickey

At 10:45 AM 6/26/2002, Lynn Winebarger wrote:
>On Wednesday 26 June 2002 08:15, Ken Anderson wrote:
> > In Jscheme, not guile, i recently redefined (define) so that groups of
> > internal defines are turned into let* or letrec as appropriate, so you can
> > write code without additional indenting:
>
>How do you handle
>(let ()
>    (define (even? x) (if (= x 0) #t (not (odd? (- x 1)))))
>    (define foo (even? 7))
>    (define (odd? x) (if (= x 1) #t (not (even? (- x 1))))))
Rather than let, say define.
(define (?)
    ...)

This would be converted into
   (letrec ((even? (lambda (x) (if (= x 0) #t (not (odd? (- x 1)))))))
     (let* ((foo (even? 7)))
       (letrec ((odd? (lambda (x)
                        (if (= x 1) #t (not (even? (- x 1)))))))))))


Procedures that refer to each other should be declared in a group, as is 
usually done with letrec.


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-06-25 22:19 macro like "my" in Perl Paul Jarc
  2002-06-25 23:16 ` Robert Uhl <ruhl@4dv.net>
  2002-06-26  2:25 ` Alex Shinn
@ 2002-07-12 20:43 ` Paul Jarc
  2002-07-13  0:09   ` Neil Jerram
  2 siblings, 1 reply; 13+ messages in thread
From: Paul Jarc @ 2002-07-12 20:43 UTC (permalink / raw)


Thanks for the input.  The scoping of identifiers in top-level defines
is close enough to what I want, so I ended up with this macro to wrap
all top-level forms, rather than trying to modify the scoping of
internal bindings.

(define-macro (top-scope . exprs)
  (let loop ((vars (map (lambda (expr)
                          (and (pair? expr)
                               (member (car expr)
                                       '(define define* define-macro))
                               (let ((x (cdr expr)))
                                 (and (pair? x)
                                      (let ((x (car x)))
                                        (cond
                                         ((symbol? x) x)
                                         ((pair? x)
                                          (let ((x (car x)))
                                            (and (symbol? x) x)))
                                         (#t #f)))))))
                        exprs)))
    (if (null? vars) #t
        (let ((sym (car vars))
              (rest (cdr vars)))
          (if (and sym (member sym rest))
              (scm-error 'misc-error "top-scope" "duplicate bindings: ~S"
                         `(,sym) #f))
          (loop rest))))
  `(begin ,@exprs))

I don't suppose there's any way to find line numbers for the error
message, is there?


paul

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-07-12 20:43 ` Paul Jarc
@ 2002-07-13  0:09   ` Neil Jerram
  2002-07-13 20:48     ` Paul Jarc
  0 siblings, 1 reply; 13+ messages in thread
From: Neil Jerram @ 2002-07-13  0:09 UTC (permalink / raw)


>>>>> "Paul" == Paul Jarc <prj@po.cwru.edu> writes:

    Paul> I don't suppose there's any way to find line numbers for the error
    Paul> message, is there?

Yes, assuming that you haven't disabled the recording of source
properties.

Anything that created a pair (or list, or improper list ...) when it
was read has the filename, line and column number of the pair's
opening parenthesis recorded as a `source property'.

Here's an example of how to access the information.

guile> (define-macro (list-no-pairs . elements)
         (let loop ((elts elements))
           (if (null? elts)
               (cons 'list elements)
               (if (pair? (car elts))
                   (error (format #f "Bad element ~S at ~A:~A:~A"
                                     (car elts)
                                     (source-property (car elts) 'filename)
                                     (source-property (car elts) 'line)
                                     (source-property (car elts) 'column)))
                   (loop (cdr elts))))))
guile> (list-no-pairs 1 2 3)
(1 2 3)
guile> (list-no-pairs 1 (2 2) 3)
standard input:25:20: In procedure error in expression (error (format #f "Bad element ~S at ~A:~A:~A" ...)):
standard input:25:20: Bad element (2 2) at standard input:36:17
ABORT: (misc-error)
guile> 

        Neil


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-07-13  0:09   ` Neil Jerram
@ 2002-07-13 20:48     ` Paul Jarc
  2002-07-16 20:49       ` Neil Jerram
  0 siblings, 1 reply; 13+ messages in thread
From: Paul Jarc @ 2002-07-13 20:48 UTC (permalink / raw)


Neil Jerram <neil@ossau.uklinux.net> wrote:
>                    (error (format #f "Bad element ~S at ~A:~A:~A"
>                                      (car elts)
>                                      (source-property (car elts) 'filename)
>                                      (source-property (car elts) 'line)
>                                      (source-property (car elts) 'column)))

Great, this works.  Although in my guile (1.5.6), this seems to be
disabled by default, so I had to add (read-enable 'positions).

> guile> (list-no-pairs 1 (2 2) 3)
> standard input:25:20: In procedure error in expression (error (format #f "Bad element ~S at ~A:~A:~A" ...)):
> standard input:25:20: Bad element (2 2) at standard input:36:17
> ABORT: (misc-error)

My error messages look like:
ERROR: Bad element (2 2) at ./script:21:11

How do you get the filename and positions at the beginning of the
line?


paul

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-07-13 20:48     ` Paul Jarc
@ 2002-07-16 20:49       ` Neil Jerram
  2002-07-16 21:05         ` Paul Jarc
  0 siblings, 1 reply; 13+ messages in thread
From: Neil Jerram @ 2002-07-16 20:49 UTC (permalink / raw)


>>>>> "Paul" == Paul Jarc <prj@po.cwru.edu> writes:

    Paul> Neil Jerram <neil@ossau.uklinux.net> wrote:
    >> (error (format #f "Bad element ~S at ~A:~A:~A"
    >> (car elts)
    >> (source-property (car elts) 'filename)
    >> (source-property (car elts) 'line)
    >> (source-property (car elts) 'column)))

    Paul> Great, this works.  Although in my guile (1.5.6), this seems to be
    Paul> disabled by default, so I had to add (read-enable 'positions).

    guile> (list-no-pairs 1 (2 2) 3)
    >> standard input:25:20: In procedure error in expression (error (format #f "Bad element ~S at ~A:~A:~A" ...)):
    >> standard input:25:20: Bad element (2 2) at standard input:36:17
    >> ABORT: (misc-error)

    Paul> My error messages look like:
    Paul> ERROR: Bad element (2 2) at ./script:21:11

    Paul> How do you get the filename and positions at the beginning of the
    Paul> line?

Sorry, I don't understand.  What exactly do you want it to look like?

        Neil


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: macro like "my" in Perl
  2002-07-16 20:49       ` Neil Jerram
@ 2002-07-16 21:05         ` Paul Jarc
  0 siblings, 0 replies; 13+ messages in thread
From: Paul Jarc @ 2002-07-16 21:05 UTC (permalink / raw)


Neil Jerram <neil@ossau.uklinux.net> wrote:
>>>>>> "Paul" == Paul Jarc <prj@po.cwru.edu> writes:
>     Paul> Neil Jerram <neil@ossau.uklinux.net> wrote:
>     >> guile> (list-no-pairs 1 (2 2) 3)
>     >> standard input:25:20: In procedure error in expression (error (format #f "Bad element ~S at ~A:~A:~A" ...)):
>     >> standard input:25:20: Bad element (2 2) at standard input:36:17
>     >> ABORT: (misc-error)
>
>     Paul> My error messages look like:
>     Paul> ERROR: Bad element (2 2) at ./script:21:11
>
>     Paul> How do you get the filename and positions at the beginning of the
>     Paul> line?
>
> Sorry, I don't understand.  What exactly do you want it to look like?

Your error message has "standard input:25:20" at the beginning of the
line, where mine has "ERROR".  But I just tried again, interactively
this time, and I get the filename and positions now.  So I guess I'm
looking for a way to enable this for scripts as well.


paul

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2002-07-16 21:05 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-06-25 22:19 macro like "my" in Perl Paul Jarc
2002-06-25 23:16 ` Robert Uhl <ruhl@4dv.net>
2002-06-26  2:25 ` Alex Shinn
2002-06-26 13:15   ` Ken Anderson
2002-06-26 14:45     ` Lynn Winebarger
2002-07-02 15:34       ` Ken Anderson
2002-06-26 14:44   ` Lynn Winebarger
2002-06-27  1:28     ` Alex Shinn
2002-07-12 20:43 ` Paul Jarc
2002-07-13  0:09   ` Neil Jerram
2002-07-13 20:48     ` Paul Jarc
2002-07-16 20:49       ` Neil Jerram
2002-07-16 21:05         ` Paul Jarc

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).