unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Easy to add with push but not to the end of a list
@ 2022-11-28  2:26 Heime
  2022-11-28  2:43 ` [External] : " Drew Adams
                   ` (3 more replies)
  0 siblings, 4 replies; 60+ messages in thread
From: Heime @ 2022-11-28  2:26 UTC (permalink / raw)
  To: Heime via Users list for the GNU Emacs text editor


Although it is easy to add to a list using push, it currently looks hideous to be able to 
add to the end of a list.  Would be appreciated if emacs could have a function as simple
to add to the end of a list? 







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

* RE: [External] : Easy to add with push but not to the end of a list
  2022-11-28  2:26 Easy to add with push but not to the end of a list Heime
@ 2022-11-28  2:43 ` Drew Adams
  2022-11-28  3:45   ` Heime
  2022-11-28 20:00   ` Emanuel Berg
  2022-11-28  5:18 ` Stefan Monnier via Users list for the GNU Emacs text editor
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 60+ messages in thread
From: Drew Adams @ 2022-11-28  2:43 UTC (permalink / raw)
  To: Heime, 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'

[-- Attachment #1: Type: text/plain, Size: 507 bytes --]

> Although it is easy to add to a list using push, it currently looks
> hideous to be able to
> add to the end of a list.  Would be appreciated if emacs could have a
> function as simple to add to the end of a list?

`add-to-list' with optional arg APPEND?
____

I wonder how you try to find such info.
Did you even look in the Elisp manual?

`add-to-list' is in the same node as `push',
node `List Variables'.

https://www.gnu.org/software/emacs/manual/html_node/elisp/List-Variables.html


[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 13532 bytes --]

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

* RE: [External] : Easy to add with push but not to the end of a list
  2022-11-28  2:43 ` [External] : " Drew Adams
@ 2022-11-28  3:45   ` Heime
  2022-11-28  6:11     ` Drew Adams
  2022-11-28 20:00   ` Emanuel Berg
  1 sibling, 1 reply; 60+ messages in thread
From: Heime @ 2022-11-28  3:45 UTC (permalink / raw)
  To: Drew Adams; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'


------- Original Message -------
On Monday, November 28th, 2022 at 2:43 AM, Drew Adams <drew.adams@oracle.com> wrote:


> > Although it is easy to add to a list using push, it currently looks
> > hideous to be able to
> > add to the end of a list. Would be appreciated if emacs could have a
> > function as simple to add to the end of a list?
> 
> 
> `add-to-list' with optional arg APPEND? 

The problem is that add-to-list enforces uniqueness.  Thusly, add-to-list is not 
an actual append, but a constrained append.  

> I wonder how you try to find such info. Did you even look in the Elisp manual?` 
> add-to-list' is in the same node as `push', node` List Variables'.
> 
> https://www.gnu.org/software/emacs/manual/html_node/elisp/List-Variables.html



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

* Re: Easy to add with push but not to the end of a list
  2022-11-28  2:26 Easy to add with push but not to the end of a list Heime
  2022-11-28  2:43 ` [External] : " Drew Adams
@ 2022-11-28  5:18 ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-11-28 20:19   ` Emanuel Berg
  2022-11-28 19:59 ` Emanuel Berg
  2022-11-30 17:10 ` Michael Heerdegen
  3 siblings, 1 reply; 60+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-11-28  5:18 UTC (permalink / raw)
  To: help-gnu-emacs

> Although it is easy to add to a list using push, it currently looks
> hideous to be able to  add to the end of a list.

That's because adding to the end of a Lisp list is a *bad* idea.

Your better option usually is to avoid doing that by keeping your list
in reverse order while you add elements to it and to reverse it at the end.

> Would be appreciated if Emacs could have a function as simple
> to add to the end of a list?

    (cl-callf PLACE (lambda (xs) (append xs (list VAL))))

while `push` is constant time, the above has O(N) complexity.


        Stefan




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

* RE: [External] : Easy to add with push but not to the end of a list
  2022-11-28  3:45   ` Heime
@ 2022-11-28  6:11     ` Drew Adams
  0 siblings, 0 replies; 60+ messages in thread
From: Drew Adams @ 2022-11-28  6:11 UTC (permalink / raw)
  To: Heime; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'

> > > Although it is easy to add to a list using push, it currently looks
> > > hideous to be able to
> > > add to the end of a list. Would be appreciated if emacs could have a
> > > function as simple to add to the end of a list?
> >
> > `add-to-list' with optional arg APPEND?
> 
> The problem is that add-to-list enforces uniqueness.  Thusly, add-to-list
> is not an actual append, but a constrained append.

In addition to what Stefan said - Lisp lists
favor access/changes at the head, and it's often
better to avoid list traversal, for performance
- which is the main message...

`add-to-list' also accepts an optional predicate
arg to test equality.  Passing it a predicate
that returns nil makes it just add.

Not that you have to use `add-to-list'.  There
are any number of ways to add something to the
end of a list, if you need to.  `add-to-list'
just happens to be one way that you have OOTB.
`append' is another: (append x (list y)).  And
`nconc'.

But again, don't work at the end of a list if
you can work at the front, and you can often
do that and just reverse at the end (traverse
the full list only once).

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

* Re: Easy to add with push but not to the end of a list
  2022-11-28  2:26 Easy to add with push but not to the end of a list Heime
  2022-11-28  2:43 ` [External] : " Drew Adams
  2022-11-28  5:18 ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-11-28 19:59 ` Emanuel Berg
  2022-11-28 21:56   ` [External] : " Drew Adams
  2022-11-29 11:17   ` Dr Rainer Woitok
  2022-11-30 17:10 ` Michael Heerdegen
  3 siblings, 2 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-28 19:59 UTC (permalink / raw)
  To: help-gnu-emacs

Heime wrote:

> Although it is easy to add to a list using push, it
> currently looks hideous to be able to add to the end of
> a list.

I don't know how it currently looks but I agree there should
be such a function in vanilla Emacs.

> Would be appreciated if emacs could have a function as
> simple to add to the end of a list?

Maybe something like this?

(defun push-last (elem lst)
  (when (listp lst)
    (setcdr (last lst) (list elem))
    lst) )

(setq lst '(1 2 3 4))

lst ; (1 2 3 4)

(push-last 5 lst) ; (1 2 3 4 5)

lst ; (1 2 3 4 5)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Easy to add with push but not to the end of a list
  2022-11-28  2:43 ` [External] : " Drew Adams
  2022-11-28  3:45   ` Heime
@ 2022-11-28 20:00   ` Emanuel Berg
  1 sibling, 0 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-28 20:00 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote:

> `add-to-list' with optional arg APPEND?
>
> I wonder how you try to find such info. Did you even look in
> the Elisp manual?
>
> `add-to-list' is in the same node as `push', node
> `List Variables'.

`push-last' will be easier to find and better without the need
for the/an optional APPEND arg ...

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-28  5:18 ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-11-28 20:19   ` Emanuel Berg
  2022-11-28 21:56     ` [External] : " Drew Adams
  2022-11-28 22:01     ` Heime
  0 siblings, 2 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-28 20:19 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier via Users list for the GNU Emacs text editor wrote:

>> Although it is easy to add to a list using push, it
>> currently looks hideous to be able to add to the end of
>> a list.
>
> That's because adding to the end of a Lisp list is
> a *bad* idea.

Let's make it as good as possible first ...

Why is the below O(N), because of `last'?

(defun push-last (elem lst)
  (let ((elem-lst (list elem)))
    (if lst
        (setcdr (last lst) elem-lst)
      (setq lst elem-lst) )
    lst) )

;; (setq nil-lst nil)
;;
;; (push-last 1 nil-lst) ; (1)
;;
;; (setq lst '(1 2 3 4))
;;
;; (push-last 5 lst) ; (1 2 3 4 5)
;;
;; lst ; (1 2 3 4 5)

-- 
underground experts united
https://dataswamp.org/~incal




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

* RE: [External] : Re: Easy to add with push but not to the end of a list
  2022-11-28 20:19   ` Emanuel Berg
@ 2022-11-28 21:56     ` Drew Adams
  2022-11-28 22:45       ` Emanuel Berg
  2022-11-28 22:01     ` Heime
  1 sibling, 1 reply; 60+ messages in thread
From: Drew Adams @ 2022-11-28 21:56 UTC (permalink / raw)
  To: Emanuel Berg, help-gnu-emacs@gnu.org

> Why is the below O(N), because of `last'?
> 
> (defun push-last (elem lst)
>   (let ((elem-lst (list elem)))
>     (if lst
>         (setcdr (last lst) elem-lst)
>       (setq lst elem-lst) )
>     lst) )

Yes.

(append lst (list elem)) also traverses the list
usually.



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

* RE: [External] : Re: Easy to add with push but not to the end of a list
  2022-11-28 19:59 ` Emanuel Berg
@ 2022-11-28 21:56   ` Drew Adams
  2022-11-28 22:18     ` Heime
  2022-11-29 11:17   ` Dr Rainer Woitok
  1 sibling, 1 reply; 60+ messages in thread
From: Drew Adams @ 2022-11-28 21:56 UTC (permalink / raw)
  To: Emanuel Berg, help-gnu-emacs@gnu.org

> I agree there should be such a function in vanilla Emacs.
> Maybe something like this?
> 
> (defun push-last (elem lst)
>   (when (listp lst)
>     (setcdr (last lst) (list elem))
>     lst))

As I said, there are umpteen different meanings /
behaviors for "add an element to the end of a list".

(setcdr (last lst) (list elem)) is one such behavior.

And that's just as succinct as (push-last elem lst),
and clearer.  It makes crystal clear that you're
opting for list modification.



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

* Re: Easy to add with push but not to the end of a list
  2022-11-28 20:19   ` Emanuel Berg
  2022-11-28 21:56     ` [External] : " Drew Adams
@ 2022-11-28 22:01     ` Heime
  2022-11-28 22:24       ` Stefan Monnier via Users list for the GNU Emacs text editor
                         ` (3 more replies)
  1 sibling, 4 replies; 60+ messages in thread
From: Heime @ 2022-11-28 22:01 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: help-gnu-emacs

------- Original Message -------
On Monday, November 28th, 2022 at 8:19 PM, Emanuel Berg <incal@dataswamp.org> wrote:


> Stefan Monnier via Users list for the GNU Emacs text editor wrote:
> 
> > > Although it is easy to add to a list using push, it
> > > currently looks hideous to be able to add to the end of
> > > a list.
> > 
> > That's because adding to the end of a Lisp list is
> > a bad idea.

The bad idea comment disregards necessity.  Suppose I am accumulating
indicators that are done at increasing value of time and want to introduce
them into another list in the order they were encountered.  What should one 
handle these things? 
 
> Let's make it as good as possible first ...
> 
> Why is the below O(N), because of `last'?
> 
> (defun push-last (elem lst)
> (let ((elem-lst (list elem)))
> (if lst
> (setcdr (last lst) elem-lst)
> (setq lst elem-lst) )
> lst) )
> 
> ;; (setq nil-lst nil)
> ;;
> ;; (push-last 1 nil-lst) ; (1)
> ;;
> ;; (setq lst '(1 2 3 4))
> ;;
> ;; (push-last 5 lst) ; (1 2 3 4 5)
> ;;
> ;; lst ; (1 2 3 4 5)
> 
> --
> underground experts united
> https://dataswamp.org/~incal



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

* RE: [External] : Re: Easy to add with push but not to the end of a list
  2022-11-28 21:56   ` [External] : " Drew Adams
@ 2022-11-28 22:18     ` Heime
  2022-11-28 22:41       ` Drew Adams
  0 siblings, 1 reply; 60+ messages in thread
From: Heime @ 2022-11-28 22:18 UTC (permalink / raw)
  To: Drew Adams; +Cc: Emanuel Berg, help-gnu-emacs@gnu.org

------- Original Message -------
On Monday, November 28th, 2022 at 9:56 PM, Drew Adams <drew.adams@oracle.com> wrote:


> > I agree there should be such a function in vanilla Emacs.
> > Maybe something like this?
> > 
> > (defun push-last (elem lst)
> > (when (listp lst)
> > (setcdr (last lst) (list elem))
> > lst))
> 
> 
> As I said, there are umpteen different meanings /
> behaviors for "add an element to the end of a list".
> 
> (setcdr (last lst) (list elem)) is one such behavior.
> 
> And that's just as succinct as (push-last elem lst),
> and clearer. It makes crystal clear that you're
> opting for list modification.

There are never any qualms about putting something at the beginning 
of a list.  One should not take a different attitude to adding after 
the last entry.




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

* Re: Easy to add with push but not to the end of a list
  2022-11-28 22:01     ` Heime
@ 2022-11-28 22:24       ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-11-28 22:58         ` Emanuel Berg
  2022-11-28 22:46       ` Emanuel Berg
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 60+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-11-28 22:24 UTC (permalink / raw)
  To: help-gnu-emacs

>> > That's because adding to the end of a Lisp list is
>> > a bad idea.
> The bad idea comment disregards necessity.

Another way to look at it is that you disregard the possibility to
change your necessity.

> Suppose I am accumulating indicators that are done at increasing value
> of time and want to introduce them into another list in the order they
> were encountered.  What should one  handle these things?

Add them in the reverse order and finish with a simple `reverse`.
That's a very standard design pattern with singly-linked lists (and in
many/most cases the final `reverse` can be an `nreverse`).
Of course, in practice I'm sure there are many other options if you
consider the problem in context where you can make changes to other
parts of your code (e.g. to use something else than a list).


        Stefan




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

* RE: [External] : Re: Easy to add with push but not to the end of a list
  2022-11-28 22:18     ` Heime
@ 2022-11-28 22:41       ` Drew Adams
  0 siblings, 0 replies; 60+ messages in thread
From: Drew Adams @ 2022-11-28 22:41 UTC (permalink / raw)
  To: Heime; +Cc: Emanuel Berg, help-gnu-emacs@gnu.org

> There are never any qualms about putting something at the beginning
> of a list.  One should not take a different attitude to adding after
> the last entry.

Qualms?  Do you understand that a list is either
nil (an atom) or a cons?  And that a cons holds
one list element and a pointer to another list?

Now think about _why_ accessing Lisp lists from
the head is different from accessing them from
the end.  To get to the end you need to cdr
down the list, cons by cons - one way or another.

(Or else you have to have saved a reference to
that last cons or its cdr.  In that case you can
get there directly.)

Should one take a different attitude to the two
lane directions when driving down a two-lane
highway?  The "business end" of a weapon or tool
versus the other end?  Qualms indeed.

Liberté, Egalité, Fraternité !  Go for it. 

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

* Re: [External] : Re: Easy to add with push but not to the end of a list
  2022-11-28 21:56     ` [External] : " Drew Adams
@ 2022-11-28 22:45       ` Emanuel Berg
  0 siblings, 0 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-28 22:45 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote:

>> Why is the below O(N), because of `last'?
>> 
>> (defun push-last (elem lst)
>>   (let ((elem-lst (list elem)))
>>     (if lst
>>         (setcdr (last lst) elem-lst)
>>       (setq lst elem-lst) )
>>     lst) )
>
> Yes.
>
> (append lst (list elem)) also traverses the list
> usually.

Now it works at least, O(n) or not ...

(defmacro push-last (elem lst)
  (if (and (symbolp lst)
           (not (symbol-value lst)) )
      (list 'setq 'lst `(list ,elem))
    (list 'nconc lst `(list ,elem)) ))

;; (setq lst ())         ; ()
;; (push-last 1 lst)     ; (1)
;; (push-last 1 lst)     ; (1 1)
;; lst                   ; (1 1)
;;
;; (setq lst '(1 2 3 4)) ; (1 2 3 4)
;; (push-last 5 lst)     ; (1 2 3 4 5)
;; (push-last 5 lst)     ; (1 2 3 4 5)
;; lst                   ; (1 2 3 4 5 5)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-28 22:01     ` Heime
  2022-11-28 22:24       ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-11-28 22:46       ` Emanuel Berg
  2022-11-28 22:50       ` Emanuel Berg
  2022-11-29  5:23       ` tomas
  3 siblings, 0 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-28 22:46 UTC (permalink / raw)
  To: help-gnu-emacs

Heime wrote:

>>> Although it is easy to add to a list using push, it
>>> currently looks hideous to be able to add to the end of
>>> a list.
>> 
>> That's because adding to the end of a Lisp list is
>> a bad idea.
>
> The bad idea comment disregards necessity.

(defmacro push-last (elem lst)
  (if (and (symbolp lst)
           (not (symbol-value lst)) )
      (list 'setq 'lst `(list ,elem))
    (list 'nconc lst `(list ,elem)) ))

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-28 22:01     ` Heime
  2022-11-28 22:24       ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-11-28 22:46       ` Emanuel Berg
@ 2022-11-28 22:50       ` Emanuel Berg
  2022-11-29  5:23       ` tomas
  3 siblings, 0 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-28 22:50 UTC (permalink / raw)
  To: help-gnu-emacs

Heime wrote:

>>> Although it is easy to add to a list using push, it
>>> currently looks hideous to be able to add to the end of
>>> a list.
>> 
>> That's because adding to the end of a Lisp list is
>> a bad idea.
>
> The bad idea comment disregards necessity.

Okay NOW it works ...

(defmacro push-last (elem lst)
  (if (and (symbolp lst)
           (not (symbol-value lst)) )
      (list 'setq lst `(list ,elem))
    (list 'nconc lst `(list ,elem)) ))

;; (setq lst ())         ; ()
;; (push-last 1 lst)     ; (1)
;; (push-last 1 lst)     ; (1 1)
;; lst                   ; (1 1)
;;
;; (setq lst '(1 2 3 4)) ; (1 2 3 4)
;; (push-last 5 lst)     ; (1 2 3 4 5)
;; (push-last 5 lst)     ; (1 2 3 4 5)
;; lst                   ; (1 2 3 4 5 5)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-28 22:24       ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-11-28 22:58         ` Emanuel Berg
  2022-11-30 14:10           ` tomas
  0 siblings, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2022-11-28 22:58 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier via Users list for the GNU Emacs text editor wrote:

> Add them in the reverse order and finish with a simple
> `reverse`. That's a very standard design pattern with
> singly-linked lists (and in many/most cases the final
> `reverse` can be an `nreverse`).

I thought about `nreverse' but if that changes all the CDRs
then that's linear as well i.e. O(n), otherwise you could do
nreverse, `push', and nreverse again ...

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-28 22:01     ` Heime
                         ` (2 preceding siblings ...)
  2022-11-28 22:50       ` Emanuel Berg
@ 2022-11-29  5:23       ` tomas
  2022-11-29  5:32         ` Emanuel Berg
                           ` (2 more replies)
  3 siblings, 3 replies; 60+ messages in thread
From: tomas @ 2022-11-29  5:23 UTC (permalink / raw)
  To: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 1489 bytes --]

On Mon, Nov 28, 2022 at 10:01:24PM +0000, Heime wrote:
> ------- Original Message -------
> On Monday, November 28th, 2022 at 8:19 PM, Emanuel Berg <incal@dataswamp.org> wrote:
> 
> 
> > Stefan Monnier via Users list for the GNU Emacs text editor wrote:
> > 
> > > > Although it is easy to add to a list using push, it
> > > > currently looks hideous to be able to add to the end of
> > > > a list.
> > > 
> > > That's because adding to the end of a Lisp list is
> > > a bad idea.
> 
> The bad idea comment disregards necessity...

Q "But I /want/ to hit this nail into the wall with a spoon!"

A "You can try. But please, do it in your living room. And
   oh, with your own spoon"

Programming is somewhere between engineering and craft. In
these realms, you usually try to think about what tools are
appropriate for a job.

Singly linked lists are a tool. They are simple, lightweight,
and appropriate for keeping things in sequence, and for adding
things at the front. Not at the end.

Core library functions express idioms. They are expected to
help people to find patterns on how to use tools appropriately
(it's not much different from tools: a screwdriver has a
handle, which spells "grip me here, please").

Adding a function to core (say `hsup') which suggests that
it is as easy to push something at the end of a list would
be misleading people to hold the screwdriver (or the knife!)
at the wrong end and hurt themselves.

Cheers
-- 
t

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

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

* Re: Easy to add with push but not to the end of a list
  2022-11-29  5:23       ` tomas
@ 2022-11-29  5:32         ` Emanuel Berg
  2022-11-29  7:56         ` Heime
  2022-11-29  8:17         ` Marcin Borkowski
  2 siblings, 0 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-29  5:32 UTC (permalink / raw)
  To: help-gnu-emacs

tomas wrote:

>> The bad idea comment disregards necessity...
>
> Q "But I /want/ to hit this nail into the wall with a spoon!"
>
> A "You can try. But please, do it in your living room. And
>    oh, with your own spoon"
>
> Programming is somewhere between engineering and craft.
> In these realms, you usually try to think about what tools
> are appropriate for a job.
>
> Singly linked lists are a tool. They are simple,
> lightweight, and appropriate for keeping things in sequence,
> and for adding things at the front. Not at the end.

Yes, but there is, for example, `last'.

Why do we have that if that is O(n) and not O(1) as is `car'?

Why car _and_ last while at the same time `push' _and not_ "push-last"?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-29  5:23       ` tomas
  2022-11-29  5:32         ` Emanuel Berg
@ 2022-11-29  7:56         ` Heime
  2022-11-29  8:33           ` Marcin Borkowski
                             ` (2 more replies)
  2022-11-29  8:17         ` Marcin Borkowski
  2 siblings, 3 replies; 60+ messages in thread
From: Heime @ 2022-11-29  7:56 UTC (permalink / raw)
  To: tomas; +Cc: help-gnu-emacs

------- Original Message -------
On Tuesday, November 29th, 2022 at 5:23 AM, <tomas@tuxteam.de> wrote:


> On Mon, Nov 28, 2022 at 10:01:24PM +0000, Heime wrote:
> 
> > ------- Original Message -------
> > On Monday, November 28th, 2022 at 8:19 PM, Emanuel Berg incal@dataswamp.org wrote:
> > 
> > > Stefan Monnier via Users list for the GNU Emacs text editor wrote:
> > > 
> > > > > Although it is easy to add to a list using push, it
> > > > > currently looks hideous to be able to add to the end of
> > > > > a list.
> > > > 
> > > > That's because adding to the end of a Lisp list is
> > > > a bad idea.
> > 
> > The bad idea comment disregards necessity...
> 
> 
> Q "But I /want/ to hit this nail into the wall with a spoon!"
> 
> A "You can try. But please, do it in your living room. And
> oh, with your own spoon"
> 
> Programming is somewhere between engineering and craft. In
> these realms, you usually try to think about what tools are
> appropriate for a job.

Programming has got nothing to do with engineering or craft.  
 
> Singly linked lists are a tool. They are simple, lightweight,
> and appropriate for keeping things in sequence, and for adding
> things at the front. Not at the end.

Stefan mentioned using reverse to put it into another list.  If needed
the execution time would not be much different than actually place
new elements at end of list.
 
> Core library functions express idioms. They are expected to
> help people to find patterns on how to use tools appropriately
> (it's not much different from tools: a screwdriver has a
> handle, which spells "grip me here, please").
> 
> Adding a function to core (say `hsup') which suggests that
> it is as easy to push something at the end of a list would
> be misleading people to hold the screwdriver (or the knife!)
> at the wrong end and hurt themselves.

Nobody will get hurt.  Just inefficient for long lists or for
large number of calls.
 
> Cheers
> --
> t



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

* Re: Easy to add with push but not to the end of a list
  2022-11-29  5:23       ` tomas
  2022-11-29  5:32         ` Emanuel Berg
  2022-11-29  7:56         ` Heime
@ 2022-11-29  8:17         ` Marcin Borkowski
  2022-11-29  8:44           ` tomas
  2 siblings, 1 reply; 60+ messages in thread
From: Marcin Borkowski @ 2022-11-29  8:17 UTC (permalink / raw)
  To: tomas; +Cc: help-gnu-emacs


On 2022-11-29, at 06:23, tomas@tuxteam.de wrote:

> Adding a function to core (say `hsup') which suggests that

I absolutely love your choice of the name here! :-)

-- 
Marcin Borkowski
http://mbork.pl



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

* Re: Easy to add with push but not to the end of a list
  2022-11-29  7:56         ` Heime
@ 2022-11-29  8:33           ` Marcin Borkowski
  2022-11-29 10:00             ` Emanuel Berg
  2022-11-29 10:15             ` Heime
  2022-11-29  8:38           ` tomas
  2022-11-29  9:54           ` Emanuel Berg
  2 siblings, 2 replies; 60+ messages in thread
From: Marcin Borkowski @ 2022-11-29  8:33 UTC (permalink / raw)
  To: Heime; +Cc: tomas, help-gnu-emacs


On 2022-11-29, at 08:56, Heime <heimeborgia@protonmail.com> wrote:

> Programming has got nothing to do with engineering or craft.

What is it, then?  (I'm genuinely curious about your opinion.)

>> Singly linked lists are a tool. They are simple, lightweight,
>> and appropriate for keeping things in sequence, and for adding
>> things at the front. Not at the end.
>
> Stefan mentioned using reverse to put it into another list.  If needed
> the execution time would not be much different than actually place
> new elements at end of list.

The difference is that you keep adding items at the front and then
reverse the list /once/.

Another pattern you might use is to ditch lists and keep the items in
a temporary buffer, keeping point at its end (which is easy with
`insert'), and then traverse the buffer to gather the results as needed.
You might even want to keep them in a buffer as a printed representation
of a list, and then read it, using the Elisp parser.  (I don't know what
function would help with that, but I'm pretty certain such a function
exists.)  Not sure how efficient this would be, but I'd guess it could
be pretty good with really large number of items.

Yet another option would be to keep the whole list in some variable, but
use another variable (say, `last') as a "pointer" to the last cons of
that list.  Then, you can define `fast-append' like this:

(defvar last nil)
(defvar my-list nil)

(defun fast-append (el)
  "Append EL at the end of `my-list' in O(1) time."
  (if (not my-list)
      (setf my-list (cons el nil)
	    last my-list)
    (setf (cdr last) (cons el nil)
	  last (cdr last))))

This then would be O(1).

>> Core library functions express idioms. They are expected to
>> help people to find patterns on how to use tools appropriately
>> (it's not much different from tools: a screwdriver has a
>> handle, which spells "grip me here, please").
>>
>> Adding a function to core (say `hsup') which suggests that
>> it is as easy to push something at the end of a list would
>> be misleading people to hold the screwdriver (or the knife!)
>> at the wrong end and hurt themselves.
>
> Nobody will get hurt.  Just inefficient for long lists or for
> large number of calls.

Every time someone appends to the end of a singly linked list, a cute
kitty dies...

;-)

-- 
Marcin Borkowski
http://mbork.pl



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

* Re: Easy to add with push but not to the end of a list
  2022-11-29  7:56         ` Heime
  2022-11-29  8:33           ` Marcin Borkowski
@ 2022-11-29  8:38           ` tomas
  2022-11-29  9:54           ` Emanuel Berg
  2 siblings, 0 replies; 60+ messages in thread
From: tomas @ 2022-11-29  8:38 UTC (permalink / raw)
  To: Heime; +Cc: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 548 bytes --]

On Tue, Nov 29, 2022 at 07:56:53AM +0000, Heime wrote:

[...]

> Programming has got nothing to do with engineering or craft.  

It seems we live in different worlds, then.

> Stefan mentioned using reverse to put it into another list.  If needed
> the execution time would not be much different than actually place
> new elements at end of list.

Your world seems to have different computers than mine.

> Nobody will get hurt [...]

Except, perhaps, your software's users. I'll try hard to not be
one of them.

Cheers
-- 
t

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

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

* Re: Easy to add with push but not to the end of a list
  2022-11-29  8:17         ` Marcin Borkowski
@ 2022-11-29  8:44           ` tomas
  2022-11-29 12:08             ` Dr Rainer Woitok
  0 siblings, 1 reply; 60+ messages in thread
From: tomas @ 2022-11-29  8:44 UTC (permalink / raw)
  To: Marcin Borkowski; +Cc: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 670 bytes --]

On Tue, Nov 29, 2022 at 09:17:58AM +0100, Marcin Borkowski wrote:
> 
> On 2022-11-29, at 06:23, tomas@tuxteam.de wrote:
> 
> > Adding a function to core (say `hsup') which suggests that
> 
> I absolutely love your choice of the name here! :-)

There are big precedents out there (cf. for example Donald Knuth's
WEB for TeX and METAFONT; it seems to have been in the air for
some time -- vestiges of that can be found in the shells (if -- fi,
case -- esac and so on; pity Lisp must have been a tad early;
otherwise we might have car -- rac, definitely a better sound than
cdr).

I'll stop now, lest I end on the fire for apostasy... ;-)

Cheers
-- 
t

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

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

* Re: Easy to add with push but not to the end of a list
  2022-11-29  7:56         ` Heime
  2022-11-29  8:33           ` Marcin Borkowski
  2022-11-29  8:38           ` tomas
@ 2022-11-29  9:54           ` Emanuel Berg
  2 siblings, 0 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-29  9:54 UTC (permalink / raw)
  To: help-gnu-emacs

Heime wrote:

>> Programming is somewhere between engineering and craft.
>> In these realms, you usually try to think about what tools
>> are appropriate for a job.
>
> Programming has got nothing to do with engineering or craft.

Unheard of :O

> Stefan mentioned using reverse to put it into another list.
> If needed the execution time would not be much different
> than actually place new elements at end of list.

I think the lists has to be double linked for it to be
theoretically possible to push-last in constant or O(1) time,
otherwise, with our car/cdr lists that are one-directional or
single linked, the execution time of such an operation will be
proportional to the length of the list, i.e. the number of
elements, so it'll be linear time or O(n) where n is the
number of elements of a conceptual/arbitrary list.

But also in practice! Only for you to notice it, i.e.
the difference between O(1) and O(n), the list probably has to
be pretty long, so a large n then ...

Start testing ...

> Nobody will get hurt. Just inefficient for long lists or for
> large number of calls.

That's exactly right.

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-29  8:33           ` Marcin Borkowski
@ 2022-11-29 10:00             ` Emanuel Berg
  2022-11-29 10:05               ` Emanuel Berg
  2022-11-29 10:15             ` Heime
  1 sibling, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2022-11-29 10:00 UTC (permalink / raw)
  To: help-gnu-emacs

Marcin Borkowski wrote:

> The difference is that you keep adding items at the front
> and then reverse the list /once/.

But if `nreverse' is O(1) then you can do it twice, first
nreverse, then `car', then nreverse.

Don't you have to flip all the cell cdr links? O(n)?

> Yet another option would be to keep the whole list in some
> variable, but use another variable (say, `last') as
> a "pointer" to the last cons

Yes of course :)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-29 10:00             ` Emanuel Berg
@ 2022-11-29 10:05               ` Emanuel Berg
  0 siblings, 0 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-29 10:05 UTC (permalink / raw)
  To: help-gnu-emacs

>> The difference is that you keep adding items at the front
>> and then reverse the list /once/.
>
> But if `nreverse' is O(1) then you can do it twice, first
> nreverse, then `car', then nreverse.

Not `car', `push' :)

But it isn't ... I mean `nreverse'.

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-29  8:33           ` Marcin Borkowski
  2022-11-29 10:00             ` Emanuel Berg
@ 2022-11-29 10:15             ` Heime
  1 sibling, 0 replies; 60+ messages in thread
From: Heime @ 2022-11-29 10:15 UTC (permalink / raw)
  To: Marcin Borkowski; +Cc: tomas, help-gnu-emacs

------- Original Message -------
On Tuesday, November 29th, 2022 at 8:33 AM, Marcin Borkowski <mbork@mbork.pl> wrote:


> On 2022-11-29, at 08:56, Heime heimeborgia@protonmail.com wrote:
> 
> > Programming has got nothing to do with engineering or craft.
> 
> 
> What is it, then? (I'm genuinely curious about your opinion.)

Programming should be included in the Department of Sports.  :)
 
> > > Singly linked lists are a tool. They are simple, lightweight,
> > > and appropriate for keeping things in sequence, and for adding
> > > things at the front. Not at the end.
> > 
> > Stefan mentioned using reverse to put it into another list. If needed
> > the execution time would not be much different than actually place
> > new elements at end of list.
> 
> 
> The difference is that you keep adding items at the front and then
> reverse the list /once/.
> 
> Another pattern you might use is to ditch lists and keep the items in
> a temporary buffer, keeping point at its end (which is easy with
> `insert'), and then traverse the buffer to gather the results as needed. You might even want to keep them in a buffer as a printed representation of a list, and then read it, using the Elisp parser. (I don't know what function would help with that, but I'm pretty certain such a function exists.) Not sure how efficient this would be, but I'd guess it could be pretty good with really large number of items. Yet another option would be to keep the whole list in some variable, but use another variable (say,` last') as a "pointer" to the last cons of
> that list. Then, you can define `fast-append' like this: (defvar last nil) (defvar my-list nil) (defun fast-append (el) "Append EL at the end of` my-list' in O(1) time."
> (if (not my-list)
> (setf my-list (cons el nil)
> last my-list)
> (setf (cdr last) (cons el nil)
> last (cdr last))))
> 
> This then would be O(1).
> 
> > > Core library functions express idioms. They are expected to
> > > help people to find patterns on how to use tools appropriately
> > > (it's not much different from tools: a screwdriver has a
> > > handle, which spells "grip me here, please").
> > > 
> > > Adding a function to core (say `hsup') which suggests that
> > > it is as easy to push something at the end of a list would
> > > be misleading people to hold the screwdriver (or the knife!)
> > > at the wrong end and hurt themselves.
> > 
> > Nobody will get hurt. Just inefficient for long lists or for
> > large number of calls.
> 
> Every time someone appends to the end of a singly linked list, a cute
> kitty dies...
> 
> ;-)

Pussy Riot it is, then!
 
> --
> Marcin Borkowski
> http://mbork.pl



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

* Re: Easy to add with push but not to the end of a list
  2022-11-28 19:59 ` Emanuel Berg
  2022-11-28 21:56   ` [External] : " Drew Adams
@ 2022-11-29 11:17   ` Dr Rainer Woitok
  1 sibling, 0 replies; 60+ messages in thread
From: Dr Rainer Woitok @ 2022-11-29 11:17 UTC (permalink / raw)
  To: Emanuel Berg, help-gnu-emacs

Emanuel,

On Monday, 2022-11-28 20:59:31 +0100, you wrote:

> ...
> (defun push-last (elem lst)
>   (when (listp lst)
>     (setcdr (last lst) (list elem))
>     lst) )

I think 

  (push-last 1 nil)

would fail  with an error message.   But apart from  the error checking,
why not just use

  (nconc lst (list elem))

Sincerely,
  Rainer



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

* Re: Easy to add with push but not to the end of a list
  2022-11-29  8:44           ` tomas
@ 2022-11-29 12:08             ` Dr Rainer Woitok
  2022-11-29 19:54               ` Of cars and mice [was: Easy to add with push but not to the end of a list] tomas
  2022-11-30  1:13               ` Easy to add with push but not to the end of a list Emanuel Berg
  0 siblings, 2 replies; 60+ messages in thread
From: Dr Rainer Woitok @ 2022-11-29 12:08 UTC (permalink / raw)
  To: tomas, help-gnu-emacs

Tomas,

On Tuesday, 2022-11-29 09:44:48 +0100, you wrote:

> ...
> There are big precedents out there (cf. for example Donald Knuth's
> WEB for TeX and METAFONT; it seems to have been in the air for
> some time -- vestiges of that can be found in the shells (if -- fi,
> case -- esac and so on; pity Lisp must have been a tad early;
> otherwise we might have car -- rac, definitely a better sound than
> cdr).

While this would be feasible  for these two functions,  it wouldn't work
for "caddr" and ilk :-)

I faintly remember  discussions back in  the early seventies  to replace
"car" and "cdr"  (which originally stood for "Contents of Address Regis-
ter" and "Contents of Decrement Register", respectively, and referred to
machine instructions on some then modern PDP hardware which were used to
access the two pointers of a cons) with "fst" and "rst" (for "first" and
"rest", respectively) which could even be nicely combined to "frrst" and
similar.  But this proposal never made it :-(

Sincerely,
  Rainer



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

* Of cars and mice [was: Easy to add with push but not to the end of a list]
  2022-11-29 12:08             ` Dr Rainer Woitok
@ 2022-11-29 19:54               ` tomas
  2022-11-30  1:17                 ` Emanuel Berg
  2022-11-30  1:13               ` Easy to add with push but not to the end of a list Emanuel Berg
  1 sibling, 1 reply; 60+ messages in thread
From: tomas @ 2022-11-29 19:54 UTC (permalink / raw)
  To: Dr Rainer Woitok; +Cc: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 1328 bytes --]

On Tue, Nov 29, 2022 at 01:08:00PM +0100, Dr Rainer Woitok wrote:
> Tomas,
> 
> On Tuesday, 2022-11-29 09:44:48 +0100, you wrote:
> 
> > ...
> > There are big precedents out there (cf. for example Donald Knuth's
> > WEB for TeX and METAFONT; it seems to have been in the air for
> > some time -- vestiges of that can be found in the shells (if -- fi,
> > case -- esac and so on; pity Lisp must have been a tad early;
> > otherwise we might have car -- rac, definitely a better sound than
> > cdr).
> 
> While this would be feasible  for these two functions,  it wouldn't work
> for "caddr" and ilk :-)

But, but... imagine car-rac-rac-rac (yes, with hyphens!). The sound!

> I faintly remember  discussions back in  the early seventies  to replace
> "car" and "cdr"  (which originally stood for "Contents of Address Regis-
> ter" and "Contents of Decrement Register", respectively, and referred to
> machine instructions on some then modern PDP hardware which were used to
> access the two pointers of a cons)

IBM 704, but we disgress badly.

>                                with "fst" and "rst" (for "first" and
> "rest", respectively) which could even be nicely combined to "frrst" and
> similar.  But this proposal never made it :-(

Pity.

Now where are the mice?

;-)

Cheers
-- 
t

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

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

* Re: Easy to add with push but not to the end of a list
  2022-11-29 12:08             ` Dr Rainer Woitok
  2022-11-29 19:54               ` Of cars and mice [was: Easy to add with push but not to the end of a list] tomas
@ 2022-11-30  1:13               ` Emanuel Berg
  1 sibling, 0 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-30  1:13 UTC (permalink / raw)
  To: help-gnu-emacs

Dr Rainer Woitok wrote:

> I faintly remember discussions back in the early seventies
> to replace "car" and "cdr" (which originally stood for
> "Contents of Address Register" and "Contents of Decrement
> Register", respectively

Cool B)

> and referred to machine instructions on some then modern PDP
> hardware which were used to access the two pointers of
> a cons) with "fst" and "rst" (for "first" and "rest",
> respectively) which could even be nicely combined to "frrst"
> and similar. But this proposal never made it :-(

Was that bad? I think `car' is more open and relaxed
than "fst" ...

PDP BTW,

  PDP 1957 Programmed (-able) Data Processor, Digital Equipment minis

so as old as Fortran (1957) and older than Lisp (1958).

https://dataswamp.org/~incal/COMP-HIST

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Of cars and mice [was: Easy to add with push but not to the end of a list]
  2022-11-29 19:54               ` Of cars and mice [was: Easy to add with push but not to the end of a list] tomas
@ 2022-11-30  1:17                 ` Emanuel Berg
  0 siblings, 0 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-30  1:17 UTC (permalink / raw)
  To: help-gnu-emacs

tomas wrote:

>> While this would be feasible for these two functions, it
>> wouldn't work for "caddr" and ilk :-)
>
> But, but... imagine car-rac-rac-rac (yes, with hyphens!).
> The sound!

What does that mean?

>> I faintly remember discussions back in the early seventies
>> to replace "car" and "cdr" (which originally stood for
>> "Contents of Address Regis- ter" and "Contents of Decrement
>> Register", respectively, and referred to machine
>> instructions on some then modern PDP hardware which were
>> used to access the two pointers of a cons)
>
> IBM 704, but we disgress badly.

IBM 704 1954 first mass-produced computer for floating-point arithmetic

> Pity. Now where are the mice? ;-)

???

https://dataswamp.org/~incal/COMP-HIST

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-28 22:58         ` Emanuel Berg
@ 2022-11-30 14:10           ` tomas
  2022-11-30 16:12             ` Emanuel Berg
  0 siblings, 1 reply; 60+ messages in thread
From: tomas @ 2022-11-30 14:10 UTC (permalink / raw)
  To: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 660 bytes --]

On Mon, Nov 28, 2022 at 11:58:27PM +0100, Emanuel Berg wrote:
> Stefan Monnier via Users list for the GNU Emacs text editor wrote:
> 
> > Add them in the reverse order and finish with a simple
> > `reverse`. That's a very standard design pattern with
> > singly-linked lists (and in many/most cases the final
> > `reverse` can be an `nreverse`).
> 
> I thought about `nreverse' but if that changes all the CDRs
> then that's linear as well i.e. O(n), otherwise you could do
> nreverse, `push', and nreverse again ...

The pattern is push, push, push, push... nreverse.

Amortized costs, it's called. It makes O(n^2) into O(n).

Cheers
-- 
t

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

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

* Re: Easy to add with push but not to the end of a list
  2022-11-30 14:10           ` tomas
@ 2022-11-30 16:12             ` Emanuel Berg
  0 siblings, 0 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-11-30 16:12 UTC (permalink / raw)
  To: help-gnu-emacs

tomas wrote:

>>> Add them in the reverse order and finish with a simple
>>> `reverse`. That's a very standard design pattern with
>>> singly-linked lists (and in many/most cases the final
>>> `reverse` can be an `nreverse`).
>> 
>> I thought about `nreverse' but if that changes all the CDRs
>> then that's linear as well i.e. O(n), otherwise you could
>> do nreverse, `push', and nreverse again ...
>
> The pattern is push, push, push, push... nreverse.

And the `push' after that?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-28  2:26 Easy to add with push but not to the end of a list Heime
                   ` (2 preceding siblings ...)
  2022-11-28 19:59 ` Emanuel Berg
@ 2022-11-30 17:10 ` Michael Heerdegen
  2022-11-30 18:17   ` [External] : " Drew Adams
  2022-11-30 19:30   ` Emanuel Berg
  3 siblings, 2 replies; 60+ messages in thread
From: Michael Heerdegen @ 2022-11-30 17:10 UTC (permalink / raw)
  To: Heime; +Cc: Heime via Users list for the GNU Emacs text editor

Heime <heimeborgia@protonmail.com> writes:

> Although it is easy to add to a list using push, it currently looks
> hideous to be able to add to the end of a list.

In addition to what has already been said: if you store and update the
last cdr of your list (in a variable for example), you can add something
to the end of the list in O(1).  The cost is the cost of maintaining
additional data.

Michael.



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

* RE: [External] : Re: Easy to add with push but not to the end of a list
  2022-11-30 17:10 ` Michael Heerdegen
@ 2022-11-30 18:17   ` Drew Adams
  2022-11-30 19:30   ` Emanuel Berg
  1 sibling, 0 replies; 60+ messages in thread
From: Drew Adams @ 2022-11-30 18:17 UTC (permalink / raw)
  To: Michael Heerdegen, Heime
  Cc: Heime via Users list for the GNU Emacs text editor

> In addition to what has already been said: if you store and update the
> last cdr of your list (in a variable for example), you can add something
> to the end of the list in O(1).  The cost is the cost of maintaining
> additional data.

Yes, I mentioned that too:

  (Or else you have to have saved a reference to
  that last cons or its cdr.  In that case you
  can get there directly.)



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

* Re: Easy to add with push but not to the end of a list
  2022-11-30 17:10 ` Michael Heerdegen
  2022-11-30 18:17   ` [External] : " Drew Adams
@ 2022-11-30 19:30   ` Emanuel Berg
  2022-12-01 15:11     ` Michael Heerdegen
  1 sibling, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2022-11-30 19:30 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

>> Although it is easy to add to a list using push, it
>> currently looks hideous to be able to add to the end of
>> a list.
>
> In addition to what has already been said: if you store and
> update the last cdr of your list (in a variable for
> example), you can add something to the end of the list in
> O(1). The cost is the cost of maintaining additional data.

You can write a function that does all of that automatically
for you but then you are restricted to using such tailor-made
functions. If you couple those functions with the data they
are to manipulate you have already a small OO system with
methods and members ...

So use `push' and provide a "push-last" and say in the
docstring it's not as fast is better ...

;;; -*- lexical-binding: t -*-
;;
;; this file:
;;   https://dataswamp.org/~incal/emacs-init/list.el

(defmacro push-last (elem lst)
  "Push ELEM to be the last element of LST.
Beware that this is O(n) while `push' is O(1)."
  (if (and (symbolp lst)
           (not (symbol-value lst)) )
      (list 'setq lst `(list ,elem))
    (list 'nconc lst `(list ,elem)) ))

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-11-30 19:30   ` Emanuel Berg
@ 2022-12-01 15:11     ` Michael Heerdegen
  2022-12-01 17:25       ` Emanuel Berg
  0 siblings, 1 reply; 60+ messages in thread
From: Michael Heerdegen @ 2022-12-01 15:11 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

> (defmacro push-last (elem lst)
>   "Push ELEM to be the last element of LST.
> Beware that this is O(n) while `push' is O(1)."
>   (if (and (symbolp lst)
>            (not (symbol-value lst)) )
>       (list 'setq lst `(list ,elem))
>     (list 'nconc lst `(list ,elem)) ))

Do you really want to test the `symbol-value' at compile (macro
expansion) time?

Michael.




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

* Re: Easy to add with push but not to the end of a list
  2022-12-01 15:11     ` Michael Heerdegen
@ 2022-12-01 17:25       ` Emanuel Berg
  2022-12-03 21:29         ` Michael Heerdegen
  0 siblings, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2022-12-01 17:25 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

> Emanuel Berg <incal@dataswamp.org> writes:
>
>> (defmacro push-last (elem lst)
>>   "Push ELEM to be the last element of LST.
>> Beware that this is O(n) while `push' is O(1)."
>>   (if (and (symbolp lst)
>>            (not (symbol-value lst)) )
>>       (list 'setq lst `(list ,elem))
>>     (list 'nconc lst `(list ,elem)) ))
>
> Do you really want to test the `symbol-value' at compile (macro
> expansion) time?

I don't know, why not?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-12-01 17:25       ` Emanuel Berg
@ 2022-12-03 21:29         ` Michael Heerdegen
  2022-12-05 23:35           ` Emanuel Berg
  0 siblings, 1 reply; 60+ messages in thread
From: Michael Heerdegen @ 2022-12-03 21:29 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

> > Do you really want to test the `symbol-value' at compile (macro
> > expansion) time?
>
> I don't know, why not?

Isn't that obvious?  Because the value at run-time might be different.
Or the symbol is not bound at all at compile time.

Michael.



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

* Re: Easy to add with push but not to the end of a list
  2022-12-03 21:29         ` Michael Heerdegen
@ 2022-12-05 23:35           ` Emanuel Berg
  2022-12-06  1:36             ` Michael Heerdegen
  0 siblings, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2022-12-05 23:35 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

>>> Do you really want to test the `symbol-value' at compile
>>> (macro expansion) time?
>>
>> I don't know, why not?
>
> Isn't that obvious? Because the value at run-time might be
> different. Or the symbol is not bound at all at
> compile time.

Okay, but how should it be then?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-12-05 23:35           ` Emanuel Berg
@ 2022-12-06  1:36             ` Michael Heerdegen
  2022-12-06  1:43               ` Emanuel Berg
  0 siblings, 1 reply; 60+ messages in thread
From: Michael Heerdegen @ 2022-12-06  1:36 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

> Okay, but how should it be then?

The expansion of calls of your macro should include the test.  Now it is
done when computing the expansion.

Use `macroexpand' and/or `macroexpand-1' to check the expansion of macro
calls.  The rest is just...normal Elisp.  You know how to write Elisp,
so write it so that the expansion you want is generated.  It's code
returning code.  So what's the code you want to produce?

Michael.




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

* Re: Easy to add with push but not to the end of a list
  2022-12-06  1:36             ` Michael Heerdegen
@ 2022-12-06  1:43               ` Emanuel Berg
  2022-12-06  2:17                 ` Michael Heerdegen
  0 siblings, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2022-12-06  1:43 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

> Use `macroexpand' and/or `macroexpand-1' to check the
> expansion of macro calls. The rest is just...normal Elisp.
> You know how to write Elisp, so write it so that the
> expansion you want is generated. It's code returning code.
> So what's the code you want to produce?

I don't know, because this can't be done with Elisp, not any
Elisp I know anyway, since the variable name will then be
evaluated ...

Here is the `push' macro - TBH, I don't know what most of that
means ...

(defmacro push (newelt place)
  "Add NEWELT to the list stored in the generalized variable PLACE.
This is morally equivalent to (setf PLACE (cons NEWELT PLACE)),
except that PLACE is evaluated only once (after NEWELT)."
  (declare (debug (form gv-place)))
  (if (symbolp place)
      ;; Important special case, to avoid triggering GV too early in
      ;; the bootstrap.
      (list 'setq place
            (list 'cons newelt place))
    (require 'macroexp)
    (macroexp-let2 macroexp-copyable-p x newelt
      (gv-letplace (getter setter) place
        (funcall setter `(cons ,x ,getter))))))

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-12-06  1:43               ` Emanuel Berg
@ 2022-12-06  2:17                 ` Michael Heerdegen
  2022-12-06  2:40                   ` Emanuel Berg
  2022-12-06  2:52                   ` Emanuel Berg
  0 siblings, 2 replies; 60+ messages in thread
From: Michael Heerdegen @ 2022-12-06  2:17 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

> I don't know, because this can't be done with Elisp, not any
> Elisp I know anyway, since the variable name will then be
> evaluated ...

I don't understand that last sentence.  We want to look at the
variable's value (at run time), no?

What happens if you compile a file with these contents for example?

#+begin_src emacs-lisp
(defun test ()
  (let ((l (list 1 2)))
    (push-last 2 l)
    l))
#+end_src

> Here is the `push' macro - TBH, I don't know what most of that
> means ...

That supports generalized variables; you don't need to do that (unless
you want to).

Michael.




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

* Re: Easy to add with push but not to the end of a list
  2022-12-06  2:17                 ` Michael Heerdegen
@ 2022-12-06  2:40                   ` Emanuel Berg
  2022-12-06 13:56                     ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-12-06 14:45                     ` Michael Heerdegen
  2022-12-06  2:52                   ` Emanuel Berg
  1 sibling, 2 replies; 60+ messages in thread
From: Emanuel Berg @ 2022-12-06  2:40 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

> What happens if you compile a file with these contents
> for example?
>
> (defun test ()
>   (let ((l (list 1 2)))
>     (push-last 2 l)
>     l))

Okay, this then?

;;; -*- lexical-binding: t -*-
;;
;; this file:
;;   https://dataswamp.org/~incal/emacs-init/list.el

(defmacro push-last (elem lst)
  "Push ELEM to be the last element of LST.
Beware that this is O(n) while `push' is O(1)."
  `(if (and (symbolp ,lst)
            (not (symbol-value ,lst)) )
       (setq ,lst (list ,elem))
     (nconc ,lst (list ,elem)) ))

>> Here is the `push' macro - TBH, I don't know what most of
>> that means ...
>
> That supports generalized variables; you don't need to do
> that (unless you want to).

Just wonder why mine looks so different ...

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-12-06  2:17                 ` Michael Heerdegen
  2022-12-06  2:40                   ` Emanuel Berg
@ 2022-12-06  2:52                   ` Emanuel Berg
  2022-12-06 17:22                     ` Michael Heerdegen
  1 sibling, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2022-12-06  2:52 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

>> Here is the `push' macro - TBH, I don't know what most of
>> that means ...
>
> That supports generalized variables; you don't need to do
> that (unless you want to).

Are the macros here correct then?

;;; -*- lexical-binding: t -*-
;;
;; this file:
;;   https://dataswamp.org/~incal/emacs-init/file-write-to.el

(require 'subr-x)

;; write

(defun write-to-file (file data)
  (setq data (format "%s" data))
  (write-region data nil file) )

;; read

(defun file-to-string (file)
  "A string with the contents of FILE."
  (interactive "Ffile: ")
  (with-temp-buffer
    (insert-file-contents file)
    (string-trim
      (buffer-substring-no-properties (point-min) (point-max)) )))

(defun file-to-integer (file)
  (string-to-number (file-to-string file)) )

(defmacro file-to-variable (file var)
  `(setq ,var ,(file-to-string file)) )

(defmacro file-to-variable-integer (file var)
  `(setq ,var ,(string-to-number (file-to-string file))) )

;; (write-to-file "~/5ifth.txt" "Leeloo Dallas Multipass")
;;
;; (file-to-string   "~/5ifth.txt")                         ; Leeloo ...
;; (file-to-variable "~/5ifth.txt" string-value)            ; Leeloo ...
;; string-value                                             ; Leeloo ...
;; (file-to-variable-integer "~/element.txt" integer-value) ; 5
;; integer-value                                            ; 5

(provide 'file-write-to)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-12-06  2:40                   ` Emanuel Berg
@ 2022-12-06 13:56                     ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-12-06 14:45                     ` Michael Heerdegen
  1 sibling, 0 replies; 60+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-06 13:56 UTC (permalink / raw)
  To: help-gnu-emacs

>> That supports generalized variables; you don't need to do
>> that (unless you want to).
>
> Just wonder why mine looks so different ...

Because when you want to do:

    (push V (aref A (cl-incf I)))

the naive expansion gives:

    (setf (aref A (cl-incf I))
          (cons V (aref A (cl-incf I))))

which will increment I twice :-(
So the expansion need to look like:

    (let ((tmp (cl-incf I)))
      (setf (aref A tmp)
            (cons V (aref A tmp))))

And of course, the same holds if A is not just a variable reference but
say a call to function that's costly or that is not pure.
Furthermore, the above performs the `cl-incf` before computing V, so if
V is an expression that uses I it changes the expected result compared
to the usual left-to-right evaluation order provided by ELisp.
So in the end you need something like:

    (let ((tmp1 V)
          (tmp2 A)
          (tmp3 (cl-incf I)))
      (setf (aref tmp2 tmp3)
            (cons tmp1 (aref tmp2 tmp3))))


-- Stefan




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

* Re: Easy to add with push but not to the end of a list
  2022-12-06  2:40                   ` Emanuel Berg
  2022-12-06 13:56                     ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-12-06 14:45                     ` Michael Heerdegen
  1 sibling, 0 replies; 60+ messages in thread
From: Michael Heerdegen @ 2022-12-06 14:45 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

> Okay, this then?
>
> ;;; -*- lexical-binding: t -*-
> ;;
> ;; this file:
> ;;   https://dataswamp.org/~incal/emacs-init/list.el
>
> (defmacro push-last (elem lst)
>   "Push ELEM to be the last element of LST.
> Beware that this is O(n) while `push' is O(1)."
>   `(if (and (symbolp ,lst)
>             (not (symbol-value ,lst)) )
>        (setq ,lst (list ,elem))
>      (nconc ,lst (list ,elem)) ))

Better - this fixes one problem.

Ok, now Stefan has told the whole story I wanted you to find out
yourself.

Anyway, my next question would have been what kinds of expressions LST
you want to support.


Michael.




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

* Re: Easy to add with push but not to the end of a list
  2022-12-06  2:52                   ` Emanuel Berg
@ 2022-12-06 17:22                     ` Michael Heerdegen
  2022-12-06 22:30                       ` Emanuel Berg
  0 siblings, 1 reply; 60+ messages in thread
From: Michael Heerdegen @ 2022-12-06 17:22 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

> Are the macros here correct then?

Depends on what you want.

> (defmacro file-to-variable (file var)
>   `(setq ,var ,(file-to-string file)) )
>
> (defmacro file-to-variable-integer (file var)
>   `(setq ,var ,(string-to-number (file-to-string file))) )

Calls of these macros will cause those FILEs to be looked up at macro
expansion/ compile time, and the file contents will be become a part of
the .elc.  I guess this is not what you want.

A second (related) problem is that FILE must be a string - a function
call like (expand-file-name "my-file" "/some/path") will not behave as
expected, because your helper functions don't expect an expression.

But `macroexpand' will tell you all of that.  I suggest to take the time
to think thoroughly about it.  Don't try to solve this by guessing or
trial and error.

Michael.




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

* Re: Easy to add with push but not to the end of a list
  2022-12-06 17:22                     ` Michael Heerdegen
@ 2022-12-06 22:30                       ` Emanuel Berg
  2022-12-08 23:15                         ` Michael Heerdegen
  0 siblings, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2022-12-06 22:30 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

>> Are the macros here correct then?
>
> Depends on what you want.
>
>> (defmacro file-to-variable (file var)
>>   `(setq ,var ,(file-to-string file)) )
>>
>> (defmacro file-to-variable-integer (file var)
>>   `(setq ,var ,(string-to-number (file-to-string file))) )
>
> Calls of these macros will cause those FILEs to be looked up at macro
> expansion/ compile time, and the file contents will be become a part of
> the .elc.  I guess this is not what you want.

It's supposed to be used for reading FILE into VAR.

In practice I didn't use them since these were better
suited ...

(defun file-to-string (file)
  "A string with the contents of FILE."
  (interactive "Ffile: ")
  (with-temp-buffer
    (insert-file-contents file)
    (string-trim
      (buffer-substring-no-properties (point-min) (point-max)) )))

(defun file-to-integer (file)
  (string-to-number (file-to-string file)) )

> A second (related) problem is that FILE must be a string -
> a function call like (expand-file-name "my-file"
> "/some/path") will not behave as expected, because your
> helper functions don't expect an expression.

Okay, but how do you check if it's an expression?

Also take a look at this, one should have a cache function and
a function to store arbitrary data and datastructures and the
corresponding to load seam-/losslessly into the same Lisp
datastructures all tho these are not the same/unaware of the ones
that was used (refered to) when saving ...

;;; -*- lexical-binding: t -*-
;;
;; this file:
;;   https://dataswamp.org/~incal/emacs-init/cache.el

(let ((cache-file (format "%svar/data-cache.el" user-emacs-directory)))
  (defun save-char-table ()
    (with-temp-buffer
      (insert "(setq standard-display-table\n\n")
      (prin1 standard-display-table (current-buffer))
      (insert "\n\n)")
      (write-file cache-file) ))
  (declare-function save-char-table nil)

  (defun load-char-table ()
    (when (file-exists-p cache-file)
      (load-file cache-file) ))
  (declare-function load-char-table nil) )

(defun set-replacement-char-table ()
  (unless (load-char-table)
    (let ((tbl standard-display-table)) ;; WARNING, ugly code ahead!
      (set-char-table-range tbl '(#x102 . #x103)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x108 . #x10b)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x10e . #x111)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x114 . #x115)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x11a . #x121)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x124 . #x129)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x12c . #x12d)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x130 . #x135)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x138 . #x13a)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x13d . #x140)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x147 . #x14b)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x14e . #x155)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x158 . #x159)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x15c . #x15f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x162 . #x169)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x16c . #x171)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x174 . #x178)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x17f . #x2c6)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2c8 . #x2c8)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2ca . #x2d8)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2da . #x2da)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2dc . #x390)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x393 . #x394)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x398 . #x398)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x39b . #x39b)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x39e . #x39e)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x3a0 . #x3a0)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x3a2 . #x3a3)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x3a5 . #x3a6)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x3a8 . #x3bb)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x3bd . #x3bf)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x3c1 . #x400)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x402 . #x404)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x407 . #x407)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x409 . #x40f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x411 . #x411)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x413 . #x414)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x416 . #x419)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x41b . #x41b)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x41f . #x41f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x423 . #x424)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x426 . #x42f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x431 . #x434)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x436 . #x43d)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x43f . #x43f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x442 . #x442)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x444 . #x444)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x446 . #x450)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x452 . #x454)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x457 . #x457)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x459 . #x4ad)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x4af . #x1fff)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x200b . #x200f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2016 . #x2017)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x201b . #x201b)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x201f . #x201f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2023 . #x2025)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2027 . #x202e)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2031 . #x2038)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x203b . #x20ab)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x20ad . #x2115)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2117 . #x2121)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2123 . #x2129)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x212c . #x218f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2194 . #x2211)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2213 . #x2247)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2249 . #x225f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2261 . #x2263)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2266 . #x2269)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x226c . #x2294)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2297 . #x2297)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x229a . #x229a)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x229d . #x245f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2469 . #x24b5)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x24eb . #x24ff)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2580 . #x2587)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2589 . #x2590)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2593 . #x259f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25a1 . #x25ad)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25af . #x25b1)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25b3 . #x25b3)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25b5 . #x25b5)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25b7 . #x25b7)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25b9 . #x25bb)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25bd . #x25bd)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25bf . #x25bf)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25c1 . #x25c1)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25c3 . #x25c7)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25c9 . #x25ce)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x25d0 . #x260f)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2613 . #x2665)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2667 . #x2716)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2719 . #x2bbc)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#x2bbe . #xfffc)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))
      (set-char-table-range tbl '(#xfffe . #x10ffff)
                            (vconcat (list (make-glyph-code #xfffd 'homoglyph))))

      (save-char-table) )))

(set-replacement-char-table)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-12-06 22:30                       ` Emanuel Berg
@ 2022-12-08 23:15                         ` Michael Heerdegen
  2022-12-28 23:52                           ` Emanuel Berg
  0 siblings, 1 reply; 60+ messages in thread
From: Michael Heerdegen @ 2022-12-08 23:15 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:


> In practice I didn't use them since these were better
> suited ...
>
> (defun file-to-string (file)
>   "A string with the contents of FILE."
>   (interactive "Ffile: ")
>   (with-temp-buffer
>     (insert-file-contents file)
>     (string-trim
>       (buffer-substring-no-properties (point-min) (point-max)) )))
>
> (defun file-to-integer (file)
>   (string-to-number (file-to-string file)) )

Yes, I wondered why you preferred a macro there at all.

> > A second (related) problem is that FILE must be a string -
> > a function call like (expand-file-name "my-file"
> > "/some/path") will not behave as expected, because your
> > helper functions don't expect an expression.
>
> Okay, but how do you check if it's an expression?

That macro argument should better be evaluated (since not only strings
make sense there), so it's _always_ an expression, even when it's a
string (that happens to be a self-evaluating expression in this
context).

And you don't want to evaluate it at expansion time.  That was your
mistake several times.  What's code normally goes into the expansion,
maybe in the original or in a transformed form.  Or it's dismissed.  The
macro is there to transform code, not to evaluate it, not even
partially.  Unless it's code actually needed to produce the expansion.
These cases are rare.  Be careful not to mix them up.

> Also take a look at this, one should have a cache function and
> a function to store arbitrary data and datastructures and the
> corresponding to load seam-/losslessly into the same Lisp
> datastructures all tho these are not the same/unaware of the ones
> that was used (refered to) when saving ...

What in particular is your question?

You don't need to reinvent `eieio-persistent' btw because it already
exists!  It allows to save and restore more or less arbitrary objects
and data; the implementation already supports a lot of different types.


Michael.



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

* Re: Easy to add with push but not to the end of a list
  2022-12-08 23:15                         ` Michael Heerdegen
@ 2022-12-28 23:52                           ` Emanuel Berg
  2022-12-31 16:57                             ` Michael Heerdegen
  0 siblings, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2022-12-28 23:52 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

> What in particular is your question?

How do you do a `pushlast' macro?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-12-28 23:52                           ` Emanuel Berg
@ 2022-12-31 16:57                             ` Michael Heerdegen
  2022-12-31 22:09                               ` Emanuel Berg
  0 siblings, 1 reply; 60+ messages in thread
From: Michael Heerdegen @ 2022-12-31 16:57 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

> How do you do a `pushlast' macro?

I would start with `push' and change the definition so that the
expansion uses an according `append' call.

Michael.



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

* Re: Easy to add with push but not to the end of a list
  2022-12-31 16:57                             ` Michael Heerdegen
@ 2022-12-31 22:09                               ` Emanuel Berg
  2023-01-01 12:16                                 ` Michael Heerdegen
  0 siblings, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2022-12-31 22:09 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

>> How do you do a `pushlast' macro?
>
> I would start with `push' and change the definition so that
> the expansion uses an according `append' call.

Like this?

A lot of unfamiliar stuff it that code ...

;;; -*- lexical-binding: t -*-
;;
;; this file:
;;   https://dataswamp.org/~incal/emacs-init/list.el

(defmacro pushlast (newelt place)
  (declare (debug (form gv-place)))
  (if (symbolp place)
      (list 'setq place
            (list 'append place (list 'cons newelt nil)) )
    (macroexp-let2 macroexp-copyable-p x newelt
      (gv-letplace (getter setter) place
        (funcall setter `(append ,getter (cons ,x nil))) ))))

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2022-12-31 22:09                               ` Emanuel Berg
@ 2023-01-01 12:16                                 ` Michael Heerdegen
  2023-01-08  4:40                                   ` Emanuel Berg
  0 siblings, 1 reply; 60+ messages in thread
From: Michael Heerdegen @ 2023-01-01 12:16 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

> (defmacro pushlast (newelt place)
>   (declare (debug (form gv-place)))
>   (if (symbolp place)
>       (list 'setq place
>             (list 'append place (list 'cons newelt nil)) )
>     (macroexp-let2 macroexp-copyable-p x newelt
>       (gv-letplace (getter setter) place
>         (funcall setter `(append ,getter (cons ,x nil))) ))))

LGTM.  But you can skip the special treatment of the simple
(symbolp place) case since your macro is not used while bootstrapping.

Michael.





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

* Re: Easy to add with push but not to the end of a list
  2023-01-01 12:16                                 ` Michael Heerdegen
@ 2023-01-08  4:40                                   ` Emanuel Berg
  2023-01-09  6:32                                     ` Emanuel Berg
  0 siblings, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2023-01-08  4:40 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

>> (defmacro pushlast (newelt place)
>>   (declare (debug (form gv-place)))
>>   (if (symbolp place)
>>       (list 'setq place
>>             (list 'append place (list 'cons newelt nil)) )
>>     (macroexp-let2 macroexp-copyable-p x newelt
>>       (gv-letplace (getter setter) place
>>         (funcall setter `(append ,getter (cons ,x nil))) ))))
>
> LGTM.  But you can skip the special treatment of the simple
> (symbolp place) case since your macro is not used
> while bootstrapping.

