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


Groups > comp.lang.misc > #2067 > unrolled thread

C: 100 Things

Started by"BartC" <bc@freeuk.com>
First post2014-04-29 17:57 +0100
Last post2014-10-25 04:50 -0700
Articles 20 on this page of 58 — 10 participants

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


Contents

  C: 100 Things "BartC" <bc@freeuk.com> - 2014-04-29 17:57 +0100
    Re: 100 Things "James Harris" <james.harris.1@gmail.com> - 2014-04-30 07:40 +0100
      Re: 100 Things "BartC" <bc@freeuk.com> - 2014-04-30 12:16 +0100
        Re: 100 Things "James Harris" <james.harris.1@gmail.com> - 2014-04-30 13:54 +0100
          Re: 100 Things "BartC" <bc@freeuk.com> - 2014-04-30 14:39 +0100
            Re: 100 Things "James Harris" <james.harris.1@gmail.com> - 2014-04-30 20:18 +0100
              Re: 100 Things "BartC" <bc@freeuk.com> - 2014-04-30 22:40 +0100
                Re: 100 Things Kaz Kylheku <kaz@kylheku.com> - 2014-04-30 22:09 +0000
                  Re: 100 Things "BartC" <bc@freeuk.com> - 2014-04-30 23:36 +0100
                    Re: 100 Things Ian Collins <ian-news@hotmail.com> - 2014-05-01 11:03 +1200
                      Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-01 09:47 +0100
                Re: 100 Things "James Harris" <james.harris.1@gmail.com> - 2014-05-01 00:35 +0100
                  Re: 100 Things Andy Walker <news@cuboid.co.uk> - 2014-05-01 11:03 +0100
                    Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-01 20:16 +0100
                  Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-01 12:44 +0100
                    Re: 100 Things "James Harris" <james.harris.1@gmail.com> - 2014-05-02 11:11 +0100
                      Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-02 13:32 +0100
                        Re: 100 Things "James Harris" <james.harris.1@gmail.com> - 2014-05-02 16:42 +0100
                          Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-02 17:54 +0100
            Re: 100 Things Ian Collins <ian-news@hotmail.com> - 2014-05-01 11:01 +1200
        Re: 100 Things "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-04-30 21:13 -0400
          Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-01 09:26 +0100
            Re: 100 Things "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-05-01 16:08 -0400
        Re: 100 Things Ian Collins <ian-news@hotmail.com> - 2014-05-01 13:42 +1200
          Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-01 09:35 +0100
            Re: 100 Things Ian Collins <ian-news@hotmail.com> - 2014-05-01 21:02 +1200
              Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-01 10:40 +0100
                Re: 100 Things Ian Collins <ian-news@hotmail.com> - 2014-05-01 22:06 +1200
            Re: 100 Things "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-05-01 11:08 +0200
              Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-01 11:02 +0100
                Re: 100 Things "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-05-01 13:57 +0200
                  Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-01 15:12 +0100
                    Re: 100 Things "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-05-01 17:18 +0200
                      Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-01 17:04 +0100
                        Re: 100 Things Kaz Kylheku <kaz@kylheku.com> - 2014-05-01 18:30 +0000
                          Re: 100 Things "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-05-01 16:08 -0400
                            Re: 100 Things Ian Collins <ian-news@hotmail.com> - 2014-05-02 08:30 +1200
                              Re: 100 Things George Neuner <gneuner2@comcast.net> - 2014-05-03 01:29 -0400
                                Re: 100 Things "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-05-03 02:37 -0400
                                  Re: 100 Things George Neuner <gneuner2@comcast.net> - 2014-05-03 15:39 -0400
                                    Re: 100 Things "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-05-03 17:30 -0400
                                Re: 100 Things Ian Collins <ian-news@hotmail.com> - 2014-05-04 20:05 +1200
                                  Re: 100 Things George Neuner <gneuner2@comcast.net> - 2014-05-04 13:28 -0400
                                    Re: 100 Things Ian Collins <ian-news@hotmail.com> - 2014-05-05 07:40 +1200
                        Re: 100 Things "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-05-01 22:00 +0200
                          Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-01 23:24 +0100
                            Re: 100 Things "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-05-02 08:59 +0200
                              Re: 100 Things "BartC" <bc@freeuk.com> - 2014-05-02 09:53 +0100
                                Re: 100 Things "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-05-02 11:22 +0200
                      Re: 100 Things Kaz Kylheku <kaz@kylheku.com> - 2014-05-01 18:26 +0000
                        Re: 100 Things "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-05-01 16:08 -0400
                          Re: 100 Things Kaz Kylheku <kaz@kylheku.com> - 2014-05-02 02:49 +0000
    Re: C: 100 Things "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-04-30 22:08 -0400
    Re: C: 100 Things "BartC" <bc@freeuk.com> - 2014-07-25 23:53 +0100
      Re: C: 100 Things "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-07-26 05:38 -0400
        Re: C: 100 Things "BartC" <bc@freeuk.com> - 2014-07-26 13:51 +0100
          Re: C: 100 Things rick.c.hodgin@gmail.com - 2014-10-25 04:48 -0700
    Re: C: 100 Things "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2014-10-25 04:50 -0700

Page 1 of 3  [1] 2 3  Next page →


#2067 — C: 100 Things

From"BartC" <bc@freeuk.com>
Date2014-04-29 17:57 +0100
SubjectC: 100 Things
Message-ID<3SQ7v.155346$AI5.24849@fx32.am4>
"BartC" <bc@freeuk.com> wrote in message
news:94y7v.153301$AI5.43400@fx32.am4...
> "Kaz Kylheku" <kaz@kylheku.com> wrote in message

>> Nobody really needs alternatives to C which are almost the same thing,
>> just with more clunky syntax and pointless limitations.
>
> Yes we do. It wouldn't take me long to list a hundred things that are
> wrong
> with C, yet after fixing all those the resulting language wouldn't do that
> much more.

"BartC" <bc@freeuk.com> wrote in message
news:57B7v.161805$Qm2.151455@fx16.am4...
> "James Harris" <james.harris.1@gmail.com> wrote in message

>> That's interesting. I think we could all come up with a list of
>> improvements we would like.
>
> I'll try and put something together. I may or may not post it. As I think
> you say somewhere, such a list will be different for everyone.

Well, I put together my list. About 115 things listed actually. Too long to
show here so is at:  http://pastebin.com/vUVpF1uA (will be edited later).

I didn't specifically set out to find faults with C, but a lot of this is
how I'm used to doing things, and wondered why C used its own unique 
approach.

And as promised, little of this actually results in a particularly higher
level language (no OOP, no templates, no dynamic datatypes, no exceptions,
no threading, nothing about the runtime library (actually that can be item #
116...).) It just makes more sense.

-- 
Bartc 

[toc] | [next] | [standalone]


#2071 — Re: 100 Things

From"James Harris" <james.harris.1@gmail.com>
Date2014-04-30 07:40 +0100
SubjectRe: 100 Things
Message-ID<ljq5sv$coh$1@dont-email.me>
In reply to#2067
"BartC" <bc@freeuk.com> wrote in message 
news:3SQ7v.155346$AI5.24849@fx32.am4...

...

(re the C language)

>>> That's interesting. I think we could all come up with a list of
>>> improvements we would like.
>>
>> I'll try and put something together. I may or may not post it. As I think
>> you say somewhere, such a list will be different for everyone.
>
> Well, I put together my list. About 115 things listed actually. Too long 
> to
> show here so is at:  http://pastebin.com/vUVpF1uA (will be edited later).

That's an amazingly long list. There are too many to comment on but I agree 
with lots of them.

> I didn't specifically set out to find faults with C, but a lot of this is
> how I'm used to doing things, and wondered why C used its own unique 
> approach.
>
> And as promised, little of this actually results in a particularly higher
> level language (no OOP, no templates, no dynamic datatypes, no exceptions,
> no threading, nothing about the runtime library (actually that can be item 
> #
> 116...).) It just makes more sense.

Yes, a good approach, IMO. I wouldn't be against adding things to a design 
but the temptation especially among those most familiar with a language - 
and who would know it better than its developer(s) - is to just keep adding. 
ISTM that C++, Java, Python, Ada have all become bloated over time. C has at 
least retained a minimalism.

James

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


#2074 — Re: 100 Things

From"BartC" <bc@freeuk.com>
Date2014-04-30 12:16 +0100
SubjectRe: 100 Things
Message-ID<kY48v.181432$Ey6.180503@fx24.am4>
In reply to#2071

"James Harris" <james.harris.1@gmail.com> wrote in message
news:ljq5sv$coh$1@dont-email.me...
> "BartC" <bc@freeuk.com> wrote in message
> news:3SQ7v.155346$AI5.24849@fx32.am4...

>> And as promised, little of this actually results in a particularly higher
>> level language (no OOP, no templates, no dynamic datatypes, no
>> exceptions,
>> no threading, nothing about the runtime library (actually that can be
>> item #
>> 116...).) It just makes more sense.
>
> Yes, a good approach, IMO. I wouldn't be against adding things to a design
> but the temptation especially among those most familiar with a language -
> and who would know it better than its developer(s) - is to just keep
> adding. ISTM that C++, Java, Python, Ada have all become bloated over
> time. C has at least retained a minimalism.

