Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #136445 > unrolled thread

An enhancement

Started byDavid Kleinecke <dkleinecke@gmail.com>
First post2018-10-08 15:44 -0700
Last post2018-10-15 14:43 +0000
Articles 20 on this page of 60 — 17 participants

Back to article view | Back to comp.lang.c


Contents

  An enhancement David Kleinecke <dkleinecke@gmail.com> - 2018-10-08 15:44 -0700
    Re: An enhancement Ian Collins <ian-news@hotmail.com> - 2018-10-09 11:48 +1300
      Re: An enhancement Spiros Bousbouras <spibou@gmail.com> - 2018-10-08 23:16 +0000
    Re: An enhancement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-10-09 00:30 +0100
      Re: An enhancement David Kleinecke <dkleinecke@gmail.com> - 2018-10-08 17:24 -0700
        Re: An enhancement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-10-09 02:12 +0100
          Re: An enhancement David Kleinecke <dkleinecke@gmail.com> - 2018-10-08 22:42 -0700
            Re: An enhancement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-10-09 14:41 +0100
          Re: An enhancement David Brown <david.brown@hesbynett.no> - 2018-10-09 11:15 +0200
            Re: An enhancement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-10-09 16:09 +0100
              GCC nested functions: deprecated? (Was: An enhancement) gazelle@shell.xmission.com (Kenny McCormack) - 2018-10-09 15:36 +0000
              Re: An enhancement David Brown <david.brown@hesbynett.no> - 2018-10-09 21:01 +0200
          Re: An enhancement Bart <bc@freeuk.com> - 2018-10-09 11:43 +0100
            Re: An enhancement already5chosen@yahoo.com - 2018-10-09 04:08 -0700
              Re: An enhancement Bart <bc@freeuk.com> - 2018-10-09 12:29 +0100
    Re: An enhancement Spiros Bousbouras <spibou@gmail.com> - 2018-10-08 23:37 +0000
      Re: An enhancement David Kleinecke <dkleinecke@gmail.com> - 2018-10-08 17:22 -0700
        Re: An enhancement Ian Collins <ian-news@hotmail.com> - 2018-10-09 13:30 +1300
        Re: An enhancement Spiros Bousbouras <spibou@gmail.com> - 2018-10-09 05:23 +0000
          Re: An enhancement David Kleinecke <dkleinecke@gmail.com> - 2018-10-08 22:50 -0700
          Re: An enhancement Richard Damon <Richard@Damon-Family.org> - 2018-10-09 08:28 -0400
        Re: An enhancement Wouter Verhelst <w@uter.be> - 2018-10-09 14:05 +0200
          C is often used as an "implementation language" for other languages.  (Was: An enhancement) gazelle@shell.xmission.com (Kenny McCormack) - 2018-10-09 13:13 +0000
            Re: C is often used as an "implementation language" for other languages.  (Was: An enhancement) David Brown <david.brown@hesbynett.no> - 2018-10-09 16:51 +0200
          Re: An enhancement Bart <bc@freeuk.com> - 2018-10-09 14:17 +0100
        Re: An enhancement Thiago Adams <thiago.adams@gmail.com> - 2018-10-09 05:20 -0700
          Re: An enhancement David Kleinecke <dkleinecke@gmail.com> - 2018-10-09 11:33 -0700
            Re: An enhancement Thiago Adams <thiago.adams@gmail.com> - 2018-10-09 13:41 -0700
      Re: An enhancement Bart <bc@freeuk.com> - 2018-10-09 12:35 +0100
    Re: An enhancement Wouter Verhelst <w@uter.be> - 2018-10-09 14:04 +0200
      Re: An enhancement Spiros Bousbouras <spibou@gmail.com> - 2018-10-09 12:29 +0000
        Re: An enhancement Wouter Verhelst <w@uter.be> - 2018-10-09 19:50 +0200
        Re: An enhancement queequeg@trust.no1 (Queequeg) - 2018-10-15 09:19 +0000
          Re: An enhancement already5chosen@yahoo.com - 2018-10-15 03:07 -0700
            Re: An enhancement Ian Collins <ian-news@hotmail.com> - 2018-10-15 23:18 +1300
              Re: An enhancement already5chosen@yahoo.com - 2018-10-15 03:39 -0700
                Re: An enhancement David Brown <david.brown@hesbynett.no> - 2018-10-15 13:03 +0200
                  Re: An enhancement Bart <bc@freeuk.com> - 2018-10-15 12:15 +0100
                    Re: An enhancement Thiago Adams <thiago.adams@gmail.com> - 2018-10-15 05:20 -0700
                      Re: An enhancement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-10-15 15:39 +0100
                    Re: An enhancement David Brown <david.brown@hesbynett.no> - 2018-10-15 14:36 +0200
                      Re: An enhancement Thiago Adams <thiago.adams@gmail.com> - 2018-10-15 05:59 -0700
                        Re: An enhancement David Brown <david.brown@hesbynett.no> - 2018-10-15 15:08 +0200
                          Re: An enhancement Thiago Adams <thiago.adams@gmail.com> - 2018-10-15 07:25 -0700
                      Re: An enhancement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-10-15 15:44 +0100
                        Re: An enhancement David Kleinecke <dkleinecke@gmail.com> - 2018-10-15 19:02 -0700
                          Re: An enhancement Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-10-16 05:55 +0000
                          Re: An enhancement jameskuyper@alumni.caltech.edu - 2018-10-16 05:37 -0700
                            Re: An enhancement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-10-16 15:11 +0100
                              Re: An enhancement David Kleinecke <dkleinecke@gmail.com> - 2018-10-16 13:33 -0700
                                Re: An enhancement David Kleinecke <dkleinecke@gmail.com> - 2018-10-16 21:27 -0700
                          Re: An enhancement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-10-16 14:57 +0100
                            Re: An enhancement scott@slp53.sl.home (Scott Lurndal) - 2018-10-16 14:24 +0000
                              Re: An enhancement mark.bluemel@gmail.com - 2018-10-16 07:28 -0700
                            Re: An enhancement Bart <bc@freeuk.com> - 2018-10-16 15:25 +0100
              Re: An enhancement Bart <bc@freeuk.com> - 2018-10-15 11:44 +0100
                Re: An enhancement David Brown <david.brown@hesbynett.no> - 2018-10-15 13:08 +0200
            Re: An enhancement Bart <bc@freeuk.com> - 2018-10-15 11:22 +0100
              Re: An enhancement David Brown <david.brown@hesbynett.no> - 2018-10-15 13:01 +0200
                Re: An enhancement Nick Bowler <nbowler@draconx.ca> - 2018-10-15 14:43 +0000

