Discussion:
Experiment: functional concepts in C
(too old to reply)
Ertugrul Söylemez
2008-11-17 11:43:14 UTC
Permalink
Hello people,

I thought it would be funny to try to bring functional concepts into the
C language. If anyone is interested, I have published the results on my
blog [1].

[1] http://blog.ertes.de/2008/11/obscure-c-from-new-perspective.html


Greets,
Ertugrul.
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
Nick Keighley
2008-11-17 12:49:30 UTC
Permalink
Post by Ertugrul Söylemez
Hello people,
I thought it would be funny to try to bring functional concepts into the
C language. If anyone is interested, I have published the results on my
blog [1].
[1]http://blog.ertes.de/2008/11/obscure-c-from-new-perspective.html
your code seems to have no whitespace in it including newlines.
I can't be bothered to re-layout it to make it readable.

(it could be a problem with my browser of course)

ah. It looks ok if I look at the source. It isn't HTML

--
Nick Keighley
Kenny McCormack
2008-11-17 13:48:42 UTC
Permalink
Post by Nick Keighley
Post by Ertugrul Söylemez
Hello people,
I thought it would be funny to try to bring functional concepts into the
C language. If anyone is interested, I have published the results on my
blog [1].
[1]http://blog.ertes.de/2008/11/obscure-c-from-new-perspective.html
your code seems to have no whitespace in it including newlines.
I can't be bothered to re-layout it to make it readable.
(it could be a problem with my browser of course)
It displays fine in lynx. You should try it.
Post by Nick Keighley
ah. It looks ok if I look at the source. It isn't HTML
It displays fine in lynx. You should try it.

Note to vippy: Of course it isn't standard C. That is stipulated early
on.
Richard Tobin
2008-11-17 14:33:05 UTC
Permalink
Post by Nick Keighley
your code seems to have no whitespace in it including newlines.
I can't be bothered to re-layout it to make it readable.
(it could be a problem with my browser of course)
ah. It looks ok if I look at the source. It isn't HTML
It's served with the mime type text/x-csrc. If your browser
treats that as HTML, it does indeed have a problem.

(My browser sensibly opens it in emacs.)

-- Richard
--
Please remember to mention me / in tapes you leave behind.
v***@gmail.com
2008-11-17 12:57:00 UTC
Permalink
Post by Ertugrul Söylemez
Hello people,
I thought it would be funny to try to bring functional concepts into the
C language. If anyone is interested, I have published the results on my
blog [1].
[1] http://blog.ertes.de/2008/11/obscure-c-from-new-perspective.html
Well your blog entry starts with
Post by Ertugrul Söylemez
C is probably the most uninteresting programming language in the world.
which is untrue and a bad way to start an article.

Reading further, in your code
<http://ertes.de/cfact/cfact1.c>

It seems you want to obfuscate your code, since you have things like
Post by Ertugrul Söylemez
puts("_Expecting one argument.\0Invalid integer." + jv); /* vippstar: jv is return value of setjmp */
Line 34 you return a value other than 0, EXIT_SUCCESS and
EXIT_FAILURE, which doesn't need to be meaningful.

The other 3 source files (cfact[2,3,4].c) are not standard C.
Bartc
2008-11-17 14:12:25 UTC
Permalink
Post by v***@gmail.com
Reading further, in your code
<http://ertes.de/cfact/cfact1.c>
It seems you want to obfuscate your code, since you have things like
Post by Ertugrul Söylemez
puts("_Expecting one argument.\0Invalid integer." + jv); /*
vippstar: jv is return value of setjmp */
I had a look to see if the OP had really put in the comment just for your
benefit. He hadn't.
--
Bartc
Ertugrul Söylemez
2008-11-17 15:36:10 UTC
Permalink
Post by v***@gmail.com
Reading further, in your code
<http://ertes.de/cfact/cfact1.c>
It seems you want to obfuscate your code, since you have things like
Post by Ertugrul Söylemez
puts("_Expecting one argument.\0Invalid integer." + jv); /*
vippstar: jv is return value of setjmp */
Yes, the first version was indeed just a funny thing, which started it
all. I'm not happy with the result though, because of what you
mentioned.

The latter three versions, those which are not standard C, are more
interesting. They implement something, which is totally natural in
functional languages, but which turns an imperative language into a
comprehensibility hell, without needing to artifically obfuscate code
like in the first version. I'd love to implement them in standard C,
but as said in another post and in the blog, that was almost impossible.


Greets,
Ertugrul.
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
v***@gmail.com
2008-11-17 15:52:15 UTC
Permalink
Post by Ertugrul Söylemez
Post by v***@gmail.com
Reading further, in your code
<http://ertes.de/cfact/cfact1.c>
It seems you want to obfuscate your code, since you have things like
Post by Ertugrul Söylemez
puts("_Expecting one argument.\0Invalid integer." + jv); /*
vippstar: jv is return value of setjmp */
Yes, the first version was indeed just a funny thing, which started it
all. I'm not happy with the result though, because of what you
mentioned.
The latter three versions, those which are not standard C, are more
interesting. They implement something, which is totally natural in
functional languages, but which turns an imperative language into a
comprehensibility hell, without needing to artifically obfuscate code
like in the first version. I'd love to implement them in standard C,
but as said in another post and in the blog, that was almost impossible.
The reason I mentioned the other three sources are not standard C is
because I did not comment on them.
If it's discussion/proposal for new C features, comp.lang.c is not the
right newsgroup. (comp.std.c would be better)
At most, your original message classifies as spam. Moreover, it's
usually better to just publish your article on usenet instead of
providing a web link.
Aatu Koskensilta
2008-11-17 16:17:30 UTC
Permalink
Post by v***@gmail.com
At most, your original message classifies as spam.
No, his original message doesn't. At worst the post classifies as
off-topic.
--
Aatu Koskensilta (***@uta.fi)

"Wovon man nicht sprechen kann, darüber muss man schweigen"
- Ludwig Wittgenstein, Tractatus Logico-Philosophicus
Nick Keighley
2008-11-18 09:11:04 UTC
Permalink
Post by Aatu Koskensilta
Post by v***@gmail.com
At most, your original message classifies as spam.
No, his original message doesn't. At worst the post classifies as
off-topic.
yes
Ertugrul Söylemez
2008-11-18 20:25:52 UTC
Permalink
Post by Aatu Koskensilta
Post by v***@gmail.com
At most, your original message classifies as spam.
No, his original message doesn't. At worst the post classifies as
off-topic.
yes
Although I'm in some sense not entitled to judge, I wouldn't consider my
original post spam. Since this is a C group, it's off-topic in that I'm
talking about implementing closures using non-standard GCC features.

This is true and fine and great and everything, but I'm very
disappointed by the responses, because all I got was being flamed off
for using extensions, not a single comment on the actual subject.
Nobody cared about the theoretical value in the (latter three) source
codes. It feels like nobody of the original responders even read the
article -- where I pointed out that I used non-standard features! -- or
bothered about understanding the code.

By the way, people break standards all the time. If standards limit you
in what you can do for no apparent reason, they are bound to be broken,
with POSIX probably being the best example, or do you GNU users set
POSIXLY_CORRECT? I don't. On the other hand, lexical closures in C
_are_ a bad extension, but being useful, fast and elegant wasn't the
point of my code anyway. It was a theoretical experiment.


Greets,
Ertugrul.
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
Kenny McCormack
2008-11-18 22:05:43 UTC
Permalink
In article <***@ertes.de>,
Ertugrul Söylemez <***@ertes.de> wrote:
...
Post by Ertugrul Söylemez
This is true and fine and great and everything, but I'm very
disappointed by the responses, because all I got was being flamed off
for using extensions, not a single comment on the actual subject.
Nobody cared about the theoretical value in the (latter three) source
codes.
That's all you'll ever get here (in clc). It's the way it is.
They do this all over Usenet now - all they do is pick on you - because
there's just no psycho-sexual benefit to the poster for doing anything
else. But it is worse here than anywhere else.
Post by Ertugrul Söylemez
It feels like nobody of the original responders even read the
article -- where I pointed out that I used non-standard features! -- or
bothered about understanding the code.
Welcome to CLC. We hope you enjoy your stay.
Post by Ertugrul Söylemez
By the way, people break standards all the time. If standards limit you
in what you can do for no apparent reason, they are bound to be broken,
with POSIX probably being the best example, or do you GNU users set
POSIXLY_CORRECT? I don't. On the other hand, lexical closures in C
_are_ a bad extension, but being useful, fast and elegant wasn't the
point of my code anyway. It was a theoretical experiment.
People here don't brook nonsense like "theoretical experiment"s.
Ertugrul Söylemez
2008-11-19 01:12:57 UTC
Permalink
Post by Ertugrul Söylemez
This is true and fine and great and everything, but I'm very
disappointed by the responses, because all I got was being flamed
off for using extensions, not a single comment on the actual
subject. Nobody cared about the theoretical value in the (latter
three) source codes.
That's all you'll ever get here (in clc). It's the way it is. They
do this all over Usenet now [...]
I can't confirm that, but yes, I expected much more positive answers
here. It seems that C is so uninteresting from a language-theoretic
standpoint that people are restricted to writing code and finding errors
in code (with using extensions being considererd one) rather than
talking a bit about the language itself and its design. The latter was
my intention.

In the functional language world, for example, this is way different.
Those people generally welcome theoretical discussions, experiments and
even criticism about the language, because one of the key points of
functional programming is to improve our way of coding and even
thinking. And it works. I'd happily replace C as the system language
by any comparably low-level functional language.

By the way, the idea was inspired by The Evolution of a Haskell
Programmer [1]. I thought, it would be funny to try to implement some
of those examples in C. Unfortunately C's type system is not
Turing-complete. On the other hand, if I haven't overlooked something
obvious, with recursive #includes, the preprocessor is.

[1] http://www.willamette.edu/~fruehr/haskell/evolution.html


Greets,
Ertugrul.
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
Aatu Koskensilta
2008-11-20 01:20:59 UTC
Permalink
Post by Ertugrul Söylemez
By the way, the idea was inspired by The Evolution of a Haskell
Programmer [1]. I thought, it would be funny to try to implement some
of those examples in C. Unfortunately C's type system is not
Turing-complete.
Neither is Haskell's.
--
Aatu Koskensilta (***@uta.fi)

"Wovon man nicht sprechen kann, darüber muss man schweigen"
- Ludwig Wittgenstein, Tractatus Logico-Philosophicus
Ertugrul Söylemez
2008-11-20 03:19:37 UTC
Permalink
Post by Aatu Koskensilta
Post by Ertugrul Söylemez
By the way, the idea was inspired by The Evolution of a Haskell
Programmer [1]. I thought, it would be funny to try to implement
some of those examples in C. Unfortunately C's type system is not
Turing-complete.
Neither is Haskell's.
Haskell's type system gives me the same computational power as Haskell
itself. Maybe I missed something?


Greets,
Ertugrul.
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
Aatu Koskensilta
2008-11-20 13:17:44 UTC
Permalink
Post by Ertugrul Söylemez
Haskell's type system gives me the same computational power as Haskell
itself. Maybe I missed something?
Yes. You're missing the fact that Haskell's type system, as defined by
the Haskell report, does not give you the same computational power as
Haskell itself.
--
Aatu Koskensilta (***@uta.fi)

