View Single Post
Old 05-13-2022, 04:30 AM   #12
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 12,457
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by davidfor View Post
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.
I hear you. Unfortunately I don't think there is a one-true answer.

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:
  1. Python and other list-handling languages such as lisp: loop over a sequence of items.
  2. Java and other C-derived languages: (initializer, condition, increment).
  3. Pascal, Fortran, and Algol-like languages: "from n to m" inclusive.
The question: which one to choose? I could go with either of the first 2. I don't like the third because the loop has different semantics than slices.

Any one of the following works for me:
  • Implement the Python range() function as a 'real' function. Example:
    Code:
        i = range(0, 5)
    returns the list '0,1,2,3,4'. One could use this in the standard 'for' as in
    Code:
        for i in range(0,5):
    or even
    Code:
        return range(0,5)
    This has the advantage of consistency with python, and doesn't introduce a new syntax for loops.
  • Go all the way to Java. Example:
    Code:
        for (i = 0, i < 5, i = i + 1):
    This makes all the choices explicit at the cost of some complexity. It is also much more error prone, but the 'limit' specification helps with that.
  • Look for wording that implies the limit is less-than. Example:
    Code:
        for i range 1 upto 5:
    This has the advantage of being simple, but the implication remains just that -- an implication. It probably won't translate well.
I am strongly tempted to go with the range() function. Its semantics are well documented, it is 'pythonic' and calibre is written in python, and it fits well into the template language architecture. And who knows, being able to generate a list of numbers in sequence might actually be useful. In this case, range() would be defined like python's range, as follows:
  • Base definition: range(start, stop, step). The argument count determines which values are provided.
  • range(5): arg count of one is 'stop'. The resulting list is '0,1,2,3,4'
  • range(1, 5): arg count of two is 'start, stop'. The list is '1,2,3,4'
  • range(0, 5, 2): arg count of three is 'start, stop, step', The list is '0,2,4'
  • range(5, 0, -1): example of negative step. The list is '5,4,3,2,1'
The values can be specified by expressions as in range(strlen(x)).

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'
The range() function is a 'list_expr'
chaley is offline   Reply With Quote