473,508 Members | 2,477 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

C closures & lexical scoping

Woah... is it just me or do C programmers don't bother talking about
how cool C can be (compared to Lisp, Haskell, etc.) - functionally
speaking?

// Lexical scoping - via nested functions
#include <stdio.h>

int main() {
int x = 10;

// lexical scoping
static void test() {
x = 123;
}
test();

printf("%d", x);
return 0;
}

// Closures
#include <stdio.h>

int triple(int num) {
return num * 3;
}

int square(int num) {
return num * num;
}

int main() {
int x = 10;

int (*func)(int);

func = square;
printf("%d\n", func(5));

func = triple;
printf("%d\n", triple(5));

return 0;
}

Chris
Dec 12 '07 #1
14 2154
In article <6e**********************************@e6g2000prf.g ooglegroups.com>,
Khookie <ch********@gmail.comwrote:
>Woah... is it just me or do C programmers don't bother talking about
how cool C can be (compared to Lisp, Haskell, etc.) - functionally
speaking?
Well...
>// Lexical scoping - via nested functions
Oops, C doesn't have nested functions. Gcc has them as an extension.
>// Closures
#include <stdio.h>

int triple(int num) {
return num * 3;
}

int square(int num) {
return num * num;
}

int main() {
int x = 10;

int (*func)(int);

func = square;
printf("%d\n", func(5));

func = triple;
printf("%d\n", triple(5));

return 0;
}
I don't see any closures there, just pointers to functions. Without
nested functions, there's nothing interesting to close over.

-- Richard
--
:wq
Dec 12 '07 #2
Philip Potter said:
jacob navia wrote:
<snip>
>>
Yeah, for instance
long long a,b,c;
...

c = a/b;

This generates a function call in C due to operator overloading...
Division is overloaded and works with long long types, but in a
32 bit system that means a function call

Not necessarily. It could easily mean an idiomatic sequence of machine
instructions (similar in concept to a C macro) instead.
Or it could simply be translated to a native division instruction, on
machines that have such a thing. Nothing in the rules prevents this.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Dec 12 '07 #3
>>>>"K" == Khookie <ch********@gmail.comwrites:

KWoah... is it just me or do C programmers don't bother talking
Kabout how cool C can be (compared to Lisp, Haskell, etc.) -
Kfunctionally speaking?

Because we've seen what happens in comp.lang.lisp, which is all about
how cool Lisp is and how misunderstood Lisp programmers are, and how
ANY DAY NOW the great unwashed masses are FINALLY going to realize
just how cool Lisp is and abandon all other programming languages.

Scarcely a parenthesis to be found.

And we're spending so much time repeatedly explaining to Jacob Navia
the concept of "topicality," and how he'd get better responses to his
posts if he posted them where they were on topic, that we just can't
muster the energy for any more foolish advocacy.

Charlton
--
Charlton Wilbur
cw*****@chromatico.net
Dec 12 '07 #4
Richard Heathfield wrote:
Philip Potter said:
>jacob navia wrote:
<snip>
>>Yeah, for instance
long long a,b,c;
...

c = a/b;

This generates a function call in C due to operator overloading...
Division is overloaded and works with long long types, but in a
32 bit system that means a function call
Not necessarily. It could easily mean an idiomatic sequence of machine
instructions (similar in concept to a C macro) instead.

Or it could simply be translated to a native division instruction, on
machines that have such a thing. Nothing in the rules prevents this.
The phrase "32 bit system" is a woolly one, but I took it to imply that
the machine did not have a long long-sized division instruction.

Phil
Dec 12 '07 #5
Philip Potter wrote:
Richard Heathfield wrote:
>Philip Potter said:
>>jacob navia wrote:
<snip>
>>>Yeah, for instance
long long a,b,c;
...

c = a/b;

This generates a function call in C due to operator overloading...
Division is overloaded and works with long long types, but in a
32 bit system that means a function call
Not necessarily. It could easily mean an idiomatic sequence of machine
instructions (similar in concept to a C macro) instead.

Or it could simply be translated to a native division instruction, on
machines that have such a thing. Nothing in the rules prevents this.

The phrase "32 bit system" is a woolly one, but I took it to imply that
the machine did not have a long long-sized division instruction.

