Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #156943 > unrolled thread
| Started by | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| First post | 2020-12-05 08:25 -0800 |
| Last post | 2021-01-06 23:07 -0800 |
| Articles | 20 on this page of 399 — 24 participants |
Back to article view | Back to comp.lang.c
Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-05 08:25 -0800
Re: Programming exercise/challenge Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> - 2020-12-05 17:33 +0100
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 11:58 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-30 09:40 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-30 18:20 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-31 01:04 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-02 22:05 +0300
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-02 14:48 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-02 19:17 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-02 19:04 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-30 21:44 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-31 02:54 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-03 09:49 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-04 00:15 +0300
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-03 21:57 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-03 23:00 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-04 00:00 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-04 20:04 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-05 07:15 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-07 22:30 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-04 18:42 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-04 21:23 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-04 23:41 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 16:39 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 16:58 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 17:08 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-05 17:11 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 17:24 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-05 17:52 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 18:30 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-05 19:56 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-06 14:51 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-05 17:49 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 18:34 +0000
Re: Programming exercise/challenge Bonita Montero <Bonita.Montero@gmail.com> - 2020-12-05 19:40 +0100
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 18:47 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-05 23:19 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-05 23:56 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-08 02:26 +0000
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-08 16:04 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:39 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-12 23:34 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 19:28 -0800
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-29 10:34 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-29 20:05 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 06:03 -0800
Re: Programming exercise/challenge dfs <nospam@dfs.com> - 2020-12-05 13:58 -0500
Re: Programming exercise/challenge Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-12-05 21:37 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 06:13 -0800
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-06 18:00 +0100
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 12:31 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 06:26 -0800
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-05 23:32 +0100
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-06 17:18 +0100
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-06 17:51 +0100
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-06 22:27 +0000
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-07 09:37 +0100
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-07 07:36 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 22:49 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-06 17:51 +0000
Re: Programming exercise/challenge dfs <nospam@dfs.com> - 2020-12-06 13:03 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-06 23:53 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-06 19:53 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-06 23:38 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-07 00:17 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 02:09 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-07 01:03 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 12:05 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-07 12:25 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 13:33 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-07 14:18 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-07 14:31 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-07 12:58 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:03 -0800
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-07 07:12 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 21:55 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 22:59 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 22:55 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 07:45 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 11:26 -0800
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-12-24 12:24 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-24 17:19 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-27 05:16 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-27 04:17 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-27 08:27 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-29 19:18 -0800
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-07 05:15 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 13:42 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 22:53 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 01:49 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-10 22:35 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 21:17 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-12 21:44 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 19:46 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-13 12:21 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 11:35 -0800
Re: Programming exercise/challenge Rosario19 <Ros@invalid.invalid> - 2020-12-31 00:46 +0100
Re: Programming exercise/challenge Rosario19 <Ros@invalid.invalid> - 2020-12-31 00:52 +0100
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-31 00:34 -0800
Re: Programming exercise/challenge Rosario19 <Ros@invalid.invalid> - 2021-01-01 08:23 +0100
Re: Programming exercise/challenge Rosario19 <Ros@invalid.invalid> - 2021-01-01 10:09 +0100
Re: Programming exercise/challenge Rosario19 <Ros@invalid.invalid> - 2021-01-01 11:38 +0100
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-01 08:24 -0800
Re: Programming exercise/challenge "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2020-12-07 07:03 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-08 02:16 +0300
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 02:39 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:18 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:17 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-08 00:27 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:20 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-07 13:44 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-07 14:01 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 22:16 +0000
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-07 15:10 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-08 01:07 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-08 00:34 +0000
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-08 18:17 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-09 00:56 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 02:30 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-09 15:14 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-09 15:44 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-12 23:56 +0300
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-12 13:29 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 00:46 +0300
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-12 13:59 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 14:17 +0300
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-13 12:58 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-13 20:57 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-14 20:44 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-23 11:15 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-23 23:45 +0300
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-23 21:36 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-24 09:11 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 15:30 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-24 23:18 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-24 23:56 -0800
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2020-12-28 12:01 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-29 19:31 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 14:47 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-08 01:59 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:26 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-07 19:02 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-08 01:15 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-07 20:38 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-08 02:19 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-08 11:44 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-08 07:32 -0500
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-08 14:40 +0000
Re: Programming exercise/challenge "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2020-12-08 06:52 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-08 17:31 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-08 20:16 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-08 20:48 +0000
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-08 15:34 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 02:54 +0300
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 12:33 +0300
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 12:43 +0300
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-09 01:52 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 00:28 +0300
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-12 21:40 +0000
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-12 13:48 -0800
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-09 01:46 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:29 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-08 10:45 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-08 17:16 +0000
Re: Programming exercise/challenge "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2020-12-08 06:39 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-07 17:48 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-07 21:03 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 03:02 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 08:02 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-09 16:49 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 13:33 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-09 19:57 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-10 01:45 +0000
Re: Programming exercise/challenge Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2020-12-10 02:15 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 11:24 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 21:57 -0500
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-10 03:32 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-10 08:19 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 11:04 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-24 19:34 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-08 02:22 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 03:04 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-09 11:59 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 08:11 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 00:02 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-10 15:12 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 10:36 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-10 22:11 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-10 23:34 +0000
Re: Programming exercise/challenge "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2020-12-10 20:11 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 21:06 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 03:03 +0300
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-08 21:21 -0500
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 12:50 +0300
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2020-12-09 08:16 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-08 23:32 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-09 12:21 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-02 19:15 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-07 01:54 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-22 22:36 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-22 23:07 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-22 20:27 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-23 13:05 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 07:45 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-23 16:49 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 11:22 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-23 16:53 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 09:55 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 21:35 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-24 18:17 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 07:57 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 11:28 -0800
Re: Programming exercise/challenge "jfbod...@gmail.com" <jfbode1029@gmail.com> - 2020-12-08 11:30 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-08 20:31 +0000
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-08 22:17 +0100
Re: Programming exercise/challenge jacobnavia <jacob@jacob.remcomp.fr> - 2020-12-08 22:15 +0100
Re: Programming exercise/challenge "jfbod...@gmail.com" <jfbode1029@gmail.com> - 2020-12-08 13:28 -0800
Re: Programming exercise/challenge "jfbod...@gmail.com" <jfbode1029@gmail.com> - 2020-12-09 12:05 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 00:04 +0300
Re: Programming exercise/challenge Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2020-12-08 21:38 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 03:25 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-09 01:00 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-09 03:09 +0000
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 00:35 +0300
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-12 22:57 +0000
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-12 23:43 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 19:47 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 23:27 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-13 14:44 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 11:47 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 03:36 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-09 14:51 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 11:35 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-10 02:33 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 00:05 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-10 14:59 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 20:32 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-12 23:45 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 19:24 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-13 00:17 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-12 19:23 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-09 19:31 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 12:01 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-09 12:25 -0800
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-23 01:00 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-24 14:34 -0800
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-26 23:03 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-27 06:29 -0800
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-28 11:52 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-29 00:38 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-28 15:29 +0300
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-28 17:12 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-28 23:54 -0800
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-29 10:26 -0600
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-29 10:37 -0600
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-29 19:59 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-30 09:17 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2020-12-31 16:54 +0300
Re: Programming exercise/challenge kegs@provalid.com (Kent Dickey) - 2020-12-31 09:16 -0600
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2020-12-31 15:56 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-07 02:41 -0800
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-31 13:01 -0800
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-12-31 14:15 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-01 08:03 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-01 07:42 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-02 21:59 +0300
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-02 14:52 -0500
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-01-02 12:30 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-02 18:17 -0500
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-02 19:22 -0500
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-01-02 17:48 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-02 22:35 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-02 18:02 -0800
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-01-03 00:42 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-04 20:12 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-04 07:04 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-04 20:22 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 04:24 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-05 06:22 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 08:55 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-05 20:22 +0300
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-05 20:27 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-05 14:20 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-05 17:23 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 10:18 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-05 18:57 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 12:58 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-05 17:31 -0500
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-05 17:50 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 19:33 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-05 23:02 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 21:00 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-06 07:42 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-06 08:55 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-06 13:29 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-06 14:09 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-06 22:11 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-07 03:10 -0800
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-07 06:40 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-09 06:27 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-10 04:32 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-11 06:58 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-11 14:40 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-15 09:46 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-17 04:13 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-17 14:18 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-17 18:02 +0000
Re: Programming exercise/challenge Richard Damon <Richard@Damon-Family.org> - 2021-01-17 15:12 -0500
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-17 21:39 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-20 10:57 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-21 11:37 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-22 00:30 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-22 09:09 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-22 13:47 -0500
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-22 19:00 +0000
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-22 19:42 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-22 21:16 +0000
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-22 16:41 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 17:46 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 09:51 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-23 18:38 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 04:52 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-23 15:45 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 09:04 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-23 23:10 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 15:39 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-23 15:59 +0000
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-25 11:40 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 09:47 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-23 18:32 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 17:26 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-24 01:55 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 08:40 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-23 20:51 -0800
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-01-24 02:28 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-24 03:49 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-24 15:38 +0300
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-01-24 14:04 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-25 07:26 -0800
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-25 16:58 +0100
Re: Programming exercise/challenge luser droog <luser.droog@gmail.com> - 2021-01-25 09:14 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 07:32 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-27 16:24 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-28 00:11 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-01-28 12:25 +0300
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-28 06:18 -0500
Re: Programming exercise/challenge Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-01-28 16:54 +0300
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-28 09:15 -0500
Re: Programming exercise/challenge Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-01-28 20:07 +0300
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-28 15:58 -0500
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-29 00:07 +0300
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-28 16:17 -0500
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-29 00:03 +0300
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-01-28 03:37 -0800
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-28 22:50 +0000
Re: Programming exercise/challenge Anton Shepelev <anton.txt@gmail.com> - 2021-01-30 23:14 +0300
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-30 20:49 +0000
Re: Programming exercise/challenge M Joshua Ryan <luser.droog@gmail.com> - 2021-01-28 00:05 -0600
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-27 11:51 -0800
Re: Programming exercise/challenge Bart <bc@freeuk.com> - 2021-01-25 17:22 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-25 12:21 -0800
Re: Programming exercise/challenge Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-01-25 14:27 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-25 19:41 -0800
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-26 04:46 +0000
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-26 06:30 -0800
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-26 15:46 +0100
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-27 03:43 -0800
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-27 13:43 +0100
Re: Programming exercise/challenge Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-01-27 17:51 +0300
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-27 11:02 -0500
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-27 17:03 +0100
Re: Programming exercise/challenge Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-01-27 07:21 -0800
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-27 17:09 +0100
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-27 17:04 +0000
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-28 10:41 +0100
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-28 18:25 +0000
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-28 10:44 +0100
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-28 21:33 +0000
Re: Programming exercise/challenge David Brown <david.brown@hesbynett.no> - 2021-01-29 10:39 +0100
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-25 23:52 -0500
Re: Programming exercise/challenge Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-26 11:37 +0000
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 08:04 -0800
Re: Programming exercise/challenge Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-01-27 19:16 +0300
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 23:38 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 13:43 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-28 03:16 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-28 06:42 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-28 13:01 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-06 13:35 -0500
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-06 19:27 +0000
Re: Programming exercise/challenge Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-06 21:25 +0000
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-06 00:37 -0500
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-06 04:34 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-06 11:54 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-05 15:28 -0800
Re: Programming exercise/challenge James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-05 13:27 -0500
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-05 15:43 -0800
Re: Programming exercise/challenge Dave Dunfield <dave.dunfield@gmail.com> - 2021-01-05 20:10 -0800
Re: Programming exercise/challenge Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-06 23:07 -0800
Page 1 of 20 [1] 2 3 … 20 Next page →
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-12-05 08:25 -0800 |
| Subject | Programming exercise/challenge |
| Message-ID | <86wnxwkyol.fsf@linuxsc.com> |
Prompted by some recent discussion regarding 'goto' statements and state machines, I would like to propose a programming exercise. (It is perhaps a bit too large to be called an exercise, but not so difficult that it deserves the label of challenge. On the other hand there are some constraints so maybe challenge is apropos. In any case somewhere in between those two bounds.) Short problem statement: a C program to remove comments from C source input. Specifics: Remove both /*...*/ and //... style comments. Don't worry about trigraphs. Read from stdin, write to stdout, and diagnostics (if any) go to stderr. If EOF is seen inside a comment, do something sensible but it doesn't matter what as long as it's sensible. Use no 'goto' statements. Limit function bodies to no more than 25 lines. Other: feel free to handle corner cases as you see fit, as long as there is some description of what choice was made. Hopefully it will be a fun exercise. It isn't trivial but it shouldn't take too long either.
[toc] | [next] | [standalone]
| From | Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> |
|---|---|
| Date | 2020-12-05 17:33 +0100 |
| Message-ID | <5fcbb652$0$16505$e4fe514c@textnews.kpn.nl> |
| In reply to | #156943 |
On 05.12.20 17:25, Tim Rentsch wrote: > Prompted by some recent discussion regarding 'goto' statements and > state machines, I would like to propose a programming exercise. > (It is perhaps a bit too large to be called an exercise, but not so > difficult that it deserves the label of challenge. On the other > hand there are some constraints so maybe challenge is apropos. In > any case somewhere in between those two bounds.) > > Short problem statement: a C program to remove comments from C > source input. > > Specifics: Remove both /*...*/ and //... style comments. Don't > worry about trigraphs. Read from stdin, write to stdout, and > diagnostics (if any) go to stderr. If EOF is seen inside a > comment, do something sensible but it doesn't matter what as long > as it's sensible. Use no 'goto' statements. Limit function > bodies to no more than 25 lines. > > Other: feel free to handle corner cases as you see fit, as long > as there is some description of what choice was made. > > Hopefully it will be a fun exercise. It isn't trivial but it > shouldn't take too long either. > If you show yours , maybe some of us will show theirs........
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-12-06 11:58 -0800 |
| Message-ID | <86pn3mk8p7.fsf@linuxsc.com> |
| In reply to | #156945 |
Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> writes: > On 05.12.20 17:25, Tim Rentsch wrote: > >> [statement of problem] > > If you show yours , maybe some of us will show theirs........ I'm interested to see what people come up with on their own, and posting some of my code early would interfere with that. So I would like to wait until there are two or more submissions that at least make an effort to follow the guidelines. At some point I expect I will time out and post something anyway even if there are no submissions, but I don't have any fixed time in mind for when that would be. By the way, the guidelines are not arbitrary. I think everyone understands that the problem can be solved with a very large function with lots of goto's, or a very large function with a big switch() statement in a while() loop. Both goto's and large functions have been argued against in the earlier thread about goto's and state machines. Part of my reason for suggesting this problem (and with the guidelines as stated) is to see how trying to follow that advice might affect a solution to this kind of problem.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-12-30 09:40 -0800 |
| Message-ID | <86a6tvur8x.fsf@linuxsc.com> |
| In reply to | #156945 |
Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> writes:
> On 05.12.20 17:25, Tim Rentsch wrote:
>
>> Prompted by some recent discussion regarding 'goto' statements and
>> state machines, I would like to propose a programming exercise.
>> (It is perhaps a bit too large to be called an exercise, but not so
>> difficult that it deserves the label of challenge. On the other
>> hand there are some constraints so maybe challenge is apropos. In
>> any case somewhere in between those two bounds.)
>>
>> Short problem statement: a C program to remove comments from C
>> source input. [...]
>
> If you show yours , maybe some of us will show theirs........
If you have been waiting for me, here it is.
This program is basically the same as the one I wrote just before
posting the exercise statement, not counting some cosmetic
cleanup and a change so comments would be replaced by a single
blank.
/* uncomment.c - remove comments from C source files */
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long Count;
typedef enum {
ALL_GOOD = 0,
UNTERMINATED_CHARACTER_LITERAL,
UNTERMINATED_STRING,
UNTERMINATED_COMMENT,
} Status;
typedef Status Reader_f( Count );
static Status restart( int );
static Reader_f
start,
sl, slbs,
slsl, slslbs,
slst, slstst, slststbs,
sq, sqbs, sqbsbs, sqbs__,
dq, dqbs, dqbsbs, dqbs__;
static Count show_sl_lcs_bs( Count );
static Count show_sl_lcs( Count );
static Count show_lcs( Count );
static int next( void );
static int outc( int );
enum {
SQ = '\'',
DQ = '\"',
SL = '/',
STAR = '*',
BS = '\\',
NL = '\n',
SP = ' ',
};
/* main */
int
main(){
return start(0) == ALL_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* top level */
Status
restart( int c ){
return ungetc( c, stdin ), start( 0 );
}
Status
start( Count n ){
int c = getchar();
return c == SL ? sl( 0 )
: c == DQ ? outc( c ), dq( 0 )
: c == SQ ? outc( c ), sq( 0 )
: c != EOF ? outc( c ), start( 0 )
:/* c == EOF */ ALL_GOOD;
}
/* slant character - top level */
Status
sl( Count n ){
int c = getchar();
return c == SL ? slsl( 0 )
: c == STAR ? slst( 0 )
: c == EOF ? show_sl_lcs( n ), ALL_GOOD
: c != BS ? show_sl_lcs( n ), restart( c )
:/* c == BS */ slbs( n );
}
Status
slbs( Count n ){
int c = getchar();
return c == EOF ? show_sl_lcs_bs( n ), ALL_GOOD
: c != NL ? show_sl_lcs_bs( n ), restart( c )
:/* c == NL */ sl( n+1 );
}
/* slant character helper functions - show counted line splices */
Count
show_sl_lcs_bs( Count n ){
return show_sl_lcs( n ), outc( BS ), 0;
}
Count
show_sl_lcs( Count n ){
return outc( SL ), show_lcs( n );
}
Count
show_lcs( Count n ){
return n > 0 ? outc( BS ), outc( NL ), show_lcs( n-1 ) : 0;
}
/* new style C comment - 'slsl' */
Status
slsl( Count n ){
int c = getchar();
return c == NL ? outc( c ), start( 0 )
: c == BS ? slslbs( n )
: c == EOF ? outc( NL ), ALL_GOOD
: slsl( 0 );
}
Status
slslbs( Count n ){
int c = getchar();
return c == NL ? slsl( 0 )
: c == EOF ? outc( NL ), ALL_GOOD
: c == BS ? slslbs( 0 )
: slsl( 0 );
}
/* old style C comment - 'slst' */
Status
slst( Count n ){
int c = getchar();
return c == EOF ? outc( NL ), UNTERMINATED_COMMENT
: c == NL ? slst( 0 )
: c == STAR ? slstst( 0 )
: slst( 0 );
}
Status
slstst( Count n ){
int c = getchar();
return c == EOF ? UNTERMINATED_COMMENT
: c == NL ? slst( 0 )
: c == SL ? outc( SP ), start( 0 )
: c == STAR ? slstst( 0 )
: c == BS ? slststbs( 0 )
: slst( 0 );
}
Status
slststbs( Count n ){
int c = getchar();
return c == EOF ? UNTERMINATED_COMMENT
: c == NL ? slstst( 0 )
: c == STAR ? slstst( 0 )
: slst( 0 );
}
/* character literals - 'sq' */
Status
sq( Count n ){
int c = next();
return c == SQ ? start( 0 )
: c == NL ? UNTERMINATED_CHARACTER_LITERAL
: c == EOF ? UNTERMINATED_CHARACTER_LITERAL
: c == BS ? sqbs( 0 )
: sq( 0 );
}
Status
sqbs( Count n ){
int c = next();
return c == NL ? sq( 0 )
: c == EOF ? UNTERMINATED_CHARACTER_LITERAL
: c == BS ? sqbsbs( 0 )
: sq( 0 );
}
Status
sqbsbs( Count n ){
int c = next();
return c == NL ? sqbs__( 0 )
: c == EOF ? UNTERMINATED_CHARACTER_LITERAL
: c == SQ ? start( 0 )
: c == BS ? sqbs( 0 )
: sq( 0 );
}
Status
sqbs__( Count n ){
int c = next();
return c == NL ? UNTERMINATED_CHARACTER_LITERAL
: c == EOF ? UNTERMINATED_CHARACTER_LITERAL
: c == BS ? sqbsbs( 0 )
: sq( 0 );
}
/* string literals - 'dq' */
Status
dq( Count n ){
int c = next();
return c == DQ ? start( 0 )
: c == NL ? UNTERMINATED_STRING
: c == EOF ? UNTERMINATED_STRING
: c == BS ? dqbs( 0 )
: dq( 0 );
}
Status
dqbs( Count n ){
int c = next();
return c == NL ? dq( 0 )
: c == EOF ? UNTERMINATED_STRING
: c == BS ? dqbsbs( 0 )
: dq( 0 );
}
Status
dqbsbs( Count n ){
int c = next();
return c == NL ? dqbs__( 0 )
: c == EOF ? UNTERMINATED_STRING
: c == DQ ? start( 0 )
: c == BS ? dqbs( 0 )
: dq( 0 );
}
Status
dqbs__( Count n ){
int c = next();
return c == NL ? UNTERMINATED_STRING
: c == EOF ? UNTERMINATED_STRING
: c == BS ? dqbsbs( 0 )
: dq( 0 );
}
/* character input */
int
next(){
return outc( getchar() );
}
/* output */
int
outc( int c ){
return c != EOF ? putchar( c ), c : c;
}
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2020-12-30 18:20 +0000 |
| Message-ID | <xx3HH.1067689$LMma.715632@fx47.ams4> |
| In reply to | #157908 |
On 30/12/2020 17:40, Tim Rentsch wrote: > Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> writes: > If you have been waiting for me, here it is. > > This program is basically the same as the one I wrote just before > posting the exercise statement, not counting some cosmetic > cleanup and a change so comments would be replaced by a single > blank. > > > /* uncomment.c - remove comments from C source files */ <snip> Does this program rely heavily on recursion? Because it tends to crash across all compilers I tried, including gcc -O0, on the handful of test files I used, mostly in the 1000s of lines. But it didn't crash with gcc -O3, leading me to suspect that any recursion was optimised out. I don't know if one of the task requirements was to have a solution that could usefully be used on typical C programs, or if another was for it to be in reasonably portable C that didn't rely on specific compilers and options.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-12-31 01:04 -0800 |
| Message-ID | <86wnwytkg7.fsf@linuxsc.com> |
| In reply to | #157910 |
Bart <bc@freeuk.com> writes:
> On 30/12/2020 17:40, Tim Rentsch wrote:
>
>> Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> writes:
>>
>> If you have been waiting for me, here it is.
>>
>> This program is basically the same as the one I wrote just before
>> posting the exercise statement, not counting some cosmetic
>> cleanup and a change so comments would be replaced by a single
>> blank.
>>
>>
>> /* uncomment.c - remove comments from C source files */
>
> <snip>
>
> Does this program rely heavily on recursion?
>
> Because it tends to crash across all compilers I tried, including gcc
> -O0, on the handful of test files I used, mostly in the 1000s of
> lines.
>
> But it didn't crash with gcc -O3, leading me to suspect that any
> recursion was optimised out.
>
> I don't know if one of the task requirements was to have a solution
> that could usefully be used on typical C programs, or if another was
> for it to be in reasonably portable C that didn't rely on specific
> compilers and options.
Apart from the description of what the program is to do (namely,
remove comments), the task requirements were stated clearly in
the original posting:
Use no 'goto' statements.
Limit function bodies to no more than 25 lines (later
revised to no more than 30-35 lines).
Of the nine summarized participants (not counting myself), all
but one followed the first stipulation, and five out of nine
followed the second stipulation.
[toc] | [prev] | [next] | [standalone]
| From | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| Date | 2021-01-02 22:05 +0300 |
| Message-ID | <20210102220509.a5956ea29c0c8b1e0a0d64c4@gmail.com> |
| In reply to | #157910 |
Bart: > Does this program rely heavily on recursion? > > Because it tends to crash across all compilers I tried, > including gcc -O0, on the handful of test files I used, > mostly in the 1000s of lines. There are two kinds of programmer: those who consider recursion a form of the loop and those who consider the loop a form of recursion. I think that the former approach is at discord with the philosophy of imperative procedural languages, where the code directly expresses actions rather than "declaring" them in some vague indirect way. I believe the original ISO C had no provision for tail-call optimisation, and rightly so: if you want a loop, write loop. -- () ascii ribbon campaign -- against html e-mail /\ http://preview.tinyurl.com/qcy6mjc [archived]
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2021-01-02 14:48 -0500 |
| Message-ID | <U54IH.56827$VZ1.53462@fx44.iad> |
| In reply to | #158103 |
On 1/2/21 2:05 PM, Anton Shepelev wrote: > Bart: > >> Does this program rely heavily on recursion? >> >> Because it tends to crash across all compilers I tried, >> including gcc -O0, on the handful of test files I used, >> mostly in the 1000s of lines. > > There are two kinds of programmer: those who consider > recursion a form of the loop and those who consider the loop > a form of recursion. I think that the former approach is at > discord with the philosophy of imperative procedural > languages, where the code directly expresses actions rather > than "declaring" them in some vague indirect way. I believe > the original ISO C had no provision for tail-call > optimisation, and rightly so: if you want a loop, write > loop. > Tail call optimization falls fulling under the AS-IF rule, If the compiler can generate code that works as if the call was made without actually using a call but just a jump, it can do so if it wants (but isn't required to). It can sometimes be a bit of work to confirm that it is ok to make the optimization, because little things like the address of any local variable leaking out of the context invalidates it. I do agree that if it is important to the program that tail call optimization be done, then the programmer should apply the transform themselves, and not hope that the compiler will do it. Just like factoring out expensive expressions that are known to be loop invariant.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-01-02 19:17 -0800 |
| Message-ID | <86pn2mso8u.fsf@linuxsc.com> |
| In reply to | #158107 |
Richard Damon <Richard@Damon-Family.org> writes: > On 1/2/21 2:05 PM, Anton Shepelev wrote: > >> Bart: >> >>> Does this program rely heavily on recursion? >>> >>> Because it tends to crash across all compilers I tried, >>> including gcc -O0, on the handful of test files I used, >>> mostly in the 1000s of lines. >> >> There are two kinds of programmer: those who consider >> recursion a form of the loop and those who consider the loop >> a form of recursion. I think that the former approach is at >> discord with the philosophy of imperative procedural >> languages, where the code directly expresses actions rather >> than "declaring" them in some vague indirect way. I believe >> the original ISO C had no provision for tail-call >> optimisation, and rightly so: if you want a loop, write >> loop. > > Tail call optimization falls fulling under the AS-IF rule, If the > compiler can generate code that works as if the call was made without > actually using a call but just a jump, it can do so if it wants (but > isn't required to). Yes, and vice versa: an iterative form may be compiled as a recursive function. Of course normally this doesn't happen, but both are allowed. > It can sometimes be a bit of work to confirm that it is ok to make the > optimization, because little things like the address of any local > variable leaking out of the context invalidates it. Yes, and there are other aspects that can prevent tail call optimization, including some that are not as obvious. However, it isn't too difficult to acquire a pretty accurate sense for which tail calls will be optimized and which ones will not. > I do agree that if it is important to the program that tail call > optimization be done, then the programmer should apply the transform > themselves, and not hope that the compiler will do it. [...] Oh I would say this differently. If it is important to the program that tail call optimization be done then it is important to verify that the compiler has done it. It isn't all that hard to write a program to scan the output of gcc -S (or clang -S) to see where there are truly recursive calls left in the compiled code. As a matter of routine I verified that my decommenting program optimized away all the recursive tail calls.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-01-02 19:04 -0800 |
| Message-ID | <86turysoum.fsf@linuxsc.com> |
| In reply to | #158103 |
Anton Shepelev <anton.txt@gmail.com> writes: > Bart: > >> Does this program rely heavily on recursion? >> >> Because it tends to crash across all compilers I tried, >> including gcc -O0, on the handful of test files I used, >> mostly in the 1000s of lines. > > There are two kinds of programmer: those who consider > recursion a form of the loop and those who consider the loop > a form of recursion. I would not put myself in either category. It is definitely possible to effect recursion using a loop formulation. It is also definitely possible to effect a loop using a recursive formulation. Loopness or recursiveness is more a property of what the algorithm is doing, not whether iteration or recursion is used to accomplish it. > I think that the former approach is at > discord with the philosophy of imperative procedural > languages, where the code directly expresses actions rather > than "declaring" them in some vague indirect way. I believe > the original ISO C had no provision for tail-call > optimisation, The ISO C standard says almost nothing about what optimisations will or will not be done. A conforming implementation may turn a recursive routine into an iterative one; it also may turn an iterative routine into a recursive one. Both are allowed by the C standard. > and rightly so: if you want a loop, write loop. If I thought of what the program is doing as a loop, I may very well have written it as an iteration. But I don't think of what the program is doing as a loop. Rather it is processing a sequence of input characters, and using recursion to process that sequence is a natural fit for how I conceptualize the program.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <563-365-8930@kylheku.com> |
|---|---|
| Date | 2020-12-30 21:44 +0000 |
| Message-ID | <20201230104155.77@kylheku.com> |
| In reply to | #157908 |
On 2020-12-30, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
> Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> writes:
>
>> On 05.12.20 17:25, Tim Rentsch wrote:
>>
>>> Prompted by some recent discussion regarding 'goto' statements and
>>> state machines, I would like to propose a programming exercise.
>>> (It is perhaps a bit too large to be called an exercise, but not so
>>> difficult that it deserves the label of challenge. On the other
>>> hand there are some constraints so maybe challenge is apropos. In
>>> any case somewhere in between those two bounds.)
>>>
>>> Short problem statement: a C program to remove comments from C
>>> source input. [...]
>>
>> If you show yours , maybe some of us will show theirs........
>
> If you have been waiting for me, here it is.
>
> This program is basically the same as the one I wrote just before
> posting the exercise statement, not counting some cosmetic
> cleanup and a change so comments would be replaced by a single
> blank.
I think it's not honest to say that your program doesn't use goto.
It just disguises it using tail calls.
Someone who reads your program is greatly assisted by recognizing the pattern
that a state machine is being implemented by a network of tail calls,
and therefore knowing, for instance, that when start calls dq, that is
to be understood as a control transfer that doesn't return (i.e. goto).
Imagine someone with no CS background trying to follow how the functions return
back to the top level start for various input cases, haha!
That entire tail-call-network section of the program beginning with the start
function down to before the I/O helpers could be turned into a big function
with labeled goto blocks. Moreover, the structure would be essentially the
same, about equally easy to follow.
There is a clear disadvantage. If there is no tail call elimination in the
compiler (which is not required by the standard) the program needs automatic
storage proprortional to the number of characters of the input. This could
happen even if the compiler supports tail calls as an optimization, but the
program is compiled without optimization.
This technique is best wielded in a language like Scheme in which tail calls
are part of the language semantics; even a non-optimizing Scheme compiler
must output tail calls.
The dogged adherence to the functional style precludes the use of the switch
statement to make selections on input characters; so nested ternary ?: has to
be used, which is awkward. C is not well geared toward this style, otherwise it
would have an N-way functional conditional. Besides, there are embeddeed
effects: outc(c) is evaluated for its side effect. So the code is not purely
functional.
Though switch is an imperative construct, its use doesn't obviously doesn't
preclude tail recursion:
Status
start( Count n ){
int c = getchar();
switch (c) {
case SL: return sl(0);
case DQ: outc(c); return dq(0);
case SQ: outc(c); return sq(0);
case EOF: return ALL_GOOD;
default: outc(c); return start(0);
}
}
This is idiomaic and readable. Also, it is free of the confusing inverted
tests like c != EOF and c != BS.
Incidentally, why did you do that? That is to say, why this:
> : c != EOF ? outc( c ), start( 0 )
> :/* c == EOF */ ALL_GOOD;
and not this?
> : c == EOF ? ALL_GOOD
> :/* default */ outc( c ), start( 0 );
The answer is: you had to, due to precedence. The above reordering is
incorrect because the comma expression is not enclosed in ? ... : and has a
lower precedence than the comma.
If we add the parenheses, they spoil the consistency of the layout,
and the reordering avoids that:
> : c == EOF ? ALL_GOOD
> :/* default */ (outc( c ), start( 0 ));
But, a possible fix is to put the parentheses in every row:
> return c == SL ? ( sl( 0 ) )
> : c == DQ ? ( outc( c ), dq( 0 ) )
> : c == SQ ? ( outc( c ), sq( 0 ) )
> : c == EOF ( ALL_GOOD )
> :/* default */ ? ( outc( c ), start( 0 ) );
(Incidentally, in one intermediate version of my program, which I did
not submit, the formatting also exhibited a table structure much like
the above. One column for the input symbols, a column for any optional
transition actions, and a column for the state transitions.)
Anyway, from the above switch, a transformation to goto is simple. We can even
maintain the appearance of tail calls with helper macros (though the argument
could be made that we perhaps shouldn't):
#define go(target, arg) (count = (arg); goto target)
#define start(arg) go(start, arg)
#define sl(arg) go(sl, arg)
#define dq(arg) go(dq, arg)
start: {
int c = getchar();
switch (c) {
case SL: sl(0);
case DQ: outc(c); dq(0);
case SQ: outc(c); sq(0);
case EOF: return ALL_GOOD;
default: outc(c); start(0);
}
}
We can make the reverse argument: hey, you have a goto structure there; did
you know you can rewrite it into tail calls and avoid goto, while preserving
essentially the same structure? Why not do that? Well, there is no payoff. The
readability doesn't improve since the structure is exactly the same. Many C
programmers don't don't understand tail recursion, or have only a very basic
understanding of what it is, not familiar with uses like this. Compilers are
not required to turn it into jumps, and might not do so if the code is built
without optimization, which is sometimes useful for debugging. Moreover, slight
changes to tail-recursive code can turn it non-tail-recursive. If even one
such a change is done in the wrong place, the code can require stack
proportional to the input size even if optimized. For instance, if we add a
debug print statement in some place which requires a tail call to return, it's
no longer a tail call:
case DQ: outc(c); debug_print_status(dq(0)); /* no longer tail */
--
TXR Programming Language: http://nongnu.org/txr
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <563-365-8930@kylheku.com> |
|---|---|
| Date | 2020-12-31 02:54 +0000 |
| Message-ID | <20201230184724.407@kylheku.com> |
| In reply to | #157913 |
On 2020-12-30, Kaz Kylheku <563-365-8930@kylheku.com> wrote:
> On 2020-12-30, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>> Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> writes:
>>
>>> On 05.12.20 17:25, Tim Rentsch wrote:
>>>
>>>> Prompted by some recent discussion regarding 'goto' statements and
>>>> state machines, I would like to propose a programming exercise.
>>>> (It is perhaps a bit too large to be called an exercise, but not so
>>>> difficult that it deserves the label of challenge. On the other
>>>> hand there are some constraints so maybe challenge is apropos. In
>>>> any case somewhere in between those two bounds.)
>>>>
>>>> Short problem statement: a C program to remove comments from C
>>>> source input. [...]
>>>
>>> If you show yours , maybe some of us will show theirs........
>>
>> If you have been waiting for me, here it is.
>>
>> This program is basically the same as the one I wrote just before
>> posting the exercise statement, not counting some cosmetic
>> cleanup and a change so comments would be replaced by a single
>> blank.
>
> I think it's not honest to say that your program doesn't use goto.
> It just disguises it using tail calls.
I whipped up a program which filters that program, turning it into one
in which Status start(Count n); is one big function containing the whole
machine represented as blocks connected with goto.
I put the filtered program only through a few very basic tests;
it's possible that the filter missed a case or something.
The following is the filtered program. The filter source code follows that.
/* uncomment.c - remove comments from C source files */
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long Count;
typedef enum {
ALL_GOOD = 0,
UNTERMINATED_CHARACTER_LITERAL,
UNTERMINATED_STRING,
UNTERMINATED_COMMENT,
} Status;
typedef Status Reader_f( Count );
static Status restart( int );
static Reader_f
start,
sl, slbs,
slsl, slslbs,
slst, slstst, slststbs,
sq, sqbs, sqbsbs, sqbs__,
dq, dqbs, dqbsbs, dqbs__;
static Count show_sl_lcs_bs( Count );
static Count show_sl_lcs( Count );
static Count show_lcs( Count );
static int next( void );
static int outc( int );
enum {
SQ = '\'',
DQ = '\"',
SL = '/',
STAR = '*',
BS = '\\',
NL = '\n',
SP = ' ',
};
/* main */
int
main(){
return start(0) == ALL_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* top level */
Status
restart( int c ){
return ungetc( c, stdin ), start( 0 );
}
/* slant character helper functions - show counted line splices */
Count
show_sl_lcs_bs( Count n ){
return show_sl_lcs( n ), outc( BS ), 0;
}
Count
show_sl_lcs( Count n ){
return outc( SL ), show_lcs( n );
}
Count
show_lcs( Count n ){
return n > 0 ? outc( BS ), outc( NL ), show_lcs( n-1 ) : 0;
}
Status start( Count n ){
start:
{
int c = getchar();
switch (c) {
case SL: n = 0; goto sl;
case DQ: outc( c ); n = 0; goto dq;
case SQ: outc( c ); n = 0; goto sq;
case EOF: return ALL_GOOD;
default: outc( c ); n = 0; goto start;
}
}
/* slant character - top level */
sl:
{
int c = getchar();
switch (c) {
case SL: n = 0; goto slsl;
case STAR: n = 0; goto slst;
case EOF: show_sl_lcs( n ); return ALL_GOOD;
case BS: n = n; goto slbs;
default: show_sl_lcs( n ); n = c; goto restart;
}
}
slbs:
{
int c = getchar();
switch (c) {
case EOF: show_sl_lcs_bs( n ); return ALL_GOOD;
case NL: n = n+1; goto sl;
default: show_sl_lcs_bs( n ); n = c; goto restart;
}
}
/* new style C comment - 'slsl' */
slsl:
{
int c = getchar();
switch (c) {
case NL: outc( c ); n = 0; goto start;
case BS: n = n; goto slslbs;
case EOF: outc( NL ); return ALL_GOOD;
default: n = 0; goto slsl;
}
}
slslbs:
{
int c = getchar();
switch (c) {
case NL: n = 0; goto slsl;
case EOF: outc( NL ); return ALL_GOOD;
case BS: n = 0; goto slslbs;
default: n = 0; goto slsl;
}
}
/* old style C comment - 'slst' */
slst:
{
int c = getchar();
switch (c) {
case EOF: outc( NL ); return UNTERMINATED_COMMENT;
case NL: n = 0; goto slst;
case STAR: n = 0; goto slstst;
default: n = 0; goto slst;
}
}
slstst:
{
int c = getchar();
switch (c) {
case EOF: return UNTERMINATED_COMMENT;
case NL: n = 0; goto slst;
case SL: outc( SP ); n = 0; goto start;
case STAR: n = 0; goto slstst;
case BS: n = 0; goto slststbs;
default: n = 0; goto slst;
}
}
slststbs:
{
int c = getchar();
switch (c) {
case EOF: return UNTERMINATED_COMMENT;
case NL: n = 0; goto slstst;
case STAR: n = 0; goto slstst;
default: n = 0; goto slst;
}
}
/* character literals - 'sq' */
sq:
{
int c = next();
switch (c) {
case SQ: n = 0; goto start;
case NL: return UNTERMINATED_CHARACTER_LITERAL;
case EOF: return UNTERMINATED_CHARACTER_LITERAL;
case BS: n = 0; goto sqbs;
default: n = 0; goto sq;
}
}
sqbs:
{
int c = next();
switch (c) {
case NL: n = 0; goto sq;
case EOF: return UNTERMINATED_CHARACTER_LITERAL;
case BS: n = 0; goto sqbsbs;
default: n = 0; goto sq;
}
}
sqbsbs:
{
int c = next();
switch (c) {
case NL: n = 0; goto sqbs__;
case EOF: return UNTERMINATED_CHARACTER_LITERAL;
case SQ: n = 0; goto start;
case BS: n = 0; goto sqbs;
default: n = 0; goto sq;
}
}
sqbs__:
{
int c = next();
switch (c) {
case NL: return UNTERMINATED_CHARACTER_LITERAL;
case EOF: return UNTERMINATED_CHARACTER_LITERAL;
case BS: n = 0; goto sqbsbs;
default: n = 0; goto sq;
}
}
/* string literals - 'dq' */
dq:
{
int c = next();
switch (c) {
case DQ: n = 0; goto start;
case NL: return UNTERMINATED_STRING;
case EOF: return UNTERMINATED_STRING;
case BS: n = 0; goto dqbs;
default: n = 0; goto dq;
}
}
dqbs:
{
int c = next();
switch (c) {
case NL: n = 0; goto dq;
case EOF: return UNTERMINATED_STRING;
case BS: n = 0; goto dqbsbs;
default: n = 0; goto dq;
}
}
dqbsbs:
{
int c = next();
switch (c) {
case NL: n = 0; goto dqbs__;
case EOF: return UNTERMINATED_STRING;
case DQ: n = 0; goto start;
case BS: n = 0; goto dqbs;
default: n = 0; goto dq;
}
}
dqbs__:
{
int c = next();
switch (c) {
case NL: return UNTERMINATED_STRING;
case EOF: return UNTERMINATED_STRING;
case BS: n = 0; goto dqbsbs;
default: n = 0; goto dq;
}
}
restart:
ungetc(n, stdin); n = 0; goto start;
}
/* character input */
int
next(){
return outc( getchar() );
}
/* output */
int
outc( int c ){
return c != EOF ? putchar( c ), c : c;
}
Filter program, written in TXR (Tim's initials, coincidentally);
@(do
(defstruct graph-node ()
name
comment
init-decl
cases)
(defstruct label ()) ;; abstract
(defstruct action ()) ;; abstract
(defstruct transition ()) ;; abstract
(defstruct default-label (label)
(:method print (me stream pretty-p)
(put-string "default:" stream)))
(defstruct regular-label (label)
symbol
(:method print (me stream pretty-p)
(put-string `case @{me.symbol}:` stream)))
(defstruct present-action (action)
action
(:method print (me stream pretty-p)
(put-string ` @{me.action};` stream)))
(defstruct absent-action (action)
(:method print (me stream pretty-p)))
(defstruct return-transition (transition)
return-expression
(:method print (me stream pretty-p)
(put-string ` return @{me.return-expression};` stream)))
(defstruct goto-transition (transition)
next-value
next-node
(:method print (me stream pretty-p)
(put-string ` n = @{me.next-value}; goto @{me.next-node};`
stream)))
(defstruct case ()
label
action
transition)
(defstruct raw-case ()
sym action next arg retval inv)
(defstruct raw-node ()
name decl raw-cases comment preamble))
@(collect)
@prologue
@(until)
Status
start( Count n ){
@(end)
@(collect :vars (raw-node))
@ (maybe)
@ (all)
/* slant character helper functions - show counted line splices */
@ (and)
@ (collect)
@preamble
@ (until)
/* new @(skip)
@ (end)
@ (end)
@ (or)
@ (bind preamble nil)
@ (end)
@ (maybe)
/*@comment*/
@ (or)
@ (bind comment nil)
@ (end)
Status
@name( Count n ){
@decl
@ (collect :vars ((sym nil) (action nil) (retval nil)
(next nil) (arg nil) (inv nil))
:gap 0)
@ (assert "bug: unhandled syntax")
@ (cases)
@/[\t ]*(return|:)/ c == @sym@\t? @action, @next( @arg )
@ (or)
@/[\t ]*(return|:)/ c == @sym@\t? @next( @arg )
@ (or)
@/[\t ]*(return|:)/ c == @sym@\t? @action, @retval
@ (or)
@/[\t ]*(return|:)/ c == @sym@\t? @retval
@ (or)
@/[\t ]*(return|:)/ c != @sym@\t? @action, @next( @arg )
@ (bind inv t)
@ (or)
@/[\t ]*(return|:)/ c != @sym@\t? @next( @arg )
@ (bind inv t)
@ (or)
@/[\t ]*(return|:)/ c != @sym@\t? @action, @retval
@ (bind inv t)
@ (or)
@/[\t ]*(return|:)/ c != @sym@\t? @retval
@ (bind inv t)
@ (or)
@\t:/*@(skip)*/@\t @next( @arg );
@ (or)
@\t:/*@(skip)*/@\t @retval;
@ (or)
@\t:@\t@\t @next( @arg );
@ (or)
@\t:@\t@\t @retval;
@ (end)
@ (until)
}
@ (end)
@ (bind raw-node @(new raw-node name name
decl decl
raw-cases (mapcar (do new raw-case sym @1
action @2
next @3
arg @4
retval @5
inv @6)
sym action next arg
retval inv)))
@ (do (set raw-node.preamble preamble
raw-node.comment comment))
@(until)
/* character input */
@(end)
@(collect)
@epilogue
@(end)
@(do
(defun remove-inv (raw-cases)
(let* ((sl (nthlast 2 raw-cases)))
(tree-case sl
((a b) (when a.inv
(when (or b.inv b.sym)
(error "~s: unhandled situation" 'remove-inv))
(zap a.inv)
(swap a.sym b.sym)
(swap (car sl) (cadr sl)))))))
(defun gather-preambles (raw-nodes)
(mappend .preamble raw-nodes))
(defun parse-raw-nodes (raw-nodes)
(collect-each ((rn raw-node))
(remove-inv rn.raw-cases)
(new graph-node
name rn.name
comment rn.comment
init-decl rn.decl
cases (collect-each ((rc rn.raw-cases))
(let ((label (if rc.sym
(new regular-label symbol rc.sym)
(new default-label)))
(action (if rc.action
(new present-action action rc.action)
(new absent-action)))
(transition (if rc.retval
(new return-transition
return-expression rc.retval)
(new goto-transition
next-node rc.next
next-value rc.arg))))
(new case
label label
action action
transition transition)))))))
@(bind graph-nodes @(parse-raw-nodes raw-node))
@(output)
@ (repeat)
@ prologue
@ (end)
@ (repeat :vars ((helpers (gather-preambles raw-node))))
@ helpers
@ (end)
Status start( Count n ){
@ (repeat :vars ((gn graph-nodes)))
@ (if gn.comment)
/*@{gn.comment}*/
@ (end)
@{gn.name}:
{
@{(trim-str gn.init-decl)}
switch (c) {
@ (repeat :vars ((ca gn.cases)))
@{ca.label}@{ca.action}@{ca.transition}
@ (end)
}
}
@ (end)
restart:
ungetc(n, stdin); n = 0; goto start;
}
@ (repeat)
@ epilogue
@ (end)
@(end)
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-01-03 09:49 -0800 |
| Message-ID | <86lfd9syfo.fsf@linuxsc.com> |
| In reply to | #157913 |
Kaz Kylheku <563-365-8930@kylheku.com> writes: > On 2020-12-30, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote: > >> Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> writes: >> >>> On 05.12.20 17:25, Tim Rentsch wrote: >>> >>>> Prompted by some recent discussion regarding 'goto' statements and >>>> state machines, I would like to propose a programming exercise. >>>> (It is perhaps a bit too large to be called an exercise, but not so >>>> difficult that it deserves the label of challenge. On the other >>>> hand there are some constraints so maybe challenge is apropos. In >>>> any case somewhere in between those two bounds.) >>>> >>>> Short problem statement: a C program to remove comments from C >>>> source input. [...] >>> >>> If you show yours , maybe some of us will show theirs........ >> >> If you have been waiting for me, here it is. >> >> This program is basically the same as the one I wrote just before >> posting the exercise statement, not counting some cosmetic >> cleanup and a change so comments would be replaced by a single >> blank. > > I think it's not honest to say that your program doesn't use goto. > It just disguises it using tail calls. Well let's see. Some people say: A 'break' statement is just a goto in disguise. A 'continue' statement is just a goto in disguise. A 'while' (or do/while) is just a goto in disguise. A 'for' is just a (syntactically sugared?) goto in disguise. A 'switch' is just a (computed?) goto in disguise. An 'if' is just a goto in disguise. And now we should add to that list: Some function calls are just gotos in disguise? I don't think so. My original posting said "Use no 'goto' statements" and that is exactly what I meant. Using 'while' or 'break' or 'continue', or any other "disguised" goto, follows both the letter and the spirit of the stipulation, as does using tail recursion. Furthermore tail calls have a distinction (and advantage) that other kinds of "disguised" gotos do not. If a 'break' or 'while' or 'continue', etc., is used, the program state ends up within the same function, including the state of variables in the function. To understand what's going on we must look for and understand how any such variables are used and modified. But tail calls don't have that problem: each function in the net of routines starts with a clean slate, and may confidently be read in isolation of all the others. So the idea that a tail call is just "a goto in disguise" doesn't hold even a tiny amount of water. > Someone who reads your program is greatly assisted by recognizing > the pattern that a state machine is being implemented by a network > of tail calls, Yes, they might. Nothing wrong with that. > and therefore knowing, for instance, that when start > calls dq, that is to be understood as a control transfer that > doesn't return (i.e. goto). That doesn't follow. A state transition is not synonymous with goto. Only people who are predisposed to think of any control transfer as a goto will conclude that these calls are meant to be understood as a goto. I don't think of them as gotos, and I certainly don't intend that other people should think of them as gotos. At some level just the opposite: part of my purpose is to offer an alternative to goto, a different way to see how a state machine might be constructed. > Imagine someone with no CS background trying to follow how the > functions return back to the top level start for various input > cases, haha! Someone with no programming background would see all the posted programs as so much gibberish. Someone with some programming background but no formal education in computer science might very well have trouble understanding the control flow. That sort of thing often happens when trying to expand people's horizons. Personally I think expanding people's horizons is often a good thing. > That entire tail-call-network section of the program beginning with > the start function down to before the I/O helpers could be turned > into a big function with labeled goto blocks. Moreover, the > structure would be essentially the same, about equally easy to > follow. So you say. I have seen your programs that take the 'goto' approach, and I don't think so. > There is a clear disadvantage. If there is no tail call elimination > in the compiler (which is not required by the standard) the program > needs automatic storage proprortional to the number of characters of > the input. This could happen even if the compiler supports tail > calls as an optimization, but the program is compiled without > optimization. [...] People who use substandard tools deserve what they get. Setting optimization levels is one reason projects are distributed with makefiles. The code I wrote works fine in the environments in which it is meant to run, and that is all that is needed. Writing code for brain-damaged compilers was not a requirement. > The dogged adherence to the functional style This is a mischaracterization. I chose to write in a functional style; I did not "doggedly adhere" to it. I have written programs to filter out comments several times over the years, using a variety of approaches. In this particular case I chose a functional style, to see what it would be like. It worked out well, so that's what I went with. I often try implementing parts of programs using a functional style. Sometimes it works, and sometimes it doesn't; when it doesn't I take a different tack. > precludes the use of > the switch statement to make selections on input characters; Oh nonsense. A switch() too can serve a functional style (as you more or less point out just a few lines down). There is nothing inherently imperative about switch() statements. > so nested ternary ?: has to be used, I chose ?: not because it has to be used, but because it gives a better look than using switch(). > which is awkward. That is your prejudice speaking. It is awkward only for people who are predisposed to think it awkward. > C is not well geared toward this style, otherwise it would have > an N-way functional conditional. An overly harsh conclusion. The high order bits map nicely onto a functional look in languages like OCaml. Some sort of expression-select construct might be nice, but the level of friction between doing that and just using ?: is pretty low. > Besides, there are embeddeed effects: outc(c) is evaluated for > its side effect. So the code is not purely functional. Output is ALWAYS imperative. We may see this problem as having two parts, a recognizer and a transducer. The recognizer part is done in a pure functional style. The transducer uses imperative output functions, because that's a better fit to the C language. (Note also that this takes away from your "dogged adherence" accusation.) > Though switch is an imperative construct, its use doesn't obviously > doesn't preclude tail recursion: [..example..] > > This is idiomaic and readable. It is idiomatic. It's also ugly. People find such code "more readable" mainly (or only?) because that is what they are used to. I have found (and there is some research that supports this) that once people get used to it, a more concise form like the ?: method is a better impedance match as far as ease of reading goes. > Also, it is free of the confusing > inverted tests like c != EOF and c != BS. The asymmetry of how ?: treats its operands is mildly annoying. But that doesn't justify throwing out the baby with the bathwater. All programming languages have some annoying aspects. > Incidentally, why did you do that? That is to say, why this: > >> : c != EOF ? outc( c ), start( 0 ) >> :/* c == EOF */ ALL_GOOD; > > and not this? > > >> : c == EOF ? ALL_GOOD >> :/* default */ outc( c ), start( 0 ); > > The answer is: you had to, due to precedence. [..further > remarks regarding using parentheses..] Like I said, the asymmetry of ?: is annoying at times. The program I posted is something I just sat down and wrote, almost as fast as I could type it. It is not what I would call a polished program. In a subsequent version I think the treatment of the penultimate case and the final case can be used to advantage, but for now I will just say the code appears pretty much just as I first wrote it. Also I think the funkiness of the last two cases isn't such a big deal once one sees what is going on. All programming languages have their own idiosyncracies; the idiosyncracy in C with ?: is rather minor in comparison with some other ones. > Anyway, from the above switch, a transformation to goto is > simple. [elaboration] You strike me as someone whose mind is stuck in a rut of always thinking of programs in terms of what goes on at the level of machine language. I should add that you are in good company, as Don Knuth strikes me the same way. I used to be that way too, but I gave it up. I still can think in terms of what's going on at the level of machine language, but mostly I don't. I consider the change a big improvement. Incidently, I note that none of the programs you posted made any effort to follow either of the two stated requirements (no goto statements, no overly long functions). If you never venture outside of your rut, very probably your views will never change. My hope is that other people will do better.
[toc] | [prev] | [next] | [standalone]
| From | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| Date | 2021-01-04 00:15 +0300 |
| Message-ID | <20210104001549.e79025fef7062a13f4143863@gmail.com> |
| In reply to | #158125 |
Tim Rentsch:
> Well let's see. Some people say:
> A 'break' statement is just a goto in disguise.
> A 'continue' statement is just a goto in disguise.
> A 'while' (or do/while) is just a goto in disguise.
> A 'for' is just a (syntactically sugared?) goto in disguise.
> A 'switch' is just a (computed?) goto in disguise.
> An 'if' is just a goto in disguise.
The last four are not goto's in disguise in that they are
control-flow structures of structured programming.
Furthermore, they involve a test of a condition. `switch' is
just a many-branched `if', as long as we forget its C
perculiarities and consider Pascal's `case' instead, which
is much closer to Dijkstra's. `if' is not structured unless
it allows operator braces ({}, begin/end, &c.) Although
expressible in terms of primitive `if' and `goto', the
structured statements are special, for they are highly
intuitive and facilitate the expression of a program in
terms of human thinking rather than machine logic.
--
() ascii ribbon campaign -- against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <563-365-8930@kylheku.com> |
|---|---|
| Date | 2021-01-03 21:57 +0000 |
| Message-ID | <20210103134439.507@kylheku.com> |
| In reply to | #158128 |
On 2021-01-03, Anton Shepelev <anton.txt@gmail.com> wrote:
> Tim Rentsch:
>
>> Well let's see. Some people say:
>> A 'break' statement is just a goto in disguise.
>> A 'continue' statement is just a goto in disguise.
>> A 'while' (or do/while) is just a goto in disguise.
>> A 'for' is just a (syntactically sugared?) goto in disguise.
>> A 'switch' is just a (computed?) goto in disguise.
>> An 'if' is just a goto in disguise.
>
> The last four are not goto's in disguise in that they are
> control-flow structures of structured programming.
> Furthermore, they involve a test of a condition. `switch' is
> just a many-branched `if', as long as we forget its C
It's clear that switch is C's computed goto. It branches unconditionally
to one of a number of labels, which have integer values. The branch is
specified by computing the integer value of a label.
More than that, switch is also a low-levelish construct for the
following reasons:
1. Though the branch is confined to the body of the switch (it cannot go
anywhere within the containing function, let a lone program), the labels
can literally be anywhere in the body of the switch:
switch (x) {
for (;;) {
while (condition) {
case 42:
// jumps to here if x is 42.
2. Explicit break; is required to terminate cases, without which they
fall through to the next case. This underscores the point that
the case labels are just goto labels; they are not the formal
headings of the clauses of a case statement.
3. Ignorance of scoped semantics: the switch branch can skip declarations
which contain variable initializations, so that the variables then
have indeterminate values in spite of their initializers.
Regarding 3, note how in C++, switch branches are forbidden to skip
over variable initializations. The only other control contruct inherited
from C which needs an additional such a constraint in C++ is goto!
This is because goto and switch are birds of a feather.
--
TXR Programming Language: http://nongnu.org/txr
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-01-03 23:00 +0000 |
| Message-ID | <n0sIH.205166$FXE7.158064@fx34.ams4> |
| In reply to | #158131 |
On 03/01/2021 21:57, Kaz Kylheku wrote:
> On 2021-01-03, Anton Shepelev <anton.txt@gmail.com> wrote:
>> Tim Rentsch:
>>
>>> Well let's see. Some people say:
>>> A 'break' statement is just a goto in disguise.
>>> A 'continue' statement is just a goto in disguise.
>>> A 'while' (or do/while) is just a goto in disguise.
>>> A 'for' is just a (syntactically sugared?) goto in disguise.
>>> A 'switch' is just a (computed?) goto in disguise.
>>> An 'if' is just a goto in disguise.
>>
>> The last four are not goto's in disguise in that they are
>> control-flow structures of structured programming.
>> Furthermore, they involve a test of a condition. `switch' is
>> just a many-branched `if', as long as we forget its C
>
> It's clear that switch is C's computed goto. It branches unconditionally
> to one of a number of labels, which have integer values. The branch is
> specified by computing the integer value of a label.
Not quite. The following is an actual computed goto (this works in gnu-C):
void* labels[]={NULL, &&L100, &&L200, &&L300, &&L400};
int n=2;
goto *labels[n];
L100:
puts("100"); exit(0);
L200:
puts("200"); exit(0);
L300:
puts("300"); exit(0);
L400:
puts("400"); exit(0);
N must be 1 to 4 (outside that, result is undefined). For N=2, will
print "200".
This is switch:
int n=200;
switch (n) {
case 100: puts("100"); exit(0);
case 200: puts("200"); exit(0);
case 300: puts("300"); exit(0);
case 400: puts("400"); exit(0);
default: puts("???"); exit(0);
Here, N must be 100, 200, 300 or 400; it can be arbitrary. A value of 0
to 3 will result in output of "???".
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <563-365-8930@kylheku.com> |
|---|---|
| Date | 2021-01-04 00:00 +0000 |
| Message-ID | <20210103154722.121@kylheku.com> |
| In reply to | #158132 |
On 2021-01-03, Bart <bc@freeuk.com> wrote:
> On 03/01/2021 21:57, Kaz Kylheku wrote:
> > On 2021-01-03, Anton Shepelev <anton.txt@gmail.com> wrote:
> >> Tim Rentsch:
> >>
> >>> Well let's see. Some people say:
> >>> A 'break' statement is just a goto in disguise.
> >>> A 'continue' statement is just a goto in disguise.
> >>> A 'while' (or do/while) is just a goto in disguise.
> >>> A 'for' is just a (syntactically sugared?) goto in disguise.
> >>> A 'switch' is just a (computed?) goto in disguise.
> >>> An 'if' is just a goto in disguise.
> >>
> >> The last four are not goto's in disguise in that they are
> >> control-flow structures of structured programming.
> >> Furthermore, they involve a test of a condition. `switch' is
> >> just a many-branched `if', as long as we forget its C
> >
> > It's clear that switch is C's computed goto. It branches unconditionally
> > to one of a number of labels, which have integer values. The branch is
> > specified by computing the integer value of a label.
>
> Not quite. The following is an actual computed goto (this works in gnu-C):
The regular switch is already a computed goto.
https://en.wikipedia.org/wiki/Goto#Computed_GOTO_and_Assigned_GOTO
The compiler extension just makes the switch capability available
in the goto construct.
> void* labels[]={NULL, &&L100, &&L200, &&L300, &&L400};
>
> int n=2;
>
> goto *labels[n];
>
> L100:
> puts("100"); exit(0);
> L200:
> puts("200"); exit(0);
> L300:
> puts("300"); exit(0);
> L400:
> puts("400"); exit(0);
This example can be rewritten as
switch (n) {
case 1:
puts("100"); exit(0);
case 2:
puts("200"); exit(0);
// etc.
}
It's not any less "computed". There is less indirection; we are just
using the domain of n as the label representations, instead of mapping n
to a table from which label representations are retrieved.
> N must be 1 to 4 (outside that, result is undefined). For N=2, will
> print "200".
>
> This is switch:
>
> int n=200;
>
> switch (n) {
> case 100: puts("100"); exit(0);
> case 200: puts("200"); exit(0);
> case 300: puts("300"); exit(0);
> case 400: puts("400"); exit(0);
> default: puts("???"); exit(0);
That's not any less computed though. It's less indirect (or more
direct). Integer values are used for the branch labels, and that allows
n to be used directly as the branch target, instead of having to be
manually mapped to a goto label.
The gcc extension brings switching capability (computed goto) to the
goto statement, that's all.
By the way, if we you were rewriting the code to eliminate the
extension, you'd likely do this, rather than mimicking the decimal
values of the label names:
switch (n) {
case 1: puts("100"); exit(0);
case 2: puts("200"); exit(0);
case 3: puts("300"); exit(0);
case 4: puts("400"); exit(0);
default: puts("???"); exit(0);
}
--
TXR Programming Language: http://nongnu.org/txr
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-01-04 20:04 -0800 |
| Message-ID | <86czykrpvj.fsf@linuxsc.com> |
| In reply to | #158128 |
Anton Shepelev <anton.txt@gmail.com> writes: > Tim Rentsch: > >> Well let's see. Some people say: >> A 'break' statement is just a goto in disguise. >> A 'continue' statement is just a goto in disguise. >> A 'while' (or do/while) is just a goto in disguise. >> A 'for' is just a (syntactically sugared?) goto in disguise. >> A 'switch' is just a (computed?) goto in disguise. >> An 'if' is just a goto in disguise. > > The last four are not goto's in disguise in that they are > control-flow structures of structured programming. I don't think of any of these as gotos in disguise. I know some people do, but I don't. It's like what someone told me once about 'return' - "you can think of it as a function call that pops the stack and sets the PC". I suppose people could think of it that way, but I surely do not. An important characteristic of "goto" is that it can go anywhere (in the same function). None of these constructs have that property. The closest might be 'switch', but even that is limited to the controlled statement of the switch(), and not the whole function.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <563-365-8930@kylheku.com> |
|---|---|
| Date | 2021-01-05 07:15 +0000 |
| Message-ID | <20210104225105.819@kylheku.com> |
| In reply to | #158168 |
On 2021-01-05, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote: > It's like what someone > told me once about 'return' - "you can think of it as a > function call that pops the stack and sets the PC". I > suppose people could think of it that way, but I surely > do not. You should broaden those horizons you like to be going on about; returning from a function is actually a function call: a call of the continuation that the function has been handed by the caller. In a system that lacks the ability to capture continuations as objects, the special case of a function return continuation can be implemented with a stack-based mechanism for saving and restoring the control, and passing data at the same time. The system can simply discard the context that is being returned from, knowing that it could not be referenced by a captured continuation, since there is no such thing. -- TXR Programming Language: http://nongnu.org/txr
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-01-07 22:30 -0800 |
| Message-ID | <86lfd4os92.fsf@linuxsc.com> |
| In reply to | #158172 |
Kaz Kylheku <563-365-8930@kylheku.com> writes: > On 2021-01-05, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote: > >> It's like what someone >> told me once about 'return' - "you can think of it as a >> function call that pops the stack and sets the PC". I >> suppose people could think of it that way, but I surely >> do not. > > You should broaden those horizons you like to be going on about; > [...] Oh get real. Being open to new ideas doesn't mean embracing every stupid idea that comes along. (and btw I am already quite familiar with CPS.)
[toc] | [prev] | [next] | [standalone]
Page 1 of 20 [1] 2 3 … 20 Next page →
Back to top | Article view | comp.lang.c
csiph-web