Let's get that money!

;;; -*- lexical-binding: t -*-
;;
;; this file:
;;   https://dataswamp.org/~incal/emacs-init/list.el

(defmacro pushlast (newelt place)
  (declare (debug (form gv-place)))
  (macroexp-let2 macroexp-copyable-p x newelt
    (gv-letplace (getter setter) place
      (funcall setter `(append ,getter (cons ,x nil))) )))

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2023-01-08  4:40                                   ` Emanuel Berg
@ 2023-01-09  6:32                                     ` Emanuel Berg
  2023-01-14 12:05                                       ` Michael Heerdegen
  0 siblings, 1 reply; 60+ messages in thread
From: Emanuel Berg @ 2023-01-09  6:32 UTC (permalink / raw)
  To: help-gnu-emacs

> ;;; -*- lexical-binding: t -*-
> ;;
> ;; this file:
> ;;   https://dataswamp.org/~incal/emacs-init/list.el
>
> (defmacro pushlast (newelt place)
>   (declare (debug (form gv-place)))
>   (macroexp-let2 macroexp-copyable-p x newelt
>     (gv-letplace (getter setter) place
>       (funcall setter `(append ,getter (cons ,x nil))) )))

How much slower than `push' for a list of 2^i items for
i \in W?

  https://dataswamp.org/~incal/data/numbers.txt

But there are some numbers missing from that list ... ?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Easy to add with push but not to the end of a list
  2023-01-09  6:32                                     ` Emanuel Berg
@ 2023-01-14 12:05                                       ` Michael Heerdegen
  0 siblings, 0 replies; 60+ messages in thread
From: Michael Heerdegen @ 2023-01-14 12:05 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

>   https://dataswamp.org/~incal/data/numbers.txt
>
> But there are some numbers missing from that list ... ?

Types of numbers?  There are (but this is not really related to Emacs so
I don't want to dive into this discussion).


Michael.



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

end of thread, other threads:[~2023-01-14 12:05 UTC | newest]

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-28  2:26 Easy to add with push but not to the end of a list Heime
2022-11-28  2:43 ` [External] : " Drew Adams
2022-11-28  3:45   ` Heime
2022-11-28  6:11     ` Drew Adams
2022-11-28 20:00   ` Emanuel Berg
2022-11-28  5:18 ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-11-28 20:19   ` Emanuel Berg
2022-11-28 21:56     ` [External] : " Drew Adams
2022-11-28 22:45       ` Emanuel Berg
2022-11-28 22:01     ` Heime
2022-11-28 22:24       ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-11-28 22:58         ` Emanuel Berg
2022-11-30 14:10           ` tomas
2022-11-30 16:12             ` Emanuel Berg
2022-11-28 22:46       ` Emanuel Berg
2022-11-28 22:50       ` Emanuel Berg
2022-11-29  5:23       ` tomas
2022-11-29  5:32         ` Emanuel Berg
2022-11-29  7:56         ` Heime
2022-11-29  8:33           ` Marcin Borkowski
2022-11-29 10:00             ` Emanuel Berg
2022-11-29 10:05               ` Emanuel Berg
2022-11-29 10:15             ` Heime
2022-11-29  8:38           ` tomas
2022-11-29  9:54           ` Emanuel Berg
2022-11-29  8:17         ` Marcin Borkowski
2022-11-29  8:44           ` tomas
2022-11-29 12:08             ` Dr Rainer Woitok
2022-11-29 19:54               ` Of cars and mice [was: Easy to add with push but not to the end of a list] tomas
2022-11-30  1:17                 ` Emanuel Berg
2022-11-30  1:13               ` Easy to add with push but not to the end of a list Emanuel Berg
2022-11-28 19:59 ` Emanuel Berg
2022-11-28 21:56   ` [External] : " Drew Adams
2022-11-28 22:18     ` Heime
2022-11-28 22:41       ` Drew Adams
2022-11-29 11:17   ` Dr Rainer Woitok
2022-11-30 17:10 ` Michael Heerdegen
2022-11-30 18:17   ` [External] : " Drew Adams
2022-11-30 19:30   ` Emanuel Berg
2022-12-01 15:11     ` Michael Heerdegen
2022-12-01 17:25       ` Emanuel Berg
2022-12-03 21:29         ` Michael Heerdegen
2022-12-05 23:35           ` Emanuel Berg
2022-12-06  1:36             ` Michael Heerdegen
2022-12-06  1:43               ` Emanuel Berg
2022-12-06  2:17                 ` Michael Heerdegen
2022-12-06  2:40                   ` Emanuel Berg
2022-12-06 13:56                     ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-12-06 14:45                     ` Michael Heerdegen
2022-12-06  2:52                   ` Emanuel Berg
2022-12-06 17:22                     ` Michael Heerdegen
2022-12-06 22:30                       ` Emanuel Berg
2022-12-08 23:15                         ` Michael Heerdegen
2022-12-28 23:52                           ` Emanuel Berg
2022-12-31 16:57                             ` Michael Heerdegen
2022-12-31 22:09                               ` Emanuel Berg
2023-01-01 12:16                                 ` Michael Heerdegen
2023-01-08  4:40                                   ` Emanuel Berg
2023-01-09  6:32                                     ` Emanuel Berg
2023-01-14 12:05                                       ` Michael Heerdegen

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).