Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[OT] Re: What is the best way to navigate #ifdef and #endif in C program

1 view
Skip to first unread message

Fren Zeee

unread,
Aug 4, 2010, 12:45:31 AM8/4/10
to Fren Zeee
On Aug 2, 5:31 pm, "Daniel (Youngwhan)" <breadn...@gmail.com> wrote:
> Hi,
>
> If there is curly brace, it is easy to navigate between them by M-C-f
> and M-C-b in c-mode.
>
> However, I cannot find a way to navigate in like curly brace when it
> comes to #ifdef, #else, and #endif.
>
> For example, if there is a code like this:
>
> #ifdef A_DEFINED
> (...100 lines)
> #else
> (... 500 lines)
> #endif
>
> , is there a easy way to move the cursor from #endif to #ifdef or
> #else and vice versa?
>
> Daniel

You might get better luck posting in a C group also.

I use #ifdef ... #endif often also to comment out blocks of code
during debugging.

My question to CLISP/ELISP/scheme people is

If there is a wrapper do nothing type function in elisp/clisp/scheme
which can have the same effect as commenting out.

This is because I dont like to do comment-region/uncomment-region in
emacs.

These three lispy languages dont seem to have comment block construct
like C ie /* and */

Pascal J. Bourguignon

unread,
Aug 4, 2010, 6:27:14 AM8/4/10
to
Fren Zeee <fren...@gmail.com> writes:

> On Aug 2, 5:31 pm, "Daniel (Youngwhan)" <breadn...@gmail.com> wrote:
>> Hi,
>>
>> If there is curly brace, it is easy to navigate between them by M-C-f
>> and M-C-b in c-mode.
>>
>> However, I cannot find a way to navigate in like curly brace when it
>> comes to #ifdef, #else, and #endif.
>>
>> For example, if there is a code like this:
>>
>> #ifdef A_DEFINED
>> (...100 lines)
>> #else
>> (... 500 lines)
>> #endif
>>
>> , is there a easy way to move the cursor from #endif to #ifdef or
>> #else and vice versa?
>>
>> Daniel
>
> You might get better luck posting in a C group also.
>
> I use #ifdef ... #endif often also to comment out blocks of code
> during debugging.
>
> My question to CLISP/ELISP/scheme people is

clisp is an implementation, not a language.

There is a language named Common Lisp, abreviated as CL. Perhaps you
mean that?

> If there is a wrapper do nothing type function in elisp/clisp/scheme
> which can have the same effect as commenting out.
>
> This is because I dont like to do comment-region/uncomment-region in
> emacs.
>
> These three lispy languages dont seem to have comment block construct
> like C ie /* and */

AFAIK, emacs lisp doesn't have any block comment feature, and I know
no standard way to do block comment in r5rs scheme, but scheme
implementation may provide the same as in Common Lisp, or with a
different syntax.

In Common Lisp you could try to use #| |#, but unfortunately, it is not like C /* and */:

int a[]={
/* hello
/* world
*/
1,2};
// a contains {1,2}.


(let ((a '(
#| hello
#| world
|#
1 2)))
a)

is a syntactic error.


You would have to write:

(let ((a '(
#| hello
#| world |#
|#
1 2)))
a)
--> (1 2)

However, in Common Lisp, you could implement a reader macro with a
behavior similar to C /* comments */.

This is the reason why there is no point asking whether there is a
feature X in CL. You can always add any feature to the language,
thanks to its macros or reader macros, and metalinguistic abilities in
general.


--
__Pascal Bourguignon__ http://www.informatimago.com/

Alessio Stalla

unread,
Aug 4, 2010, 6:38:46 AM8/4/10
to
On Aug 4, 12:27 pm, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

> In Common Lisp you could try to use #| |#, but unfortunately, it is not like C /* and */:

Unfortunately? I don't find it unfortunate that I can nest comments,
while in the C-family I cannot.

Alessio

Pascal J. Bourguignon

unread,
Aug 4, 2010, 7:57:10 AM8/4/10
to
Alessio Stalla <alessi...@gmail.com> writes:

Unfortunately for the OP, since he requested something like C /* comments */ ... ;-)

Elena

unread,
Aug 4, 2010, 10:37:49 AM8/4/10
to
On Aug 4, 10:27 am, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

> This is the reason why there is no point asking whether there is a
> feature X in CL.  You can always add any feature to the language,
> thanks to its macros or reader macros, and metalinguistic abilities in
> general.

Can macros really add features or can they just add syntactic sugar? A
custom "case" statement is just syntactic sugar, tail call
optimization is a feature.

Arzobispo Andante

unread,
Aug 4, 2010, 10:59:55 AM8/4/10
to
Elena <egar...@gmail.com> wrote:

> Can macros really add features or can they just add syntactic sugar? A
> custom "case" statement is just syntactic sugar, tail call
> optimization is a feature.

I can see no reason why a macro could not transform tail-recursive code
into iterative code. That would basically achieve the same observable
effect of TCO, i.e. getting rid of stack growth.

--
AA

Peter Keller

unread,
Aug 4, 2010, 11:09:05 AM8/4/10
to
In comp.lang.lisp Elena <egar...@gmail.com> wrote:
> On Aug 4, 10:27?am, p...@informatimago.com (Pascal J. Bourguignon)

> wrote:
>> This is the reason why there is no point asking whether there is a
>> feature X in CL. ?You can always add any feature to the language,

>> thanks to its macros or reader macros, and metalinguistic abilities in
>> general.
>
> Can macros really add features or can they just add syntactic sugar? A
> custom "case" statement is just syntactic sugar, tail call
> optimization is a feature.

This book:

http://letoverlambda.com/index.cl/toc

Specifically:
http://letoverlambda.com/index.cl/guest/chap5.html#sec_4

Would show you how to write a macro such that it adds Scheme's tail call
optimized "named let" into Common Lisp. This goes beyond the concept
of syntactic sugar and enters the domain of pure code transformation.

So yes, you can add features.

However, I don't know if you can add "any" feature to CL. :)

For example, could I add the ability for a function to introspect
into its own display and see an annotated mapping of the machine
registers in context? Or could I ask a piece of memory how many times
it has been moved in a generational garbage collector and where was
its last physical location?

Of course, I could add these things, but not with CL as it exists
today since there is no means to get that information outside of
implementation specific APIs which extend the meaning and domain of CL.

Later,
-pete


Peter Keller

unread,
Aug 4, 2010, 11:35:48 AM8/4/10
to
In comp.lang.lisp Peter Keller <psi...@cs.wisc.edu> wrote:
> For example, could I add the ability for a function to introspect
> into its own display and see an annotated mapping of the machine
> registers in context?

Let me make a correction to this one. I *may* be able to add this because
CL comes with disassemble. But it all comes down to how much information is
provided to me by the implementation and how it is presented to me.

-pete

Elena

unread,
Aug 4, 2010, 12:20:05 PM8/4/10
to
On Aug 4, 4:45 am, Fren Zeee <frenz...@gmail.com> wrote:
> If there is a wrapper do nothing type function in elisp/clisp/scheme
> which can have the same effect as commenting out.

In Emacs Lisp, if you are looking for a way to comment out blocks of
text, you are out of luck. I've read Pythonistas use multi-line
strings as multi-line comments (strings are always multi-line in
Emacs).

If you are looking for a way to comment out blocks of code, you can do
that with a macro. I remember having seen a "comment" macro inside
Emacs Lisp packages kindly published by Pascal J. Bourguignon here:
http://www.informatimago.com/develop/emacs/index.html

Elena

unread,
Aug 4, 2010, 12:23:40 PM8/4/10
to
On Aug 4, 4:45 am, Fren Zeee <frenz...@gmail.com> wrote:
> If there is a wrapper do nothing type function in elisp/clisp/scheme
> which can have the same effect as commenting out.

Scheme multi-line comments are here:

http://srfi.schemers.org/srfi-30/srfi-30.html