Page 3 of 3 — ← Prev page 1 2 [3]


#136781

FromDavid Brown <david.brown@hesbynett.no>
Date2018-10-15 14:36 +0200
Message-ID<pq21ks$7r5$1@dont-email.me>
In reply to#136779
On 15/10/18 13:15, Bart wrote:
> On 15/10/2018 12:03, David Brown wrote:
>> On 15/10/18 12:39, already5chosen@yahoo.com wrote:
> 
>>> I am not an expert, but would think that majority of experts would
>>> say that 'error' in your example is not lambda.
>>>
>>
>> It /is/ a C++ lambda - there is no doubt about it.  You could, perhaps,
>> argue that it is not a common use of lambdas, or that it is unusual for
>> lambdas to be named in this way - you'd be wrong, I think, but it would
>> at least make sense.
> 
> In that case let me be the first to ask: what's the difference between
> such a thing, and a regular named function?
> 
> (I can see lambdas being used in this fashion (made-up syntax):
> 
>    fn = lambda{|x,y| x*x-y*y};
> 
>    print(fn(10,5));     # output 75
> 
> but the lambda itself is anonymous.)
> 

The lambda itself is indeed anonymous - but you can assign it to an
identifier to give it a name.  In that respect, it is exactly like an
integer constant in C - the number "42" is anonymous and can be used
anonymously "x = y + 42;".  You can also give it a name, "const int
the_answer = 42;" and then use that name "x = y + the_answer;" to get
the same effect.

In the same way, it is common to use lambda functions without bothering
with a name, because you are immediately passing it to another function.
 For example, in gui programming in languages like Python and Javascript
it is popular to pass a lambda to an event handler as the actions to be
carried out when a button is pressed (or whatever) - there is no need
for a named function declared and defined elsewhere.  Other common uses
are to pass a function to an algorithm that steps through a data
structure, or to pass a comparison to a filter or sort algorithm.

However, lambdas can be more than just functions - they are closures,
and can capture local data by reference or value.  The point of that is
not so obvious when you use the lambda as a local function in the same
context, but becomes relevant when it is passed to another function.

<https://en.wikipedia.org/wiki/Closure_%28computer_programming%29>

[toc] | [prev] | [next] | [standalone]


#136782

FromThiago Adams <thiago.adams@gmail.com>
Date2018-10-15 05:59 -0700
Message-ID<f43a0aed-e69b-42cd-bcd4-f4d3fe066379@googlegroups.com>
In reply to#136781
On Monday, October 15, 2018 at 9:36:54 AM UTC-3, David Brown wrote:
..
> However, lambdas can be more than just functions - they are closures,
> and can capture local data by reference or value.  The point of that is
> not so obvious when you use the lambda as a local function in the same
> context, but becomes relevant when it is passed to another function.
> 
> <https://en.wikipedia.org/wiki/Closure_%28computer_programming%29>

The closure is a concept hard to implement in C because 
it needs simultaneously the concept of struct and function.
Something that is together must be implemented
in a sparse way that is much more difficult to understand
and maintain.

For instance, using lambdas:

void Run(void (*callback)(void*), void* data);

int main()
{  
  Run([](void* data){  
    printf("first");
    Run([](void* data){
      printf("second");
    }, 0);     
  }, 0);
}

Now in C:

void Run(void (*callback)(void*), void* data);

static void _lambda_1(void* data){
      printf("second");
    }

static void _lambda_0(void* data){
  
    printf("first");
    Run(_lambda_1, 0);     
  }

int main()
{  
  Run(_lambda_0, 0);
}

I have 3 places to edit to create something
that is logically together and localized.
With captures the problem is worst.

[toc] | [prev] | [next] | [standalone]


#136783

FromDavid Brown <david.brown@hesbynett.no>
Date2018-10-15 15:08 +0200
Message-ID<pq23gh$ide$1@dont-email.me>
In reply to#136782
On 15/10/18 14:59, Thiago Adams wrote:
> On Monday, October 15, 2018 at 9:36:54 AM UTC-3, David Brown wrote:
> ..
>> However, lambdas can be more than just functions - they are closures,
>> and can capture local data by reference or value.  The point of that is
>> not so obvious when you use the lambda as a local function in the same
>> context, but becomes relevant when it is passed to another function.
>>
>> <https://en.wikipedia.org/wiki/Closure_%28computer_programming%29>
> 
> The closure is a concept hard to implement in C because 
> it needs simultaneously the concept of struct and function.
> Something that is together must be implemented
> in a sparse way that is much more difficult to understand
> and maintain.

Agreed.  Closures really need to be supported by the language to be
usable.  But here we are talking about someone who wants to add features
to their C compiler.

[toc] | [prev] | [next] | [standalone]


#136784

FromThiago Adams <thiago.adams@gmail.com>
Date2018-10-15 07:25 -0700
Message-ID<9a575b70-48a6-4e45-a292-a981d9ea6b13@googlegroups.com>
In reply to#136783
On Monday, October 15, 2018 at 10:08:44 AM UTC-3, David Brown wrote:
> On 15/10/18 14:59, Thiago Adams wrote:
> > On Monday, October 15, 2018 at 9:36:54 AM UTC-3, David Brown wrote:
> > ..
> >> However, lambdas can be more than just functions - they are closures,
> >> and can capture local data by reference or value.  The point of that is
> >> not so obvious when you use the lambda as a local function in the same
> >> context, but becomes relevant when it is passed to another function.
> >>
> >> <https://en.wikipedia.org/wiki/Closure_%28computer_programming%29>
> > 
> > The closure is a concept hard to implement in C because 
> > it needs simultaneously the concept of struct and function.
> > Something that is together must be implemented
> > in a sparse way that is much more difficult to understand
> > and maintain.
> 
> Agreed.  Closures really need to be supported by the language to be
> usable.  But here we are talking about someone who wants to add features
> to their C compiler.

