unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Understanding dotimes skipping by 2
@ 2018-09-27 22:48 Tim Johnson
  2018-09-28  1:29 ` Van L
  0 siblings, 1 reply; 13+ messages in thread
From: Tim Johnson @ 2018-09-27 22:48 UTC (permalink / raw)
  To: Emacs

using GNU Emacs 26.1 (GTK+ Version) on ubuntu 14.04
 
the following code snippet is as follows:
(setq l `(1 2 3 4 5 6 7 8 9 0))
(1 2 3 4 5 6 7 8 9 0)
;; iterate through a list two elements at a time
(let ((x 0))
  (dotimes (/ (length l) 2)
    (progn
      (insert (format "%s %s, " (nth x l) (nth (+ x 1) l)))
      (setq x (+ x 2)))))

;; and below are the results
1 2, 3 4, 5 6, 7 8, 9 0, nil nil, nil nil, nil nil, nil nil, nil nil, 2

I'm confused about the output (nil etc...)which follow the expected numbers. 
could someone explain?
P.S. I get the same output without the `progn form
thanks
-- 
Tim Johnson
http://www.tj49.com



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
       [not found] <mailman.1418.1538089091.1284.help-gnu-emacs@gnu.org>
@ 2018-09-27 23:14 ` Marco Wahl
  2018-09-27 23:17   ` Eric Abrahamsen
  2018-09-27 23:32   ` Tim Johnson
  0 siblings, 2 replies; 13+ messages in thread
From: Marco Wahl @ 2018-09-27 23:14 UTC (permalink / raw)
  To: help-gnu-emacs

Tim Johnson <tim@akwebsoft.com> writes:

> the following code snippet is as follows:
> (setq l `(1 2 3 4 5 6 7 8 9 0))

> ;; iterate through a list two elements at a time
> (let ((x 0))
>   (dotimes (/ (length l) 2)
>     (progn
>       (insert (format "%s %s, " (nth x l) (nth (+ x 1) l)))
>       (setq x (+ x 2)))))
>
> ;; and below are the results
> 1 2, 3 4, 5 6, 7 8, 9 0, nil nil, nil nil, nil nil, nil nil, nil nil, 2
>
> I'm confused about the output (nil etc...)which follow the expected numbers. 
> could someone explain?
> P.S. I get the same output without the `progn form

Looks like "/" is a variable which gets bound to the values of 0 up to
(length l) and the result of the loop is 2.

It's in the documentation (C-h f dotimes).


HTH
-- 
Marco


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
  2018-09-27 23:14 ` Marco Wahl
@ 2018-09-27 23:17   ` Eric Abrahamsen
  2018-09-27 23:59     ` Tim Johnson
  2018-09-27 23:32   ` Tim Johnson
  1 sibling, 1 reply; 13+ messages in thread
From: Eric Abrahamsen @ 2018-09-27 23:17 UTC (permalink / raw)
  To: help-gnu-emacs

Marco Wahl <marcowahlsoft@gmail.com> writes:

> Tim Johnson <tim@akwebsoft.com> writes:
>
>> the following code snippet is as follows:
>> (setq l `(1 2 3 4 5 6 7 8 9 0))
>
>> ;; iterate through a list two elements at a time
>> (let ((x 0))
>>   (dotimes (/ (length l) 2)
>>     (progn
>>       (insert (format "%s %s, " (nth x l) (nth (+ x 1) l)))
>>       (setq x (+ x 2)))))
>>
>> ;; and below are the results
>> 1 2, 3 4, 5 6, 7 8, 9 0, nil nil, nil nil, nil nil, nil nil, nil nil, 2
>>
>> I'm confused about the output (nil etc...)which follow the expected numbers. 
>> could someone explain?
>> P.S. I get the same output without the `progn form
>
> Looks like "/" is a variable which gets bound to the values of 0 up to
> (length l) and the result of the loop is 2.
>
> It's in the documentation (C-h f dotimes).

To add to that -- if you want to consume a loop two elements at a time,
you'd be better off using `cl-loop' and its "by" keyword.




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
  2018-09-27 23:14 ` Marco Wahl
  2018-09-27 23:17   ` Eric Abrahamsen
@ 2018-09-27 23:32   ` Tim Johnson
  1 sibling, 0 replies; 13+ messages in thread
From: Tim Johnson @ 2018-09-27 23:32 UTC (permalink / raw)
  To: help-gnu-emacs

* Marco Wahl <marcowahlsoft@gmail.com> [180927 15:16]:
> Tim Johnson <tim@akwebsoft.com> writes:
> 
> > the following code snippet is as follows:
> > (setq l `(1 2 3 4 5 6 7 8 9 0))
> 
> > ;; iterate through a list two elements at a time
> > (let ((x 0))
> >   (dotimes (/ (length l) 2)
> >     (progn
> >       (insert (format "%s %s, " (nth x l) (nth (+ x 1) l)))
> >       (setq x (+ x 2)))))
> >
> > ;; and below are the results
> > 1 2, 3 4, 5 6, 7 8, 9 0, nil nil, nil nil, nil nil, nil nil, nil nil, 2
> >
> > I'm confused about the output (nil etc...)which follow the expected numbers. 
> > could someone explain?
> > P.S. I get the same output without the `progn form
> 
> Looks like "/" is a variable which gets bound to the values of 0 up to
> (length l) and the result of the loop is 2.
> 
> It's in the documentation (C-h f dotimes).
  You've revealed that I have a syntax error in the code above.
  `/ was being treated as a variable
  I needed an outer parens for the arguments and needed to add a
  count variable.
    ;; 
    (dotimes (count (/ (length l) 2)) ;; what I'm after (I think)
> HTH
  Thanks, helpful indeed
-- 
Tim Johnson
http://www.tj49.com



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
  2018-09-27 23:17   ` Eric Abrahamsen
@ 2018-09-27 23:59     ` Tim Johnson
  0 siblings, 0 replies; 13+ messages in thread
From: Tim Johnson @ 2018-09-27 23:59 UTC (permalink / raw)
  To: help-gnu-emacs

* Eric Abrahamsen <eric@ericabrahamsen.net> [180927 15:28]:
> Marco Wahl <marcowahlsoft@gmail.com> writes:
<...> >
> > It's in the documentation (C-h f dotimes).
> 
> To add to that -- if you want to consume a loop two elements at a time,
> you'd be better off using `cl-loop' and its "by" keyword.
> 
Thanks: wasn't aware of the cl library... 

-- 
Tim Johnson
http://www.tj49.com



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
  2018-09-27 22:48 Understanding dotimes skipping by 2 Tim Johnson
@ 2018-09-28  1:29 ` Van L
  2018-09-28  2:56   ` Tim Johnson
  2018-09-28  9:11   ` Joost Kremers
  0 siblings, 2 replies; 13+ messages in thread
From: Van L @ 2018-09-28  1:29 UTC (permalink / raw)
  To: Emacs


> the following code snippet is as follows:
> (setq l `(1 2 3 4 5 6 7 8 9 0))
> (1 2 3 4 5 6 7 8 9 0)
> ;; iterate through a list two elements at a time
> (let ((x 0))
>  (dotimes (/ (length l) 2)
>    (progn
>      (insert (format "%s %s, " (nth x l) (nth (+ x 1) l)))
>      (setq x (+ x 2)))))
> 
> ;; and below are the results
> 1 2, 3 4, 5 6, 7 8, 9 0, nil nil, nil nil, nil nil, nil nil, nil nil, 2
> 
> I'm confused about the output (nil etc...)which follow the expected numbers. 
> could someone explain?

The first argument to dotimes needs a symbol to value binding at a guess.

The character l and 1 are too easy to confuse in reading you might want to avoid that.

(setq q '(1 2 3 4 5 6 7 8 9 0))
(let ((x 0))
  (dotimes (i (/ (length q) 2))
    (progn
      (insert (format "%s %s, " (nth x q) (nth (+ x 1) q)))
      (setq x (+ x 2)))))

; 1 2, 3 4, 5 6, 7 8, 9 0, 




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
  2018-09-28  1:29 ` Van L
@ 2018-09-28  2:56   ` Tim Johnson
  2018-09-28  9:11   ` Joost Kremers
  1 sibling, 0 replies; 13+ messages in thread
From: Tim Johnson @ 2018-09-28  2:56 UTC (permalink / raw)
  To: help-gnu-emacs

* Van L <van@scratch.space> [180927 17:39]:
> 
> > the following code snippet is as follows:
> > (setq l `(1 2 3 4 5 6 7 8 9 0))
> > (1 2 3 4 5 6 7 8 9 0)
> > ;; iterate through a list two elements at a time
> > (let ((x 0))
> >  (dotimes (/ (length l) 2)
> >    (progn
> >      (insert (format "%s %s, " (nth x l) (nth (+ x 1) l)))
> >      (setq x (+ x 2)))))
> > 
> > ;; and below are the results
> > 1 2, 3 4, 5 6, 7 8, 9 0, nil nil, nil nil, nil nil, nil nil, nil nil, 2
> > 
> > I'm confused about the output (nil etc...)which follow the expected numbers. 
> > could someone explain?
> 
> The first argument to dotimes needs a symbol to value binding at a guess.
> 
> The character l and 1 are too easy to confuse in reading you might want to avoid that.
> 
> (setq q '(1 2 3 4 5 6 7 8 9 0))
> (let ((x 0))
>   (dotimes (i (/ (length q) 2))
>     (progn
>       (insert (format "%s %s, " (nth x q) (nth (+ x 1) q)))
>       (setq x (+ x 2)))))
> 
> ; 1 2, 3 4, 5 6, 7 8, 9 0, 
  Good practices tip. Thanks Van ..
-- 
Tim Johnson
http://www.tj49.com



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
  2018-09-28  1:29 ` Van L
  2018-09-28  2:56   ` Tim Johnson
@ 2018-09-28  9:11   ` Joost Kremers
  2018-09-28  9:50     ` Van L
                       ` (2 more replies)
  1 sibling, 3 replies; 13+ messages in thread
From: Joost Kremers @ 2018-09-28  9:11 UTC (permalink / raw)
  To: Van L; +Cc: Emacs


On Fri, Sep 28 2018, Van L wrote:
>> the following code snippet is as follows:
>> (setq l `(1 2 3 4 5 6 7 8 9 0))
>> (1 2 3 4 5 6 7 8 9 0)
>> ;; iterate through a list two elements at a time
>> (let ((x 0))
>>  (dotimes (/ (length l) 2)
>>    (progn
>>      (insert (format "%s %s, " (nth x l) (nth (+ x 1) l)))
>>      (setq x (+ x 2)))))
>> 
>> ;; and below are the results
>> 1 2, 3 4, 5 6, 7 8, 9 0, nil nil, nil nil, nil nil, nil nil, 
>> nil nil, 2
>> 
>> I'm confused about the output (nil etc...)which follow the 
>> expected numbers. 
>> could someone explain?
>
> The first argument to dotimes needs a symbol to value binding at 
> a guess.

There is, actually... The first argument of `dotimes' should be a 
list of three elements: a symbol to be bound as a list variable, 
an expression to calculate the upper bound of the loop and an 
expression to be returned as the final result. 

In the OP's code, the first element of the list is `/', so that 
gets bound as list variable. (Yes, in Lisp that's possible).

The second element is `(length l)', which returns the value 10, so 
that the loop is executed 10 times. The first five of these, `(nth 
x l)' and `(nth (+ x 1) l)' refer to elements in the list, after 
that, the return value of both function calls in `nil', hence the 
list of nil's in the output.

The third element of the first argument of `dotimes' here is the 
value 2, so that is returned as the final result, which is why the 
`2' appears at the end.

> The character l and 1 are too easy to confuse in reading you 
> might want to avoid that.
>
> (setq q '(1 2 3 4 5 6 7 8 9 0))
> (let ((x 0))
>   (dotimes (i (/ (length q) 2))
>     (progn
>       (insert (format "%s %s, " (nth x q) (nth (+ x 1) q)))
>       (setq x (+ x 2)))))
>
> ; 1 2, 3 4, 5 6, 7 8, 9 0, 

A few comments:

- `progn' really isn't necessary here, so should be avoided.
- `dotimes' isn't really appropriate here, either, because you're 
  not doing anything with the loop variable `i'. A `while' loop 
  would be more idiomatic:

```
(let ((x 0))
  (while (< x (length l))
    (insert (format "%s %s, " (nth x l) (nth (1+ x) l)))
    (setq x (+ x 2))))
```

- Note also the use of `(1+ x)' instead of (+ x 1). Though 
  honestly I don't know what the difference really is. It's just 
  the idiom I'm used to.

HTH

-- 
Joost Kremers
Life has its moments



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
  2018-09-28  9:11   ` Joost Kremers
@ 2018-09-28  9:50     ` Van L
  2018-09-28 12:23       ` Eli Zaretskii
  2018-09-28 17:47     ` Tim Johnson
  2018-09-28 18:16     ` Noam Postavsky
  2 siblings, 1 reply; 13+ messages in thread
From: Van L @ 2018-09-28  9:50 UTC (permalink / raw)
  To: Emacs


> - Note also the use of `(1+ x)' instead of (+ x 1). Though  honestly I don't know what the difference really is. It's just  the idiom I'm used to.

The 1+ syntactic sugar seems to cost performance by needing more lines of code and it is less general in power to process the argument list if it were to be extended like (+ x 1 2 3). There is no '(+1 x)' implemented in src/data.c

Could 1+ be an infix plus operator crutch?

  ┌────
  │  1  DEFUN ("1+", Fadd1, Sadd1, 1, 1, 0,
  │  2         doc: /* Return NUMBER plus one.  NUMBER may be a number or a marker.
  │  3  Markers are converted to integers.  */)
  │  4    (register Lisp_Object number)
  │  5  {
  │  6    CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (number);
  │  7  
  │  8    if (FLOATP (number))
  │  9      return (make_float (1.0 + XFLOAT_DATA (number)));
  │ 10  
  │ 11    XSETINT (number, XINT (number) + 1);
  │ 12    return number;
  │ 13  }
  └────

  ┌────
  │ 1  DEFUN ("+", Fplus, Splus, 0, MANY, 0,
  │ 2         doc: /* Return sum of any number of arguments, which are numbers or markers.
  │ 3  usage: (+ &rest NUMBERS-OR-MARKERS)  */)
  │ 4    (ptrdiff_t nargs, Lisp_Object *args)
  │ 5  {
  │ 6    return arith_driver (Aadd, nargs, args);
  │ 7  }
  └────




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
  2018-09-28  9:50     ` Van L
@ 2018-09-28 12:23       ` Eli Zaretskii
  2018-09-28 12:26         ` Van L
  0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2018-09-28 12:23 UTC (permalink / raw)
  To: Help-gnu-emacs

> From: Van L <van@scratch.space>
> Date: Fri, 28 Sep 2018 19:50:12 +1000
> 
> 
> The 1+ syntactic sugar seems to cost performance by needing more lines of code

Please compare the actual performance, not the LOC.  The correlation
between those two is not necessarily high.

Also, arith_driver is a function with non-zero LOC, and you should
include that in the metrics, at least.

> and it is less general in power to process the argument list if it were to be extended like (+ x 1 2 3).

Of course it's less general: otherwise, why have a separate function?



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
  2018-09-28 12:23       ` Eli Zaretskii
@ 2018-09-28 12:26         ` Van L
  0 siblings, 0 replies; 13+ messages in thread
From: Van L @ 2018-09-28 12:26 UTC (permalink / raw)
  To: Help-gnu-emacs


> Of course it's less general: otherwise, why have a separate function?

I don’t care to see the point. What a piece of futz!


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
  2018-09-28  9:11   ` Joost Kremers
  2018-09-28  9:50     ` Van L
@ 2018-09-28 17:47     ` Tim Johnson
  2018-09-28 18:16     ` Noam Postavsky
  2 siblings, 0 replies; 13+ messages in thread
From: Tim Johnson @ 2018-09-28 17:47 UTC (permalink / raw)
  To: help-gnu-emacs

* Joost Kremers <joost.kremers@phil.uni-goettingen.de> [180928 08:32]:
<...> The first argument of `dotimes' should be a list of
> three elements: a symbol to be bound as a list variable, an expression to
> calculate the upper bound of the loop and an expression to be returned as
> the final result.
> 
> In the OP's code, the first element of the list is `/', so that gets bound
> as list variable. (Yes, in Lisp that's possible).
> 
> The second element is `(length l)', which returns the value 10, so that the
> loop is executed 10 times. The first five of these, `(nth x l)' and `(nth (+
> x 1) l)' refer to elements in the list, after that, the return value of both
> function calls in `nil', hence the list of nil's in the output.
> 
> The third element of the first argument of `dotimes' here is the value 2, so
> that is returned as the final result, which is why the `2' appears at the
> end.
<...> 
> A few comments:
> 
> - `progn' really isn't necessary here, so should be avoided.
> - `dotimes' isn't really appropriate here, either, because you're  not doing
> anything with the loop variable `i'. A `while' loop  would be more
> idiomatic:
> 
> ```
> (let ((x 0))
>  (while (< x (length l))
>    (insert (format "%s %s, " (nth x l) (nth (1+ x) l)))
>    (setq x (+ x 2))))
> ```
> 
> - Note also the use of `(1+ x)' instead of (+ x 1). Though  honestly I don't
> know what the difference really is. It's just  the idiom I'm used to.
> 
> HTH
  Yes, helps a lot. I've learned (or relearned) much.
  thank you
-- 
Tim Johnson
http://www.tj49.com



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Understanding dotimes skipping by 2
  2018-09-28  9:11   ` Joost Kremers
  2018-09-28  9:50     ` Van L
  2018-09-28 17:47     ` Tim Johnson
@ 2018-09-28 18:16     ` Noam Postavsky
  2 siblings, 0 replies; 13+ messages in thread
From: Noam Postavsky @ 2018-09-28 18:16 UTC (permalink / raw)
  To: joost.kremers; +Cc: Van L, Help Gnu Emacs mailing list

On Fri, 28 Sep 2018 at 12:26, Joost Kremers
<joost.kremers@phil.uni-goettingen.de> wrote:

> - Note also the use of `(1+ x)' instead of (+ x 1). Though
>   honestly I don't know what the difference really is. It's just
>   the idiom I'm used to.

There's no difference except for the human reader: compare
(disassemble (lambda (x) (1+ x))) and (disassemble (lambda (x) (+ 1
x))), the same code is generated.



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2018-09-28 18:16 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-09-27 22:48 Understanding dotimes skipping by 2 Tim Johnson
2018-09-28  1:29 ` Van L
2018-09-28  2:56   ` Tim Johnson
2018-09-28  9:11   ` Joost Kremers
2018-09-28  9:50     ` Van L
2018-09-28 12:23       ` Eli Zaretskii
2018-09-28 12:26         ` Van L
2018-09-28 17:47     ` Tim Johnson
2018-09-28 18:16     ` Noam Postavsky
     [not found] <mailman.1418.1538089091.1284.help-gnu-emacs@gnu.org>
2018-09-27 23:14 ` Marco Wahl
2018-09-27 23:17   ` Eric Abrahamsen
2018-09-27 23:59     ` Tim Johnson
2018-09-27 23:32   ` Tim Johnson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).