Phil
I just wanted to point out the basic unity between operators and
functions. An operator can lead to a function call when an operation
is absent in the real machine. In a 32 bit system precisely most of
the time there is no 64 bit division. (Actually I have never seen a 32
bit system with native 64 bit integer division...)

Of course it can be inlined.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Dec 12 '07 #6
Charlton Wilbur wrote:
>>>>>"K" == Khookie <ch********@gmail.comwrites:

KWoah... is it just me or do C programmers don't bother talking
Kabout how cool C can be (compared to Lisp, Haskell, etc.) -
Kfunctionally speaking?

Because we've seen what happens in comp.lang.lisp, which is all about
how cool Lisp is and how misunderstood Lisp programmers are, and how
ANY DAY NOW the great unwashed masses are FINALLY going to realize
just how cool Lisp is and abandon all other programming languages.

Scarcely a parenthesis to be found.

And we're spending so much time repeatedly explaining to Jacob Navia
the concept of "topicality," and how he'd get better responses to his
posts if he posted them where they were on topic, that we just can't
muster the energy for any more foolish advocacy.

Charlton

Yes, you are spending way too much time bashing navia as it seems.

You would better keep quiet then, and apply your own advice.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Dec 12 '07 #7
Charlton Wilbur <cw*****@chromatico.netwrites:
>>>>>"K" == Khookie <ch********@gmail.comwrites:

KWoah... is it just me or do C programmers don't bother talking
Kabout how cool C can be (compared to Lisp, Haskell, etc.) -
Kfunctionally speaking?

Because we've seen what happens in comp.lang.lisp, which is all about
how cool Lisp is and how misunderstood Lisp programmers are, and how
ANY DAY NOW the great unwashed masses are FINALLY going to realize
just how cool Lisp is and abandon all other programming languages.

Scarcely a parenthesis to be found.

And we're spending so much time repeatedly explaining to Jacob Navia
Who is "we"? The royal "we"?
Dec 12 '07 #8
jacob navia wrote:
Philip Potter wrote:
>Richard Heathfield wrote:
>>Philip Potter said:
jacob navia wrote:
Yeah, for instance
long long a,b,c;
...
>
c = a/b;
>
This generates a function call in C due to operator overloading...
Division is overloaded and works with long long types, but in a
32 bit system that means a function call
Not necessarily. It could easily mean an idiomatic sequence of machine
instructions (similar in concept to a C macro) instead.
Or it could simply be translated to a native division instruction, on
machines that have such a thing. Nothing in the rules prevents this.
The phrase "32 bit system" is a woolly one, but I took it to imply that
the machine did not have a long long-sized division instruction.

I just wanted to point out the basic unity between operators and
functions. An operator can lead to a function call when an operation
is absent in the real machine. In a 32 bit system precisely most of
the time there is no 64 bit division. (Actually I have never seen a 32
bit system with native 64 bit integer division...)

Of course it can be inlined.
In which case why make it a function call in the first place? The thread
about the comparison between operators and function calls is over.
Dec 12 '07 #9
On Dec 12, 2:28 am, Khookie <chris.k...@gmail.comwrote:
Woah... is it just me or do C programmers don't bother talking about
how cool C can be (compared to Lisp, Haskell, etc.) - functionally
speaking?
The set of C programmers who

- are interested in Lisp and Haskell, but
- seriously misunderstand lexical closures, and who
- don't know what is or isn't a GCC extension

is probably vanishingly small.
// Lexical scoping - via nested functions
#include <stdio.h>