The local function feature also would help,
at least to keep everything together.

void F() 
{   
  struct Capture {
     int something;
  };

  struct Capture* capture = { .. };

  void _lambda_1(void* data){ 
      struct Capture* capture = data;
      printf("second"); 
    } 

  void _lambda_0(void* data){  
    struct Capture* capture = data;
    printf("first"); 
    Run(_lambda_1, 0);     
  } 

  Run(_lambda_0, &capture); 
} 

Note that I added a struct for capture.

This keeps everything together.
In case we need to delete the function F
because it will not used anymore them all
relative parts structs and functions will
be deleted together making this code much
more simple to maintain compared with spare
type declaration and functions.

I guess the problem to implement this in C
is to use more memory. (problem for the original design)
I suspect the local functions must be implemented
in memory and then at the end they can be generated on disk.



[toc] | [prev] | [next] | [standalone]


#136787

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-10-15 15:44 +0100
Message-ID<87lg6zl15t.fsf@bsb.me.uk>
In reply to#136781
David Brown <david.brown@hesbynett.no> writes:

> On 15/10/18 13:15, Bart wrote:
>> On 15/10/2018 12:03, David Brown wrote:
>>> On 15/10/18 12:39, already5chosen@yahoo.com wrote:
>> 
>>>> I am not an expert, but would think that majority of experts would
>>>> say that 'error' in your example is not lambda.
>>>>
>>>
>>> It /is/ a C++ lambda - there is no doubt about it.  You could, perhaps,
>>> argue that it is not a common use of lambdas, or that it is unusual for
>>> lambdas to be named in this way - you'd be wrong, I think, but it would
>>> at least make sense.
>> 
>> In that case let me be the first to ask: what's the difference between
>> such a thing, and a regular named function?
>> 
>> (I can see lambdas being used in this fashion (made-up syntax):
>> 
>>    fn = lambda{|x,y| x*x-y*y};
>> 
>>    print(fn(10,5));     # output 75
>> 
>> but the lambda itself is anonymous.)
>> 
>
> The lambda itself is indeed anonymous - but you can assign it to an
> identifier to give it a name.

Using the right terminology can help here.  A lambda expression is a
syntactic entity -- it exists only in the text of the program.  The
result of evaluating a lambda expression is what C++ calls a closure
object.  It is that object which is referred to by the name 'error' in
Ian's example.

When people talk of "a lambda" it is not usually clear whether they are
talking about a lambda expression or the "function object" that results
from its evaluation.  Often, though, it does not matter much.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#136795

FromDavid Kleinecke <dkleinecke@gmail.com>
Date2018-10-15 19:02 -0700
Message-ID<67308640-f9fc-4e4e-9dde-6af1a061aa72@googlegroups.com>
In reply to#136787
On Monday, October 15, 2018 at 7:44:53 AM UTC-7, Ben Bacarisse wrote:
> David Brown <david.brown@hesbynett.no> writes:
> 
> > On 15/10/18 13:15, Bart wrote:
> >> On 15/10/2018 12:03, David Brown wrote:
> >>> On 15/10/18 12:39, already5chosen@yahoo.com wrote:
> >> 
> >>>> I am not an expert, but would think that majority of experts would
> >>>> say that 'error' in your example is not lambda.
> >>>>
> >>>
> >>> It /is/ a C++ lambda - there is no doubt about it.  You could, perhaps,
> >>> argue that it is not a common use of lambdas, or that it is unusual for
> >>> lambdas to be named in this way - you'd be wrong, I think, but it would
> >>> at least make sense.
> >> 
> >> In that case let me be the first to ask: what's the difference between
> >> such a thing, and a regular named function?
> >> 
> >> (I can see lambdas being used in this fashion (made-up syntax):
> >> 
> >>    fn = lambda{|x,y| x*x-y*y};
> >> 
> >>    print(fn(10,5));     # output 75
> >> 
> >> but the lambda itself is anonymous.)
> >> 
> >
> > The lambda itself is indeed anonymous - but you can assign it to an
> > identifier to give it a name.
> 
> Using the right terminology can help here.  A lambda expression is a
> syntactic entity -- it exists only in the text of the program.  The
> result of evaluating a lambda expression is what C++ calls a closure
> object.  It is that object which is referred to by the name 'error' in
> Ian's example.
> 
> When people talk of "a lambda" it is not usually clear whether they are
> talking about a lambda expression or the "function object" that results
> from its evaluation.  Often, though, it does not matter much.
 
I'm not sure anybody got my point. I'm not trying to
provide C with any new features or capabilities. I'm
trying to document conventional C code better.

I though I gave the game away completely by pointing out
that any conventional C program could be modified - using
my enhancement into a succession of simpler statements 
which never embed a complex statement in another statement.
If I do that - and make the labels explanatory - I have
what I consider good top-down documentation of the program
structure. Often no additional comments are needed.

[toc] | [prev] | [next] | [standalone]


#136796

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2018-10-16 05:55 +0000
Message-ID<slrnpsav9p.f78.grahn+nntp@frailea.sa.invalid>
In reply to#136795
On Tue, 2018-10-16, David Kleinecke wrote:

[people discussing C++-style lambdas]

> I'm not sure anybody got my point. I'm not trying to
> provide C with any new features or capabilities. I'm
> trying to document conventional C code better.

Most of the discussion in comp.lang.c is about people implementing
their own C-like languages ... and you /did/ write at one point:
"Since I am writing a compiler an enhancement is easy."  Those things
together probably explain why your point was lost.

> I though I gave the game away completely by pointing out
> that any conventional C program could be modified - using
> my enhancement into a succession of simpler statements 
> which never embed a complex statement in another statement.
> If I do that - and make the labels explanatory - I have
> what I consider good top-down documentation of the program
> structure. Often no additional comments are needed.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#136800