"Wovon man nicht sprechen kann, darüber muss man schweigen"
- Ludwig Wittgenstein, Tractatus Logico-Philosophicus
Jon Harrop
2008-11-23 22:23:33 UTC
Permalink
Post by Aatu Koskensilta
Post by Ertugrul Söylemez
Haskell's type system gives me the same computational power as Haskell
itself. Maybe I missed something?
Yes. You're missing the fact that Haskell's type system, as defined by
the Haskell report, does not give you the same computational power as
Haskell itself.
I think you mean Haskell 98 and he doesn't. Regardless, Haskell 98 is almost
entirely unused today (GHC's extended Haskell is the defacto standard).
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
Aatu Koskensilta
2008-11-24 13:53:39 UTC
Permalink
Post by Jon Harrop
Post by Aatu Koskensilta
Yes. You're missing the fact that Haskell's type system, as defined by
the Haskell report, does not give you the same computational power as
Haskell itself.
I think you mean Haskell 98 and he doesn't. Regardless, Haskell 98 is almost
entirely unused today (GHC's extended Haskell is the defacto standard).
Right. Multi-parameter type classes and functional dependencies in
particular allow us to perform arbitrary computations on the type
level. Such magic has its charm, though the charm is alas not entirely
unlike that of advanced C++ template magic.

We must not lose sight of the fact this discussion is cross-posted in
comp.lang.c, where all discussion absolutely must be limited to what
is standard conforming. Non-standard extensions of Haskell are thus
obviously even more off-topic than standard Haskell.

Also, when setting follow-ups, its a matter of courtesy to include a
note of that in the body of the post.

In closing, just to please the C crowd:

void main()
--
Aatu Koskensilta (***@uta.fi)

"Wovon man nicht sprechen kann, darüber muss man schweigen"
- Ludwig Wittgenstein, Tractatus Logico-Philosophicus
v***@gmail.com
2008-11-18 22:08:24 UTC
Permalink
Post by Ertugrul Söylemez
Post by Aatu Koskensilta
Post by v***@gmail.com
At most, your original message classifies as spam.
No, his original message doesn't. At worst the post classifies as
off-topic.
yes
Hm... Yes what?
Post by Ertugrul Söylemez
Although I'm in some sense not entitled to judge, I wouldn't consider my
original post spam. Since this is a C group, it's off-topic in that I'm
talking about implementing closures using non-standard GCC features.
Spam: off-topic message luring views.
Your post: interesting off-topic discussion seeking different POVs.
At worst: spam.

If you disagree, that's fine. I don't think it was such an important
statement nor an outrageous insult (nor an insult at all in fact) so
let's just move on.
Post by Ertugrul Söylemez
This is true and fine and great and everything, but I'm very
disappointed by the responses, because all I got was being flamed off
for using extensions, not a single comment on the actual subject.
You haven't been flamed yet, unless you see messages I don't.
Post by Ertugrul Söylemez
Nobody cared about the theoretical value in the (latter three) source
codes. It feels like nobody of the original responders even read the
article -- where I pointed out that I used non-standard features! -- or
bothered about understanding the code.
Because your message was off-topic. There's another possibility that
some cared, but chosen not to pollute this newsgroup with more off-
topic messages. Another reason to be on-topic.
Post by Ertugrul Söylemez
By the way, people break standards all the time.
True, but of little value. People break the law all the time as well -
that doesn't mean the law shouldn't exist, nor the opposite, that the
law is perfect.
Post by Ertugrul Söylemez
If standards limit you
in what you can do for no apparent reason, they are bound to be broken,
with POSIX probably being the best example, or do you GNU users set
POSIXLY_CORRECT? I don't.
The reason might not be apparent, but it exists. If you have any REAL
queries about the reason a feature was included/excluded from C, you
can ask here. For example, you could ask the reason the standard
doesn't require the execution environment to free the memory allocated
by malloc, realloc, calloc upon program termination. You'll probably
get an answer similar to "feature X couldn't be supported in system Y
- Y being old, new, future, imaginary system"

As for POSIXLY_CORRECT, well, that's another off-topic query. As far
as the C standard is concerned, POSIXLY_CORRECT is an identifier for
the programmer, not the implementation. What POSIX programmers should
actually do is a query for comp.unix.programmer, but since it's a
quick one:

IEEE-1003.1-2004:
<http://www.opengroup.org/onlinepubs/009695399/basedefs/
xbd_chap02.html>
Post by Ertugrul Söylemez
The system shall [...], and shall set the symbolic constant _POSIX_VERSION to the value 200112L.
An on-topic remark: _POSIX_VALUE is an identifier for the
implementation, because it starts with an underscore and that
underscore is followed by an uppercase letter.
Post by Ertugrul Söylemez
On the other hand, lexical closures in C
_are_ a bad extension, but being useful, fast and elegant wasn't the
point of my code anyway. It was a theoretical experiment.
You've already been told this is off-topic. Please don't bring more
off-topic statements for fact-checking.
Kenny McCormack
2008-11-18 22:10:53 UTC
Permalink
In article <b32b6712-4488-400d-898f-***@i18g2000prf.googlegroups.com>,
<***@gmail.com> wrote nothing of value:
<flushed>

You are such a tool...
Keith Thompson
2008-11-18 23:05:19 UTC
Permalink
Post by v***@gmail.com
Post by Ertugrul Söylemez
Post by Aatu Koskensilta
Post by v***@gmail.com
At most, your original message classifies as spam.
No, his original message doesn't. At worst the post classifies as
off-topic.
yes
Hm... Yes what?
Post by Ertugrul Söylemez
Although I'm in some sense not entitled to judge, I wouldn't consider my
original post spam. Since this is a C group, it's off-topic in that I'm
talking about implementing closures using non-standard GCC features.
Spam: off-topic message luring views.
Your post: interesting off-topic discussion seeking different POVs.
At worst: spam.
No, that's not what the word "spam" means. Spam on Usenet is an
excessively cross-posted message; the most commonly accepted meaning
is anything that exceeds the Breidbart Index. A single message posted
to a single newsgroup might be inappropriate, but it cannot be spam.

[...]
Post by v***@gmail.com
Post by Ertugrul Söylemez
If standards limit you
in what you can do for no apparent reason, they are bound to be broken,
with POSIX probably being the best example, or do you GNU users set
POSIXLY_CORRECT? I don't.
[...]
Post by v***@gmail.com
As for POSIXLY_CORRECT, well, that's another off-topic query. As far
as the C standard is concerned, POSIXLY_CORRECT is an identifier for
the programmer, not the implementation. What POSIX programmers should
actually do is a query for comp.unix.programmer, but since it's a
<http://www.opengroup.org/onlinepubs/009695399/basedefs/
xbd_chap02.html>
Post by Ertugrul Söylemez
The system shall [...], and shall set the symbolic constant _POSIX_VERSION to the value 200112L.
An on-topic remark: _POSIX_VALUE is an identifier for the
implementation, because it starts with an underscore and that
underscore is followed by an uppercase letter.
<OT>That doesn't have much to do with POSIXLY_CORRECT, which is the
name of an environment variable, not a C identifier.</OT>

[...]
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
v***@gmail.com
2008-11-18 23:44:11 UTC
Permalink
Post by Keith Thompson
Post by v***@gmail.com
Spam: off-topic message luring views.
No, that's not what the word "spam" means. Spam on Usenet is an
excessively cross-posted message; the most commonly accepted meaning
is anything that exceeds the Breidbart Index. A single message posted
to a single newsgroup might be inappropriate, but it cannot be spam.
I don't really want to argue with definitions for English words, but I
think the jargon file disagrees with you.
<http://catb.org/jargon/html/S/spam.html>
In particular, see 2, "this is _often_ done with cross-posting
[...]" (emphasis added by me)

<snip>
Post by Keith Thompson
<OT>That doesn't have much to do with POSIXLY_CORRECT, which is the
name of an environment variable, not a C identifier.</OT>
Whatever POSIXLY_CORRECT is, it's defined in a standard other than C
(and for that matter, POSIX). C (and POSIX) says POSIXLY_CORRECT is an
identifier in the programmers namespace, which means he is under
complete control of what it is.
Keith Thompson
2008-11-19 02:44:23 UTC
Permalink
Post by v***@gmail.com
Post by Keith Thompson
Post by v***@gmail.com
Spam: off-topic message luring views.
No, that's not what the word "spam" means. Spam on Usenet is an
excessively cross-posted message; the most commonly accepted meaning
is anything that exceeds the Breidbart Index. A single message posted
to a single newsgroup might be inappropriate, but it cannot be spam.
I don't really want to argue with definitions for English words,
... and yet ...
Post by v***@gmail.com
but I
think the jargon file disagrees with you.
<http://catb.org/jargon/html/S/spam.html>
In particular, see 2, "this is _often_ done with cross-posting
[...]" (emphasis added by me)
I don't disagree with the jargon file; if you'll read the rest of the
entry, you'll see that the first two meanings have largely fallen into
disuses.

Meaning 2 describes what I'd call "trolling", i.e., posting something
inflammatory with the intent of starting an argument. I don't think
that's what the OP intended to do.
Post by v***@gmail.com
<snip>
Post by Keith Thompson
<OT>That doesn't have much to do with POSIXLY_CORRECT, which is the
name of an environment variable, not a C identifier.</OT>
Whatever POSIXLY_CORRECT is, it's defined in a standard other than C
(and for that matter, POSIX).
I'm not sure that it's defined in any standard. For purposes of this
newsgroup, it suffices to say that it's not defined in the C standard
(and nobody has suggested that it is). The previous poster mentioned
POSIXLY_CORRECT in passing in the context of talking about conforming
or not conforming to standards. (GNU software often doesn't quite
conform to POSIX by default; setting POSIXLY_CORRECT causes it to
conform more closely.) It was a real-world example meant to
illustrate a point.
Post by v***@gmail.com
C (and POSIX) says POSIXLY_CORRECT is an
identifier in the programmers namespace, which means he is under
complete control of what it is.
POSIXLY_CORRECT in this context *is not an identifier*. It's the name
of an environment variable, which means it's a string whose address
you could pass to getenv(). If you want to mention that it's
off-topic, fine, but why go off on a tangent about how that particular
character string could be used as an identifier in a C program?
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
v***@gmail.com
2008-11-19 18:02:41 UTC
Permalink
<snip>
Post by Keith Thompson
Post by v***@gmail.com
Whatever POSIXLY_CORRECT is, it's defined in a standard other than C
(and for that matter, POSIX).
I'm not sure that it's defined in any standard. For purposes of this
newsgroup, it suffices to say that it's not defined in the C standard
(and nobody has suggested that it is). The previous poster mentioned
POSIXLY_CORRECT in passing in the context of talking about conforming
or not conforming to standards. (GNU software often doesn't quite
conform to POSIX by default; setting POSIXLY_CORRECT causes it to
conform more closely.) It was a real-world example meant to
illustrate a point.
Post by v***@gmail.com
C (and POSIX) says POSIXLY_CORRECT is an
identifier in the programmers namespace, which means he is under
complete control of what it is.
POSIXLY_CORRECT in this context *is not an identifier*. It's the name
of an environment variable, which means it's a string whose address
you could pass to getenv(). If you want to mention that it's
off-topic, fine, but why go off on a tangent about how that particular
character string could be used as an identifier in a C program?
Because I completely missed what Ertugrul said/illustrated with
POSIXCLY_CORRECT. I see it now that you pointed it out, thanks.
Arnold Snarb
2008-11-19 20:06:40 UTC
Permalink
[blah blah blah blah blah]
Mental note: remember to *never* cross-post to comp.lang.c.


--AS
Ertugrul Söylemez
2008-11-19 00:48:37 UTC
Permalink
Post by v***@gmail.com
Post by Ertugrul Söylemez
This is true and fine and great and everything, but I'm very
disappointed by the responses, because all I got was being flamed
off for using extensions, not a single comment on the actual
subject.
You haven't been flamed yet, unless you see messages I don't.
Your interpretation may be different.
Post by v***@gmail.com
Post by Ertugrul Söylemez
Nobody cared about the theoretical value in the (latter three)
source codes. It feels like nobody of the original responders even
read the article -- where I pointed out that I used non-standard
features! -- or bothered about understanding the code.
Because your message was off-topic. There's another possibility that
some cared, but chosen not to pollute this newsgroup with more off-
topic messages. Another reason to be on-topic.
Being standards-compliant is one thing, simply being counter-innovative
is another. What do we need comp.std.c for, if this newsgroup is about
and only about standard C, and if going beyond it is evil? Where should
I post this instead? In my opinion, this _is_ a C-related topic, at
least because it shows something that is difficult to implement in
standard C.

By the way, according to your view, GCC and most other compilers are not
C compilers. They compile some language derived from C.
Post by v***@gmail.com
Post by Ertugrul Söylemez
By the way, people break standards all the time.
True, but of little value. People break the law all the time as well -
that doesn't mean the law shouldn't exist, nor the opposite, that the
law is perfect.
Your view appears to be that in a law-related newsgroup, one shouldn't
talk about the limits of law and/or about breaking it.
Post by v***@gmail.com
Post by Ertugrul Söylemez
If standards limit you in what you can do for no apparent reason,
they are bound to be broken, with POSIX probably being the best
example, or do you GNU users set POSIXLY_CORRECT? I don't.
The reason might not be apparent, but it exists. If you have any REAL
queries about the reason a feature was included/excluded from C, you
can ask here. [...]
This is a discussion forum, not a support forum.
Post by v***@gmail.com
As for POSIXLY_CORRECT, well, that's another off-topic query. [...]
That was not a query at all.
Post by v***@gmail.com
Post by Ertugrul Söylemez
On the other hand, lexical closures in C _are_ a bad extension, but
being useful, fast and elegant wasn't the point of my code anyway.
It was a theoretical experiment.
You've already been told this is off-topic. Please don't bring more
off-topic statements for fact-checking.
You told me. I'm unable to find any etiquette or posting rules. This
is a C-related topic. The group name suggests it's on-topic.


Greets,
Ertugrul.
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
Phil Carmody
2008-11-19 01:19:28 UTC
Permalink
Post by Ertugrul Söylemez
Post by v***@gmail.com
Post by Ertugrul Söylemez
This is true and fine and great and everything, but I'm very
disappointed by the responses, because all I got was being flamed
off for using extensions, not a single comment on the actual
subject.
You haven't been flamed yet, unless you see messages I don't.
Your interpretation may be different.
Post by v***@gmail.com
Post by Ertugrul Söylemez
Nobody cared about the theoretical value in the (latter three)
source codes. It feels like nobody of the original responders even
read the article -- where I pointed out that I used non-standard
features! -- or bothered about understanding the code.
Because your message was off-topic. There's another possibility that
some cared, but chosen not to pollute this newsgroup with more off-
topic messages. Another reason to be on-topic.
Being standards-compliant is one thing, simply being counter-innovative
is another. What do we need comp.std.c for, if this newsgroup is about
and only about standard C, and if going beyond it is evil?
You're confusing talking about the standard and talking about
programming using the standard. For example, I rarely have any
interest in discussions about upcoming propositions and drafts
of the standard, so I don't generally hang aroung comp.std.c.
Yet I have a strong interest in programming portable C, so I
do hang around here. I don't see the two groups as being much
more related than a French linguistics group is to a French
chat group, or a beer-drinkers group is to a brewing group.

Phil
--
I tried the Vista speech recognition by running the tutorial. I was
amazed, it was awesome, recognised every word I said. Then I said the
wrong word ... and it typed the right one. It was actually just
detecting a sound and printing the expected word! -- pbhj on /.
Ertugrul Söylemez
2008-11-19 01:39:47 UTC
Permalink
Post by Phil Carmody
Post by Ertugrul Söylemez
Being standards-compliant is one thing, simply being
counter-innovative is another. What do we need comp.std.c for, if
this newsgroup is about and only about standard C, and if going
beyond it is evil?
You're confusing talking about the standard and talking about
programming using the standard. For example, I rarely have any
interest in discussions about upcoming propositions and drafts of the
standard, so I don't generally hang aroung comp.std.c. Yet I have a
strong interest in programming portable C, so I do hang around here. I
don't see the two groups as being much more related than a French
linguistics group is to a French chat group, or a beer-drinkers group
is to a brewing group.
There is of course nothing wrong with that. Feel free not to
participate in this thread.

I'm talking both about the language and about programming in it (or how
doing certain things is difficult). This discussion is, of course, by
no means productive, but as said, I never intended to contribute useful
code. I thought, some people would like to discuss the theoretical
aspects of C, or at least find my code amusing.

After all, I could have written the same code without using extensions.
It's just that it would be ten times as long and ten times as
incomprehensible.


Greets,
Ertugrul.
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
James Kuyper
2008-11-19 03:12:48 UTC
Permalink
...
Post by Ertugrul Söylemez
Being standards-compliant is one thing, simply being counter-innovative
is another. What do we need comp.std.c for, if this newsgroup is about
and only about standard C,
comp.std.c is for discussions about the C standard. comp.lang.c is for
discussions about how to use the language defined by that standard.
Proposed changes to the standard are on-topic in comp.std.c, and
off-topic in comp.lang.c. If you are talking about an extension to C
that you do not propose standardizing, it's off-topic in both groups.

I have no idea what's on-topic in comp.lang.functional.
Post by Ertugrul Söylemez
... and if going beyond it is evil?
Going beyond the standard isn't evil, just off-topic. You're wasting
time (yours and other peoples) by discussing it here, just as you would
be wasting time going to a butcher shop when you're trying to buy flowers.

...
Post by Ertugrul Söylemez
By the way, according to your view, GCC and most other compilers are not
C compilers. They compile some language derived from C.
gcc has a mode that fully-conforms to C90, making it definitely a C
compiler when used in that mode. It has another mode that comes pretty
close to fully conforming to C99. It is "almost" a C compiler when used
in that mode.

...
Post by Ertugrul Söylemez
Post by v***@gmail.com
Post by Ertugrul Söylemez
By the way, people break standards all the time.
True, but of little value. People break the law all the time as well -
that doesn't mean the law shouldn't exist, nor the opposite, that the
law is perfect.
Your view appears to be that in a law-related newsgroup, one shouldn't
talk about the limits of law and/or about breaking it.
comp.std.c is the equivalent of a "law-related" group in this context,
and discussion of changes to the standard would certainly be on-topic there.
Richard Tobin
2008-11-19 09:24:35 UTC
Permalink
Post by Ertugrul Söylemez
Being standards-compliant is one thing, simply being counter-innovative
is another. What do we need comp.std.c for, if this newsgroup is about
and only about standard C, and if going beyond it is evil? Where should
I post this instead? In my opinion, this _is_ a C-related topic, at
least because it shows something that is difficult to implement in
standard C.
There is no agreement about what is topical in comp.lang.c.
Originally it was very broad, often including discussions about unix.
At some point several of the most prolific posters seem to have
decided that only discussion of standard C was acceptable. If they
have succeeded in imposing this view, it is only by repeated
assertion, so they can have no complaint if the issue swings the other
way.

So if you feel (as I do) that discussion of improvements to C is
reasonable in comp.lang.c, I suggest that you just go ahead and
discuss them, and ignore the complaints. Don't waste your time
arguing about topicality.

-- Richard
--
Please remember to mention me / in tapes you leave behind.
d***@csclub.uwaterloo.ca.invalid
2008-11-19 18:51:35 UTC
Permalink
[Followup-To trimmed to comp.lang.c only]
Post by Ertugrul Söylemez
Post by v***@gmail.com
Because your message was off-topic. There's another possibility that
some cared, but chosen not to pollute this newsgroup with more off-
topic messages. Another reason to be on-topic.
Being standards-compliant is one thing, simply being counter-innovative
is another.
Your innovation is my users' heap of useless code. The whole point of
standardization *is* to limit innovation in the interface, to
facilitate innovation at the next level up by giving users a consistent
platform to build on.

If you want to make a better compiler, that kind of innovation would be
welcomed by (many of the) people here, but it's not really appropriate
for discussion here; there are other places to talk about playing with
compilers and hacking on any particular compiler you want to start
with.
If you want to use (or implement) language features that C doesn't
have, then, well, you're not using C anymore, so it's kind of useless
to talk about it in comp.lang.c.

But if you want to do something new and interesting and implement it in
C, *that*'s (part of) what this newsgroup is here for. Despite what
our resident trolls and whiners would have you believe, there's plenty
of room for innovation there, and most of that room is *created by* the
fact that we have a standard language to build on and don't have to
worry about whether I'm using the same compiler you are.

(If you want to discuss whether some extension to the language would be
useful, that's kind of a grey area; but it's more off-topic than
on-topic, and it's more likely to be tolerated when it's coming from
people who already have a history of making interesting contributions
that are unambiguously on-topic.)
Post by Ertugrul Söylemez
Where should
I post this instead? In my opinion, this _is_ a C-related topic, at
least because it shows something that is difficult to implement in
standard C.
Building functional abstractions in C is a C-related topic and is
appropriate for discussion here.
Building functional abstractions in GCC's not-quite-C default language
is appropriate for discussion in places intended for discussion of
programming in GCC's not-quite-C default language.
Learning to recognize the difference is the first step on the path to
wisdom.
Post by Ertugrul Söylemez
By the way, according to your view, GCC and most other compilers are not
C compilers. They compile some language derived from C.
Adding "by default" in appropriate places would make that sentence
perfectly correct.
One of the few bits of compiler-specific information that's generally
considered acceptable here is how to make the compiler speak C and not
its own C-like dialect. (For GCC it's '-ansi -pedantic' for C90, and
'-std=c99 -pedantic' for a partial C99 implementation.)
Post by Ertugrul Söylemez
Post by v***@gmail.com
You've already been told this is off-topic. Please don't bring more
off-topic statements for fact-checking.
You told me. I'm unable to find any etiquette or posting rules. This
is a C-related topic. The group name suggests it's on-topic.
For etiquette and posting rules,
<http://www.clc-wiki.net/wiki/C_community:comp.lang.c:Introduction>
is probably a good place to start.
(It may or may not be mentioned somewhere there, but a thick skin and a
willingness to learn are both pretty much essential.)


(It is rather unfortunate that most of the comments you got were on the
parts of your post that used GCC extensions; there's an interesting and
on-topic discussion hiding in the parts of your post that are
restricted to standard C.)


dave
--
Dave Vandervies dj3vande at eskimo dot com
Post by Ertugrul Söylemez
[P]rotect the originals with something that has sharp teeth, long tentacles
and a big appetite. --Alexander Schreiber and Michel
In other words: Keep it with you. Buijsman in the scary devil monastery
Aatu Koskensilta
2008-11-20 01:19:00 UTC
Permalink
Post by v***@gmail.com
Spam: off-topic message luring views.
Your post: interesting off-topic discussion seeking different POVs.
At worst: spam.
You're quite mistaken as to what spam is.
--
Aatu Koskensilta (***@uta.fi)

"Wovon man nicht sprechen kann, darüber muss man schweigen"
- Ludwig Wittgenstein, Tractatus Logico-Philosophicus
d***@csclub.uwaterloo.ca.invalid
2008-11-19 18:13:41 UTC
Permalink
Post by Ertugrul Söylemez
This is true and fine and great and everything, but I'm very
disappointed by the responses, because all I got was being flamed off
for using extensions, not a single comment on the actual subject.
Nobody cared about the theoretical value in the (latter three) source
codes. It feels like nobody of the original responders even read the
article -- where I pointed out that I used non-standard features! -- or
bothered about understanding the code.
Your original subject is something I have some interest in, and my
initial impression was that you're going about it in entirely the wrong
way.
If I get the opportunity to do so before the article expires from my
newsserver (which may or may not happen), I intend to take a close
enough look at it to come up with something coherent and substantial to
say. But that will take a bit longer than noticing and pointing out
that you're using ill-advised extensions that most of the world doesn't
have available would.
Post by Ertugrul Söylemez
By the way, people break standards all the time. If standards limit you
in what you can do for no apparent reason, they are bound to be broken,
...and if you're lucky, you will soon realize why the standard imposes
that restriction. (If you're not lucky, you won't reach that
realization until you have a large mess of non-compliant stuff to deal
with.)
Post by Ertugrul Söylemez
with POSIX probably being the best example, or do you GNU users set
POSIXLY_CORRECT? I don't.
This (or equivalent mental discipline) is in fact recommended by most
of the people I know who regularly use GNU tools. They've all been
bitten at one time or another by assuming GNU extensions where they
don't exist and can't be added.


dave
--
Dave Vandervies dj3vande at eskimo dot com
Post by Ertugrul Söylemez
[P]rotect the originals with something that has sharp teeth, long tentacles
and a big appetite. --Alexander Schreiber and Michel
In other words: Keep it with you. Buijsman in the scary devil monastery
Sean G. McLaughlin
2008-11-17 15:52:28 UTC
Permalink
Post by v***@gmail.com
Post by Ertugrul Söylemez
Hello people,
I thought it would be funny to try to bring functional concepts into the
C language. If anyone is interested, I have published the results on my
blog [1].
[1] http://blog.ertes.de/2008/11/obscure-c-from-new-perspective.html
Well your blog entry starts with
Post by Ertugrul Söylemez
C is probably the most uninteresting programming language in the world.
which is untrue and a bad way to start an article.
You have misquoted the OP by omitting the subordinate clause and making
the main clause a sentence standing on its own. The original text is,
for those who are too lazy to read the article,

"C is probably one of the most uninteresting programming languages in
the world, *from a language theory standpoint.*"
Ertugrul Söylemez
2008-11-17 16:25:40 UTC
Permalink
Post by Sean G. McLaughlin
Post by v***@gmail.com
Well your blog entry starts with
Post by Ertugrul Söylemez
C is probably the most uninteresting programming language in the world.
which is untrue and a bad way to start an article.
You have misquoted the OP by omitting the subordinate clause and
making the main clause a sentence standing on its own. The original
text is, for those who are too lazy to read the article,
"C is probably one of the most uninteresting programming languages in
the world, *from a language theory standpoint.*"
No, no, I added this later in response to vippstar's comment, and I
pointed this out here. Sorry for the confusion.


Greets,
Ertugrul.
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
s***@gmail.com
2008-11-17 20:27:25 UTC
Permalink
Post by v***@gmail.com
Line 34 you return a value other than 0, EXIT_SUCCESS and
EXIT_FAILURE, which doesn't need to be meaningful.
Whether the return status is meaningful or not is completely dependent
on the environment that executes the program. Even 0, EXIT_SUCCESS and
EXIT_FAILURE might not be meaningful (though, at least for 0, this
would be very rare).
Post by v***@gmail.com
The other 3 source files (cfact[2,3,4].c) are not standard C.
Unsurprisingly, considering that the original post talked about
"bringing functional concepts into the C language."

Sebastian
Keith Thompson
2008-11-17 20:46:49 UTC
Permalink
Post by s***@gmail.com
Post by v***@gmail.com
Line 34 you return a value other than 0, EXIT_SUCCESS and
EXIT_FAILURE, which doesn't need to be meaningful.
Whether the return status is meaningful or not is completely dependent
on the environment that executes the program. Even 0, EXIT_SUCCESS and
EXIT_FAILURE might not be meaningful (though, at least for 0, this
would be very rare).
They're meaningful for any conforming hosted C implementation. Can
you cite an implementation where they're not?

[...]
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
s***@gmail.com
2008-11-17 21:07:24 UTC
Permalink
Post by Keith Thompson
Post by s***@gmail.com
Post by v***@gmail.com
Line 34 you return a value other than 0, EXIT_SUCCESS and
EXIT_FAILURE, which doesn't need to be meaningful.
Whether the return status is meaningful or not is completely dependent
on the environment that executes the program. Even 0, EXIT_SUCCESS and
EXIT_FAILURE might not be meaningful (though, at least for 0, this
would be very rare).
They're meaningful for any conforming hosted C implementation.
Then there is no conforming hosted C implementation. No compiler could
possibly predict how all the programs in a system will interpret exit
codes from other programs.

Note: When I said "environment" in my previous post, I didn't just
mean the operating system. Any program can execute another program and
interpret its exit status however it wants.

Sebastian
Keith Thompson
2008-11-17 21:14:46 UTC
Permalink
Since this is no longer relevant to comp.lang.functional, I'm
redirecting followups.
Post by s***@gmail.com
Post by Keith Thompson
Post by s***@gmail.com
Post by v***@gmail.com
Line 34 you return a value other than 0, EXIT_SUCCESS and
EXIT_FAILURE, which doesn't need to be meaningful.
Whether the return status is meaningful or not is completely dependent
on the environment that executes the program. Even 0, EXIT_SUCCESS and
EXIT_FAILURE might not be meaningful (though, at least for 0, this
would be very rare).
They're meaningful for any conforming hosted C implementation.
Then there is no conforming hosted C implementation. No compiler could
possibly predict how all the programs in a system will interpret exit
codes from other programs.
Note: When I said "environment" in my previous post, I didn't just
mean the operating system. Any program can execute another program and
interpret its exit status however it wants.
Every hosted system I'm familiar with has a convention for
interpreting status codes. For example, Unix uses 0 for success, and
OpenVMS uses odd numbers for success. Certainly there's nothing
preventing any individual program running on such a system from
violating those conventions -- but so what? The command line
interpreter (e.g., the shell on Unix) is required to follow the
conventions; see, for example, the behavior of the "if" and "while"
statements in the Bourne shell.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
v***@gmail.com
2008-11-18 12:24:10 UTC
Permalink
Post by Keith Thompson
Post by s***@gmail.com
Post by v***@gmail.com
Line 34 you return a value other than 0, EXIT_SUCCESS and
EXIT_FAILURE, which doesn't need to be meaningful.
Whether the return status is meaningful or not is completely dependent
on the environment that executes the program. Even 0, EXIT_SUCCESS and
EXIT_FAILURE might not be meaningful (though, at least for 0, this
would be very rare).
They're meaningful for any conforming hosted C implementation. Can
you cite an implementation where they're not?
He is a troll, why are you wasting your time?
Kenny McCormack
2008-11-18 14:34:02 UTC
Permalink
Post by v***@gmail.com
Post by Keith Thompson
Post by s***@gmail.com
Post by v***@gmail.com
Line 34 you return a value other than 0, EXIT_SUCCESS and
EXIT_FAILURE, which doesn't need to be meaningful.
Whether the return status is meaningful or not is completely dependent
on the environment that executes the program. Even 0, EXIT_SUCCESS and
EXIT_FAILURE might not be meaningful (though, at least for 0, this
would be very rare).
They're meaningful for any conforming hosted C implementation. Can
you cite an implementation where they're not?
He is a troll, why are you wasting your time?
Believe me in this: If there is one thing Keith Thompson has lots and
lots of, it is time (on his hands).
s***@gmail.com
2008-11-18 17:57:52 UTC
Permalink
Post by v***@gmail.com
Post by s***@gmail.com
Post by v***@gmail.com
Line 34 you return a value other than 0, EXIT_SUCCESS and
EXIT_FAILURE, which doesn't need to be meaningful.
Whether the return status is meaningful or not is completely dependent
on the environment that executes the program. Even 0, EXIT_SUCCESS and
EXIT_FAILURE might not be meaningful (though, at least for 0, this
would be very rare).
They're meaningful for any conforming hosted C implementation.  Can
you cite an implementation where they're not?
He is a troll, why are you wasting your time?
I'd like to remind you of a thread, and especially of a particular
post:

http://groups.google.com/group/comp.lang.c/msg/7ce5393c60e40b19

where it was proven who of the two of us is a troll. (You yourself
admitted it; read the last line.)

Sebastian
Phil Carmody
2008-11-17 13:04:30 UTC
Permalink
Post by Ertugrul Söylemez
Hello people,
I thought it would be funny to try to bring functional concepts into the
C language. If anyone is interested, I have published the results on my
blog [1].
[1] http://blog.ertes.de/2008/11/obscure-c-from-new-perspective.html
"I have written four versions of the factorial function in C
[...]
Version 2 — using function pointer continuations"

[ which contains:
void fact(int x, void (*e)(char *), void (*k)(int)) {
void mulCont(int y) {
k(x*y);
}
... ]

Version 3 — implementing algebraic lists and folds using closures

[ which contains:
void cons(int x, list xs, void (*k)(list)) {
void concat(void (*end)(), void (*more)(int)) {
more(x);
xs(end, more);
}
... ]

Version 4 — lambda calculus with fixpoint operator

[ which contains:
void fix(int (*f)(int (*)(int), int), void (*k)(int (*)(int))) {
int ldf(int x) {
int y;
... ]
"""


Perhaps you'd like to reword the introduction to say "I have written
four versions of the factorial function, one of which is in C and
the rest of them are not in C."?

Phil
--
I tried the Vista speech recognition by running the tutorial. I was
amazed, it was awesome, recognised every word I said. Then I said the
wrong word ... and it typed the right one. It was actually just
detecting a sound and printing the expected word! -- pbhj on /.
Ertugrul Söylemez
2008-11-17 15:28:37 UTC
Permalink
[...]
Yes, the latter three solutions are not standard C, but I pointed this
out in the article. Implementing closures without this GCC extension is
near to impossible without implementing full garbage collection and some
notion of 'thunks'. About the blog entry starting, vippstar, you're
right. I adjusted it.

Thank you all for your comments.


Greets,
Ertugrul.
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
Keith Thompson
2008-11-19 05:57:29 UTC
Permalink
Post by Ertugrul Söylemez
I thought it would be funny to try to bring functional concepts into the
C language. If anyone is interested, I have published the results on my
blog [1].
[1] http://blog.ertes.de/2008/11/obscure-c-from-new-perspective.html
Of the four programs you posted, three of them depend on a
non-standard extension, namely nested function definitions. As such,
they are, in my opinion, examples of using function concepts in a
C-like language (namely GNU C), not in C itself. (I wonder if similar
things could be done using only standard C -- but I don't wonder
enough to spend a whole lot of time thinking about it.)

If you think that these three programs are an argument in favor of
adding features to C itself, then comp.std.c would be the best place
to make that argument. I offer no opinion (at least for now) on
whether it would be a good idea.

Going back to the first program, it is in standard C, but some of the
coding is quite obscure. For example, in one place you write:
puts("_Expecting one argument.\0Invalid integer." + jv);
where jv has been set to either 1 or 25 in a call to longjmp. Some
other problems I found:

Your factorial function is declared to return an int, but it doesn't
return a value, and the call doesn't attempt to use the returned
value. (The result is returned via longjmp().)

You use the atoi() function, which invokes undefined behavior for
certain arguments.

Your variable names are unnecessarily terse. You use the name "p"
both for a static int in the factorial function, and for a jmp_buf.
If you want to illustrate an unconventional technique, I think it's
best to make the rest of the code as clear as possible.

Here's my version of your program:

/* Factorial function using continuations in C.
* Copyright (C) 2008, Ertugrul Söylemez
* Modified by Keith Thompson
*/

#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>

enum error_code {
no_error,
bad_arg_count,
invalid_integer
};

static char *errors[] = {
/* no_error (unused) */ NULL,
/* bad_arg_count */ "Expecting one argument.\n",
/* invalid_integer */ "Invalid integer.\n"
};


void factorial(int x, jmp_buf err, jmp_buf print) {
static int product;
jmp_buf recurse;
int jv;

product = 1;
if (x < 0) longjmp(err, invalid_integer);
jv = setjmp(recurse);
if (!jv) longjmp(recurse, x);

product *= jv;
if (jv > 1) longjmp(recurse, jv-1);
longjmp(print, product);
}


int main(int argc, char **argv) {
jmp_buf err;
jmp_buf print;
int jv;
int x;
char *endptr;

jv = setjmp(err);
if (jv) {
fputs(errors[jv], stderr);
return EXIT_FAILURE;
}

jv = setjmp(print);
if (jv) {
printf("%d\n", jv);
return 0;
}

if (argc != 2) {
longjmp(err, bad_arg_count);
}
x = strtol(argv[1], &endptr, 10);
if (argv[1][0] != '\0' && *endptr == '\0') {
factorial(x, err, print);
}
else {
longjmp(err, invalid_integer);
}
}
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Richard Tobin
2008-11-19 09:27:47 UTC
Permalink
Post by Keith Thompson
If you think that these three programs are an argument in favor of
adding features to C itself, then comp.std.c would be the best place
to make that argument.
I think this is quite wrong. It implies that there's no place for
discussion of extending C unless it's with a view to standardising it,
which would be absurdly premature in most cases.

There's a standard for C, but that doesn't mean that anything not
in the standard isn't C.

-- Richard
--
Please remember to mention me / in tapes you leave behind.
Keith Thompson
2008-11-19 09:30:55 UTC
Permalink
Post by Richard Tobin
Post by Keith Thompson
If you think that these three programs are an argument in favor of
adding features to C itself, then comp.std.c would be the best place
to make that argument.
I think this is quite wrong. It implies that there's no place for
discussion of extending C unless it's with a view to standardising it,
which would be absurdly premature in most cases.
There's a standard for C, but that doesn't mean that anything not
in the standard isn't C.
When I say "adding features to C itself", I'm referring specifically
to making changes to the C standard.

You can add features to a C implementation, but then you're just
implementing extensions on top of C, not changing C itself.

Followups to comp.lang.c.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Kenny McCormack
2008-11-19 10:51:11 UTC
Permalink
Post by Richard Tobin
Post by Keith Thompson
If you think that these three programs are an argument in favor of
adding features to C itself, then comp.std.c would be the best place
to make that argument.
I think this is quite wrong. It implies that there's no place for
discussion of extending C unless it's with a view to standardising it,
which would be absurdly premature in most cases.
There's a standard for C, but that doesn't mean that anything not
in the standard isn't C.
Uh oh. You're in trouble now.

Expect massive flaming to be coming your way, from the likes of
KeithyWeithy and VippyVippy.

FWIW, and I may be wrong, but I thought you *were* one of the regs/butt-buddy
club. Have you had a recent religious-experience/conversion? If so,
praise the lord (I saw the light!)
Phil Carmody
2008-11-19 13:51:58 UTC
Permalink
Post by Richard Tobin
Post by Keith Thompson
If you think that these three programs are an argument in favor of
adding features to C itself, then comp.std.c would be the best place
to make that argument.
I think this is quite wrong. It implies that there's no place for
discussion of extending C unless it's with a view to standardising it,
which would be absurdly premature in most cases.
You seem to be conflating the concepts of "extending C", and
"coming up with your own C-like language". Extending C is
changing C, i.e. modifying the standard that defines C.

Phil
--
I tried the Vista speech recognition by running the tutorial. I was
amazed, it was awesome, recognised every word I said. Then I said the
wrong word ... and it typed the right one. It was actually just
detecting a sound and printing the expected word! -- pbhj on /.
Paul Rubin
2009-02-05 10:58:44 UTC
Permalink
Post by Ertugrul Söylemez
[1] http://blog.ertes.de/2008/11/obscure-c-from-new-perspective.html
I hereby nomninate you for membership in "evil geniuses for a better
tomorrow". ;-)
Ertugrul Söylemez
2009-02-05 13:48:00 UTC
Permalink
Post by Paul Rubin
Post by Ertugrul Söylemez
[1] http://blog.ertes.de/2008/11/obscure-c-from-new-perspective.html
I hereby nomninate you for membership in "evil geniuses for a better
tomorrow". ;-)
Oh hehe, I almost forgot that piece of code. It's not that evil. I'm
just abusing a highly imperative language for highly functional
stuff. ;)

BTW, I'll refrain from calling that language "C" again, but rather call
it "a C-like language". The last time I made the mistake to call it "C"
got me flamed off in comp.lang.c. =)


Greets,
Ertugrul.
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://blog.ertes.de/
Stefan Ram
2010-01-25 22:14:14 UTC
Permalink
Post by Ertugrul Söylemez
I thought it would be funny to try to bring functional
concepts into the C language.
To me, a lack of automatic memory management makes
functional programming difficult in C.

How does one usually deal with the following problem?

A function returns a value that is passed to another
function, say

print( read() )

. Now, one would like to see it this way that the value
is created by »read« and consumed by »print«.

When the size and structure of the value is dynamic, »read«
will allocate parts of the value.

So, when »print« is »consuming« the value, it seems
natural for »print« to call »free« on this value later.

But there, the problems start:

- When parts of the argument structure are shared,
they possibly should not be freed.

- A client of »print« might pass in objects with
static or automatic storage duration, which
should not be freed at all.

One might work out a set of rules to deal with all this,
but I believe programming is much more complicate this way.

I believe some people have a concept of »ownership« of
objects with allocated storage duration that might be
passed or not be passed with those objects. But we do not
have common guidelines in C for this ownership transfer?

In the end, one might invest more time in thinking about
memory management than about the actual programming problem.

So, I believe, this is the real problem, when one tries
to do functional programming in C.
Paul Rubin
2010-01-25 22:36:53 UTC
Permalink
Post by Stefan Ram
A function returns a value that is passed to another
function, say
print( read() )
I once wrote an embedded lisp interpreter where you'd write
something like

Lisp_value f() {
mark();
...
print (wrap (read()));
...
release ();
}

Basically the interpreter had a stack of values protected from garbage
collection. wrap(...) would push a value onto the stack and return the
same value. mark() would save a "frame pointer" and push the old frame
pointer onto the stack, and release() would pop back to the saved frame
pointer. Throwing an exception would pop the stack back to the frame
pointer saved by the exception handler. So that temporary value
returned by read() would be protected through the dynamic context of
f(), and of course saving any further references would make it reachable
by gc. This really wasn't too bad. If you wanted to use read/print in
a loop you could put the value in a mutable cell in order to avoid
unwanted stack growth, something like:

Lisp_value x = Nil;
wrap_ref(&x);
for (...) {
x = read();
print (x);
}
Post by Stefan Ram
- When parts of the argument structure are shared,
they possibly should not be freed.
- A client of »print« might pass in objects with
static or automatic storage duration, which
should not be freed at all.
Well sure, but such sharing would be discovered by a tracing gc.
Post by Stefan Ram
In the end, one might invest more time in thinking about
memory management than about the actual programming problem.
Maybe for a high performance system. The simple-minded thing that I did
was fairly easy to use and worked reliably, though I guess it
may have had some efficiency shortcomings, and couldn't have handled
an evaluation model that allowed (e.g.) saved continuations.
Stefan Ram
2010-01-25 22:55:05 UTC
Permalink
Post by Paul Rubin
Well sure, but such sharing would be discovered by a tracing gc.
Yes, the whole point of my post is that C usually does
/not have/ a GC. So I infer that functional programming,
therefore, is difficult or nearly impossible (beyond a
certain level of complexity) in C.
jacob navia
2010-01-25 23:08:19 UTC
Permalink
Post by Stefan Ram
Post by Paul Rubin
Well sure, but such sharing would be discovered by a tracing gc.
Yes, the whole point of my post is that C usually does
/not have/ a GC. So I infer that functional programming,
therefore, is difficult or nearly impossible (beyond a
certain level of complexity) in C.
I have been proposing a garbage collector forC since 2004. The
garbage collector is a part of thestandard lcc-win distribution.

The same collector is available for most workstation environments.

jacob
ld
2010-01-25 23:22:58 UTC
Permalink
Post by Paul Rubin
Well sure, but such sharing would be discovered by a tracing gc.
  Yes, the whole point of my post is that C usually does
  /not have/ a GC. So I infer that functional programming,
  therefore, is difficult or nearly impossible (beyond a
  certain level of complexity) in C.
I have already answered to this kind of question recently. You don't
need a GC, just a richer set of ownership rules. In the C Object
System (100% C lib) I use new, delete and autoDelete (delayed delete)
for object creation/destruction and retain, release and autoRelease
(delayed release) for object ownership. The reason why there is a
difference between creation and ownership comes from the possibility
to convert a posteriori an existing code back and forth to something
semi-gc where all new do an autoDelete and no delete are required from
the user (and obviously the rule does not apply to retain/release life-
cycle). Since I have adopted these rules with _local_ balance (new <->
delete/autoDelete, retain <-> release/autoRelease), I don't have
anymore memory leaks.

Once you have ownership, you need few more concepts to be able to
program in C as you would in Lisp (and beyond). Another (big) step is
the implementation of generic closures (high order functions and high
order messages) and there you need the full expressive power of COS...

cheers,

ld.
Stefan Ram
2010-01-25 23:33:25 UTC
Permalink
Post by ld
I have already answered to this kind of question recently.
You don't need a GC, just a richer set of ownership rules.
Yes, please give me the URI of this set!
ld
2010-01-25 23:44:01 UTC
Permalink
Post by ld
I have already answered to this kind of question recently.
You don't need a GC, just a richer set of ownership rules.
  Yes, please give me the URI of this set!
I mentioned the list of messages in my post. You can find the semantic
explanation in the paper

http://cos.cvs.sourceforge.net/viewvc/cos/doc/cos-draft-dls09.pdf

or in the slides

http://cos.cvs.sourceforge.net/viewvc/cos/doc/slides-cos.pdf

You can also read the doc on ownership and memory management from the
Apple dev center since they use autoRelease pools for more than a
decade in Cocoa (and still nowadays despite of the introduction of the
GC with Objective-C 2.0).

The code can be browsed on the cvs repository (things in CosBase are
stable but on CosStd and CosExt are unstable).

cheers,

ld.
Paul Rubin
2010-01-26 03:04:34 UTC
Permalink
Post by Stefan Ram
Post by Paul Rubin
Well sure, but such sharing would be discovered by a tracing gc.
Yes, the whole point of my post is that C usually does
/not have/ a GC. So I infer that functional programming,
therefore, is difficult or nearly impossible (beyond a
certain level of complexity) in C.
The functional programming would only work on a certain class of objects
within the C program, that are collected by an internal gc. Sometimes
what this leads to is called "Greenspun's Tenth Law" ;-).

There are also so-called conservative gc's for C and C++ (that treat all
data words as possible heap pointers) but at least as a matter of
principle, those can be considered unsatisfying.

Anyway I came late into this thread, but I don't think anyone was
proposing to embed Haskell as cpp macros or anything like that ;-). The
idea is just that it's possible for one's C programs to be influenced by
functional style, and to implement some nontrivial functional constructs
through a few coding disciplines supported by some utility functions.
BGB / cr88192
2010-01-26 04:25:54 UTC
Permalink
Post by Paul Rubin
Post by Stefan Ram
Post by Paul Rubin
Well sure, but such sharing would be discovered by a tracing gc.
Yes, the whole point of my post is that C usually does
/not have/ a GC. So I infer that functional programming,
therefore, is difficult or nearly impossible (beyond a
certain level of complexity) in C.
The functional programming would only work on a certain class of objects
within the C program, that are collected by an internal gc. Sometimes
what this leads to is called "Greenspun's Tenth Law" ;-).
There are also so-called conservative gc's for C and C++ (that treat all
data words as possible heap pointers) but at least as a matter of
principle, those can be considered unsatisfying.
yeah.
they can tend to be slow and unreliable, and can be rather ill-behaved for
certain usage patterns...

ideally, it would be preferable to avoid a conservative GC (and instead use
precise GC), but alas, for C, this leads to far too much hassle/overhead
(having to mess with registering and unregistering roots, ...).

the JVM seem to use an alternate strategy for JNI:
references are "local" or "global", where local references have a
constrained lifespan (and may be destroyed after the JNI method returns).


for C, I have ended up developing a sort of pseudo-GC strategy (used mostly
in my compiler internals), where the allocator just sort of naively
allocates from sliding buffers, which may be destroyed/reused when done.

any data to preserved then is, manually, copied elsewhere (although, more
often, it is just discarded, with the result having been "transcribed" into
a different form).
if made automatic, I guess this would be a sort of crude copy-collector.

OTOH, this could be made into a "semi-automatic" API, whereby one could
instruct the system to copy the data, but it goes about the actual logistics
of doing so (likely with the help of user-registered "copy" handlers). (in
the "manual" strategy, usually type-specific data-copying functions are
written for any data needing to be copied...).

but, anyways, the main advantage of this strategy is that it does well for
the usage patterns which seem to pop up in my compiler: producing large
volumes of objects in short bursts, which almost all turn into garbage.

this particular usage-cases tend to kill my main GC (which tends to work
best with a gradual accumulation of garbage at a relatively low rate).
Post by Paul Rubin
Anyway I came late into this thread, but I don't think anyone was
proposing to embed Haskell as cpp macros or anything like that ;-). The
idea is just that it's possible for one's C programs to be influenced by
functional style, and to implement some nontrivial functional constructs
through a few coding disciplines supported by some utility functions.
yeah.
Haskell mixed in with C would be nasty...

well, of note:
I do have support for a "closure" facility in my case (via an API call).

however, I haven't really exactly used it much (except in a few edge cases
where it was needed), and generally it would require manually "capturing"
the bindings in the form of a heap-allocated struct (or similar).

so, in general, it has neither the grace nor the elegance of the FP
analogue.

it tends to be actually more usable just to pass an object with the funtion
embedded in a function pointer (even though) you can't simply call this as
if it were a function pointer. this tends actually to be a lot more
convinient, as well as being faster (via lack of crufty "transfer thunks")
and typically generating less garbage...
ld
2010-01-26 11:15:51 UTC
Permalink
Post by Paul Rubin
Anyway I came late into this thread,
we all came late, the thread started in 2008 ;-)
Post by Paul Rubin
but I don't think anyone was
proposing to embed Haskell as cpp macros or anything like that ;-).
I did something close with COS because once you have implemented loop
in cpp, you get a functional language (with gc) ;-) So I get things
like map, foldl, foldr, filter, etc...

See chaos-pp on sourceforge for a serious lib like this, mine is
focused (and limited) for COS.
Post by Paul Rubin
The
idea is just that it's possible for one's C programs to be influenced by
functional style, and to implement some nontrivial functional constructs
through a few coding disciplines supported by some utility functions.
Right. The library of COS is mainly written in a functional style
inspired by Haskell. For example, you can look at

http://cos.cvs.sourceforge.net/viewvc/cos/CosStd/include/cos/gen/algorithm.h?view=markup

where each generic function (in the CLOS sens) with a 'fun' parameter
expect a functor (closure).

cheers,

ld.
Ertugrul Söylemez
2010-01-27 19:32:06 UTC
Permalink
Post by Paul Rubin
Yes, the whole point of my post is that C usually does /not have/
a GC. So I infer that functional programming, therefore, is
difficult or nearly impossible (beyond a certain level of
complexity) in C.
The functional programming would only work on a certain class of
objects within the C program, that are collected by an internal gc.
Sometimes what this leads to is called "Greenspun's Tenth Law" ;-).
There are also so-called conservative gc's for C and C++ (that treat
all data words as possible heap pointers) but at least as a matter of
principle, those can be considered unsatisfying.
Anyway I came late into this thread, but I don't think anyone was
proposing to embed Haskell as cpp macros or anything like that ;-).
The idea is just that it's possible for one's C programs to be
influenced by functional style, and to implement some nontrivial
functional constructs through a few coding disciplines supported by
some utility functions.
The problem is not garbage collection. It just makes it even more
complicated. C is missing some very important high level control
constructs, most notably closures. The only functional programming you
can do in C is continuation passing style, which is already an
improvement over the usual purely imperative style. You get some
limited, but safe resource management that way.

I have written an article about that, which you can find here:
<http://blog.ertes.de/2009/02/continuations-for-secure-code.html>.

That article builds on the just-for-fun article, which started this
thread, and turns it into something actually useful.


Greets
Ertugrul
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://blog.ertes.de/
ld
2010-01-27 23:00:47 UTC
Permalink
Post by Paul Rubin
  Yes, the whole point of my post is that C usually does /not have/
  a GC. So I infer that functional programming, therefore, is
  difficult or nearly impossible (beyond a certain level of
  complexity) in C.
The functional programming would only work on a certain class of
objects within the C program, that are collected by an internal gc.
Sometimes what this leads to is called "Greenspun's Tenth Law" ;-).
There are also so-called conservative gc's for C and C++ (that treat
all data words as possible heap pointers) but at least as a matter of
principle, those can be considered unsatisfying.
Anyway I came late into this thread, but I don't think anyone was
proposing to embed Haskell as cpp macros or anything like that ;-).
The idea is just that it's possible for one's C programs to be
influenced by functional style, and to implement some nontrivial
functional constructs through a few coding disciplines supported by
some utility functions.
The problem is not garbage collection.  It just makes it even more
complicated.  C is missing some very important high level control
constructs, most notably closures.  The only functional programming you
can do in C is continuation passing style, which is already an
improvement over the usual purely imperative style.  You get some
limited, but safe resource management that way.
<http://blog.ertes.de/2009/02/continuations-for-secure-code.html>.
That article builds on the just-for-fun article, which started this
thread, and turns it into something actually useful.
you should remove "This is impossible in C" from the last line of your
article since with my C lib, I use closures as I would in FP. For
example:

Haskell:
fmap (\x -> fmap (\y -> fmap (\z -> fun3 x y z) zs) ys) xs

C Object System:
gmap(gmap(gmap(fun3(aLzy2(__1), aLzy(__1), __1), zs), ys), xs)

The main difference is that Haskell closures have lexical scoping and
lazy evaluation while COS closures have dynamic scoping (placeholders)
and C has strict evaluation. This is why you need to delay the
evaluation of the closure' arguments to the proper evaluation
environment (e.g. geval) using the aLzy() qualifier:

aLzy2(__1) -> 1st argument of the outer map <=> x
aLzy (__1) -> 1st argument of the middle map <=> y
__1 -> 1st argument of the inner map <=> z

Dynamic scoping also means that you can build the closure outside the
lexical scope:

OBJ fun = fun3(aLzy2(__1), aLzy(__1), __1);
gmap(gmap(gmap(fun, zs), ys), xs);

is also valid (and impossible in Haskell AFAIK).

regards,

ld.
Ertugrul Söylemez
2010-01-28 06:13:24 UTC
Permalink
Post by ld
The problem is not garbage collection.  It just makes it even more
complicated.  C is missing some very important high level control
constructs, most notably closures.  The only functional programming
you can do in C is continuation passing style, which is already an
improvement over the usual purely imperative style.  You get some
limited, but safe resource management that way.
<http://blog.ertes.de/2009/02/continuations-for-secure-code.html>.
That article builds on the just-for-fun article, which started this
thread, and turns it into something actually useful.
you should remove "This is impossible in C" from the last line of your
article since with my C lib, I use closures as I would in FP. For
fmap (\x -> fmap (\y -> fmap (\z -> fun3 x y z) zs) ys) xs
gmap(gmap(gmap(fun3(aLzy2(__1), aLzy(__1), __1), zs), ys), xs)
Of course you can always write an interpreter for a richer language.
That's not really 'doing it in C'. Just look at glib, which implements
a complete object oriented language on top of C. You're developing in
your higher language, which is expressed in terms of C.
Post by ld
The main difference is that Haskell closures have lexical scoping and
lazy evaluation while COS closures have dynamic scoping (placeholders)
and C has strict evaluation. This is why you need to delay the
evaluation of the closure' arguments to the proper evaluation
aLzy2(__1) -> 1st argument of the outer map <=> x
aLzy (__1) -> 1st argument of the middle map <=> y
__1 -> 1st argument of the inner map <=> z
Dynamic scoping also means that you can build the closure outside the
OBJ fun = fun3(aLzy2(__1), aLzy(__1), __1);
gmap(gmap(gmap(fun, zs), ys), xs);
is also valid (and impossible in Haskell AFAIK).
It's not impossible. Your closure can be a stateful computation:

myClosure = do
x <- gets var1
y <- gets var2
return (x+y)

In can also alter that surrounding state this way. Adding the
continuation monad it can even escape into its current context:

myClosure escape = do
x <- lift get
when (x == 2) (escape True)
return False

The 'escape' function may be a continuation, so the caller can instruct
this function to escape anywhere he wants, if the state happens to be 2.
I use this often to escape from 'forever' computations to a higher
context (which may even be unknown at that point).

I don't think that you can construct any control structure in C, which
can't be expressed easily in Haskell.


Greets
Ertugrul
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://blog.ertes.de/
Paul Rubin
2010-01-28 06:43:35 UTC
Permalink
Post by Ertugrul Söylemez
I don't think that you can construct any control structure in C, which
can't be expressed easily in Haskell.
Interrupt handler?
Ertugrul Söylemez
2010-01-28 07:41:08 UTC
Permalink
Post by Paul Rubin
Post by Ertugrul Söylemez
I don't think that you can construct any control structure in C,
which can't be expressed easily in Haskell.
Interrupt handler?
That's not a control structure. In fact it's rather an "out of control"
structure. How you handle interrupts depends on the context. If you're
using an operating system, you can use signal handlers or operating
system functions for that. Some interrupts are converted to exceptions
in many languages. There is no difference to C here, except that you
don't have exceptions in C and you can exploit Haskell's concurrency
system, which is also missing in C.

If instead you're _writing_ an operating system, it depends on what your
hardware abstractions look like. See House [1] for an example. So yes,
these things are well possible to do in Haskell.

[1] http://programatica.cs.pdx.edu/House/


Greets
Ertugrul
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://blog.ertes.de/
ld
2010-01-28 11:25:52 UTC
Permalink
Post by Ertugrul Söylemez
Post by ld
The problem is not garbage collection.  It just makes it even more
complicated.  C is missing some very important high level control
constructs, most notably closures.  The only functional programming
you can do in C is continuation passing style, which is already an
improvement over the usual purely imperative style.  You get some
limited, but safe resource management that way.
<http://blog.ertes.de/2009/02/continuations-for-secure-code.html>.
That article builds on the just-for-fun article, which started this
thread, and turns it into something actually useful.
you should remove "This is impossible in C" from the last line of your
article since with my C lib, I use closures as I would in FP. For
    fmap (\x -> fmap (\y -> fmap (\z -> fun3 x y z) zs) ys) xs
    gmap(gmap(gmap(fun3(aLzy2(__1), aLzy(__1), __1), zs), ys), xs)
Of course you can always write an interpreter for a richer language.
That's not really 'doing it in C'.  Just look at glib, which implements
a complete object oriented language on top of C.  You're developing in
your higher language, which is expressed in terms of C.
Yes, that is a DSL but more general than usually done since its goal
is to extend the programming paradigms available in C. So for you, the
hundred of so DSL developed on top of Haskell are not Haskell?
Text.Printf is not Haskell? Yes, DSL are usually hackish, but there is
good advantage to stay with the same language.
Post by Ertugrul Söylemez
Post by ld
The main difference is that Haskell closures have lexical scoping and
lazy evaluation while COS closures have dynamic scoping (placeholders)
and C has strict evaluation. This is why you need to delay the
evaluation of the closure' arguments to the proper evaluation
aLzy2(__1) -> 1st argument of the outer  map <=> x
aLzy (__1) -> 1st argument of the middle map <=> y
      __1  -> 1st argument of the inner  map <=> z
Dynamic scoping also means that you can build the closure outside the
OBJ fun = fun3(aLzy2(__1), aLzy(__1), __1);
gmap(gmap(gmap(fun, zs), ys), xs);
is also valid (and impossible in Haskell AFAIK).
  myClosure = do
    x <- gets var1
    y <- gets var2
    return (x+y)
But then you have to encapsulate fmap elements into the State monad
since you use is as a kind of placeholder...
Post by Ertugrul Söylemez
In can also alter that surrounding state this way.  Adding the
  myClosure escape = do
    x <- lift get
    when (x == 2) (escape True)
    return False
The 'escape' function may be a continuation, so the caller can instruct
this function to escape anywhere he wants, if the state happens to be 2.
I use this often to escape from 'forever' computations to a higher
context (which may even be unknown at that point).
Yep, this is the way Haskell manage exception AFAIK.
Post by Ertugrul Söylemez
I don't think that you can construct any control structure in C, which
can't be expressed easily in Haskell.
you mean something like:

defmethod(OBJ, ifThenElse, TrueFalse, Functor, Functor)
retmethod(_1 == True ? geval(_2) : geval(_3));
endmethod

The second expression (held by _3) remains unevaluated if the boolean
(_1) is False. Comparing to Haskell, you have to force laziness as in
the previous example to break strict evaluation of C. But this is also
true in almost all language except haskell (e.g. scheme).

regards,

ld.
Stefan Ram
2010-01-28 18:01:56 UTC
Permalink
Post by Ertugrul Söylemez
Of course you can always write an interpreter for a richer language.
That's not really 'doing it in C'.
Yes, that was also my point.

The assignment to »teach C« usually is /not/ fulfilled by
teaching to create functions as

gmap(gmap(gmap(fun3(aLzy2(__1), aLzy(__1), __1), zs), ys), xs)

although this is a part of a C program.

But to teach C, one usually writes programs using only those
concepts of the language that come »out of the box«, i.e.,
are available from an (from every) implementation of C
according to ISO/IEC 9899:1999 (E).

For example, I would teach Linux system calls in C only iff
the assignment is not »teach C«, but »teach Linux system
programming in C«. However, I /do/ include some examples
showing how third party libraries can be employed in own
projects, but otherwise, I do not make the source code
depending on them.
ld
2010-01-28 20:09:26 UTC
Permalink
Post by Ertugrul Söylemez
Of course you can always write an interpreter for a richer language.
That's not really 'doing it in C'.
  Yes, that was also my point.
There is a strong difference between an interpreter, a preprocessor
and an embedded DSL.
  The assignment to »teach C« usually is /not/ fulfilled by
  teaching to create functions as
gmap(gmap(gmap(fun3(aLzy2(__1), aLzy(__1), __1), zs), ys), xs)
  although this is a part of a C program.
The statement was that closures cannot be built/used in C. I agree
that explaining the code above is beyond an advanced course on C, but
nevertheless it is possible in C.
Stefan Ram
2010-01-28 20:46:14 UTC
Permalink
Post by ld
The statement was that closures cannot be built/used in C. I agree
that explaining the code above is beyond an advanced course on C, but
nevertheless it is possible in C.
When given /only/ a C implementation, one needs a lot of
effort to build such a library and then use it. One does not
need this effort when using a language where these features
are already part of the language. So, yes, it is possible in
C, but might be more effort.

You might say that one does not need to implement those
features oneself, but can use a third-party library »L« for it.
But then, the basis for development would not be »C«, but »C+L«.
Nothing is wrong with using »C+L« as a basis, but it should
just not be called »C«, but »C+L«.
Nick
2010-01-28 08:26:50 UTC
Permalink
Post by Ertugrul Söylemez
Post by Paul Rubin
Yes, the whole point of my post is that C usually does /not have/
a GC. So I infer that functional programming, therefore, is
difficult or nearly impossible (beyond a certain level of
complexity) in C.
The functional programming would only work on a certain class of
objects within the C program, that are collected by an internal gc.
Sometimes what this leads to is called "Greenspun's Tenth Law" ;-).
There are also so-called conservative gc's for C and C++ (that treat
all data words as possible heap pointers) but at least as a matter of
principle, those can be considered unsatisfying.
Anyway I came late into this thread, but I don't think anyone was
proposing to embed Haskell as cpp macros or anything like that ;-).
The idea is just that it's possible for one's C programs to be
influenced by functional style, and to implement some nontrivial
functional constructs through a few coding disciplines supported by
some utility functions.
The problem is not garbage collection. It just makes it even more
complicated. C is missing some very important high level control
constructs, most notably closures. The only functional programming you
can do in C is continuation passing style, which is already an
improvement over the usual purely imperative style. You get some
limited, but safe resource management that way.
<http://blog.ertes.de/2009/02/continuations-for-secure-code.html>.
That article builds on the just-for-fun article, which started this
thread, and turns it into something actually useful.
Commenting there is so painful (the comment editor embedded in the page
doesn't recognise arrow keys!) I'll reply here instead!

It's an interesting approach, and I can certainly see its value in a
structure that requires a lot of specialised initialisation and
destruction. You could replace:

struct foo *foop = Create_Foo_Structure();
lots-and-lots-of-code-using foop
Release_Foo_Structure(foop)

with

withFoo(dofoopstuff);

but, of course, you have to create dofoopstuff(struct foo *foop) before
you can do that, and in that case writing:

struct foo *foop = Create_Foo_Structure();
dofoopstuff(foop);
Release_Foo_Structure(foop)

does the same job, and you aren't likely to forget to release it when
it's only two lines from creation.

And that's where I think this fails. If this is the only benefit you
get (in C obviously - I know some of the stuff you can do in a better
framework) then it doesn't seem to give anything more than a programming
discipline that says:
- remove anything that uses an allocated structure (including a file
pointer) into a separate function.
- call the function immediately between allocation and release of the
structures, and don't place /any/ other code in there.

Still a neat idea, but I'm not convinced it normally has any practical
value.
--
Online waterways route planner | http://canalplan.eu
Plan trips, see photos, check facilities | http://canalplan.org.uk
Ertugrul Söylemez
2010-01-30 04:56:19 UTC
Permalink
Post by Nick
Post by Ertugrul Söylemez
The problem is not garbage collection. It just makes it even more
complicated. C is missing some very important high level control
constructs, most notably closures. The only functional programming
you can do in C is continuation passing style, which is already an
improvement over the usual purely imperative style. You get some
limited, but safe resource management that way.
<http://blog.ertes.de/2009/02/continuations-for-secure-code.html>.
That article builds on the just-for-fun article, which started this
thread, and turns it into something actually useful.
Commenting there is so painful (the comment editor embedded in the
page doesn't recognise arrow keys!) I'll reply here instead!
As soon as my own blog software is up and running, I'll go away from
Blogger anyway, so I really prefer comments here.
Post by Nick
It's an interesting approach, and I can certainly see its value in a
structure that requires a lot of specialised initialisation and
struct foo *foop = Create_Foo_Structure();
lots-and-lots-of-code-using foop
Release_Foo_Structure(foop)
with
withFoo(dofoopstuff);
but, of course, you have to create dofoopstuff(struct foo *foop)
struct foo *foop = Create_Foo_Structure();
dofoopstuff(foop);
Release_Foo_Structure(foop)
does the same job, and you aren't likely to forget to release it when
it's only two lines from creation.
That's a general problem of the way C programmers think. Yes, if you
need it only once, you are faster just writing it out. But the point
here is not efficiency, it's safety! It's specifically that "you aren't
likely to forget" part of your reasoning, which is the big problem.
With that support function at hand, you _will not_ forget, and that's a
great advantage.
Post by Nick
And that's where I think this fails. If this is the only benefit you
get (in C obviously - I know some of the stuff you can do in a better
framework) then it doesn't seem to give anything more than a
- remove anything that uses an allocated structure (including a file
pointer) into a separate function.
- call the function immediately between allocation and release of the
structures, and don't place /any/ other code in there.
Still a neat idea, but I'm not convinced it normally has any practical
value.
This is the only benefit, yes. But it's not a small benefit. It will
help make C code safer. It's just that I'm afraid someone needs to drop
this into a somewhat large library. Otherwise nobody will use it.


Greets
Ertugrul
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://blog.ertes.de/
Nick
2010-01-30 11:19:49 UTC
Permalink
Post by Ertugrul Söylemez
Post by Nick
Post by Ertugrul Söylemez
The problem is not garbage collection. It just makes it even more
complicated. C is missing some very important high level control
constructs, most notably closures. The only functional programming
you can do in C is continuation passing style, which is already an
improvement over the usual purely imperative style. You get some
limited, but safe resource management that way.
<http://blog.ertes.de/2009/02/continuations-for-secure-code.html>.
That article builds on the just-for-fun article, which started this
thread, and turns it into something actually useful.
Commenting there is so painful (the comment editor embedded in the
page doesn't recognise arrow keys!) I'll reply here instead!
As soon as my own blog software is up and running, I'll go away from
Blogger anyway, so I really prefer comments here.
Post by Nick
It's an interesting approach, and I can certainly see its value in a
structure that requires a lot of specialised initialisation and
struct foo *foop = Create_Foo_Structure();
lots-and-lots-of-code-using foop
Release_Foo_Structure(foop)
with
withFoo(dofoopstuff);
but, of course, you have to create dofoopstuff(struct foo *foop)
struct foo *foop = Create_Foo_Structure();
dofoopstuff(foop);
Release_Foo_Structure(foop)
does the same job, and you aren't likely to forget to release it when
it's only two lines from creation.
That's a general problem of the way C programmers think.
Rather, I think, with the way people think when they are programming in
C. Because of the way C works we are limited to just doing this.
Post by Ertugrul Söylemez
Yes, if you
need it only once, you are faster just writing it out. But the point
here is not efficiency, it's safety! It's specifically that "you aren't
likely to forget" part of your reasoning, which is the big problem.
With that support function at hand, you _will not_ forget, and that's a
great advantage.
In this discussion I'm not actually that bothered about efficiency -
either in terms of programmer effort or execution. I'm more bothered
about benefits traded off against drawbacks.

To me, there's a big drawback here in that you end up splitting what may
well conceptually be a single piece of code into multiple functions. If
you could stick literal functions in the call, for example, you could
put three line sequences that need a file pointer inside the "with
pointer" call. But in C you can't.

So you are going to end up with your logical block of code scattered
into lots of little bits.

That to me seems a big drawback. You say - correctly - that you are
less likely to forget to free the resource. I sort of agree, but - in
my C programming experience - you tend to forget to release the resource
(or, far worse, release it twice) when you have the code all in one
block.
Post by Ertugrul Söylemez
Post by Nick
And that's where I think this fails. If this is the only benefit you
get (in C obviously - I know some of the stuff you can do in a better
framework) then it doesn't seem to give anything more than a
- remove anything that uses an allocated structure (including a file
pointer) into a separate function.
- call the function immediately between allocation and release of the
structures, and don't place /any/ other code in there.
Still a neat idea, but I'm not convinced it normally has any practical
value.
This is the only benefit, yes. But it's not a small benefit. It will
help make C code safer. It's just that I'm afraid someone needs to drop
this into a somewhat large library. Otherwise nobody will use it.
And this is where I disagree. Once you've done the breaking the code
into little nuggets then wrapping each with "acquire" and "release" is
going to be simple. You really aren't going to forget to do that
sequence, or put two releases in there. So the rather clumsy syntax
gains you nothing.

I summary, I think that the limitations of C mean that this doesn't give
enough benefits. But you've got me thinking about a hideous generic
"WITH_RESOURCE" macro that takes an acquire function, a function to
call, a release function, and a pile of arguments!
--
Online waterways route planner | http://canalplan.eu
Plan trips, see photos, check facilities | http://canalplan.org.uk
Ertugrul Söylemez
2010-01-31 11:02:12 UTC
Permalink
Post by Nick
Yes, if you need it only once, you are faster just writing it out.
But the point here is not efficiency, it's safety! It's
specifically that "you aren't likely to forget" part of your
reasoning, which is the big problem. With that support function at
hand, you _will not_ forget, and that's a great advantage.
In this discussion I'm not actually that bothered about efficiency -
either in terms of programmer effort or execution. I'm more bothered
about benefits traded off against drawbacks.
To me, there's a big drawback here in that you end up splitting what
may well conceptually be a single piece of code into multiple
functions. If you could stick literal functions in the call, for
example, you could put three line sequences that need a file pointer
inside the "with pointer" call. But in C you can't.
So you are going to end up with your logical block of code scattered
into lots of little bits.
That to me seems a big drawback. You say - correctly - that you are
less likely to forget to free the resource. I sort of agree, but - in
my C programming experience - you tend to forget to release the
resource (or, far worse, release it twice) when you have the code all
in one block.
Indeed, there is little syntactic support, but ...
Post by Nick
Post by Nick
And that's where I think this fails. If this is the only benefit
you get (in C obviously - I know some of the stuff you can do in a
better framework) then it doesn't seem to give anything more than a
programming discipline that says: - remove anything that uses an
allocated structure (including a file pointer) into a separate
function. - call the function immediately between allocation and
release of the structures, and don't place /any/ other code in
there.
Still a neat idea, but I'm not convinced it normally has any
practical value.
This is the only benefit, yes. But it's not a small benefit. It
will help make C code safer. It's just that I'm afraid someone
needs to drop this into a somewhat large library. Otherwise nobody
will use it.
And this is where I disagree. Once you've done the breaking the code
into little nuggets then wrapping each with "acquire" and "release" is
going to be simple. You really aren't going to forget to do that
sequence, or put two releases in there. So the rather clumsy syntax
gains you nothing.
I summary, I think that the limitations of C mean that this doesn't
give enough benefits. But you've got me thinking about a hideous
generic "WITH_RESOURCE" macro that takes an acquire function, a
function to call, a release function, and a pile of arguments!
... that idea is actually great. Yes, a macro should work very well
here. I haven't thought of that.


Greets
Ertugrul
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://blog.ertes.de/
Pascal J. Bourguignon
2010-02-14 14:55:41 UTC
Permalink
Post by Stefan Ram
Post by Paul Rubin
Well sure, but such sharing would be discovered by a tracing gc.
Yes, the whole point of my post is that C usually does
/not have/ a GC. So I infer that functional programming,
therefore, is difficult or nearly impossible (beyond a
certain level of complexity) in C.
When the Lisp Machines had only a few megaconses of memory, if not half
a megacons, I've been told they could run for a week without needing a
garbage collection, and people just rebooted them once a week to avoid
it.

Well, next month I'll buy a PC, a PERSONAL computer with 24 GB ram, or
3 Gconses. I guess it could run without a garbage collection for a
month!

Perhaps today, for short lived C processes, you just don't have to care
about free anymore. Just malloc, and exit.
--
__Pascal Bourguignon__
http://www.informatimago.com
Ertugrul Söylemez
2010-02-14 23:22:32 UTC
Permalink
Post by Pascal J. Bourguignon
Post by Paul Rubin
Well sure, but such sharing would be discovered by a tracing gc.
Yes, the whole point of my post is that C usually does /not have/
a GC. So I infer that functional programming, therefore, is
difficult or nearly impossible (beyond a certain level of
complexity) in C.
When the Lisp Machines had only a few megaconses of memory, if not
half a megacons, I've been told they could run for a week without
needing a garbage collection, and people just rebooted them once a
week to avoid it.
Well, next month I'll buy a PC, a PERSONAL computer with 24 GB ram, or
3 Gconses. I guess it could run without a garbage collection for a
month!
Perhaps today, for short lived C processes, you just don't have to
care about free anymore. Just malloc, and exit.
This reasoning is used by many PHP programmers today. It's one reason
why PHP programs are so error-prone and why PHP errors are often hard to
find. There is no excuse for unfreed resources, particularly in
languages, which are unsafe by nature, like C and PHP. It _will_ get
you into trouble sooner or later.

Note that in both C and PHP most results are computed solely through
side-effects and are never obtained in a direct fashion. It is very
important that you get these side effects under control, even if your
process is short-lived. My proposal is one way of doing this.

The better way is to avoid using side effects altogether, but that's
close to impossible in C (and PHP).


Greets
Ertugrul
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://blog.ertes.de/
Hyman Rosen
2010-02-16 15:29:12 UTC
Permalink
Post by Ertugrul Söylemez
Post by Pascal J. Bourguignon
Perhaps today, for short lived C processes, you just don't have to
care about free anymore. Just malloc, and exit.
This reasoning is used by many PHP programmers today. It's one reason
why PHP programs are so error-prone and why PHP errors are often hard to
find. There is no excuse for unfreed resources, particularly in
languages, which are unsafe by nature, like C and PHP. It _will_ get
you into trouble sooner or later.
There is generally no need to free resources just before
program exit, because the operating system will do that
for you - a program which spends a bunch of time freeing
every allocated object and then exits has just wasted all
of that time. It's important to free resources which can
be allocated in an unbounded fashion. That is, a program
should act like a garbage collector - unreachable objects
must be reclaimed, but reachable ones don't need to be.
Andrew Poelstra
2010-02-16 15:45:49 UTC
Permalink
Post by Hyman Rosen
Post by Ertugrul Söylemez
Post by Pascal J. Bourguignon
Perhaps today, for short lived C processes, you just don't have to
care about free anymore. Just malloc, and exit.
This reasoning is used by many PHP programmers today. It's one reason
why PHP programs are so error-prone and why PHP errors are often hard to
find. There is no excuse for unfreed resources, particularly in
languages, which are unsafe by nature, like C and PHP. It _will_ get
you into trouble sooner or later.
There is generally no need to free resources just before
program exit, because the operating system will do that
What basis do you have for this absurd claim...
Post by Hyman Rosen
for you - a program which spends a bunch of time freeing
every allocated object and then exits has just wasted all
...or this one? The OS, if it frees your memory, needs just
as much CPU time as your code would, had you chosen to make
it portable to machines who are not your mother.
Post by Hyman Rosen
of that time. It's important to free resources which can
be allocated in an unbounded fashion. That is, a program
should act like a garbage collector - unreachable objects
must be reclaimed, but reachable ones don't need to be.
io_x
2010-02-16 16:00:17 UTC
Permalink
Post by Andrew Poelstra
Post by Hyman Rosen
Post by Ertugrul Söylemez
Post by Pascal J. Bourguignon
Perhaps today, for short lived C processes, you just don't have to
care about free anymore. Just malloc, and exit.
This reasoning is used by many PHP programmers today. It's one reason
why PHP programs are so error-prone and why PHP errors are often hard to
find. There is no excuse for unfreed resources, particularly in
languages, which are unsafe by nature, like C and PHP. It _will_ get
you into trouble sooner or later.
There is generally no need to free resources just before
program exit, because the operating system will do that
What basis do you have for this absurd claim...
Post by Hyman Rosen
for you - a program which spends a bunch of time freeing
every allocated object and then exits has just wasted all
...or this one? The OS, if it frees your memory, needs just
as much CPU time as your code would,
this should be wrong, bacause OS should free
all big arrays of chars
that give to the malloc function (heap) instead you
have to free all the sub arrays of these big arrays
Post by Andrew Poelstra
had you chosen to make
it portable to machines who are not your mother.
Post by Hyman Rosen
of that time. It's important to free resources which can
be allocated in an unbounded fashion. That is, a program
should act like a garbage collector - unreachable objects
must be reclaimed, but reachable ones don't need to be.
Hyman Rosen
2010-02-16 15:57:17 UTC
Permalink
Post by Andrew Poelstra
Post by Hyman Rosen
There is generally no need to free resources just before
program exit, because the operating system will do that
What basis do you have for this absurd claim...
Experience. Logic.
Post by Andrew Poelstra
Post by Hyman Rosen
for you - a program which spends a bunch of time freeing
every allocated object and then exits has just wasted all
...or this one? The OS, if it frees your memory, needs just
as much CPU time as your code would, had you chosen to make
it portable to machines who are not your mother.
No. A program which insists on freeing its allocated memory
does so by going through each allocated object individually
freeing it. This can involve large amounts of time when the
program has allocated millions of objects in its data
structures. Upon program exit, the operating system reclaims
all memory allocated by the program in one action, and that
takes essentially no time at all.

This is not even to mention that when a program frees allocated
memory through 'free', it is usually doing nothing but placing
that memory back onto an internal data structure so that it may
be allocated again. It is seldom returned to the operating system
because it was not allocated that way; allocators request large
blocks and break them up internally to the program.
Andrew Poelstra
2010-02-16 16:25:06 UTC
Permalink
Post by Hyman Rosen
Post by Andrew Poelstra
Post by Hyman Rosen
There is generally no need to free resources just before
program exit, because the operating system will do that
What basis do you have for this absurd claim...
Experience. Logic.
Experience, perhaps, if your experience is truly that limited.

Logic, no.
Post by Hyman Rosen
Post by Andrew Poelstra
Post by Hyman Rosen
for you - a program which spends a bunch of time freeing
every allocated object and then exits has just wasted all
...or this one? The OS, if it frees your memory, needs just
as much CPU time as your code would, had you chosen to make
it portable to machines who are not your mother.
No. A program which insists on freeing its allocated memory
does so by going through each allocated object individually
freeing it. This can involve large amounts of time when the
program has allocated millions of objects in its data
structures. Upon program exit, the operating system reclaims
all memory allocated by the program in one action, and that
takes essentially no time at all.
Perhaps you should write memory managers, if you can really
reclaim millions of individually allocated blocks in a single
action. (Though given your belief there is no need to do so,
I have an idea of how it might work...)
Post by Hyman Rosen
This is not even to mention that when a program frees allocated
memory through 'free', it is usually doing nothing but placing
that memory back onto an internal data structure so that it may
be allocated again. It is seldom returned to the operating system
because it was not allocated that way; allocators request large
blocks and break them up internally to the program.
Allocators allocate. To ascribe anything more to them is
presumptuous and unjustified.
toby
2010-02-16 15:57:39 UTC
Permalink
Post by Andrew Poelstra
Post by Hyman Rosen
Post by Pascal J. Bourguignon
Perhaps today, for short lived C processes, you just don't have to
care about free anymore.  Just malloc, and exit.
This reasoning is used by many PHP programmers today.  It's one reason
why PHP programs are so error-prone and why PHP errors are often hard to
find.  There is no excuse for unfreed resources, particularly in
languages, which are unsafe by nature, like C and PHP.  It _will_ get
you into trouble sooner or later.
There is generally no need to free resources just before
program exit, because the operating system will do that
What basis do you have for this absurd claim...
Post by Hyman Rosen
for you - a program which spends a bunch of time freeing
every allocated object and then exits has just wasted all
...or this one? The OS, if it frees your memory, needs just
as much CPU time as your code would,
AFAICT Hyman is correctly pointing out that meticulous free'ing of
individual allocations is potentially expensive and pointless
maintenance, if the process is terminating. The operating system does
not do the equivalent free'ing operations, but rather, the heap just
goes away, at no cost.
Post by Andrew Poelstra
had you chosen to make
it portable to machines who are not your mother.
Post by Hyman Rosen
of that time. It's important to free resources which can
be allocated in an unbounded fashion. That is, a program
should act like a garbage collector - unreachable objects
must be reclaimed, but reachable ones don't need to be.
Seebs
2010-02-16 17:09:02 UTC
Permalink
Post by Andrew Poelstra
...or this one? The OS, if it frees your memory, needs just
as much CPU time as your code would, had you chosen to make
it portable to machines who are not your mother.
Not generally true.

Imagine that I have allocated a linked list of a million nodes, each
pointing to 1024 bytes of data. On a typical malloc implementation,
freeing these will result in no fewer than two million separate operations,
each of which may also result in complicated operations as the library
consolidates free space, etcetera.

The operating system will simply mark my pages unused -- which it has to do
whether or not I've freed them in terms of the library operation.

The operating system can do it faster because it doesn't need to care about
the internals and bookkeeping of the malloc arena.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-***@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
Andrew Poelstra
2010-02-16 17:18:14 UTC
Permalink
Post by Seebs
Post by Andrew Poelstra
...or this one? The OS, if it frees your memory, needs just
as much CPU time as your code would, had you chosen to make
it portable to machines who are not your mother.
Not generally true.
Imagine that I have allocated a linked list of a million nodes, each
pointing to 1024 bytes of data. On a typical malloc implementation,
freeing these will result in no fewer than two million separate operations,
each of which may also result in complicated operations as the library
consolidates free space, etcetera.
The operating system will simply mark my pages unused -- which it has to do
whether or not I've freed them in terms of the library operation.
The operating system can do it faster because it doesn't need to care about
the internals and bookkeeping of the malloc arena.
But you would need to have found a gigabyte of contiguous memory
dedicated to your program for this to be simple - otherwise you
would be in memory space also used by other applications, and
bookkeeping does matter.
Seebs
2010-02-16 17:30:29 UTC
Permalink
Post by Andrew Poelstra
But you would need to have found a gigabyte of contiguous memory
dedicated to your program for this to be simple - otherwise you
would be in memory space also used by other applications, and
bookkeeping does matter.
It's rather more complicated on most systems. But, in general, there is
nothing you can do inside the program that will reduce the total amount of
bookkeeping that needs to be done on exit, and simply not freeing anything
(as in free()) does not increase the amount of bookkeeping that needs to be
done.

The closest you could get is that some implementations may be such that,
once you've freed all the storage allocated within a given block of
OS-provided storage, you can return that block to the OS, meaning that it does
the bookkeeping to free that block right away, rather than having to do it
after you exit, but this can't make things any *better*, and may make things
*worse*. (For instance, if you end up releasing a block between two other
blocks -- the OS might have to do extra work there that it wouldn't if all
three were released at once.)

Note that "contiguous" is pretty much irrelevant on most modern systems,
as program address spaces are all virtual anyway.

So the fact remains: In general, on all the major platforms in use, there is
no possible case where calling free() a lot right before termination can make
things any better, and there are many obvious cases where they can make things
worse by orders of magnitude.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-***@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
Andrew Poelstra
2010-02-16 18:06:42 UTC
Permalink
Post by Seebs
So the fact remains: In general, on all the major platforms in use, there is
no possible case where calling free() a lot right before termination can make
things any better, and there are many obvious cases where they can make things
worse by orders of magnitude.
Leaving aside OS's that do not or cannot cleanup, because to the
best of my knowledge no "big" OS's are in use that are like that:


I am going to disagree with you on this point: on my system, if a program
cleans up its own memory, I see a delay between clicking the X (or Ctrl+C,
or whatever) and the program actually dying. During this time it does its
cleanup, plays with the hard drive and whatever. Meanwhile, I am free to
do other things.

However, if the program just dies, I see a quick and painless exit. And
then the kernel takes over to do cleanup, which has a higher priority than
the dead program. And while it's cleaning up, the rest of my system is
sluggish, even if only for a second.

Better the cleanup be done with the program's CPU slices than my UI's,
I say.


Andrew
jacob navia
2010-02-16 17:38:40 UTC
Permalink
Post by Andrew Poelstra
Post by Hyman Rosen
Post by Ertugrul Söylemez
Post by Pascal J. Bourguignon
Perhaps today, for short lived C processes, you just don't have to
care about free anymore. Just malloc, and exit.
This reasoning is used by many PHP programmers today. It's one reason
why PHP programs are so error-prone and why PHP errors are often hard to
find. There is no excuse for unfreed resources, particularly in
languages, which are unsafe by nature, like C and PHP. It _will_ get
you into trouble sooner or later.
There is generally no need to free resources just before
program exit, because the operating system will do that
What basis do you have for this absurd claim...
"Absurd claim"

ALL OS do that. If not, they would run a single leaking program and
would die immediately.

I have never seen an OS that did not do that.
Post by Andrew Poelstra
Post by Hyman Rosen
for you - a program which spends a bunch of time freeing
every allocated object and then exits has just wasted all
...or this one? The OS, if it frees your memory, needs just
as much CPU time as your code would,
No, in most cases it will use a single free() call
since all memory allocated for a process will be in
a single heap.
Post by Andrew Poelstra
had you chosen to make
it portable to machines who are not your mother.
Nonsense
Andrew Poelstra
2010-02-16 17:51:25 UTC
Permalink
Post by jacob navia
Post by Andrew Poelstra
Post by Hyman Rosen
Post by Ertugrul Söylemez
Post by Pascal J. Bourguignon
Perhaps today, for short lived C processes, you just don't have to
care about free anymore. Just malloc, and exit.
This reasoning is used by many PHP programmers today. It's one reason
why PHP programs are so error-prone and why PHP errors are often hard to
find. There is no excuse for unfreed resources, particularly in
languages, which are unsafe by nature, like C and PHP. It _will_ get
you into trouble sooner or later.
There is generally no need to free resources just before
program exit, because the operating system will do that
What basis do you have for this absurd claim...
"Absurd claim"
ALL OS do that. If not, they would run a single leaking program and
would die immediately.
Not immediately. And if this was an embedded system, eventually
the watchdog would kick and the programmer would (hopefully)
realize that his code was buggy and needed fixing.
Post by jacob navia
I have never seen an OS that did not do that.
Again, in embedded systems many OS's choose not to support
bad programming. There are no users downloading garbage
from the Internet and blithely expecting it to run despite
barely being compilable.
Post by jacob navia
Post by Andrew Poelstra
Post by Hyman Rosen
for you - a program which spends a bunch of time freeing
every allocated object and then exits has just wasted all
...or this one? The OS, if it frees your memory, needs just
as much CPU time as your code would,
No, in most cases it will use a single free() call
since all memory allocated for a process will be in
a single heap.
But in "most cases" there is so little memory allocated
that the equivalent free() calls will take practically
zero time anyway. In the cases that a ton of memory is
used, then the OS has its work set out for it whether or
not the code is explicitly calling free().
Post by jacob navia
Post by Andrew Poelstra
had you chosen to make
it portable to machines who are not your mother.
Seebs
2010-02-16 17:53:26 UTC
Permalink
Post by jacob navia
ALL OS do that. If not, they would run a single leaking program and
would die immediately.
I have never seen an OS that did not do that.
Have you never seen Windows 3.1 or DOS? Both had C implementations where
malloc() could reserve memory that lived past program termination. I think
the Amiga did too.

I mean, not saying that it's still a major issue for most people. But there
certainly did exist such machines, and some people may care about them.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-***@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
Richard Heathfield
2010-02-15 07:25:46 UTC
Permalink
Pascal J. Bourguignon wrote:

<snip>
Post by Pascal J. Bourguignon
Perhaps today, for short lived C processes, you just don't have to care
about free anymore. Just malloc, and exit.
Perhaps that's the reasoning used by the Firefox guys. When running
Win32, I choose Firefox rather than IE, but that's becoming a harder
decision than it should be. The other day, I peeked at Task Manager and
found that Firefox (which I rarely leave running for long because I know
it's a hog) had grabbed well over half a gigabyte of memory. I rarely
have more than one window open, and rarely more than one (perhaps two or
three, and very occasionally up to a dozen) tabs in that window. Half a
gigabyte. It's just ludicrous. And it slows everything else down,
because less available RAM means more swapping, and more swapping means
more disk access.

Stupid stupid stupid. Don't follow their bad example. Write code
properly. *Please*.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
santosh
2010-02-15 07:57:58 UTC
Permalink
Post by v***@gmail.com
<snip>
Post by Pascal J. Bourguignon
Perhaps today, for short lived C processes, you just don't have to care
about free anymore. Just malloc, and exit.
Perhaps that's the reasoning used by the Firefox guys. When running
Win32, I choose Firefox rather than IE, but that's becoming a harder
decision than it should be. The other day, I peeked at Task Manager and
found that Firefox (which I rarely leave running for long because I know
it's a hog) had grabbed well over half a gigabyte of memory. I rarely
have more than one window open, and rarely more than one (perhaps two or
three, and very occasionally up to a dozen) tabs in that window. Half a
gigabyte. It's just ludicrous.
Are you sure that's physical memory? During normal use (similar to
what you describe), Firefox does grab over 500 megabytes of virtual
memory, but usually only about a couple of hundred Mb of physical
memory. Atleast, that's the usage pattern for me here. And I'm running
Linux, but I suspect memory usage is quite similar in Windows too.
Post by v***@gmail.com
And it slows everything else down,
because less available RAM means more swapping, and more swapping means
more disk access.
I notice though that all popular graphical browsers have roughly
comparable memory consumption. Certainly, in my experience, Firefox,
SeaMonkey, Galeon, Chrome. Opera tends to consume about 50 Mb less
than these.
Post by v***@gmail.com
Stupid stupid stupid. Don't follow their bad example. Write code
properly. *Please*.
I wouldn't single out Firefox though. The fact that all major
graphical browsers consume roughly similar amounts of memory for
similar use seems to show that either there's a good reason or that
fine grained resource management gets unmanageably complicated in very
large software projects.

It'd be interesting to see what difference a garbage collector does to
a program like Firefox (assuming it doesn't already have one inside.)
It would give us a clue as to whether the memory hogging is due to
tangible requirements or just accumulation of expired objects.
Richard Heathfield
2010-02-15 09:15:15 UTC
Permalink
<snip>
Post by santosh
Half a gigabyte. It's just ludicrous.
Are you sure that's physical memory?
Well, of course your asking the question makes me doubt the answer, and
I lack the time to check in more detail right now, BUT...
Post by santosh
During normal use (similar to
what you describe), Firefox does grab over 500 megabytes of virtual
memory, but usually only about a couple of hundred Mb of physical
memory.
*ONLY* a couple of hundred megabytes? Can you hear yourself? :-)
Post by santosh
Atleast, that's the usage pattern for me here. And I'm running
Linux,
Likewise. I actually use both OSs (on different machines).

<snip>
Post by santosh
I notice though that all popular graphical browsers have roughly
comparable memory consumption. Certainly, in my experience, Firefox,
SeaMonkey, Galeon, Chrome. Opera tends to consume about 50 Mb less
than these.
Yes, but they're only Web browsers. They're not supposed to hold the
entire Internet in RAM!
Post by santosh
Stupid stupid stupid. Don't follow their bad example. Write code
properly. *Please*.
I wouldn't single out Firefox though. The fact that all major
graphical browsers consume roughly similar amounts of memory for
similar use seems to show that either there's a good reason or that
fine grained resource management gets unmanageably complicated in very
large software projects.
It'd be nice if someone with too much time on their hands could write a
"lite" Web browser that guarantees never to use more than, say, 64MB of
memory. If that means some hard decisions on feature selection, so be it.

(There is a Linux distro - I think it's "Puppy" BICBW - that restricts
itself to no more than 50MB of disk space. Not the same thing as RAM,
obviously, but it's a similar idea.)

<snip>
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
Willem
2010-02-15 17:43:00 UTC
Permalink
Richard Heathfield wrote:
) santosh wrote:
)> Are you sure that's physical memory?
)
) Well, of course your asking the question makes me doubt the answer, and
) I lack the time to check in more detail right now, BUT...
)
) > During normal use (similar to
)> what you describe), Firefox does grab over 500 megabytes of virtual
)> memory, but usually only about a couple of hundred Mb of physical
)> memory.
)
) *ONLY* a couple of hundred megabytes? Can you hear yourself? :-)

<snip>

Isn't that just the in-memory cache though ?
Could very well even be a config option.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
Andrew Poelstra
2010-02-15 18:19:37 UTC
Permalink
Post by Willem
)> Are you sure that's physical memory?
)
) Well, of course your asking the question makes me doubt the answer, and
) I lack the time to check in more detail right now, BUT...
)
) > During normal use (similar to
)> what you describe), Firefox does grab over 500 megabytes of virtual
)> memory, but usually only about a couple of hundred Mb of physical
)> memory.
)
) *ONLY* a couple of hundred megabytes? Can you hear yourself? :-)
<snip>
Isn't that just the in-memory cache though ?
Could very well even be a config option.
That might explain why it also takes ten seconds to load, while
Opera takes four and Chrome just over one.

IME since 2.1 (IIRC) Firefox has been progressively slower and
bloatier. The latest version was a slight uptick, but not much.
Post by Willem
SaSW, Willem
jacob navia
2010-01-25 23:05:13 UTC
Permalink
Post by Stefan Ram
Post by Ertugrul Söylemez
I thought it would be funny to try to bring functional
concepts into the C language.
To me, a lack of automatic memory management makes
functional programming difficult in C.
snip...
Post by Stefan Ram
In the end, one might invest more time in thinking about
memory management than about the actual programming problem.
So, I believe, this is the real problem, when one tries
to do functional programming in C.
It depends what "C" you are using.

lcc-win proposes a garbage collector in its standard distribution.
All the problems above are solved with a gc
Stefan Ram
2010-01-25 23:12:51 UTC
Permalink
Post by jacob navia
It depends what "C" you are using.
I thought about something along the lines of
ISO/IEC 9899:1999 (E).
jacob navia
2010-01-25 23:21:53 UTC
Permalink
Post by Stefan Ram
Post by jacob navia
It depends what "C" you are using.
I thought about something along the lines of
ISO/IEC 9899:1999 (E).
The gc is a library, like a graphics library or a network library.

Are you implying that you can't do network programming in C because "network" doesn't appear in the
standard?

The standard doesn't speak a word about graphics either. You can't do graphics in C then?

Your viewpoint of limiting C to what is explicitly said in the standard is just another way of the old:

"You can't do anything serious in C"

and then (implicitly)

"Use C++" or whatever
Keith Thompson
2010-01-25 23:36:23 UTC
Permalink
jacob navia <***@nospam.org> writes:
[...]
Post by jacob navia
Your viewpoint of limiting C to what is explicitly said in the
"You can't do anything serious in C"
and then (implicitly)
"Use C++" or whatever
You wouldn't be waging a campaign against C99, would you?
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Ian Collins
2010-01-26 18:46:38 UTC
Permalink
Post by jacob navia
lcc-win proposes a garbage collector in its standard distribution.
All the problems above are solved with a gc
As they say on the BBC, other distributions with a garbage collector are
available. The Boehm GC has been used on many platforms. It is
distributed with Sun Studio for example.

I don't see other platforms actively promoting it like you do, perhaps
they should? It can be a very useful diagnostic tool as well as a
collector.
--
Ian Collins
Robert Latest
2010-01-27 16:46:09 UTC
Permalink
["Followup-To:" header set to comp.lang.c.]
Post by jacob navia
lcc-win proposes a garbage collector in its standard distribution.
All the problems above are solved with a gc
Why insist on "lcc-win" when the garbage collector can be linked into
any C program on any hosted implementation?

robert
Loading...