Why LINKED_LIST, an ITERATOR can't use do_while?

46 views
Skip to first unread message

Brother Bill

unread,
Jun 30, 2024, 3:14:02 PMJun 30
to Eiffel Users
local
    a_list: LINKED_LIST [STRING]
do
    create a_list.make
    a_list.extend ("The Moon is Full")
    a_list.do_while (...)

Compile: Unknown identifier `do_while'
1. LINKED_LIST has an ancestor ITERABLE
2. ITERABLE has ANY export of do_while

Shouldn't a_list have access to do_while?

What am I missing?

Bertrand Meyer

unread,
Jun 30, 2024, 4:22:54 PMJun 30
to eiffel...@googlegroups.com, me...@inf.ethz.ch

ITERABLE does not have do_while. ITERATOR does.

 

You can set a LINEAR_ITERATOR  to have a_list as its target and then iterate on it as you like using the iterator.

 

You can also do the equivalent without any specific objects by using an across… loop.

 

-- BM

--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/eiffel-users/a168c672-d47a-4f7f-b4e8-a74f496c4cfdn%40googlegroups.com.

Brother Bill

unread,
Jul 1, 2024, 8:24:55 AMJul 1
to Eiffel Users
Bertrand, 
local
    a_list: LINKED_LIST [STRING]
    b_list: LINEAR_ITERATOR [STRING]
do
   b_list := a_list
Error:  VJAR: Source of assignment is not compatible with target.

ITERATOR [STRING] is not an ancestor of LINKED_LIST [STRING] 
ITERATOR [G] is not among the ancestors of LINKED_LIST [STRING], only ITERABLE [G]

Exactly how can one set a LINEAR_ITERATOR b_list to have a_list as its target and then iterate on it as you like using the iterator?

Ancestors of class LINKED_LIST
-------------------------------------------------------------------------------------------------------------
LINKED_LIST [G]
DYNAMIC_LIST [G]
LIST [G]
CHAIN [G]
SEQUENCE [G]
FINITE [G]
BOX [G]
CONTAINER [G]
ITERABLE [G]
ANY
BILINEAR [G]
LINEAR [G]
TRAVERSABLE [G]
CONTAINER [G]...
ACTIVE [G]
BAG [G]
COLLECTION [G]
CONTAINER [G]...
INDEXABLE [G, H -> INTEGER_32]
TABLE [G, H]
BAG [G]...
READABLE_INDEXABLE [G]
ITERABLE [G]...
CURSOR_STRUCTURE [G]
ACTIVE [G]...
DYNAMIC_CHAIN [G]
UNBOUNDED [G]
FINITE [G]...
DYNAMIC_TABLE [G, H]
TABLE [G, H]...
CHAIN [G]...


rfo amalasoft.com

unread,
Jul 1, 2024, 9:10:45 AMJul 1
to eiffel...@googlegroups.com
An iterator can iterate across and iterable.  they're not the same thing.  it's client-supplier, not inheritance
R

From: eiffel...@googlegroups.com <eiffel...@googlegroups.com> on behalf of Brother Bill <brother...@gmail.com>
Sent: Monday, July 1, 2024 8:24 AM
To: Eiffel Users <eiffel...@googlegroups.com>
Subject: Re: [eiffel-users] Why LINKED_LIST, an ITERATOR can't use do_while?
 

Bertrand Meyer

unread,
Jul 1, 2024, 9:13:56 AMJul 1
to eiffel...@googlegroups.com, me...@inf.ethz.ch

Dear Bill,

 

Again if you simply want to iterate on a list you don’t need any specific library mechanisms (other than the property that list classes inherit from ITERABLE). Just use “across”:

 

                across a_list as l until nc loop whatever end

 

where nc is the negation of the “while” condition.

 

If you want to use a richer set of iterators then you can use the iterator classes. Lists and such are not iterators, so the corresponding classes do not have do_while etc. You can iterate *on* a list by using a distinct “iterator object”, which has the ability to perform all kinds of iteration schemes on any list (not just one). It chooses its victim at any particular stage by setting it to be its “target”, and then it can iterate on it to its heart’s content.

 

In other words `do_while’ is not performed by the list but on the list, *by* another object. (Actually that’s not in other words, it’s in the same words, just pushing the point.)


With best regards,

 

-- Bertrand Meyer  

Brother Bill

unread,
Jul 1, 2024, 10:49:12 AMJul 1
to Eiffel Users
Eiffel does not have 'while' keyword.
This works:

list_traversal_agents_3
    local
        a_list: LINKED_LIST [STRING]
    do
        create a_list.make
        a_list.extend ("The Moon is Full")
        a_list.extend ("Master charge")
        a_list.extend ("Black cat bone")

        across a_list as iter until not iter.item.has ('M') loop
    iter.item.append (" - Albert Collins")
        end

-- for each item in a_list, print_element with no arguments
        a_list.do_all (agent print_element)
    end

Bertrand Meyer

unread,
Jul 1, 2024, 11:05:31 AMJul 1
to eiffel...@googlegroups.com, me...@inf.ethz.ch

Ulrich Windl

unread,
Jul 1, 2024, 11:50:14 AMJul 1
to eiffel...@googlegroups.com
Actually Eiffel has a while loop; it's called "loop" 😉

Ian Joyner

unread,
Jul 1, 2024, 7:44:23 PMJul 1
to Eiffel Users
Across or ‘for each’ is a good form of loop for two reasons. The first is that it logically matches what we often want to do — process each element sequentially in a structure.

The second is physical. We should not think operationally, but across loops should move across the elements with a pointer, incrementing at each step, saving having to compute ‘base address + index’ on every iteration.

That is of course the basis of C’s primitive for loop where the programmer must take responsibility to manage the pointer (and giving the problems of C’s pointer arithmetic).

Burroughs also do this with descriptors and powerful string handling to scan across sequential elements in a single instruction with bounds checking.

Thus the form of across (for each) loop has become important to generate optimal code for any platform while on the surface presenting a logical view of the program where programmers should think.

Ian

Ulrich Windl

unread,
Jul 2, 2024, 7:36:43 AMJul 2
to eiffel...@googlegroups.com
Hi!

I'm not convinced that ‘base address + index’ (and fetching the value at the address) is more expensive than getting the pointer's value via indirect addressing to do another indirect addressing.
Usually I don't care about it, but you claimed the first is more expensive than the latter.

Ulrich

Ian Joyner

unread,
Jul 2, 2024, 8:05:57 AMJul 2
to Eiffel Users
Hello Ulrich.

It is somewhat platform dependent. And as I say the programmer should not be thinking about it or aware of it. C forces the programmer to think about it. It should be abstracted.

However, 'base address + index' is more likely to be slower since on each iteration that must be recomputed as well as increment the index. With pointer manipulation you are working with the already computed address which is incremented. Thus only an increment is required, not an increment + add.

Ian
> --
> You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/eiffel-users/84839210-0c8b-4115-a7c1-6a348953b131%40gmail.com.

Reply all
Reply to author
Forward
0 new messages