Fromjameskuyper@alumni.caltech.edu
Date2018-10-16 05:37 -0700
Message-ID<efdb1dd9-41c7-4416-a108-95789dd2857b@googlegroups.com>
In reply to#136795
On Monday, October 15, 2018 at 10:02:43 PM UTC-4, David Kleinecke wrote:
...
> I'm not sure anybody got my point. I'm not trying to
> provide C with any new features or capabilities. I'm
> trying to document conventional C code better.

I would recommend, in the future, that if you're not proposing to add a new feature to C, that you avoid wording such as the following:

> I want to propose an enhancement:
>
> Add to C the statement type
>    DO identifier SEMICOLON
> where the identifier is a label. The meaning is that
> the statement just identified is replaced by the
> statement following the label. 

I have no idea how you reconcile, in your own head, that statement
with your claim that you're not proposing a new feature for C, so
I have no idea how to fix the wording to better match your intent.
But that wording clearly suggests adds a new feature to C, a new
statement type.

[toc] | [prev] | [next] | [standalone]


#136808

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-10-16 15:11 +0100
Message-ID<877eiij818.fsf@bsb.me.uk>
In reply to#136800
jameskuyper@alumni.caltech.edu writes:

> On Monday, October 15, 2018 at 10:02:43 PM UTC-4, David Kleinecke wrote:
> ...
>> I'm not sure anybody got my point. I'm not trying to
>> provide C with any new features or capabilities. I'm
>> trying to document conventional C code better.
>
> I would recommend, in the future, that if you're not proposing to add
> a new feature to C, that you avoid wording such as the following:
>
>> I want to propose an enhancement:
>>
>> Add to C the statement type
>>    DO identifier SEMICOLON
>> where the identifier is a label. The meaning is that
>> the statement just identified is replaced by the
>> statement following the label. 
>
> I have no idea how you reconcile, in your own head, that statement
> with your claim that you're not proposing a new feature for C, so
> I have no idea how to fix the wording to better match your intent.
> But that wording clearly suggests adds a new feature to C, a new
> statement type.

My initial response was going to be along these lines.  I have the same
tendency to take people very literally, but the OP's original wording
can be reconciled with the latest post.  He is only proposing that
blocks can be moved, labelled, and then "performed" using the "do"
keyword.  I think DK believes that this is simply organisational -- it
allows what, to him, is a more natural reading order for the code -- and
so introduces nothing that raises to the level of a "new feature" in his
mind.

It's a new feature in my mind, for sure, but you get a better debate
trying to work out what people really mean.

In fact, I suspect if DK thought through all the consequences he might
consider it a new feature too.  It's not at all obvious why this
proposal would ban these named blocks from "doing" each other, or even
themselves.  That would allow some very unusual code structures that are
not simply the result of moving code around to get a different reading
order.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#136843

FromDavid Kleinecke <dkleinecke@gmail.com>
Date2018-10-16 13:33 -0700
Message-ID<1ecf373e-e0b6-495d-ae11-22eb0766201e@googlegroups.com>
In reply to#136808
On Tuesday, October 16, 2018 at 7:11:42 AM UTC-7, Ben Bacarisse wrote:
> jameskuyper@alumni.caltech.edu writes:
> 
> > On Monday, October 15, 2018 at 10:02:43 PM UTC-4, David Kleinecke wrote:
> > ...
> >> I'm not sure anybody got my point. I'm not trying to
> >> provide C with any new features or capabilities. I'm
> >> trying to document conventional C code better.
> >
> > I would recommend, in the future, that if you're not proposing to add
> > a new feature to C, that you avoid wording such as the following:
> >
> >> I want to propose an enhancement:
> >>
> >> Add to C the statement type
> >>    DO identifier SEMICOLON
> >> where the identifier is a label. The meaning is that
> >> the statement just identified is replaced by the
> >> statement following the label. 
> >
> > I have no idea how you reconcile, in your own head, that statement
> > with your claim that you're not proposing a new feature for C, so
> > I have no idea how to fix the wording to better match your intent.
> > But that wording clearly suggests adds a new feature to C, a new
> > statement type.
> 
> My initial response was going to be along these lines.  I have the same
> tendency to take people very literally, but the OP's original wording
> can be reconciled with the latest post.  He is only proposing that
> blocks can be moved, labelled, and then "performed" using the "do"
> keyword.  I think DK believes that this is simply organisational -- it
> allows what, to him, is a more natural reading order for the code -- and
> so introduces nothing that raises to the level of a "new feature" in his
> mind.
> 
> It's a new feature in my mind, for sure, but you get a better debate
> trying to work out what people really mean.
> 
> In fact, I suspect if DK thought through all the consequences he might
> consider it a new feature too.  It's not at all obvious why this
> proposal would ban these named blocks from "doing" each other, or even
> themselves.  That would allow some very unusual code structures that are
> not simply the result of moving code around to get a different reading
> order.

I already forbear doing more than one thing C allows so I
think simply not doing silly stuff is the best cure for
silly programming. 

A lot depends on what one means by "feature". I think of
adding a feature as meaning adding something new one can
do. The new things you can do with my enhancement are
trivial. 