Which also is first hit when searching the Net for "scheme multi line
comments".

Emmy Noether

unread,
Aug 5, 2010, 2:00:39 PM8/5/10
to

I would remove a function block by wrapping in one of man conditionals
like

(cond (f (comment-out-block)) )

the short circuit evaluation would not even process it.

I plan to test this idea in the future.

Elena

unread,
Aug 5, 2010, 3:04:23 PM8/5/10
to
On 4 Ago, 17:09, Peter Keller <psil...@cs.wisc.edu> wrote:
> Specifically:http://letoverlambda.com/index.cl/guest/chap5.html#sec_4
>
> Would show you how to write a macro such that it adds Scheme's tail call
> optimized "named let" into Common Lisp.  This goes beyond the concept
> of syntactic sugar and enters the domain of pure code transformation.

Indeed, code transformation is what sets CL's macros apart. However,
TCO is much more than that. Read here:

http://stackoverflow.com/questions/2181852/tail-call-elimination-in-clojure

However, TCO could also just not be possible in CL because of its
design:

http://www.cliki.net/Tail%20Recursion

Elena

unread,
Aug 5, 2010, 3:08:11 PM8/5/10
to
Moreover, full escaping continuations (a la Scheme) are likely to be
out of reach. And that can make sense, too. I once asked on
comp.lang.scheme how to guarantee release of resources and basically
Schemers answered you can't guarantee anything like that when
continuation come into the picture.

Peter Keller

unread,
Aug 5, 2010, 5:10:48 PM8/5/10
to
In comp.lang.lisp Elena <egar...@gmail.com> wrote:
> On 4 Ago, 17:09, Peter Keller <psil...@cs.wisc.edu> wrote:
>> Specifically:http://letoverlambda.com/index.cl/guest/chap5.html#sec_4
>>
>> Would show you how to write a macro such that it adds Scheme's tail call
>> optimized "named let" into Common Lisp. ?This goes beyond the concept

>> of syntactic sugar and enters the domain of pure code transformation.
>
> Indeed, code transformation is what sets CL's macros apart. However,
> TCO is much more than that. Read here:
>
> http://stackoverflow.com/questions/2181852/tail-call-elimination-in-clojure

After reading that, I assert that I don't know how to take base CL
and make it tail recursive since redefining things like defun and
whatnot lead to package lock errors. Even things like define-compiler-macro
can't redefine any of the CL macros or functions.

One probably could have success if they created forms like defun-tco,
labels-tco, flet-tco, etc which kept track of their code expansions
and rewrote them to be tco. But at that point you've implemented a
tco enforced lisp dialect on top of CL.

> However, TCO could also just not be possible in CL because of its
> design:
>
> http://www.cliki.net/Tail%20Recursion

It may be true, I don't know.

-pete

Pascal J. Bourguignon

unread,
Aug 5, 2010, 7:46:26 PM8/5/10
to
Peter Keller <psi...@cs.wisc.edu> writes:

> In comp.lang.lisp Elena <egar...@gmail.com> wrote:
>> On 4 Ago, 17:09, Peter Keller <psil...@cs.wisc.edu> wrote:
>>> Specifically:http://letoverlambda.com/index.cl/guest/chap5.html#sec_4
>>>
>>> Would show you how to write a macro such that it adds Scheme's tail call
>>> optimized "named let" into Common Lisp. ?This goes beyond the concept
>>> of syntactic sugar and enters the domain of pure code transformation.
>>
>> Indeed, code transformation is what sets CL's macros apart. However,
>> TCO is much more than that. Read here:
>>
>> http://stackoverflow.com/questions/2181852/tail-call-elimination-in-clojure
>
> After reading that, I assert that I don't know how to take base CL
> and make it tail recursive since redefining things like defun and
> whatnot lead to package lock errors. Even things like define-compiler-macro
> can't redefine any of the CL macros or functions.
>
> One probably could have success if they created forms like defun-tco,
> labels-tco, flet-tco, etc which kept track of their code expansions
> and rewrote them to be tco. But at that point you've implemented a
> tco enforced lisp dialect on top of CL.