int main() {
int x = 10;

// lexical scoping
static void test() {
x = 123;
}
Function nesting is a GCC extension, not standard C.

More importantly, it doesn't implement first class lexical closures.
It has ``downward funargs'' only, like Pascal.

True lexical closures means being able to do something like this:

static int (*test(void))(void)
{
int local = 42;
int nested(void)
{
return local;
}

return &nested;
}

int main(void)
{
int (*func)(void) = test();
printf("%d\n", func());
return 0;
}

The output is 42, because in this imaginary C dialect, &nested creates
a closure instead of just a regular function pointer. A closure is an
object which contains not just the address of the function, but also
the function's captured lexical environment in which the ``int local =
42'' binding is in effect. That environment survives the termination
of the test() call, which is why when we call func(), it returns the
value 42.

The above is not permitted by the GCC extension. The GCC manual says
that ``all hell will break loose''.
Dec 12 '07 #10
Khookie wrote:
>
Woah... is it just me or do C programmers don't bother talking
about how cool C can be (compared to Lisp, Haskell, etc.) -
functionally speaking?

// Lexical scoping - via nested functions
#include <stdio.h>

int main() {
int x = 10;

// lexical scoping
static void test() {
x = 123;
}
...
Illegal. C doesn't allow nested functions.

--
Merry Christmas, Happy Hanukah, Happy New Year
Joyeux Noel, Bonne Annee.
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Dec 13 '07 #11
cr88192 wrote:
"Richard" <rg****@gmail.comwrote in message
news:pn************@news.individual.net...
>"cr88192" <cr*****@hotmail.comwrites:
>>"Mark Bluemel" <ma**********@pobox.comwrote in message
news:fj**********@aioe.org...
....
>>>What about all us dysfunctional programmers?
sitting around scoffing at the idea of the compiler silently inserting
runtime calls, and other things, whenever we use certain language
features...
I don't understand. It can do just that.

often cases, yes.

none the less, people tend to dislike this kind of thing in C land (even as
such, it happens sometimes), albeit it is a very common occurance in most
non-C languages (where there are hidden runtime calls pretty much
everywhere...).
Why do you think people tend to dislike it, and why do you think it's an
uncommon feature of C compilers? Whether it's better to implement a
feature using a function call or by inlining the code that would
otherwise be in such a function is precisely the kind of optimizing
detail that I want the compiler to worry about, not me.
Dec 13 '07 #12

"James Kuyper" <ja*********@verizon.netwrote in message
news:Gs98j.17607$k22.13445@trnddc02...
cr88192 wrote:
>"Richard" <rg****@gmail.comwrote in message
news:pn************@news.individual.net...
>>"cr88192" <cr*****@hotmail.comwrites:

"Mark Bluemel" <ma**********@pobox.comwrote in message
news:fj**********@aioe.org...
...
>>>>What about all us dysfunctional programmers?
sitting around scoffing at the idea of the compiler silently inserting
runtime calls, and other things, whenever we use certain language
features...
I don't understand. It can do just that.

often cases, yes.

none the less, people tend to dislike this kind of thing in C land (even
as such, it happens sometimes), albeit it is a very common occurance in
most non-C languages (where there are hidden runtime calls pretty much
everywhere...).

Why do you think people tend to dislike it, and why do you think it's an
uncommon feature of C compilers?
having compilers that produce code unsuitible for OS development is one
reason.
in userspace, there is less reason for concern.

Whether it's better to implement a feature using a function call or by
inlining the code that would otherwise be in such a function is precisely
the kind of optimizing detail that I want the compiler to worry about, not
me.
well, the reason it would involve a function call, is because it would have
to allocate memory for the binding frames (an inherently non-inlining
operation).

worse yet, absent GC, of explicitly freeing function pointers (probably via
a special function), there is no real way to know when exactly these
closures/binding frames are no longer needed, so one will end up with a
memory leak...

Dec 13 '07 #13
cr88192 wrote:
"James Kuyper" <ja*********@verizon.netwrote in message
news:Gs98j.17607$k22.13445@trnddc02...
cr88192 wrote:
"Richard" <rg****@gmail.comwrote in message
news:pn************@news.individual.net...
"cr88192" <cr*****@hotmail.comwrites:

"Mark Bluemel" <ma**********@pobox.comwrote in message
news:fj**********@aioe.org...
...
>>>What about all us dysfunctional programmers?
sitting around scoffing at the idea of the compiler silently inserting
runtime calls, and other things, whenever we use certain language
features...
I don't understand. It can do just that.

often cases, yes.

none the less, people tend to dislike this kind of thing in C land (even
as such, it happens sometimes), albeit it is a very common occurance in
most non-C languages (where there are hidden runtime calls pretty much
everywhere...).
Why do you think people tend to dislike it, and why do you think it's an
uncommon feature of C compilers?

having compilers that produce code unsuitible for OS development is one
reason.
in userspace, there is less reason for concern.
I've developed code exclusively in user space, so I'm unfamiliar with
the requirements of OS developement. Why would the occurrence of a
function call to implement, for instance, long long multiplication on
a 16-bit platform, render the code unsuitable for such development?
Whether it's better to implement a feature using a function call or by
inlining the code that would otherwise be in such a function is precisely
the kind of optimizing detail that I want the compiler to worry about, not
me.

well, the reason it would involve a function call, is because it would have
to allocate memory for the binding frames (an inherently non-inlining
operation).
This isn't my area of expertise, so I'm not quite sure what that
sentence means. However, I suspect that it doesn't mean what you
intended it to mean. It sounds to me like you've reversed cause and
effect; surely the function call is the reason for the binding frames,
not vice-versa? The reason for involving a function call would be to
reduce the code size; the reason for inlining the function call would
be to reduce execution time. Binding frames, as you've described them,
seem very expensive; they would seem, if anything, to be a reason for
not involving a function call.
worse yet, absent GC, of explicitly freeing function pointers (probably via
a special function), there is no real way to know when exactly these
closures/binding frames are no longer needed, so one will end up with a
memory leak...
Again, this isn't my area of current expertise, but back when I did do
assembly language programming, in none of the three languages I
learned did executing a function require allocation of memory in a
fashion that was difficult to deallocate. Memory was allocated as
needed from the stack by the simple expedient of changing the value of
a register, and it was returned to the stack by the simple expedient
of restoring the original value of that register. I'm sure more
complicated schemes are needed on other platforms.

I'm sure that you're talking about something much more complicated
than what I'm thinking of. But is there any reason why "inserting
runtime function calls ... whenever we use certain language features"
has to refer to what you're thinking of, rather than what I'm thinking
of?
Dec 13 '07 #14
Chris Dollin wrote:
ja*********@verizon.net wrote:
....
>than what I'm thinking of. But is there any reason why "inserting
runtime function calls ... whenever we use certain language features"
has to refer to what you're thinking of, rather than what I'm thinking
of?

I believe he's exclusively thinking of support for upward closures
(ie nested functions that access outer locals and are also exported
out of the enclosing function), and he seems to think that constructing
such a closure would /have/ to involve a function call.
Sorry, I should have realized the comment about "certain features" was
meant to be a reference to the subject of this thread. I thought that
the discussion had wandered off-subject, and that this was just a
generic gripe about all language features that an implementation might
implemented using function calls. I apologize for wasting people's time
with my misunderstanding.

Discussions that stay on-subject! What will they think of next? :-)
Dec 14 '07 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
2289
by: Matt Knepley | last post by:
I must be misunderstanding how Python 2.3 handles lexical scoping. Here is a sample piece of code: def run(): a = 1 def run2(b): print a run2(2) print a run()
14
1539
by: Alexander May | last post by:
When I define a function in the body of a loop, why doesn't the function "close" on the loop vairable? See example below. Thanks, Alex C:\Documents and Settings\Alexander May>python Python...
5
1710
by: paolo veronelli | last post by:
I've a vague idea of the differences,I don't know scheme anyway. I'd like to see an example to show what is missing in python about closures and possibly understand if ruby is better in this...
76
3686
by: Nick Coghlan | last post by:
GvR has commented that he want to get rid of the lambda keyword for Python 3.0. Getting rid of lambda seems like a worthy goal, but I'd prefer to see it dropped in favour of a different syntax,...
18
1770
by: jslowery | last post by:
I am not completely knowledgable about the status of lexical scoping in Python, but it was my understanding that this was added in a long time ago around python2.1-python2.2 I am using python2.4...
2
1556
by: Jon Harrop | last post by:
Just debating somewhere else whether or not Python might be considered a functional programming language. Lua, Ruby and Perl all seem to provide first class lexical closures. What is the current...
2
1243
by: Fernando Perez | last post by:
Hi all, consider the following small example: """ Small test to try to understand a strange subtlety with closures """ def outer(nmax):
3
8770
by: globalrev | last post by:
i cant figure outif python has lexical or general scope. it seems functions have lexical scope but with some restrictions and some non-function scopes are dynamic?
26
2780
by: Aaron \Castironpi\ Brady | last post by:
Hello all, To me, this is a somewhat unintuitive behavior. I want to discuss the parts of it I don't understand. .... f= lambda: n .... 9 9
0
7231
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7336
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
7066
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7504
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5643
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5059
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4724
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3214
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3198
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.