I didn't give a more elaborate example because I've just
changed computers and all my old work is no longer easily
accessible. Point me at some source code I can read without
decompressing (I still haven't got any of it working) and
I show you an example.

[toc] | [prev] | [next] | [standalone]


#136860

FromDavid Kleinecke <dkleinecke@gmail.com>
Date2018-10-16 21:27 -0700
Message-ID<d4e37429-5d5c-4ab8-b015-5815929110d7@googlegroups.com>
In reply to#136843
On Tuesday, October 16, 2018 at 1:34:10 PM UTC-7, David Kleinecke wrote:
> On Tuesday, October 16, 2018 at 7:11:42 AM UTC-7, Ben Bacarisse wrote:
> > jameskuyper@alumni.caltech.edu writes:
> > 
> > > On Monday, October 15, 2018 at 10:02:43 PM UTC-4, David Kleinecke wrote:
> > > ...
> > >> I'm not sure anybody got my point. I'm not trying to
> > >> provide C with any new features or capabilities. I'm
> > >> trying to document conventional C code better.
> > >
> > > I would recommend, in the future, that if you're not proposing to add
> > > a new feature to C, that you avoid wording such as the following:
> > >
> > >> I want to propose an enhancement:
> > >>
> > >> Add to C the statement type
> > >>    DO identifier SEMICOLON
> > >> where the identifier is a label. The meaning is that
> > >> the statement just identified is replaced by the
> > >> statement following the label. 
> > >
> > > I have no idea how you reconcile, in your own head, that statement
> > > with your claim that you're not proposing a new feature for C, so
> > > I have no idea how to fix the wording to better match your intent.
> > > But that wording clearly suggests adds a new feature to C, a new
> > > statement type.
> > 
> > My initial response was going to be along these lines.  I have the same
> > tendency to take people very literally, but the OP's original wording
> > can be reconciled with the latest post.  He is only proposing that
> > blocks can be moved, labelled, and then "performed" using the "do"
> > keyword.  I think DK believes that this is simply organisational -- it
> > allows what, to him, is a more natural reading order for the code -- and
> > so introduces nothing that raises to the level of a "new feature" in his
> > mind.
> > 
> > It's a new feature in my mind, for sure, but you get a better debate
> > trying to work out what people really mean.
> > 
> > In fact, I suspect if DK thought through all the consequences he might
> > consider it a new feature too.  It's not at all obvious why this
> > proposal would ban these named blocks from "doing" each other, or even
> > themselves.  That would allow some very unusual code structures that are
> > not simply the result of moving code around to get a different reading
> > order.
> 
> I already forbear doing more than one thing C allows so I
> think simply not doing silly stuff is the best cure for
> silly programming. 
> 
> A lot depends on what one means by "feature". I think of
> adding a feature as meaning adding something new one can
> do. The new things you can do with my enhancement are
> trivial. 
> 
> I didn't give a more elaborate example because I've just
> changed computers and all my old work is no longer easily
> accessible. Point me at some source code I can read without
> decompressing (I still haven't got any of it working) and
> I show you an example.

I got decompressing working and rewrote some actual code in
my proposed style. There are probably errors and the code
fits poorly into 72 character lines:

static void remove_tag_with_minimal_damage (
   GtkTextBuffer* buffer, 
   GtkTextTag* tag,
   const GtkTextIter* begin,
   const GtkTextIter* end) {
   GtkTextIter tag_begin = *begin;
   GtkTextIter tag_end;
   gint count = 1;
   if (!gtk_text_iter_starts_tag (&tag_begin, tag)) do 
         move_forward_to_a_start_tag_1;
   while (gtk_text_iter_starts_tag (&tag_begin, tag) && 
         gtk_text_iter_compare (&tag_begin, end) < 0) do 
         find_matching start_tag;
   return;}
move_forward_to_a_start_tag_1: {
   if (!gtk_text_iter_forward_to_tag_toggle (&tag_begin, 
         tag)) return;}
find_matching start_tag: { /* We might have found the start 
         of another tag embedded inside this tag. So keep 
         scanning forward until we have reached the right 
         number of end tags. */
   tag_end = tag_begin;
   while (gtk_text_iter_forward_to_tag_toggle (&tag_end, 
         tag)) do move_to_next_end_tag;
   if (gtk_text_iter_ends_tag (&tag_end, tag)) do 
         remove_the_tag;}
move_to_next_end_tag: {
   if (gtk_text_iter_starts_tag (&tag_end, tag)) count++; 
   else if (gtk_text_iter_ends_tag (&tag_end, tag)) do 
         found_a_possible_end_tag;}
remove_the_tag: {
   gtk_text_buffer_remove_tag (buffer, tag, &tag_begin, 
         &tag_end);
   tag_begin = tag_end; /* Move to the next start tag. 
         It's possible to have an overlapped end tag, 
         which would be non-ideal, but possible. */
   if (!gtk_text_iter_starts_tag (&tag_begin, tag)) do 
         move_forward_to_a_start_tag_2;}
do found_a_possible_end_tag: {  
   if (--count == 0) break;}
move_forward_to_a_start_tag_2: {
   while (gtk_text_iter_forward_to_tag_toggle 
         (&tag_begin, tag)) do break_if_start_tag_found;}
break_if_start_tag_found:  {
   if (gtk_text_iter_starts_tag (&tag_begin, tag)) break;}}

[toc] | [prev] | [next] | [standalone]


#136807

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-10-16 14:57 +0100
Message-ID<87d0saj8pe.fsf@bsb.me.uk>
In reply to#136795
David Kleinecke <dkleinecke@gmail.com> writes:

> On Monday, October 15, 2018 at 7:44:53 AM UTC-7, Ben Bacarisse wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>> 
>> > On 15/10/18 13:15, Bart wrote:
>> >> On 15/10/2018 12:03, David Brown wrote:
>> >>> On 15/10/18 12:39, already5chosen@yahoo.com wrote:
>> >> 
>> >>>> I am not an expert, but would think that majority of experts would
>> >>>> say that 'error' in your example is not lambda.
>> >>>>
>> >>>
>> >>> It /is/ a C++ lambda - there is no doubt about it.  You could, perhaps,
>> >>> argue that it is not a common use of lambdas, or that it is unusual for
>> >>> lambdas to be named in this way - you'd be wrong, I think, but it would
>> >>> at least make sense.
>> >> 
>> >> In that case let me be the first to ask: what's the difference between
>> >> such a thing, and a regular named function?
>> >> 
>> >> (I can see lambdas being used in this fashion (made-up syntax):
>> >> 
>> >>    fn = lambda{|x,y| x*x-y*y};
>> >> 
>> >>    print(fn(10,5));     # output 75
>> >> 
>> >> but the lambda itself is anonymous.)
>> >> 
>> >
>> > The lambda itself is indeed anonymous - but you can assign it to an
>> > identifier to give it a name.
>> 
>> Using the right terminology can help here.  A lambda expression is a
>> syntactic entity -- it exists only in the text of the program.  The
>> result of evaluating a lambda expression is what C++ calls a closure
>> object.  It is that object which is referred to by the name 'error' in
>> Ian's example.
>> 
>> When people talk of "a lambda" it is not usually clear whether they are
>> talking about a lambda expression or the "function object" that results
>> from its evaluation.  Often, though, it does not matter much.
>  
> I'm not sure anybody got my point.

I am not surprised.  The example you gave was either pointless or had
potentially undefined behaviour.  Here it is:

    int foo (int x) {
        if (x < 0) do trivial_case;
        else if (x == 0) do easy_case;
        else do usual_case;
        return;
     trivial_case: { 
        .... }
     easy_case: { 
        .... }
     usual_case: { 
        .... }}

If all the ... code fragments end with "return <exp>;" it's all
well-defined but pointless -- just use goto.  If, as appears to be the
case, you expect a "do label;" statements to "come back" like a function
call, that lone return either gives undefined behaviour or you are
writing pre-ANSI C (C without "void").  But even in pre-ANSI C, it was
conventional to leave the int implied when a function did not return a
value.  The result was I did not know what you really intended.

> I'm not trying to
> provide C with any new features or capabilities. I'm
> trying to document conventional C code better.

Eh?  The conventional code that corresponds to this fragment is just
fine as it is:

    void foo (int x)
    {
        if (x < 0) {
            // trivial case
            ...
        }
        else if (x == 0) {
            // easy_case
            ...
        }
        else {
            // usual_case
            ...
        }
        return;
     }

> I though I gave the game away completely by pointing out
> that any conventional C program could be modified - using
> my enhancement into a succession of simpler statements 
> which never embed a complex statement in another statement.

This is a non-problem as far as I can see.  I find nesting to be a
natural code structuring concept.  I will skip the details of each
branch when reading the code (a "folding" editor will help) so I don't
need the code tree to be flattened.

And your example would have been more interesting if it illustrated how
to simplify some code that would otherwise have more nesting.  I suspect
it does not improve the readability.

> If I do that - and make the labels explanatory - I have
> what I consider good top-down documentation of the program
> structure. Often no additional comments are needed.

There has to be a better reason to alter a programming language than to
permit labels to act as quasi comments.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#136809

Fromscott@slp53.sl.home (Scott Lurndal)
Date2018-10-16 14:24 +0000
Message-ID<bwmxD.295612$sO2.207640@fx41.iad>
In reply to#136807
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>David Kleinecke <dkleinecke@gmail.com> writes:
>

>> I'm not sure anybody got my point.
>
>I am not surprised.  The example you gave was either pointless or had
>potentially undefined behaviour.  Here it is:
>
>    int foo (int x) {
>        if (x < 0) do trivial_case;
>        else if (x == 0) do easy_case;
>        else do usual_case;
>        return;
>     trivial_case: { 
>        .... }
>     easy_case: { 
>        .... }
>     usual_case: { 
>        .... }}
>
>If all the ... code fragments end with "return <exp>;" it's all
>well-defined but pointless -- just use goto.  If, as appears to be the
>case, you expect a "do label;" statements to "come back" like a function
>call, that lone return either gives undefined behaviour or you are
>writing pre-ANSI C (C without "void"). 

Agree - just use goto.

Or you can use

  PERFORM trivial_case.

or

  PERFORM trivial_case THRU usual_case.


 :-)