It is almost trivial to provide a package (possibly even named
"COMMON-LISP") which is like the "COMMON-LISP" package, but that is
not the implementation's "COMMON-LISP" package.

See for example:
http://www.informatimago.com/develop/lisp/small-cl-pgms/ibcl/

The trick is in defining a defpackage form such as:

(defmacro defpackage (name &rest options)
`(cl:defpackage ,name
,@(mapcar
(lambda (option)
(if (listp option)
(case (first option)
((:use)
(substitute "IBCL" "COMMON-LISP"
(substitute "IBCL" "CL" option)))
((:shadowing-import-from :import-from)
(if (member (string (second option))
'("CL" "COMMON-LISP")
:test (function string=))
(list* (first option)
"IBCL"
(cddr option))
option))
(otherwise option))))
options)))

where you substitute the "COMMON-LISP" package for your own. (You
also need to define your own reader and loader, but these components
are available too).

Aaron W. Hsu

unread,
Aug 6, 2010, 12:59:13 AM8/6/10
to
Fren Zeee <fren...@gmail.com> writes:

>My question to CLISP/ELISP/scheme people is

>If there is a wrapper do nothing type function in elisp/clisp/scheme
>which can have the same effect as commenting out.

>This is because I dont like to do comment-region/uncomment-region in
>emacs.

>These three lispy languages dont seem to have comment block construct
>like C ie /* and */

Actually, there are a lot of them in common use. Here are the one's I
use regularly, and you can check with your implementation to see if it
provides them:

#| |# block comments
#; Expression comments

I find the expression comments to be very useful. Basically, it let's
you comment out the next expression, such as this:

(if (test)
#;(bad
nothing
or another)
(good thing)
(other thing))

Now, some people don't like it because it plays with their Emacs
commenting modes. Since I don't use Emacs, this doesn't bother me. ;-)
On the other hand, the workaround if you don't want to hack your Scheme
highlighting is to do something like this instead:

(if (test)
#;
(bad
nothing
or another)
(good thing)
(other thing))

This will keep the highlighting mostly in check and still do the same
thing.

Aaron W. Hsu

Pascal Costanza

unread,
Aug 6, 2010, 6:43:37 AM8/6/10
to

Here is a way how to do TCO in Common Lisp:
http://groups.google.com/group/comp.lang.lisp/msg/8f9dcf58a00aca27

It can't be implemented as just a macro, because it requires the
cooperation of different parts of a program. You can only do that as a
"real" language extension.

Macros provide "only" syntactic sugar, in the sense that they perform
only local program transformations.


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/

Elena

unread,
Aug 6, 2010, 7:17:51 AM8/6/10
to
On Aug 6, 10:43 am, Pascal Costanza <p...@p-cos.net> wrote:
> Here is a way how to do TCO in Common Lisp:http://groups.google.com/group/comp.lang.lisp/msg/8f9dcf58a00aca27
>
> It can't be implemented as just a macro, because it requires the
> cooperation of different parts of a program. You can only do that as a
> "real" language extension.

Thanks for the link, Pascal.

IMHO, that would be a better way to make TCO available, that is: TCO
should be explicit, since you know beforehand whether you want your
function to be tail recursive or not. Then, whenever you fail to
implement a tail recursion among mutually recursive functions, the
compiler should complain. If I'm not mistaken, OCaml has (somewhat)
explicit TCO. Or detecting such errors would better be left to test
cases?

Pascal J. Bourguignon

unread,
Aug 6, 2010, 9:55:36 AM8/6/10
to
Elena <egar...@gmail.com> writes:

You're all forgetting something.

In Common Lisp, most tail calls ARE NOT tail calls.

This is because of dynamic binding. Not only of variables, but also
of unwind frames, a lot of them are hidden in with-* macros, catch
frames, condition handlers, restarts, etc.

So even if TCO was mandatory, it couldn't be applied often in Common
Lisp programs.

0 new messages