|
|
#1 |
|
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,525
Karma: 8065948
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Request for opinion: a template while loop
I have been thinking about adding a while loop construct to the template language. This would permit looping based on a count or some test between two lists. The construct would be what one would expect:
Code:
while expr do
<<stuff>>
od
Code:
while expr:
<<stuff>>
od
The problem: this construct would for the first time permit infinite loops in the template language. A template infinite loop would freeze the GUI and be nearly impossible to fix because the user could never get past the loop to the editor. One possible fix is to limit the number of iterations to something, perhaps 1000. The loop would exit if this limit is hit. That would permit getting to the editor to fix it, albeit with some delays. This solution opens the door to a language construct to specify the limit, for example: Code:
while expr limit <numeric expression> do
<<stuff>>
od
An alternate construct would be to avoid the problem by not using a while loop but instead require a counting for loop and a break statement, such as: Code:
for var range N to M:
<<stuff>>
if <something> then break fi;
<<stuff>>
rof
Thoughts on
|
|
|
|
|
|
#2 |
|
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,609
Karma: 28549044
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
I vote for a for loop. Since the language is meant for newcomers to programming to be able to use, its safer.
|
|
|
|
| Advert | |
|
|
|
|
#3 |
|
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 24,905
Karma: 47303824
Join Date: Jul 2011
Location: Sydney, Australia
Device: Kobo:Touch,Glo, AuraH2O, GloHD,AuraONE, ClaraHD, Libra H2O; tolinoepos
|
I'd go with the for loop as well. I've seen the condition on while loops mess up far to many times.
|
|
|
|
|
|
#4 |
|
Custom User Title
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 11,360
Karma: 79528341
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
|
As someone who's good at breaking things, the for loop seems a lot more difficult to break.
|
|
|
|
|
|
#5 |
|
Bibliophagist
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 48,197
Karma: 174315444
Join Date: Jul 2010
Location: Vancouver
Device: Kobo Sage, Libra Colour, Lenovo M8 FHD, Paperwhite 4, Tolino epos
|
|
|
|
|
| Advert | |
|
|
|
|
#6 |
|
Custom User Title
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 11,360
Karma: 79528341
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
|
|
|
|
|
|
|
#7 |
|
Bibliophagist
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 48,197
Karma: 174315444
Join Date: Jul 2010
Location: Vancouver
Device: Kobo Sage, Libra Colour, Lenovo M8 FHD, Paperwhite 4, Tolino epos
|
|
|
|
|
|
|
#8 |
|
Custom User Title
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 11,360
Karma: 79528341
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
|
Could this be a simple use case for a while loop?
I was thinking something like this in an action chain: Code:
while select($identifiers, 'mobi-asin') do columnupdate_identifiers_amazon() od Last edited by ownedbycats; 05-10-2022 at 04:23 AM. |
|
|
|
|
|
#9 | |
|
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,525
Karma: 8065948
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
|
|
|
|
|
|
|
#10 |
|
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,525
Karma: 8065948
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
I am implementing the for/range loop.
Syntax: Code:
for_expr ::= for_list | for_range
for_list ::= 'for' identifier 'in' list_expr
[ 'separator' separator_expr ] ':' expression_list 'rof'
for_range ::= 'for' variable 'range' [ start_expr 'to' ] stop_expr
[ 'limit' limit_expr ] ':' expression_list 'rof'
Code:
program: res = ''; for i range 0 to strlen($title): c = substr($title, i, i+1); res = strcat(res, if mod(i, 2) == 0 then uppercase(c) else c fi) rof The limit specified the maximum number of loop iterations allowed. It is set to 1000 if omitted. |
|
|
|
|
|
#11 | |
|
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 24,905
Karma: 47303824
Join Date: Jul 2011
Location: Sydney, Australia
Device: Kobo:Touch,Glo, AuraH2O, GloHD,AuraONE, ClaraHD, Libra H2O; tolinoepos
|
Quote:
Except that I really don't like the handling of the range. Firstly, I will never remember the upper limit rules. I will automatically write "strlen($title) - 1" and wonder why it doesn't work properly. I would always expect that the range to handle both the start number and the last number. |
|
|
|
|
|
|
#12 | |
|
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,525
Karma: 8065948
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
We start with the fact that like in python, ranges in the template language are 'i = start' to 'i < stop'. Consider list slices and substrings. Why should a loop from 1 to strlen(x) do something different than substr(x,1,strlen(x)) or sublist(x,1,4,',')? We then should consider previous knowledge, which argues for doing what some other language already does. There are three basic formulations that I remember:
Any one of the following works for me:
In this case, range() would be defined like python's range, as follows:
Using this scheme the for statement syntax would be mostly unchanged. The only change is to add the 'limit' clause. Code:
for_expr ::= 'for' identifier 'in' list_expr [ 'separator' separator_expr ]
[ 'limit' limit_expr ] ':' expression_list 'rof'
|
|
|
|
|
|
|
#13 |
|
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,609
Karma: 28549044
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
From a usability perspective I like range, however, range has th eissue of performance, which is why though the initial python implementation of range returned a list of numbers, in later versions it was changed to return an iterator over numbers.
|
|
|
|
|
|
#14 | |
|
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,525
Karma: 8065948
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
Code:
program:
for i in range(1, 10, 1) limit 1000:
<<something>>
rof
Code:
generator = (str(j) for i,j in enumerate(range(start, stop, step)) if i < limit)
for lv in generator:
user_vars[loop_var] = lv
<<execute the block>>
It might be better from an error reporting standpoint not to check the limit in the generator but instead use an enumerate() when looping, checking the limit explicitly, and raising an exception if it is exceeded. Something like: Code:
generator = (str(j) for j in range(start, stop, step))
for count, lv in enumerate(generator):
if count > limit:
raise (ERROR)
user_vars[loop_var] = lv
<<execute the block>>
|
|
|
|
|
|
|
#15 |
|
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,609
Karma: 28549044
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
You could have both, in the for loop context make range special and everywhere else have it return a list. Reporting an error when limit is exceeded seems better to me.
If you do have range be a special function in the for context, you can statically determine when limit is excedded instead of checking on every iteration. |
|
|
|
![]() |
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Template: Converting a search & replace into a template | ownedbycats | Library Management | 11 | 03-26-2021 05:32 AM |
| Request for comments: new template language operations | chaley | Library Management | 3 | 02-27-2021 01:09 PM |
| Request: Match Calibre Filename template recipe | cbook7 | Library Management | 10 | 06-05-2020 06:11 AM |
| Request: template-making assistance for column built from other columns | iienderii | Library Management | 9 | 04-04-2016 11:27 PM |
| Request for Feedback on E-book Web Template | andreasw | Writers' Corner | 5 | 05-14-2011 01:34 AM |