[toc] | [prev] | [next] | [standalone]


#136811

Frommark.bluemel@gmail.com
Date2018-10-16 07:28 -0700
Message-ID<445a7d84-db43-4a3e-893e-08acf427f1da@googlegroups.com>
In reply to#136809
On Tuesday, 16 October 2018 15:24:16 UTC+1, Scott Lurndal  wrote:

> Or you can use
> 
>   PERFORM trivial_case.
> 
> or
> 
>   PERFORM trivial_case THRU usual_case.

It's probably 30 years since I wrote COBOL and that still made me twitch!

[toc] | [prev] | [next] | [standalone]


#136810

FromBart <bc@freeuk.com>
Date2018-10-16 15:25 +0100
Message-ID<jxmxD.101227$p%6.63048@fx26.am4>
In reply to#136807
On 16/10/2018 14:57, Ben Bacarisse wrote:
> David Kleinecke <dkleinecke@gmail.com> writes:

>> I'm not sure anybody got my point.
> 
> I am not surprised.  The example you gave was either pointless or had
> potentially undefined behaviour.  Here it is:
> 
>      int foo (int x) {
>          if (x < 0) do trivial_case;
>          else if (x == 0) do easy_case;
>          else do usual_case;
>          return;
>       trivial_case: {
>          .... }
>       easy_case: {
>          .... }
>       usual_case: {
>          .... }}
> 
> If all the ... code fragments end with "return <exp>;" it's all
> well-defined but pointless -- just use goto.  If, as appears to be the
> case, you expect a "do label;" statements to "come back" like a function
> call, that lone return either gives undefined behaviour or you are
> writing pre-ANSI C (C without "void").

Obviously, the return was omitted, probably by mistake.
> Eh?  The conventional code that corresponds to this fragment is just
> fine as it is:
> 
>      void foo (int x)
>      {
>          if (x < 0) {
>              // trivial case
>              ...
>          }
>          else if (x == 0) {
>              // easy_case
>              ...
>          }
>          else {
>              // usual_case
>              ...
>          }
>          return;
>       }
> 
>> I though I gave the game away completely by pointing out
>> that any conventional C program could be modified - using
>> my enhancement into a succession of simpler statements
>> which never embed a complex statement in another statement.
> 
> This is a non-problem as far as I can see.  I find nesting to be a
> natural code structuring concept.  I will skip the details of each
> branch when reading the code (a "folding" editor will help) so I don't
> need the code tree to be flattened.
> 
> And your example would have been more interesting if it illustrated how
> to simplify some code that would otherwise have more nesting.  I suspect
> it does not improve the readability.

[Warning: examples not in C follow]

Take this case statement (this example can be expression with switch in 
C, minus the @ and :: parts, and with break added):

     case x
     when 10,20 then
         @forty
         print "A"
     when 30 then
     thirty::
         print "B"
     when 40 then
     forty::
         print "C"
     else
         print "X"
         @thirty
     esac

Normal output (without those extras) is one of A, B, C or X. The "::" 
defines special labels for each block, and the @ is a form of GOSUB. The 
@forty will execute the '40' block, then 'return' to proceed to print "A".