I think there is a place for a low-level language placed roughly where C is,
but it seems to have completely dominated this area to the exclusion of
everything else.

Doubtless there will be competitive languages we've never heard of (perhaps
people creating their own projects like me), but it would be nice to have
something mainstream that I could actually like! (I don't really like C, in
case that's not already apparent.)

It's interesting to know what other approaches are possible in this area (my
ideas come from experience with Algol, Pascal and (to a lesser extent)
Fortran (all a long time ago), so are probably dated.

As for C being minimalist, I don't know if a language needing these types
and macros (remembering to substitute all the combinations of 8 16, 32 and
64 every time you see N):

intN_t
uintN_t
int_leastN_t
uint_leastN_t
int_fastN_t
uint_fastN_t
intptr_t
uintptr_t
intmax_t
uintmax_t
INTN_MIN
INTN_MAX
UINTN_MAX
INT_LEASTN_MIN
INT_LEASTN_MAX
UINT_LEASTN_MAX
INT_FASTN_MIN
INT_FASTN_MAX
UINT_FASTN_MAX
INTPTR_MIN
INTPTR_MAX
UINTPTR_MAX
INTMAX_MIN
INTMAX_MAX
UINTMAX_MAX
PTRDIFF_MIN
PTRDIFF_MAX
SIG_ATOMIC_MIN
SIG_ATOMIC_MAX
SIZE_MAX
WCHAR_MIN
WCHAR_MAX
WINT_MIN
WINT_MAX
INTN_C(value)
UINTN_C(value)
INTMAX_C(value)
UINTMAX_C(value

and maybe this lot too, as some of these seem to be different from those
above:

#define CHAR_BIT 8
#define CHAR_MAX UCHAR_MAX or SCHAR_MAX
#define CHAR_MIN 0 or SCHAR_MIN
#define INT_MAX +32767
#define INT_MIN -32767
#define LONG_MAX +2147483647
#define LONG_MIN -2147483647
#define LLONG_MAX +9223372036854775807
#define LLONG_MIN -9223372036854775807
#define MB_LEN_MAX 1
#define SCHAR_MAX +127
#define SCHAR_MIN -127
#define SHRT_MAX +32767
#define SHRT_MIN -32767
#define UCHAR_MAX 255
#define USHRT_MAX 65535
#define UINT_MAX 65535
#define ULONG_MAX 4294967295
#define ULLONG_MAX 18446744073709551615

and much more, could actually be called minimalist. (More like maximalist,
as this lot could easily be condensed into a handful of language features.)

It's a joke really, but not particularly funny as this language and its
ideas seem to have permeated everywhere. You take the crude C for-loop,
which is 'for (expr; expr; expr)', and you see it practically unchanged in
C++, C#, Java, Javascript, PHP, Perl, even newer ones such as Go and Dart
(although Go has at least dropped the parentheses!).

That is actually astonishing; has it really never occurred to anyone to add
a /simple/ iterative loop statement to any of these? It must apparently have
affected their minds too! (Fortunately a few other languages: Lua, Ruby and
Python for example, have finally seen the light regarding for-loops at
least. Those aren't low-level languages though.)

(I wouldn't be surprised if it's because they all start off with
off-the-shelf lexing and parsing tools that come with a ready-made C
grammar.)

-- 
Bartc 

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


#2076 — Re: 100 Things

From"James Harris" <james.harris.1@gmail.com>
Date2014-04-30 13:54 +0100
SubjectRe: 100 Things
Message-ID<ljqrp2$pli$1@dont-email.me>
In reply to#2074
"BartC" <bc@freeuk.com> wrote in message 
news:kY48v.181432$Ey6.180503@fx24.am4...

...

> I think there is a place for a low-level language placed roughly where C 
> is,
> but it seems to have completely dominated this area to the exclusion of
> everything else.
>
> Doubtless there will be competitive languages we've never heard of 
> (perhaps
> people creating their own projects like me), but it would be nice to have

Yes, there could well be some good replacements that we have never heard of.

> something mainstream that I could actually like! (I don't really like C, 
> in
> case that's not already apparent.)

Unlike you I believe C is great even though it has its faults.

> It's interesting to know what other approaches are possible in this area 
> (my
> ideas come from experience with Algol, Pascal and (to a lesser extent)
> Fortran (all a long time ago), so are probably dated.

I too would like to know of alternatives. What I wouldn't want to do, 
though, is to invest considerable time in learning something new only to 
find out later that either the language or its toolchain was not mature 
enough to allow some things to be done.

It is relatively easy to produce a language which does a few things better 
than C but also does some other things not as well or not at all!

> As for C being minimalist, I don't know if a language needing these types
> and macros (remembering to substitute all the combinations of 8 16, 32 and
> 64 every time you see N):

... (snipped the many examples)

Yes, very valid. I completely agree.

I don't know why data sizes are so poorly managed in C and other languages. 
Sub-word and multi-word arithmetic is not too hard for a code generator to 
do.

If a programmer wants an 8-bit or 128-bit integer shouldn't they be inbuilt? 
IMO it should not be necessary to add a library and make library calls to 
handle things like wide integers.

One thing I would say in defence of C is that, at least with some 
machinations, it does allow a programmer to specify integer sizes. Most 
languages just give you an integer and that's it!

> and much more, could actually be called minimalist. (More like maximalist,
> as this lot could easily be condensed into a handful of language 
> features.)

Yes.

> It's a joke really, but not particularly funny as this language and its
> ideas seem to have permeated everywhere. You take the crude C for-loop,
> which is 'for (expr; expr; expr)', and you see it practically unchanged in
> C++, C#, Java, Javascript, PHP, Perl, even newer ones such as Go and Dart
> (although Go has at least dropped the parentheses!).
>
> That is actually astonishing; has it really never occurred to anyone to 
> add
> a /simple/ iterative loop statement to any of these? It must apparently 
> have
> affected their minds too!

I cannot speak for their minds! but IMO C's for statement is much better 
than you suggest. Do you remember reading computer science texts on how 
loops were formed? Books I read years ago used to talk about categorising 
loops into definite and indefinite iteration and, at some length, about what 
could happen to the loop control variable at the end of the loop and whether 
it should even be in scope.

In one stroke C's for loop removes those issues and makes it manifest in the 
syntax what steps the program will take to control the loop. It reduces a 
loop to the essentials and it means that one compact loop control statement 
can be used in almost all types of loop. IMO that's quite brilliant! I'm not 
surprised if it got copied to other languages.

James

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


#2077 — Re: 100 Things

From"BartC" <bc@freeuk.com>
Date2014-04-30 14:39 +0100
SubjectRe: 100 Things
Message-ID<K278v.218753$vB1.137675@fx36.am4>
In reply to#2076
"James Harris" <james.harris.1@gmail.com> wrote in message
news:ljqrp2$pli$1@dont-email.me...
> "BartC" <bc@freeuk.com> wrote in message

>>(I don't really like C, in
>> case that's not already apparent.)
>
> Unlike you I believe C is great even though it has its faults.

I first used Algol60 and then Pascal (at college), so when I was first came
across C it already looked primitive. That opinion hasn't improved greatly..

> It is relatively easy to produce a language which does a few things better
> than C but also does some other things not as well or not at all!

It doesn't need to be all or nothing. For example, it's usually possible to
have modules in C as well as whatever other language is being used. However,
if you're locked in to a C 'ecosystem', with the OS using C as an interface
language; using linkers that come with C compilers; using the C runtime
library; using 'make'; using a host of third party libraries which come with
C header files so that you can only use them easily from C; are used to a
debugger which assumes C sources etc. then I agree it can be hard to break
out of all that or find a way for new language to fit it.

>You take the crude C for-loop,

>> That is actually astonishing; has it really never occurred to anyone to
>> add
>> a /simple/ iterative loop statement to any of these? It must apparently
>> have
>> affected their minds too!
>
> I cannot speak for their minds! but IMO C's for statement is much better
> than you suggest. Do you remember reading computer science texts on how
> loops were formed? Books I read years ago used to talk about categorising
> loops into definite and indefinite iteration and, at some length, about
> what could happen to the loop control variable at the end of the loop and
> whether it should even be in scope.

> In one stroke C's for loop removes those issues and makes it manifest in
> the syntax what steps the program will take to control the loop. It
> reduces a loop to the essentials and it means that one compact loop
> control statement can be used in almost all types of loop. IMO that's
> quite brilliant! I'm not surprised if it got copied to other languages.

Yes, C's for loop is quite powerful and very flexible (although so are 'if'
and 'goto'!). But it is possible to have both that, and a dedicated loop for
the 99% of situations (in my case) where I do need a for-loop to just count
from A to B.

(Actually my syntax, as well has having 'for', 'to', 'do' and so on (all
from Algol68 really, where they are versions of a general for-loop) also 
have a C-style for-loop, with syntax 'cfor a,b,c do ...' to acknowledge the 
extra potential it has. But so far I haven't used it!)

C (and some of those derived languages) do allow you to create a macro such 
as FOR(i,a,b), but it might raise eyebrows if you showed such code to anyone 
else. This basic stuff really needs to be part of the language proper.

-- 
Bartc 

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


#2081 — Re: 100 Things

From"James Harris" <james.harris.1@gmail.com>
Date2014-04-30 20:18 +0100
SubjectRe: 100 Things
Message-ID<ljria6$8ka$1@dont-email.me>
In reply to#2077
"BartC" <bc@freeuk.com> wrote in message 
news:K278v.218753$vB1.137675@fx36.am4...

...

>> In one stroke C's for loop removes those issues and makes it manifest in
>> the syntax what steps the program will take to control the loop. It
>> reduces a loop to the essentials and it means that one compact loop
>> control statement can be used in almost all types of loop. IMO that's
>> quite brilliant! I'm not surprised if it got copied to other languages.
>
> Yes, C's for loop is quite powerful and very flexible (although so are 
> 'if'
> and 'goto'!). But it is possible to have both that, and a dedicated loop 
> for
> the 99% of situations (in my case) where I do need a for-loop to just 
> count
> from A to B.

That reminds me of some more benefits of C's for construct. In addition to 
those mentioned before if you want a step of something other than 1 your 
languages might accept a step as in

 A to B step C

but then if C can be positive or negative the compiler won't know whether 
you want the loop to execute or not. If you intend the loop to always ascend 
and C to be positive but don't know for sure that it is, for example, you 
might have to code

  if C > 0 then for X = A to B step C

Programmers would often omit the initial test of C and then because it 
didn't know whether C would be positive or negative the compiler would have 
to select different loop termination conditions dynamically - one for a 
rising step and the other for a falling step. Or perhaps the programmer 
wanted the difference between A and B to control the direction of the 
iteration and not the step. No one can know unless the syntax is changed so 
that something is added to the statement like a stepup or stepdown keyword. 
The whole thing is a terrible bundle of questions and uncertainties. C's for 
loop does away with all of them by allowing the programmer to state exactly 
what he or she wants.

Another issue is the terminating value. I remember in Basic having to write 
things like

  for i = a to b - 1

where the - 1 or something like it had to be added to modify the termination 
value. C's for loop allows a natural slight adjustment to the termination 
condition by means of < vs <=. Contrast these two

  for (i = 0; i < len; i++)
  for (i = 1; i <= len; i++)

Both of those are idiomatic. The requirement for a slight adjustment is 
common and can be expressed easily in C.

Further, a loop can be controlled by all kinds of things other than a 
stepping integer if that's what the programmer wants: input, lists, 
pointers, even floats can make sense with the < or <= qualifiers where they 
would be inappropriate for the A to B form.

Oh, and one more thing. This is related to the problems with your preference 
that I mentioned in the earlier post. Significant text has been written 
about whether the index might be modified during the course of the loop. And 
also whether the terminating value has to be constant or not. There are a 
number of permutations: loop index yes, terminating value no, neither, both 
etc. Different languages have chosen differently and their choices need to 
be documented in the language definition. These are yet more things for the 
programmer to remember. Again, C's for loop does away with all of that. The 
C code shows exactly what the programmer has chosen to be done. What you see 
in the code will be what the program is expected to do. No complex rules to 
remember. Very sweet, great design, IMO!

James

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


#2082 — Re: 100 Things

From"BartC" <bc@freeuk.com>
Date2014-04-30 22:40 +0100
SubjectRe: 100 Things
Message-ID<85e8v.227832$gV7.159905@fx21.am4>
In reply to#2081

"James Harris" <james.harris.1@gmail.com> wrote in message
news:ljria6$8ka$1@dont-email.me...
> "BartC" <bc@freeuk.com> wrote in message
> news:K278v.218753$vB1.137675@fx36.am4...

>> Yes, C's for loop is quite powerful and very flexible (although so are
>> 'if'
>> and 'goto'!). But it is possible to have both that, and a dedicated loop
>> for
>> the 99% of situations (in my case) where I do need a for-loop to just
>> count
>> from A to B.
>
> That reminds me of some more benefits of C's for construct. In addition to
> those mentioned before if you want a step of something other than 1 your
> languages might accept a step as in
>
> A to B step C
>
> but then if C can be positive or negative the compiler won't know whether
> you want the loop to execute or not. If you intend the loop to always
> ascend and C to be positive but don't know for sure that it is, for
> example, you might have to code
>
>  if C > 0 then for X = A to B step C
>
> Programmers would often omit the initial test of C and then because it
> didn't know whether C would be positive or negative the compiler would
> have to select different loop termination conditions dynamically - one for
> a rising step and the other for a falling step.

But how would C's for-loop help here? Surely you still have to choose
between a <= or >= terminating condition?

> Or perhaps the programmer wanted the difference between A and B to control
> the direction of the iteration and not the step. No one can know unless
> the syntax is changed so that something is added to the statement like a
> stepup or stepdown keyword. The whole thing is a terrible bundle of
> questions and uncertainties.

Maybe. Although over many years of programming the number of times I've
needed a step other then 1 or -1 has been so few, that I actually removed
the 'step' option from my for-loops for a couple of decades. I've put it
back now, but require the direction to be known or indicated at compile
time, otherwise it assumes positive. A dynamic loop-counting direction is
too unusual a requirement for it to compromise the simplicity of the
standard for-loop construct. There any number of ways to code such a thing
without special language support. But if you say it's easy in C, then the C
version is still there waiting to be dusted off!

> Another issue is the terminating value. I remember in Basic having to
> write things like
>
>  for i = a to b - 1
>
> where the - 1 or something like it had to be added to modify the
> termination value. C's for loop allows a natural slight adjustment to the
> termination condition by means of < vs <=. Contrast these two
>
>  for (i = 0; i < len; i++)
>  for (i = 1; i <= len; i++)

Yes, C is zero-based so 0..N-1 loops might be more common than 1..N.

My languages tend to be 1-based, but are also any-based, so loops might be

 for i :=A.lwb to A.upb do ....

But I can also write a for-loop as;

 for i in A.bounds do ....

or as just:

 for i in A do ...

(This 'in' form expects a range value, one of the new types I suggested in
my list).

Alternatively, if we are iterating over an array, it's possible to just do:

 forall x in A do....        # x is each value of A in turn
 forall i,x in A do ....         # and here supplies the index too.

These forms will work for arrays of any base include C's 0-based ones.

I suppose an alternative to 'to', such as 'upto' can indicate a count to N-1
instead of 1, but it hints a bit of tackiness. (I already have, in addition,
'downto', 'in' and 'inrev'. But so far just writing -1 hasn't been a
problem, and does away with an extra language feature to document.

> Further, a loop can be controlled by all kinds of things other than a
> stepping integer if that's what the programmer wants: input, lists,
> pointers, even floats can make sense with the < or <= qualifiers where
> they would be inappropriate for the A to B form.

Sure. I'm not saying discard this complex loop completely and just have a
basic iterative loop. I'm saying have the basic forms too for the simple
cases: 'for', 'to' and 'do'. Syntax is free!

> Oh, and one more thing. This is related to the problems with your
> preference that I mentioned in the earlier post. Significant text has been
> written about whether the index might be modified during the course of the
> loop. And also whether the terminating value has to be constant or not.
> There are a number of permutations: loop index yes, terminating value no,
> neither, both etc. Different languages have chosen differently and their
> choices need to be documented in the language definition. These are yet
> more things for the programmer to remember. Again, C's for loop does away
> with all of that. The C code shows exactly what the programmer has chosen
> to be done.

Not really. What happens here:

 for (i=0; i<strlen(s); ++i)  ?

Is strlen(s) always called once; is it called once if the compiler can
determine that s won't change; or is it called per-iteration?

-- 
Bartc 

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


#2083 — Re: 100 Things

FromKaz Kylheku <kaz@kylheku.com>
Date2014-04-30 22:09 +0000
SubjectRe: 100 Things
Message-ID<20140430150416.549@kylheku.com>
In reply to#2082
On 2014-04-30, BartC <bc@freeuk.com> wrote:
> Not really. What happens here:
>
>  for (i=0; i<strlen(s); ++i)  ?
>
> Is strlen(s) always called once; is it called once if the compiler can
> determine that s won't change; or is it called per-iteration?

Since strlen is a standard C function, the compiler can know that it has
no side effects, and that it can be hoisted out of the loop if the loop
doesn't alter the variable s, and doesn't potentially modify any memory
that could be inside s.

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


#2084 — Re: 100 Things

From"BartC" <bc@freeuk.com>
Date2014-04-30 23:36 +0100
SubjectRe: 100 Things
Message-ID<BWe8v.380788$H82.192335@fx23.am4>
In reply to#2083

"Kaz Kylheku" <kaz@kylheku.com> wrote in message
news:20140430150416.549@kylheku.com...
> On 2014-04-30, BartC <bc@freeuk.com> wrote:
>> Not really. What happens here:
>>
>>  for (i=0; i<strlen(s); ++i)  ?
>>
>> Is strlen(s) always called once; is it called once if the compiler can
>> determine that s won't change; or is it called per-iteration?
>
> Since strlen is a standard C function, the compiler can know that it has
> no side effects, and that it can be hoisted out of the loop if the loop
> doesn't alter the variable s, and doesn't potentially modify any memory
> that could be inside s.

But in the absence of optimisation, or if the compiler can't determine what
happens to s, the expectation seems to be that the terminating expression is
calculated repeatedly.

That's what I used to do, but now I calculate any such expression just once,
whether it can change or not. That's a slightly saner way of doing things as
the maximum loop iterations are known in advance. (That probably suits a
simpler iteration statement better than C's more open-ended one.)

(It also gives the compiler I'm working on now its first performance edge
over gcc:

int main(void) {
 char* s="one two three four five six seven eight nine ten eleven twelve";
 int i,n;

 for (n=1; n<=10000000; ++n)
  for (i=0; i<strlen(s); ++i) {}
}

20 seconds for the above (using -O0; anything else would just eliminate the
whole thing). But 2 seconds for my effort:

import clib

proc start=
 ichar s:="one two three four five six seven eight nine ten eleven twelve"

 to 10 million do
  to strlen(s) do
  od
 od

end

)

-- 
Bartc 

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


#2086 — Re: 100 Things

FromIan Collins <ian-news@hotmail.com>
Date2014-05-01 11:03 +1200
SubjectRe: 100 Things
Message-ID<bsddq3Fd2otU2@mid.individual.net>
In reply to#2084
BartC wrote:
> "Kaz Kylheku" <kaz@kylheku.com> wrote:
>>
>> Since strlen is a standard C function, the compiler can know that it has
>> no side effects, and that it can be hoisted out of the loop if the loop
>> doesn't alter the variable s, and doesn't potentially modify any memory
>> that could be inside s.
>
> But in the absence of optimisation, or if the compiler can't determine what
> happens to s, the expectation seems to be that the terminating expression is
> calculated repeatedly.
>
> That's what I used to do, but now I calculate any such expression just once,
> whether it can change or not. That's a slightly saner way of doing things as
> the maximum loop iterations are known in advance. (That probably suits a
> simpler iteration statement better than C's more open-ended one.)
>
> (It also gives the compiler I'm working on now its first performance edge
> over gcc:

Comparing performance without optimisation (or regards to correctness!) 
is pointless.

-- 
Ian Collins

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


#2096 — Re: 100 Things

From"BartC" <bc@freeuk.com>
Date2014-05-01 09:47 +0100
SubjectRe: 100 Things
Message-ID<hTn8v.204521$q95.152789@fx22.am4>
In reply to#2086

"Ian Collins" <ian-news@hotmail.com> wrote in message
news:bsddq3Fd2otU2@mid.individual.net...
> BartC wrote:
>> "Kaz Kylheku" <kaz@kylheku.com> wrote:
>>>
>>> Since strlen is a standard C function, the compiler can know that it has
>>> no side effects, and that it can be hoisted out of the loop if the loop
>>> doesn't alter the variable s, and doesn't potentially modify any memory
>>> that could be inside s.
>>
>> But in the absence of optimisation, or if the compiler can't determine
>> what
>> happens to s, the expectation seems to be that the terminating expression
>> is
>> calculated repeatedly.
>>
>> That's what I used to do, but now I calculate any such expression just
>> once,
>> whether it can change or not. That's a slightly saner way of doing things
>> as
>> the maximum loop iterations are known in advance. (That probably suits a
>> simpler iteration statement better than C's more open-ended one.)
>>
>> (It also gives the compiler I'm working on now its first performance edge
>> over gcc:
>
> Comparing performance without optimisation (or regards to correctness!) is
> pointless.

It's optimisation that would be pointless here because the fragment of code 
did nothing useful and so would be optimised away.

The point of interest is that C seems to specify that a loop terminator
expression is expected to be re-evaluated on each iteration (unless it can
figure out it doesn't need to be), whereas I've decided that it should be
evaluated once at the start of the loop. That gives a very easy advantage
(which I will need because there's no way I will match gcc's -O3
optimisations).

It's useful to the programmer as well because they then have the confidence
to write:

 for (i=0; i<strlen(s); ++i) ....

without having reservations about whether strlen(s) is going to be evaluated
once or strlen() times, or going to the trouble of storing strlen() is a
variable first.a

(And I have used this approach for many years without it being a problem. If
a loop limit is in fact a moving target, then that would need to be coded
differently, but needs a lot more care anyway.)

-- 
Bartc 

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


#2087 — Re: 100 Things

From"James Harris" <james.harris.1@gmail.com>
Date2014-05-01 00:35 +0100
SubjectRe: 100 Things
Message-ID<ljs1cm$kig$1@dont-email.me>
In reply to#2082
"BartC" <bc@freeuk.com> wrote in message 
news:85e8v.227832$gV7.159905@fx21.am4...
>
>
> "James Harris" <james.harris.1@gmail.com> wrote in message
> news:ljria6$8ka$1@dont-email.me...
>> "BartC" <bc@freeuk.com> wrote in message
>> news:K278v.218753$vB1.137675@fx36.am4...
>
>>> Yes, C's for loop is quite powerful and very flexible (although so are
>>> 'if'
>>> and 'goto'!). But it is possible to have both that, and a dedicated loop
>>> for
>>> the 99% of situations (in my case) where I do need a for-loop to just
>>> count
>>> from A to B.
>>
>> That reminds me of some more benefits of C's for construct. In addition 
>> to
>> those mentioned before if you want a step of something other than 1 your
>> languages might accept a step as in
>>
>> A to B step C
>>
>> but then if C can be positive or negative the compiler won't know whether
>> you want the loop to execute or not. If you intend the loop to always
>> ascend and C to be positive but don't know for sure that it is, for
>> example, you might have to code
>>
>>  if C > 0 then for X = A to B step C
>>
>> Programmers would often omit the initial test of C and then because it
>> didn't know whether C would be positive or negative the compiler would
>> have to select different loop termination conditions dynamically - one 
>> for
>> a rising step and the other for a falling step.
>
> But how would C's for-loop help here? Surely you still have to choose
> between a <= or >= terminating condition?

C's for loop allows the programmer to explicitly select <, <=, > or >. In 
what I understand to be your preferred syntax, though, there is nowhere to 
put the <= or >= terminating condition and there's nothing there to tell the 
compiler whether X is supposed to increase from A to B or to decrease from A 
to B. When the step is a signed variable or an expression that could be 
positive or negative and when the semantics of the language state that the 
sign of the step controls the direction of iteration how can the compiler 
generate code for the loop termination test? It needs to know the direction 
so that it knows whether to code the loop test as, say, <= or >=.

Alternatively if the language design is that the direction of the loop is to 
be controlled by the relative values of A and B rather than the step the 
compiler still has the same problem. It doesn't know whether X should ascend 
or descend and, hence, it doesn't know whether to go on while X <= B or to 
go on while X >= B. Poor compiler! I think it would have no choice but to 
write code for both tests and select between them at run time. Am I wrong?

By contrast I meant that in C one could write

  for (i = A; i <= B; i += C) /* for an ascending loop */

or

  for (i = A; i >= B; i -= C) /* for a descending loop */

and the job is done. Then there is no ambiguity over whether the loop 
variable is expected to increase or decrease. The effect in C doesn't need 
to be documented or remembered. What the programmer intends can be expressed 
clearly in the source code.

Don't get me wrong. I didn't just choose this at random. When I started on a 
design for loops I looked at the kinds of loop control you prefer. I spent 
some time on it, went over some of the same ground as I've mentioned and 
wrestled with the necessary choices: what I thought the semantics should be 
and/or how I could change the syntax so that the programmer's intentions 
could be made clear. In the end I realised the transparent simplicity of C's 
for statement removed all of those issues and just allows the programmer to 
state what is wanted.

That's not to say that there's no way to improve on C's for loop. ;-)

>> Or perhaps the programmer wanted the difference between A and B to 
>> control
>> the direction of the iteration and not the step. No one can know unless
>> the syntax is changed so that something is added to the statement like a
>> stepup or stepdown keyword. The whole thing is a terrible bundle of
>> questions and uncertainties.
>
> Maybe. Although over many years of programming the number of times I've
> needed a step other then 1 or -1 has been so few, that I actually removed
> the 'step' option from my for-loops for a couple of decades. I've put it
> back now, but require the direction to be known or indicated at compile
> time, otherwise it assumes positive. A dynamic loop-counting direction is
> too unusual a requirement for it to compromise the simplicity of the
> standard for-loop construct. There any number of ways to code such a thing
> without special language support. But if you say it's easy in C, then the 
> C
> version is still there waiting to be dusted off!

Yes, acknowledged that you can have both.

>> Another issue is the terminating value. I remember in Basic having to
>> write things like
>>
>>  for i = a to b - 1
>>
>> where the - 1 or something like it had to be added to modify the
>> termination value. C's for loop allows a natural slight adjustment to the
>> termination condition by means of < vs <=. Contrast these two
>>
>>  for (i = 0; i < len; i++)
>>  for (i = 1; i <= len; i++)
>
> Yes, C is zero-based so 0..N-1 loops might be more common than 1..N.
>
> My languages tend to be 1-based, but are also any-based, so loops might be
>
> for i :=A.lwb to A.upb do ....
>
> But I can also write a for-loop as;
>
> for i in A.bounds do ....
>
> or as just:
>
> for i in A do ...
>
> (This 'in' form expects a range value, one of the new types I suggested in
> my list).
>
> Alternatively, if we are iterating over an array, it's possible to just 
> do:
>
> forall x in A do....        # x is each value of A in turn
> forall i,x in A do ....         # and here supplies the index too.
>
> These forms will work for arrays of any base include C's 0-based ones.

Am going off topic a bit but I would be interested to hear your views on 
this. Because

  for x in A

is a good concept but, at the same time, a loop might need to iterate over 
two or more arrays rather than just one I have toyed with the following

    x = nextof A

Then each time the statement is reached x gets assigned the next value of A. 
Of course, this would normally appear in a loop. It could head a loop by 
writing something like

  loop x = nextof A
    ... loop body
  end loop

It is similar to your x in A approach but also allows other loop controls to 
be added to the same loop if required, along the lines of

  loop x = nextof A, y = nextof B
    ... loop body
  end loop

Exhaustion of either A or B would terminate the loop. A or B could be 
functions that generate sequences.

I like that the above is flexible (and also compact) but I don't think it's 
quite right yet. Any thoughts on it?

> I suppose an alternative to 'to', such as 'upto' can indicate a count to 
> N-1
> instead of 1, but it hints a bit of tackiness. (I already have, in 
> addition,
> 'downto', 'in' and 'inrev'. But so far just writing -1 hasn't been a
> problem, and does away with an extra language feature to document.
>
>> Further, a loop can be controlled by all kinds of things other than a
>> stepping integer if that's what the programmer wants: input, lists,
>> pointers, even floats can make sense with the < or <= qualifiers where
>> they would be inappropriate for the A to B form.
>
> Sure. I'm not saying discard this complex loop completely and just have a
> basic iterative loop. I'm saying have the basic forms too for the simple
> cases: 'for', 'to' and 'do'. Syntax is free!

Syntax is free and I freely acknowledge that you make good syntax choices. 
But consider: if a language includes the simpler form then its designer has 
to deal with and document its semantics for the age-old issues mentioned 
above and earlier. A given programmer may choose not to use the simpler form 
at all but if he or she has to read someone else's code the programmer might 
still need to learn the complex and somewhat arbitrary rules that the 
language applies to those loops.

>> Oh, and one more thing. This is related to the problems with your
>> preference that I mentioned in the earlier post. Significant text has 
>> been
>> written about whether the index might be modified during the course of 
>> the
>> loop. And also whether the terminating value has to be constant or not.
>> There are a number of permutations: loop index yes, terminating value no,
>> neither, both etc. Different languages have chosen differently and their
>> choices need to be documented in the language definition. These are yet
>> more things for the programmer to remember. Again, C's for loop does away
>> with all of that. The C code shows exactly what the programmer has chosen
>> to be done.
>
> Not really. What happens here:
>
> for (i=0; i<strlen(s); ++i)  ?
>
> Is strlen(s) always called once; is it called once if the compiler can
> determine that s won't change; or is it called per-iteration?

As you know, in the expressed form strlen is at least nominally called once 
per iteration. An optimising compiler might improve on that if it can prove 
that strlen(s) will not change in the loop but the programmer's intention is 
clear (even if unwise).

It's easy to rewrite in a better form such as either of these

  for (i = strlen(s) - 1; i >= 0; --i)
  for (i = 0, slen = strlen(s); i < slen; ++i)

Apart from processing the string in the same order as your original the 
latter has the advantage that if the code changes the length of the string 
then both slen and i can be adjusted as the iterations progress.

Don't worry. I don't expect to convince you and I can see the appeal of the 
simpler form.

James

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


#2102 — Re: 100 Things

FromAndy Walker <news@cuboid.co.uk>
Date2014-05-01 11:03 +0100
SubjectRe: 100 Things
Message-ID<JZo8v.62500$FD6.39366@fx10.fr7>
In reply to#2087
On 01/05/14 00:35, James Harris wrote:
> "BartC" <bc@freeuk.com> wrote in message
> news:85e8v.227832$gV7.159905@fx21.am4...

	[Not really the topic of this article, but I was (pleasantly)
surprised by how many of Bart's 115 Things I agreed with!  Anyway ...]

> C's for loop allows the programmer to explicitly select <, <=, > or >.

	Or, in other words, *forces* the programmer explicitly to select
[or, of course, to supply some other Boolean construct or (empty)], with
a decent chance of a resultant bug.

>									 In
> what I understand to be your preferred syntax, though, there is nowhere to
> put the <= or >= terminating condition and there's nothing there to tell the
> compiler whether X is supposed to increase from A to B or to decrease from A
> to B. When the step is a signed variable or an expression that could be
> positive or negative and when the semantics of the language state that the
> sign of the step controls the direction of iteration how can the compiler
> generate code for the loop termination test? It needs to know the direction
> so that it knows whether to code the loop test as, say, <= or >=.

	Yes, that's the sort of thing that compilers do.  But since a large
majority of loops in practice are incrementing by 1, a large majority of the
others are decrementing by 1, and a large majority of the few left over are
incrementing/decrementing by a compile-time constant, you're talking about
less than 1% of loops for which the test is slightly complicated, and so
performance takes a tiny hit.  That same hit is still there in C;  it's
inherent in not knowing at compile-time which way the loop will run [and
so the programmer having to write in that complexity "by hand"].

> Alternatively if the language design is that the direction of the loop is to
> be controlled by the relative values of A and B rather than the step the
> compiler still has the same problem. It doesn't know whether X should ascend
> or descend and, hence, it doesn't know whether to go on while X <= B or to
> go on while X >= B. Poor compiler! I think it would have no choice but to
> write code for both tests and select between them at run time. Am I wrong?

	No;  that's what compilers do.  See above!

> By contrast I meant that in C one could write
>    for (i = A; i <= B; i += C) /* for an ascending loop */
> or
>    for (i = A; i >= B; i -= C) /* for a descending loop */
> and the job is done.  Then there is no ambiguity over whether the loop
> variable is expected to increase or decrease.

	Even when you don't know the sign of C?  That way lie bugs!
But in any case, if you want that degree of control, C already has
the "while" loop.  The problem, such as it is, with C's loops is the
existence of *three* different loop syntaxes when only one is needed,
while still not having a proper "loop-and-a-half" syntax [beyond what
can be done with "break" and "continue"].

>						 The effect in C doesn't need
> to be documented or remembered. What the programmer intends can be expressed
> clearly in the source code.

	Not really.  It's only "clear" because C has acquired various
standard forms, so that "everyone knows" what "for (i = 0; i < n; i++)"
means, and we [with any luck] no longer get obscure bugs by writing
"i <= n" or by changing the value of "n" or "i" within the loop. It's
easy to forget how hard programming is to a beginner, or when you first
use a language which has made different choices from the language(s)
you are familiar with.

[...]
>>> Further, a loop can be controlled by all kinds of things other than a
>>> stepping integer if that's what the programmer wants: input, lists,
>>> pointers, even floats can make sense with the < or <= qualifiers where
>>> they would be inappropriate for the A to B form.
>> Sure. I'm not saying discard this complex loop completely and just have a
>> basic iterative loop. I'm saying have the basic forms too for the simple
>> cases: 'for', 'to' and 'do'.

	For loops other than with a stepping integer, you can, in all
sensible languages, use "while" instead:

	while read (x); x > 0 do print (sqrt(x)) od;
	while ptr /= 0 do { whatever }; ptr := ptr.next od

and so on.  Horses for courses!

>>				Syntax is free!
> Syntax is free  [...].

	No it isn't.  It's very cheap in compilation time, but that is
very cheap anyway these days.  It's not free in complexity of manuals
or syntax charts or however else people get used to your language, and
it's not free in design time if people have to deliberate [eg, in C]
over the choice between "for", "while" and "do" -- *especially* if [as
in C] the choice is not that important.

> But consider: if a language includes the simpler form then its designer has
> to deal with and document its semantics for the age-old issues mentioned
> above and earlier. A given programmer may choose not to use the simpler form
> at all but if he or she has to read someone else's code the programmer might
> still need to learn the complex and somewhat arbitrary rules that the
> language applies to those loops.

	This seems a bit strained!  How long does it take to learn that
"for i to n do stmt od" will evaluate "n" once and will obey "stmt" with
"i" set successively to 1, 2, 3, ,,,, n [and not at all if "n" is zero or
negative], whereas "while expr do stmt od" will repeatedly evaluate "expr"
and obey "stmt" for as long as "expr" returns the value "true"?  Now your
turn to explain the allegedly less complex and arbitrary rules that C has
for "for", "while" and "do" in less than four lines.

-- 
Andy Walker,
Nottingham.

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


#2116 — Re: 100 Things

From"BartC" <bc@freeuk.com>
Date2014-05-01 20:16 +0100
SubjectRe: 100 Things
Message-ID<z4x8v.236209$hB4.223271@fx20.am4>
In reply to#2102
"Andy Walker" <news@cuboid.co.uk> wrote in message
news:JZo8v.62500$FD6.39366@fx10.fr7...
> On 01/05/14 00:35, James Harris wrote:
>> "BartC" <bc@freeuk.com> wrote in message

>>> Syntax is free!
>> Syntax is free  [...].
>
> No it isn't.  It's very cheap in compilation time, but that is
> very cheap anyway these days.  It's not free in complexity of manuals
> or syntax charts or however else people get used to your language, and

Control statements are usually a tiny part of any language reference. (In a 
C# book I have, 'for' takes up one page out of 200. In a Lua reference, 
'for' is one screen out of about 100.)

But define your general 'for' statement like this example:

 for var := expr to expr by expr while expr do .... end

And make it possible to leave parts out, then you get at least four loop
statements in one: for, to, do, and while.

Anyway additional statements, that do not need to be part of the core
language, can be in an appendix. When someone has become familiar with the
language, then they can understand more easily these extra features without 
needing detailed explanations.

> it's not free in design time if people have to deliberate [eg, in C]
> over the choice between "for", "while" and "do" -- *especially* if [as
> in C] the choice is not that important.

I think more time can be spent in figuring out how to express their
requirements when the only constructs available are lacking (breaking out of
a two-level loop for example), or in simply typing (and sorting out typos)
when there is a lot of fiddly, unnecessary syntax:

  for (i=0; i<M; ++i)
   for (j=0; i<N; ++i)
    ....

The above is an interesting example; I had intended to leave in one typo
(the last 'i'), to show a typical problem, but eventually realised there
were two! Neither would occur with a statement that only requires a loop
variable to be written once. And sometimes a loop variable can be dispensed
with altogether, if it is not needed (eg. to M do ... ).

So throwing in extra syntax of the right kind, can increase productivity
(and improve readability).

(I know you can go too far if the syntax gets too 'cute', or puts too much
emphasis on compactness (Ruby for example), so it is necessary to be
restrained.)

-- 
Bartc 

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


#2105 — Re: 100 Things

From"BartC" <bc@freeuk.com>
Date2014-05-01 12:44 +0100
SubjectRe: 100 Things
Message-ID<Nsq8v.316223$%n2.142416@fx30.am4>
In reply to#2087
"James Harris" <james.harris.1@gmail.com> wrote in message
news:ljs1cm$kig$1@dont-email.me...
> "BartC" <bc@freeuk.com> wrote in message
> news:85e8v.227832$gV7.159905@fx21.am4...
>> "James Harris" <james.harris.1@gmail.com> wrote in message

>> But how would C's for-loop help here? Surely you still have to choose
>> between a <= or >= terminating condition?
>
> C's for loop allows the programmer to explicitly select <, <=, > or >. In
> what I understand to be your preferred syntax, though, there is nowhere to
> put the <= or >= terminating condition and there's nothing there to tell
> the compiler whether X is supposed to increase from A to B or to decrease
> from A to B.

Pretty much every language with a conventional (non-C) 'for' statement will
have a way to iterate up or down. I use:

for i:=A to B do            Step +1
for i:=A downto B do        Step -1
for i:=A to B by C do
for i:=A downto B by C do

With the 'by' forms expecting C to be a constant (either positive or
negative; it will make 'to' into 'downto' as needed). (If not, it is assumed
to be positive or negative respectively).

(BTW the 'downto' method is from Pascal, which I thought was a good
simplification in forcing a loop direction to be known at compile-time.)

> When the step is a signed variable or an expression that could be positive
> or negative and when the semantics of the language state that the sign of
> the step controls the direction of iteration how can the compiler generate
> code for the loop termination test? It needs to know the direction so that
> it knows whether to code the loop test as, say, <= or >=.

This is easy. You just don't worry about it. Or prohibit it when the
compiler can't figure out what to do.

> Alternatively if the language design is that the direction of the loop is
> to be controlled by the relative values of A and B rather than the step
> the compiler still has the same problem. It doesn't know whether X should
> ascend or descend and, hence, it doesn't know whether to go on while X <=
> B or to go on while X >= B. Poor compiler! I think it would have no choice
> but to write code for both tests and select between them at run time. Am I
> wrong?

(Have you ever looked at the code you've written, and counted how many times
you've used 'for', and what proportion use simple +1 or -1 iteration, and
what proportion used anything more complex?

You might be overestimating the number of times you need a more complex
loop.)

>> Alternatively, if we are iterating over an array, it's possible to just
>> do:
>>
>> forall x in A do....        # x is each value of A in turn
>> forall i,x in A do ....         # and here supplies the index too.

> Am going off topic a bit but I would be interested to hear your views on
> this. Because
>
>  for x in A
>
> is a good concept but, at the same time, a loop might need to iterate over
> two or more arrays rather than just one I have toyed with the following
>
>    x = nextof A
>
> Then each time the statement is reached x gets assigned the next value of
> A. Of course, this would normally appear in a loop. It could head a loop
> by writing something like
>
>  loop x = nextof A
>    ... loop body
>  end loop
>
> It is similar to your x in A approach

I'm not sure x=nextof A will work in the body, unless x is recognised as
being the official loop index or variable. Because some state is needed to
remember where it's up to.

At the head of a loop, then yes it's just another syntax for stepping to the
next value.

(In my 'for x in A' form, there is an implicit loop index behind the scenes
storing the state, which can be exposed by using 'for i,x in A'. You need
the index to write back into A (when x is the value of the element and not a
reference), to index a parallel array, for all sorts of things.

I haven't gotten around to using proper iterators yet. But probably too
advanced at this level.)

> but also allows other loop controls to be added to the same loop if
> required, along the lines of
>
>  loop x = nextof A, y = nextof B
>    ... loop body
>  end loop
>
> Exhaustion of either A or B would terminate the loop. A or B could be
> functions that generate sequences.

I do allow multiple arrays, but it is sometimes difficult to get across
exactly what they mean. If I write this (which is dynamic code);

a:=(10,20,30,40)
b:=(100,200,300,400,500)

forall i,x,y in a,b do
 println i,x,y
od

then the output is:

1 10 100
2 20 200
3 30 300
4 40 400

It goes with the length of A, so B needs to be at least the same length
(otherwise there's an array bounds error).

However, someone might expect the iteration to be nested (ie. the equivalent
of 'for x in a do for y in b do' but within the convenience of a single 
'for') and perform 5x6 iterations.

> I like that the above is flexible (and also compact) but I don't think
> it's quite right yet. Any thoughts on it?

No, it's fine, provided it's made clear the arrays are scanned in parallel.
Accessing the loop index however, either explicitly as I have it, or through
some construct, I think would be useful.

You might also have to clarify what happens when the arrays are modified
(made shorter or longer) within the loop. (As I implement it, the number of
iterations is fixed at the start of the loop. So it will miss out elements
if a list is extended, and generate a bounds error if shortened. Not a
sophisticated way to do it, but simple. and efficient.)

And, you might need 'prevof' in order to iterate backwards. (As you have it,
you scan scan A forwards, and B backwards in the same loop, which I can't do 
easily.)

-- 
Bartc
 

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


#2140 — Re: 100 Things

From"James Harris" <james.harris.1@gmail.com>
Date2014-05-02 11:11 +0100
SubjectRe: 100 Things
Message-ID<ljvr0j$cgl$1@dont-email.me>
In reply to#2105
"BartC" <bc@freeuk.com> wrote in message 
news:Nsq8v.316223$%n2.142416@fx30.am4...
> "James Harris" <james.harris.1@gmail.com> wrote in message
> news:ljs1cm$kig$1@dont-email.me...
>> "BartC" <bc@freeuk.com> wrote in message
>> news:85e8v.227832$gV7.159905@fx21.am4...
>>> "James Harris" <james.harris.1@gmail.com> wrote in message
>
>>> But how would C's for-loop help here? Surely you still have to choose
>>> between a <= or >= terminating condition?
>>
>> C's for loop allows the programmer to explicitly select <, <=, > or >. In
>> what I understand to be your preferred syntax, though, there is nowhere 
>> to
>> put the <= or >= terminating condition and there's nothing there to tell
>> the compiler whether X is supposed to increase from A to B or to decrease
>> from A to B.
>
> Pretty much every language with a conventional (non-C) 'for' statement 
> will
> have a way to iterate up or down. I use:
>
> for i:=A to B do            Step +1
> for i:=A downto B do        Step -1
> for i:=A to B by C do
> for i:=A downto B by C do
>
> With the 'by' forms expecting C to be a constant (either positive or
> negative; it will make 'to' into 'downto' as needed). (If not, it is 
> assumed
> to be positive or negative respectively).
>
> (BTW the 'downto' method is from Pascal, which I thought was a good
> simplification in forcing a loop direction to be known at compile-time.)

If "to" always meant "upto" and there was a separate "downto" the direction 
issue is resolved. Of course, the word "to" doesn't sound like it is always 
ascending and IIRC a Basic allowed "to" to step downwards as in

  for P = 10 to 1 step -1

But if "to" can mean either direction depending on the use of "by" that 
sounds a little complicated!

>> When the step is a signed variable or an expression that could be 
>> positive
>> or negative and when the semantics of the language state that the sign of
>> the step controls the direction of iteration how can the compiler 
>> generate
>> code for the loop termination test? It needs to know the direction so 
>> that
>> it knows whether to code the loop test as, say, <= or >=.
>
> This is easy. You just don't worry about it. Or prohibit it when the
> compiler can't figure out what to do.

Umm, not sure about that. Consider

  S = function_call();
  for P = Q to R step S;

Can the compiler figure out what to do? Probably not. Now compare that with

  S = -1;
  for P = Q to R step S;

Can the compiler figure out here what to do? Probably yes but only if it 
does data flow analysis. Yet the statement in question is the same in each 
case. I think your idea of defining the direction by a keyword is *much* 
better than stating that the step controls the direction.

>> Alternatively if the language design is that the direction of the loop is
>> to be controlled by the relative values of A and B rather than the step
>> the compiler still has the same problem. It doesn't know whether X should
>> ascend or descend and, hence, it doesn't know whether to go on while X <=
>> B or to go on while X >= B. Poor compiler! I think it would have no 
>> choice
>> but to write code for both tests and select between them at run time. Am 
>> I
>> wrong?
>
> (Have you ever looked at the code you've written, and counted how many 
> times
> you've used 'for', and what proportion use simple +1 or -1 iteration, and
> what proportion used anything more complex?

Sorry, I cannot say I have. So ... I have pulled out the following from the 
only significant piece of C I have worked on recently.

$ cat sformat.c | grep "^ *for"
    for (; padding_reqd-- > 0;) *p++ = pad_char;
  for (i = 0; i < qspaces; i++) *dest++ = ' ';
  for (i = 0; i < qzeroes; i++) *dest++ = '0';
  for (i = 0; i < qdigits; i++) *dest++ = *p++;
  for (i = 0; i < qspaces; i++) *dest++ = ' ';
  for (i = 0; i < qzeroes; i++) *dest++ = '0';
  for (i = 0; i < qdigits; i++) *dest++ = *p++;
  for (i = 0; i < qspaces; i++) *dest++ = ' ';
  for (i = 0; i < qzeroes; i++) *dest++ = '0';
  for (i = 0; i < qdigits; i++) *dest++ = *p++;
  for (; (ch = *f++);)
      for (more = 1; more;)
      for (;;)
        for (;;)
      for (more = 1; more;)

You can see a mixture in there. Some use your standard up paramaters, one 
counts down, one loops until it reaches a zero byte, two use a "more" flag 
and two others simply loop.

If you wanted to see a 90+% run of standard up or down parameters I bet you 
are disappointed! ;-) In reality this is just a sample piece of code and is 
not meant to be typical. I might use the standard up or down loops a lot 
more overall. The above forms just suited the code I was writing at the 
time.

As programmers we get in to the mindset of writing code in a certain way and 
tend to adapt the problem to the way our minds work. You maybe use the form 
you do so much because you have become accustomed to thinking in that way. 
Similarly, I expect I use C's for mechanism in the way I do because I have 
got used to that approach.

We started this subthread because you expressed surprise that few languages 
had added anything simpler to C's for loop. I have tried to explain why I 
think that C's approach is so good that it doesn't need the addition you 
would like, and why that addition can bring with it a lot of unwanted 
baggage.

My own loop preference is not C's but I still think C's form brilliantly 
simplifies some of these long-standing issues. Because of that and because 
it subsumes the type you prefer I am not surprised that other langages have 
copied C and not added another form.

> You might be overestimating the number of times you need a more complex
> loop.)

When programming in C I don't think of the C for loop as being complex; it 
seems quite natural to use.

In Python, however, I often write things like

  for record in records:

...

Thanks for your comments on my nextof call (snipped).

James

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


#2142 — Re: 100 Things

From"BartC" <bc@freeuk.com>
Date2014-05-02 13:32 +0100
SubjectRe: 100 Things
Message-ID<EfM8v.147725$vM2.40475@fx18.am4>
In reply to#2140
"James Harris" <james.harris.1@gmail.com> wrote in message
news:ljvr0j$cgl$1@dont-email.me...
> "BartC" <bc@freeuk.com> wrote in message

>>I use:
>>
>> for i:=A to B do            Step +1
>> for i:=A downto B do        Step -1
>> for i:=A to B by C do
>> for i:=A downto B by C do
>>
>> With the 'by' forms expecting C to be a constant (either positive or
>> negative; it will make 'to' into 'downto' as needed). (If not, it is
>> assumed
>> to be positive or negative respectively).
>>
>> (BTW the 'downto' method is from Pascal, which I thought was a good
>> simplification in forcing a loop direction to be known at compile-time.)
>
> If "to" always meant "upto" and there was a separate "downto" the
> direction issue is resolved. Of course, the word "to" doesn't sound like
> it is always ascending and IIRC a Basic allowed "to" to step downwards as
> in
>
>  for P = 10 to 1 step -1
>
> But if "to" can mean either direction depending on the use of "by" that
> sounds a little complicated!

Lua just uses "," in place of "to". In that sense, "," defines both
directions, but needs an explicit -1 step for a downward loop. So the idea
was that "to" could be used in the same way, if the user wants to:

for i:=a to b by 1
for i:=a to b by -1

The "downto" form is an easy and obvious alternative to the -1 step, however
an explicit step size here is more ambiguous:

for i:=a downto b by 1
for i:=a downto b by -1

Do these both count downwards? Perhaps the compiler apply -abs() to the step
which is added to at each iteration.

>> This is easy. You just don't worry about it. Or prohibit it when the
>> compiler can't figure out what to do.
>
> Umm, not sure about that. Consider
>
>  S = function_call();
>  for P = Q to R step S;
>
> Can the compiler figure out what to do? Probably not. Now compare that
> with
>
>  S = -1;
>  for P = Q to R step S;
>
> Can the compiler figure out here what to do?

But what about:

 for P = Q to R step function_call();

Here the loop could be oscillating backwards and forwards! The sensible
thing here is calculate the step only at the start then have it invariant
(if it isn't already so).

A loop which is always counts up or down, but which it is is not known until
runtime, a compiler can just about deal with (but will be inefficient as
this check needs to be done per iteration, unless you duplicate the loop 
body). One that constantly change direction would be too messy though, and 
too odd for a compiler to spend too much time supporting.

My decision (and Pascal's) is that a loop direction must be determinable at
compile time.

>> (Have you ever looked at the code you've written, and counted how many
>> times
>> you've used 'for', and what proportion use simple +1 or -1 iteration, and
>> what proportion used anything more complex?
>
> Sorry, I cannot say I have. So ... I have pulled out the following from
> the only significant piece of C I have worked on recently.
>
> $ cat sformat.c | grep "^ *for"
>  for (; padding_reqd-- > 0;) *p++ = pad_char;
>  for (i = 0; i < qspaces; i++) *dest++ = ' ';
>  for (i = 0; i < qzeroes; i++) *dest++ = '0';
>  for (i = 0; i < qdigits; i++) *dest++ = *p++;
>  for (i = 0; i < qspaces; i++) *dest++ = ' ';
>  for (i = 0; i < qzeroes; i++) *dest++ = '0';
>  for (i = 0; i < qdigits; i++) *dest++ = *p++;
>  for (i = 0; i < qspaces; i++) *dest++ = ' ';
>  for (i = 0; i < qzeroes; i++) *dest++ = '0';
>  for (i = 0; i < qdigits; i++) *dest++ = *p++;
>  for (; (ch = *f++);)
>  for (more = 1; more;)
>  for (;;)
>  for (;;)
>  for (more = 1; more;)
>
> You can see a mixture in there. Some use your standard up paramaters, one
> counts down, one loops until it reaches a zero byte, two use a "more" flag
> and two others simply loop.
>
> If you wanted to see a 90+% run of standard up or down parameters I bet
> you are disappointed! ;-) In reality this is just a sample piece of code
> and is not meant to be typical.

But in this sample:

* There are 15 for-loops, as written
* 2 of those are infinite loops, which I wouldn't have written as for (but
as do .... end)
* 4 of them look like they'd be happier as while-loops

That leaves 9, all of which appear to be simple iterations (all upwards and 
with a step of 1). They are also all 0 to N-1 loops, however .... done of 
those appear to use the loop index, socould have been written as 1..N, or 
even with loop index at all, as what I call 'to' loops.

So this is inconclusive, except to show that you like using for(a;b;c) loops
for all sorts of purposes other than actual iteration! So more sample data
is needed.

However, this is what the 15 loops look when rewritten using what I consider
the most apt loop statement (I appreciate that C will not have the 'do' and
'to' forms unless you create a macro version). (I've taken the liberty of
switching syntax):

while padding_reqd-- >0 do ...
to qspaces do dest++^:=' ' end
to qzeroes do ...
to qdigits do ...
to qspaces do ...
to qzeroes do ...
to qdigits do ...
to qspaces do ...
to qzeroes do ...
to qdigits do ...
while (ch:=f++^) do ...
more:=1; while more do ...
do ...
do ...
more:=1; while more do ...

> We started this subthread because you expressed surprise that few
> languages had added anything simpler to C's for loop. I have tried to
> explain why I think that C's approach is so good that it doesn't need the
> addition you would like, and why that addition can bring with it a lot of
> unwanted baggage.

Well, OK. I think (for most of the above examples) having to introduce a 
variable i, initialise it, increment it, and compare it to N, is also quite 
a bit of baggage compared with just writing N!

-- 
Bartc 

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


#2143 — Re: 100 Things

From"James Harris" <james.harris.1@gmail.com>
Date2014-05-02 16:42 +0100
SubjectRe: 100 Things
Message-ID<lk0ecl$ihg$1@dont-email.me>
In reply to#2142
"BartC" <bc@freeuk.com> wrote in message 
news:EfM8v.147725$vM2.40475@fx18.am4...
> "James Harris" <james.harris.1@gmail.com> wrote in message
> news:ljvr0j$cgl$1@dont-email.me...
>> "BartC" <bc@freeuk.com> wrote in message
>
>>>I use:
>>>
>>> for i:=A to B do            Step +1
>>> for i:=A downto B do        Step -1
>>> for i:=A to B by C do
>>> for i:=A downto B by C do
>>>
>>> With the 'by' forms expecting C to be a constant (either positive or
>>> negative; it will make 'to' into 'downto' as needed). (If not, it is
>>> assumed
>>> to be positive or negative respectively).

I've just read that again and it still seems complicated. Have I got the 
following right?

  for i := A to B by C do (i.e. using *to*)
  - if C is a constant and positive the loop will count up
  - if C is a constant and negative the loop will count down
  - if C is a variable the loop will count up

  for i := A downto B by C do (i.e. using *downto*)
  - if C is a constant and positive the loop will count down (?)
  - if C is a constant and negative the loop will count down
  - if C is a variable the loop will count down

>>> (BTW the 'downto' method is from Pascal, which I thought was a good
>>> simplification in forcing a loop direction to be known at compile-time.)
>>
>> If "to" always meant "upto" and there was a separate "downto" the
>> direction issue is resolved. Of course, the word "to" doesn't sound like
>> it is always ascending and IIRC a Basic allowed "to" to step downwards as
>> in
>>
>>  for P = 10 to 1 step -1
>>
>> But if "to" can mean either direction depending on the use of "by" that
>> sounds a little complicated!
>
> Lua just uses "," in place of "to". In that sense, "," defines both
> directions, but needs an explicit -1 step for a downward loop. So the idea
> was that "to" could be used in the same way, if the user wants to:
>
> for i:=a to b by 1
> for i:=a to b by -1
>
> The "downto" form is an easy and obvious alternative to the -1 step, 
> however
> an explicit step size here is more ambiguous:
>
> for i:=a downto b by 1
> for i:=a downto b by -1
>
> Do these both count downwards? Perhaps the compiler apply -abs() to the 
> step
> which is added to at each iteration.

I'm not sure if you are saying your favoured loop works that way or not but 
none of those issues need to arise. With C the questions don't need to be 
asked. Nor do the answers need to be remembered.

>>> This is easy. You just don't worry about it. Or prohibit it when the
>>> compiler can't figure out what to do.
>>
>> Umm, not sure about that. Consider
>>
>>  S = function_call();
>>  for P = Q to R step S;
>>
>> Can the compiler figure out what to do? Probably not. Now compare that
>> with
>>
>>  S = -1;
>>  for P = Q to R step S;
>>
>> Can the compiler figure out here what to do?
>
> But what about:
>
> for P = Q to R step function_call();
>
> Here the loop could be oscillating backwards and forwards! The sensible
> thing here is calculate the step only at the start then have it invariant
> (if it isn't already so).

That depends on whether the step is resolved once before the loop starts or 
at the beginning of each iteration. And it is not apparent from the syntax 
(as discussed in previous posts).

> A loop which is always counts up or down, but which it is is not known 
> until
> runtime, a compiler can just about deal with (but will be inefficient as
> this check needs to be done per iteration, unless you duplicate the loop 
> body). One that constantly change direction would be too messy though, and 
> too odd for a compiler to spend too much time supporting.
>
> My decision (and Pascal's) is that a loop direction must be determinable 
> at
> compile time.

Going a bit off topic here but if you want to use that loop form why not 
just have upto and downto keywords? Then the loop direction is always 
immediately clear.

...

>> If you wanted to see a 90+% run of standard up or down parameters I bet
>> you are disappointed! ;-) In reality this is just a sample piece of code
>> and is not meant to be typical.
>
> But in this sample:

I did say this was not representative so you should not read too much in to 
it. But I can see from your reply that you think of these loops as different 
sorts. That's your preference.

My own language goes even further than C and reduces down to one loop type. 
After all a loop is a loop. You would love it. ;-)

...

>> We started this subthread because you expressed surprise that few
>> languages had added anything simpler to C's for loop. I have tried to
>> explain why I think that C's approach is so good that it doesn't need the
>> addition you would like, and why that addition can bring with it a lot of
>> unwanted baggage.
>
> Well, OK. I think (for most of the above examples) having to introduce a 
> variable i, initialise it, increment it, and compare it to N, is also 
> quite a bit of baggage compared with just writing N!

By baggage I meant the issues and questions that are associated with those 
kinds of loops but are not apparent in the syntax, i.e. all the questions we 
have discussed and for which there is no universally accepted model so that 
different languages use different choices.

Having said that, I should add that I could work with a language which had a 
simplified X to Y loop - as long as I could remember the answers to all the 
questions, that is. ;-)

James

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


#2144 — Re: 100 Things

From"BartC" <bc@freeuk.com>
Date2014-05-02 17:54 +0100
SubjectRe: 100 Things
Message-ID<%4Q8v.396809$H82.95203@fx23.am4>
In reply to#2143
"James Harris" <james.harris.1@gmail.com> wrote in message
news:lk0ecl$ihg$1@dont-email.me...

>>>> for i:=A to B do            Step +1
>>>> for i:=A downto B do        Step -1
>>>> for i:=A to B by C do
>>>> for i:=A downto B by C do
>>>>
>>>> With the 'by' forms expecting C to be a constant (either positive or
>>>> negative; it will make 'to' into 'downto' as needed). (If not, it is
>>>> assumed
>>>> to be positive or negative respectively).
>
> I've just read that again and it still seems complicated. Have I got the
> following right?

You're right, it's too complicated! It shouldn't be necessary to think twice
about a construction like this.

(TBH I haven't used 'for' with 'by' or 'step' yet; I'm not even sure if I've 
implemented it!)

So I will revise those forms of the statements to be:

for i:=a to b by c do        # always counts upwards
for i:=a downto b by c do    # always counts downwards

With perhaps abs() applied to c by the compiler to ensure the right
behaviour with downto.

> I'm not sure if you are saying your favoured loop works that way or not
> but none of those issues need to arise. With C the questions don't need to
> be asked. Nor do the answers need to be remembered.

There are some ambiguities with the C construct too (I think someone already
pointed this out):

for (i=a; i>=b; i-=c;) ....

This works as expected only when c is positive. (Or c is negative and you do
i+=c.)

(But my problem with it isn't so much that, it's this; when I first typed
this example, I mistyped it as 'for (i=a; i>=b; ++c)'. It's a lot easier to
write nonsense, but still have a legal program that gets past the compiler.)

> My own language goes even further than C and reduces down to one loop
> type. After all a loop is a loop. You would love it. ;-)

Maybe C's 'for' should have been named 'loop' since it's more general.

-- 
Bartc 

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


#2085 — Re: 100 Things

FromIan Collins <ian-news@hotmail.com>
Date2014-05-01 11:01 +1200
SubjectRe: 100 Things
Message-ID<bsddmvFd2otU1@mid.individual.net>
In reply to#2077
BartC wrote:
> "James Harris" <james.harris.1@gmail.com> wrote
>
>> In one stroke C's for loop removes those issues and makes it manifest in
>> the syntax what steps the program will take to control the loop. It
>> reduces a loop to the essentials and it means that one compact loop
>> control statement can be used in almost all types of loop. IMO that's
>> quite brilliant! I'm not surprised if it got copied to other languages.
>
> Yes, C's for loop is quite powerful and very flexible (although so are 'if'
> and 'goto'!). But it is possible to have both that, and a dedicated loop for
> the 99% of situations (in my case) where I do need a for-loop to just count
> from A to B.

Well C++ has a range for construct that simplifies things considerably.
For example, given some vector v,

for ( auto x : v ) doSomething(x);

will iterate through v.  I don't see any reason why this couldn't be 
added to C.

-- 
Ian Collins

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


Page 1 of 3  [1] 2 3  Next page →

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


csiph-web