Now outputs will be one of CA, B, C or XB. It used for sharing short 
fragments of code without using goto, or duplicating code, or having to 
start using complex approaches such as functions, or local functions, or 
local named lambdas.

The feature can also be used to with purpose-written blocks:

     print "A "
     print "B "

     blockdef fred::
         print "X"
         print "Y "
     end

     print "C "
     @fred
     print "D "
     @fred
     print "E "

The syntax sucks, but this block is written anywhere; normal execution 
'steps around' it. Running the whole thing gives the output:

    A B C XY D XY E.

Again, this is just about light-weight code sharing.

Such blocks don't recurse, but they can call each other. They have 
access to the same local variables as normal code. (You can goto into or 
out of such a block, but it will probably go wrong. A compiler ought to 
disallow that).

-- 
bart

[toc] | [prev] | [next] | [standalone]


#136775

FromBart <bc@freeuk.com>
Date2018-10-15 11:44 +0100
Message-ID<ec_wD.60403$5A2.52746@fx25.am4>
In reply to#136772
On 15/10/2018 11:18, Ian Collins wrote:
> On 15/10/18 23:07, already5chosen@yahoo.com wrote:
>> On Monday, October 15, 2018 at 12:19:44 PM UTC+3, Queequeg wrote:
>>> Spiros Bousbouras <spibou@gmail.com> wrote:
>>>
>>>> I think what David really wants is local functions (i.e.
>>>> functions within functions) which do not accept any parameters ,
>>>> do not return a value and a syntax which allows the compiler to
>>>> recognise that it is a local function call without having
>>>> encountered first a declaration or definition for the local
>>>> function. The specific example he gave can be written using
>>>> goto's but the more general case cannot (without very convoluted
>>>> gymnastics).
>>>
>>> I guess he should learn about lambda functions in C++11.
>>>
>>> -- https://www.youtube.com/watch?v=9lSzL1DqQn0
>>
>>
>> I don't think so.
>>
>> 1. Lambda functions are anonymous. David wants *named* nested
>> functions. Being named is critically important, because [it seems to
>> me that] important point of his proposal is an ability to call it
>> from more than one location in the outer function.
> 
> You can name C++ lambdas.  From a bit of my own code:
> 
>    auto error = [this]( std::string function )
>    {
>      LOG_ERROR("Open: "+function+" failed %s", strerror(errno) );
>      close(fd);
>      fd = kInvalidFd;
>      return false;
>    };
> 
>    int Opt = 0;
>    if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &Opt, sizeof(Opt)) != 0)
>    {
>      return error("setsockopt");
>    }
> 
>    ... repeated in similar fashion for various socket operations ...

Which bit is the named lambda?

(BTW using identifiers such as 'function' in example code of what could 
be an unfamiliar language is confusing. 'function' looks like it could 
be a keyword.)

>> 2. Lambda functions are in-place David wants his nested functions to
>> be defined at the end of outer function because he feels that it
>> would improve readability for top-down oriented readers. It seems
>> likely that David himself is top-down character so he should know
>> their needs better than decisively bottom-up people like myself.
> 
> Maybe, but I can't help feeling that's a bit like declaring a variable 
> after it's used!

(What's wrong with that? Example from an actual language:

     proc start=
         a:=17
         b:=4
         c:=a/b
         println c

         real a,b,c
     end

     Output: 4.25

No different from calling a function which is defined later (C doesn't 
allow this without a prior declaration**, but I'm sure many languages 
do), or using goto with a label defined later (C allows this one).

Think of it as a glossary which usually goes at the end of a book.)

(** Despite this, often this can work, but with warnings, or sometimes 
with none. It's just that kind of language  - yeah, but, maybe, 
sometimes, it depends .... Expecting yes or no is apparently too much to 
expect.)

[toc] | [prev] | [next] | [standalone]


#136778

FromDavid Brown <david.brown@hesbynett.no>
Date2018-10-15 13:08 +0200
Message-ID<pq1sfu$8lj$1@dont-email.me>
In reply to#136775
On 15/10/18 12:44, Bart wrote:
> On 15/10/2018 11:18, Ian Collins wrote:
>> On 15/10/18 23:07, already5chosen@yahoo.com wrote:
>>> On Monday, October 15, 2018 at 12:19:44 PM UTC+3, Queequeg wrote:
>>>> Spiros Bousbouras <spibou@gmail.com> wrote:
>>>>
>>>>> I think what David really wants is local functions (i.e.
>>>>> functions within functions) which do not accept any parameters ,
>>>>> do not return a value and a syntax which allows the compiler to
>>>>> recognise that it is a local function call without having
>>>>> encountered first a declaration or definition for the local
>>>>> function. The specific example he gave can be written using
>>>>> goto's but the more general case cannot (without very convoluted
>>>>> gymnastics).
>>>>
>>>> I guess he should learn about lambda functions in C++11.
>>>>
>>>> -- https://www.youtube.com/watch?v=9lSzL1DqQn0
>>>
>>>
>>> I don't think so.
>>>
>>> 1. Lambda functions are anonymous. David wants *named* nested
>>> functions. Being named is critically important, because [it seems to
>>> me that] important point of his proposal is an ability to call it
>>> from more than one location in the outer function.
>>
>> You can name C++ lambdas.  From a bit of my own code:
>>
>>    auto error = [this]( std::string function )
>>    {
>>      LOG_ERROR("Open: "+function+" failed %s", strerror(errno) );
>>      close(fd);
>>      fd = kInvalidFd;
>>      return false;
>>    };
>>
>>    int Opt = 0;
>>    if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &Opt, sizeof(Opt)) != 0)
>>    {
>>      return error("setsockopt");
>>    }
>>
>>    ... repeated in similar fashion for various socket operations ...
> 
> Which bit is the named lambda?

	auto error = [this]( std::string function ) { ... }

"error" is the identifier given to the lambda.

> 
> (BTW using identifiers such as 'function' in example code of what could
> be an unfamiliar language is confusing. 'function' looks like it could
> be a keyword.)
> 

I expect Ian wrote this intending it to be read by people familiar with
C++11, so that the concept of lambdas would not be unfamiliar.  And if
he used a lambda in these circumstances then I expect the turn up quite
regularly in his code - again, they will not be unfamiliar.


[toc] | [prev] | [next] | [standalone]


#136773

FromBart <bc@freeuk.com>
Date2018-10-15 11:22 +0100
Message-ID<OTZwD.36269$8g.31326@fx08.am4>
In reply to#136771
On 15/10/2018 11:07, already5chosen@yahoo.com wrote:
> On Monday, October 15, 2018 at 12:19:44 PM UTC+3, Queequeg wrote:
>> Spiros Bousbouras <spibou@gmail.com> wrote:
>>
>>> I think what David really wants is local functions (i.e. functions within
>>> functions) which do not accept any parameters , do not return a value and a
>>> syntax which allows the compiler to recognise that it is a local function
>>> call without having encountered first a declaration or definition for the
>>> local function. The specific example he gave can be written using  goto's
>>> but the more general case cannot (without very convoluted gymnastics).
>>
>> I guess he should learn about lambda functions in C++11.
>>
>> -- 
>> https://www.youtube.com/watch?v=9lSzL1DqQn0
> 
> 
> I don't think so.
> 
> 1. Lambda functions are anonymous.
> David wants *named* nested functions.
> Being named is critically important, because [it seems to me that] important point of his proposal is an ability to call it from more than one location in the outer function.
> 
> 2. Lambda functions are in-place
> David wants his nested functions to be defined at the end of outer function because he feels that it would improve readability for top-down oriented readers. It seems likely that David himself is top-down character so he should know their needs better than decisively bottom-up people like myself.
> 

I was about to post the same thing. Most reactions have been to dismiss 
the proposal in the OP or suggest something this is inferior or more 
complex.

The lambda idea is completely inappropriate; it seemed to be forgotten 
that the OP is /implementing/ such a feature not merely learning how to 
use it (and the C++ version may have taken man-years of effort to do).

-- 
bart

[toc] | [prev] | [next] | [standalone]


#136776

FromDavid Brown <david.brown@hesbynett.no>
Date2018-10-15 13:01 +0200
Message-ID<pq1s1h$63c$1@dont-email.me>
In reply to#136773
On 15/10/18 12:22, Bart wrote:
> On 15/10/2018 11:07, already5chosen@yahoo.com wrote:
>> On Monday, October 15, 2018 at 12:19:44 PM UTC+3, Queequeg wrote:
>>> Spiros Bousbouras <spibou@gmail.com> wrote:
>>>
>>>> I think what David really wants is local functions (i.e. functions
>>>> within
>>>> functions) which do not accept any parameters , do not return a
>>>> value and a
>>>> syntax which allows the compiler to recognise that it is a local
>>>> function
>>>> call without having encountered first a declaration or definition
>>>> for the
>>>> local function. The specific example he gave can be written using 
>>>> goto's
>>>> but the more general case cannot (without very convoluted gymnastics).
>>>
>>> I guess he should learn about lambda functions in C++11.
>>>
>>> -- 
>>> https://www.youtube.com/watch?v=9lSzL1DqQn0
>>
>>
>> I don't think so.
>>
>> 1. Lambda functions are anonymous.
>> David wants *named* nested functions.
>> Being named is critically important, because [it seems to me that]
>> important point of his proposal is an ability to call it from more
>> than one location in the outer function.
>>

As Ian says, you can give lambda functions a name.

>> 2. Lambda functions are in-place
>> David wants his nested functions to be defined at the end of outer
>> function because he feels that it would improve readability for
>> top-down oriented readers. It seems likely that David himself is
>> top-down character so he should know their needs better than
>> decisively bottom-up people like myself.

C is a "declare before use" language.  This is a design decision with
its pros and cons.  It would be very much against the flavour of C to
decide that this one feature was "use before declare".

Could C be turned into a language mostly like C, but without the need to
declare identifiers before use?  Yes, I think it could, for the most
part.  (You would not want to do it for macros.)  But I would do that as
a general extension to the language, not just for one specific new feature.

>>
> 
> I was about to post the same thing. Most reactions have been to dismiss
> the proposal in the OP or suggest something this is inferior or more
> complex.

I am far from convinced that his idea has enough use or merit to warrant
the complexity and confusion of having it.  Nested functions of some
sort are a good deal more flexible, and would cover his request if
combined with a relaxation of the "declare before use" requirement of C.

> 
> The lambda idea is completely inappropriate; it seemed to be forgotten
> that the OP is /implementing/ such a feature not merely learning how to
> use it (and the C++ version may have taken man-years of effort to do).
> 

No, this has not been forgotten (not by me, anyway).  If the OP wants to
invent his own wheel, then that's his choice - but it will see little
use outside his own programming with his own compiler.  If he copies
existing wheels, that changes dramatically - instead of a private
language with private features that no one else knows about or uses,
he'd have a C compiler with a useful C++ feature implemented.  People
could use his tool and this feature, safe in the knowledge that if they
need to switch tools, they can always move to a C++ compiler.

And since these features (lambdas and gcc nested functions) exist today,
he can try them out - he can see how the code looks with these features,
and see what the generated assembly is like.  That is a massive benefit.

The OP should look closely at these features, and learn from them -
taking advantage of the man-years of effort and experience they
represent.  Then he can decide if he wants to copy them, or go his own way.

[toc] | [prev] | [next] | [standalone]


#136786

FromNick Bowler <nbowler@draconx.ca>
Date2018-10-15 14:43 +0000
Message-ID<pq2936$ijm$1@dont-email.me>
In reply to#136776
On Mon, 15 Oct 2018 13:01:04 +0200, David Brown wrote:
> C is a "declare before use" language.  This is a design decision with
> its pros and cons.  It would be very much against the flavour of C to
> decide that this one feature was "use before declare".

This is not exactly true; C already has labeled statements and labels
do not need to be declared before they are used.

Presumably that is why the OP specifically used labels in the proposal.

[toc] | [prev] | [standalone]


Page 3 of 3 — ← Prev page 1 2 [3]

Back to top | Article view | comp.lang.c


csiph-web