Learn to Program using Alice

Lists

Learn the differences between an Alice array and an Alice list, including some of the pros and cons of each.  Learn about the methods and functions belonging to lists and arrays.  Learn about an apparent bug involving list methods and functions along with a workaround for the bug.  Learn how to use the tiles labeled forAllInOrder and forAllTogether with lists.

Published:  April 16, 2007
By Richard G. Baldwin

Alice Programming Notes # 185


Preface

This tutorial lesson is part of a series designed to teach you how to program using the Alice programming environment under the assumption that you have no prior programming knowledge or experience.

Have some fun

Because Alice is an interactive graphics 3D programming environment, it is not only useful for learning how to program, Alice makes learning to program fun.  Therefore, you should be sure to explore the many possibilities for being creative provided by Alice while you are learning to program using these tutorials.  And above all have fun in the process of learning.

General

In the lesson titled "Arrays," I taught you how to create and use arrays in your Alice programs.  In this lesson, I will begin by explaining the differences between an array and a list, including some of the pros and cons of each.

Then I will compare the methods and functions belonging to a list with the methods and functions belonging to an array.

After that I will present and explain a simple program that illustrates most of the methods and functions belonging to a list.  Along the way, I will identify and explain one method and one function that appear to be unusable due to bugs.  I will also present and explain a workaround for those bugs.

Finally, I will present and explain a program that illustrates the use of the following tiles from the bottom of the Alice development screen:

Viewing tip

I recommend that you open another copy of this document in a separate browser window and use the following links to easily find and view the figures and listings while you are reading about them.

Figures

Listings

Supplementary material

Once you have mastered Alice, I recommend that you also study the other lessons in my extensive collection of online programming tutorials.  You will find a consolidated index at www.DickBaldwin.com.

General background information

Lists are very similar to arrays except that they are better and easier to use in many respects.

The bad news about lists as compared to arrays

Let's get the bad news about lists out of the way first.  Generally speaking, in most languages, arrays are more efficient than lists in either or both of two areas:

In other words, in many programming languages (possibly including Alice) if you can do the same job using either a list or an array, the use of an array may require less total memory and the version of the program that uses the array may run faster.

The good news about lists as compared to arrays

That having been said, let's get to the good news about lists.  While lists and arrays both store data organized using an integer numeric index, lists are tremendously more flexible and easier to use than arrays in many applications.

Comparison in a nutshell

Both lists and arrays are data structures that are used to group and to organize data or objects.  In a nutshell, here are some of the differences between arrays and lists in Alice:

There are probably other important differences as well which I simply didn't think about while writing this material.

Methods, functions, and iterators

As mentioned earlier, Alice arrays and Alice lists both organize and store their data using an integer numeric index.  Therefore, that isn't the thing that separates the two.  The big difference between Alice arrays and Alice lists results from major differences in the availability of the following programming structures: 

A lack of good technical information
Unfortunately, just like most technical information regarding Alice, an identification of the available methods and functions that apply to arrays and lists is one of the best-kept secrets in the world.  If this information has been published anywhere other than in commercially available textbooks, I am not aware of the location.  While the Alice software is free, the textbooks are not free.  Therein lies part of my purpose in publishing these free online Alice programming tutorials.  To be really useful, free software deserves to be represented by high-quality free documentation.

What does this mean?

To a certain extent, arrays and lists behave like objects in Alice.  By this, I mean that just like objects, it is possible to call methods and functions on arrays and lists to cause them to either perform specific operations or to return values. (I'll have more to say about iterators later.)

Identifying available methods

One way to identify some of the available methods is to create the data structure (array or list variable) and then drag and drop the variable onto a new line in the edit pane.  This will pop up a menu identifying some, and possibly all of the available methods for that data structure.  For example, if you drop an Object[] array variable on a new line in the edit pane, the menu shown in Figure 1 will appear on the screen.

Figure 1. Methods belonging to an Object[] array variable.

You learned how to use these three methods in the earlier lesson titled "Arrays" (see Resources).

List methods

In contrast, if you drop an Object[] list variable on a new line in the edit pane, the menu shown in Figure 2 will appear on the screen.  (Note that I am using the "Java Style in Color" display preference.)

Figure 2. Methods belonging to an Object[] list variable. 

The first and last menu items in Figure 2 are the same as and have the same meaning as the first and last menu items in Figure 1.  (You learned how to use those methods in the earlier lesson titled "Arrays.")  However, the seven methods in the middle of Figure 2 essentially replace the single method in the middle in Figure 1.  The availability of these methods causes an Alice list to be much more flexible that an Alice array as described in my earlier synopsis of the differences

What about the functions?

One way to identify the available functions is to drag the tile that represents an array or list variable and drop it on a placeholder in an expression in the edit pane.  If the data structure contains any functions whose return type matches the type of the placeholder, a menu should pop up identifying the functions that return a value of that type.  (As I will explain later, this doesn't always seem to work for arrays.)  If there are no functions that return that type, the border surrounding the tile that you are dragging will not turn green, meaning that you are not allowed to drop that tile on that placeholder.

Functions of type Object belonging to an Object[] array variable

For example, if you drop an Object[] array variable's tile on a placeholder of type Object in the edit pane, the menu containing the single item shown in Figure 3 will appear on the screen. 

Figure 3. Functions of type Object belonging to an Object[] array variable.

As the name of the function implies, this function can be used to retrieve an object located at a specific index in the array.  This menu item should be available for an array of any type provided the type of data stored in the array matches the type of the placeholder.

Functions of type Object belonging to an Object[] list variable

In contrast, if you drop an Object[] list variable's tile on a placeholder of type Object in the edit pane, the menu shown in Figure 4 will appear on the screen.

Figure 4. Functions of type Object belonging to an Object[] list variable.

The Alice list provides three more functions in this case than the Alice array with the last item in Figure 4 being the same as the single item in Figure 3.

Functions of type Number belonging to an Object[] list variable

If you drop an Object[] list variable's tile on a placeholder of type Number in the edit pane, the menu shown in Figure 5 will appear on the screen.

Figure 5. Functions of type Number belonging to an Object[] list variable. 

These are very significant functions.  Obviously, the first function will return the size of the list.  The last two can be used to determine if there is an element in the list that matches a particular specification, and if so, to learn where it is located in the list.

What about an array in this regard

In contrast, with my copy of Alice 2.0 running under Windows XP, if you drop an Object[] array variable's tile on a placeholder of type Number in the edit pane, the menu that appears on the screen is identical to Figure 1.  That is not what I would expect, and quite frankly it doesn't make any sense to me.  It is as though I missed the target and dropped the tile on a new line immediately above or immediately below the target placeholder.  However, I was very careful to make certain that I didn't miss the drop target.

I would have expected to see a function that returns the number of elements in the array, as a minimum.

This problem also occurs if I do the same thing with a String[] array variable's tile or with a Boolean[] array variable's tile except that the last line is missing from the menu shown in Figure 1.  (It may also be true for other types as well, with the exception of type Number, but I haven't tested against all possible types.)

Seems to work correctly for Number[] array

On the other hand, if I do the same thing with a Number[] array variable's tile, the menu that appears on the screen is shown in Figure 6.  I would expect the first line in that menu to appear only for the case of an array of type Number[], but I would expect the second line to be there regardless of the type of data stored in the array.

Figure 6. Functions of type Number belonging to a Number[] array variable.

Sometimes you get lucky

I accidentally discovered that I can work around the problem by first constructing the statement to get the length of the array using a dummy array of type Number[] as a placeholder and then replacing the reference to the dummy array by a reference to another array of a different type.  However, that doesn't seem right to me. That requires me to declare a dummy array variable of type Number whether I need it or not.

I don't know if this is a bug in Alice 2.0 or not, but it definitely seems strange that it is possible to determine the size of an array containing data of type Number at runtime and it is not possible to determine the size of arrays containing data of other types without going through a complicated workaround.

The array length

I have a vague recollection of having seen an Alice menu item somewhere that returns the length of an array, (which is Java's name for the size of an array), but I don't remember where it was, and I can't find it now.  As I said earlier, technical details regarding Alice are some of the best-kept secrets in the world.

The Java Iterator interface
For example, Java has an interface type named Iterator.  An object of this type can iterate the data structure object to which it is linked without the programmer needing to know anything about the underlying implementation of the data structure.  However, the programmer does need to know about object-oriented programming using Java.

List iterators

To iterate a data structure simply means to gain sequential access to every element contained in the structure so that you can take some action using each element.  Ideally, this is accomplished without the programmer needing to know anything about the underlying implementation of the data structure.

Iterating an array

In the earlier lesson titled "Arrays," I taught you how to use a for loop to iterate an array.  That procedure doesn't fit the description of an iterator given above, because you must know something about the underlying implementation to be able to write the code.  However, since the underlying implementation of an array is straightforward, the procedure works just fine.  There are no built-in iterators for arrays in Alice.  If you need to iterate an Alice array, you must design and program the iterator code yourself

A list iterator and its first cousin

However, there is a built-in iterator (along with a built-in first cousin to an iterator) for an Alice list.  There are two tiles on the bottom of the Alice development screen with the following names that I haven't previously discussed in this series of tutorial lessons:

These tiles are designed to be used exclusively with lists.  They cannot be used with arrays.  As mentioned above, if you need an array iterator in Alice, you must design and program the iterator code yourself.

The forAllInOrder tile

The forAllInOrder tile can be used to create a list iterator that meets the above description.  The code that is produced by using this tile allows you to access and take the same action on all the elements in the list in a sequential fashion without knowing anything about the underlying implementation of the list.

Concurrent programming
This is an area where Alice really shines.  For example, doing concurrent programming in Java requires a great deal more knowledge about object-oriented programming using Java than is the case using either the forAllTogether tile or the doTogether tile in Alice.

The forAllTogether tile

The forAllTogether tile can be used to create a process that comes close to, but doesn't exactly meet the above description.  The code that is produced by using this tile allows you to access and take the same action on all the elements in the list concurrently (instead of sequentially) without knowing anything about the underlying implementation of the list.  (This tile is similar to the doTogether tile, except that it applies to the contents of a list instead of the contents of a block of code.)

I will provide examples of the use of both of these tiles later in this lesson.

Preview

In this lesson, I will present and explain two relatively simple programs.  The first program named Alice0185a illustrates how to:

The second program named Alice0185b illustrates the use and behavior of the following tiles:

Discussion and sample code

The program named Alice0185a

The source code for this program is shown in Listing 1.  (You can download an executable version of both programs from this lesson by following the link in Resources.) 

The printList method

The purpose of this world -level method is to display the contents of a String[] list that is received as an incoming parameter.

The program begins by declaring an empty local variable of type String.  This variable is used to concatenate the individual elements from the list, separated by a space character, into a single string that makes it easy to print the contents of the list on a single line of output text.

This method calls the size method on the incoming list to get the number of elements in the list.  Then it uses that value as the limiting value in the conditional clause of a for loop.  During each iteration of the loop, the next element is fetched from the list and concatenated onto the string followed by a space to separate one element from the next.  The string continues to grow in length during each iteration of the loop.

When the loop terminates, the contents of the string variable are printed producing one line of output in the print area below the World Running... panel on the Alice screen.

The main method

The main method declares an empty String[] list and then consists of a long series of sequential method and function calls, (including calls to the printList method), which are designed to illustrate the behavior of some of the methods and functions identified in Figure 2, Figure 4, and Figure 5.

The output produced by the program is shown in Figure 7.

Figure 7. Output from the program named Alice0185a.
Start the list with an a.
the value of world.printList.printString is  a 
Add c at the end.
the value of world.printList.printString is  a c 
Insert b at index 1.
the value of world.printList.printString is  a b c 
Add d at the end.
the value of world.printList.printString is  a b c d 
Get and display info about the list.
Size of list = 4
First index of c = 2
Last index of b = 1
the value of world.main.__Unnamed37__.__Unnamed0__
 is First item from list = a
Note: The following is incorrect.
Last item from list = null
Note: Calling removeLast causes runtime error.
Remove at index 2.
the value of world.printList.printString is  a b d 
Remove at index 0.
the value of world.printList.printString is  b d 
Remove at index 1.
the value of world.printList.printString is  b 
Clear the list.
the value of world.printList.printString is  
The End

The code in the main method is straightforward and shouldn't require an explanation.  With two notable exceptions, you should be able to compare the code with the output and understand exactly what is going on.

Is this a bug?

The two exceptions are highlighted in boldface in Figure 7.  The boldface text describes what appears to be a bug in Alice that makes it impossible to call removeLast (see Figure 2) or last item from list (see Figure 4) and get reliable and correct results.  Calling removeLast on a list that is not empty causes the program to abort with a runtime error.  Calling last item from list on a list that is not empty returns null, which is clearly incorrect.  Both symptoms are probably the result of the same underlying bug.

Workarounds for the bug

Fortunately, the size function works correctly, making it possible to get the number of elements in the list and use that information to:

The program named Alice0185b

The purpose of this program is to illustrate the use of the following two tiles from the bottom of the Alice development screen to traverse the contents of a list:

I explained the purpose and behavior of these tiles earlier.

Figure 8 shows a screen shot of this program while it is running.

Figure 8. Screen shot of program named Alice0185b while running.

Description of the program

This program begins by declaring an empty Object[] list with a variable named aList.

Then the program adds the five objects shown in Figure 8 to the list.  After that, the program uses the forAllInOrder tile to cause each of the objects to turn LEFT by 1 revolution in sequential order.  First the penguin turns.  Then the cow turns, followed in order by the hare, the monkey, and the tortoise.  (The hare is about half way through his turn in Figure 8.)

Following that, the program uses the forAllTogether tile to cause all five objects to move FORWARD by 0.5 meters concurrently.  In other words, all of the objects move forward together.

Finally, the penguin says "That's all, Goodbye" and the program terminates.

Run the program

Executable versions of the programs that I explained in this lesson are available for downloading (see Resources).  I encourage you to either download those programs, or copy the code from Listing 1 and Listing 2 into your Alice development environment and run the programs.  Experiment with the code, making changes, and observing the results of your changes.

Summary

I began the lesson by explaining the differences between an Alice array and an Alice list, including some of the pros and cons of each.

Then I compared the methods and functions belonging to a list with the methods and functions belonging to an array.

Then I presented and explained a simple program that illustrates most of the methods and functions belonging to a list.  Along the way, I identified one method and one function that appear to be unusable due to bugs.  I also explained a workaround for those bugs.

Finally, I presented and explained a program that illustrates the use of the following tiles from the bottom of the Alice development screen:

What's next?

In future lessons I will teach you about the following topics and perhaps some other topics as well:

So stay tuned.  There will be lots of fun ahead.

Resources

General resources

Resources from earlier lessons in the series titled "Learn to Program using Alice"

Downloads

Complete program listings

Complete listings of the programs discussed in this lesson are presented in Listing 1 and Listing 2 below.

Listing 1. Source code for the program named Alice0185a.

Alice0185a's Code

Created by: Dick Baldwin

world

Events

When the world starts
Do:
world.main ( );


Methods

  public void main ( ) {
    String[] aList = ; Number num = 0 ;
       // Copyright 2007, R.G.Baldwin
  // Illustrates 7 methods for manipulating list contents.
  // Also illustrates several list functions.
  print( Start the list with an a. );
  aList .add( 0, a ); duration = 0 seconds
  world.printList ( theList = aList );
  print( Add c at the end. );
  aList .add( c ); duration = 0 seconds
  world.printList ( theList = aList );
  print( Insert b at index 1. );
  aList .add( 1 , b ); duration = 0 seconds
  world.printList ( theList = aList );
  print( Add d at the end. );
  aList .add( d ); duration = 0 seconds
  world.printList ( theList = aList );
  print( Get and display info about the list. );
  num .set( value , ( aList .size() ) ); duration = 0 seconds
  print( ( Size of list = + ( num .toString() ) ) );
  num .set( value , ( aList .indexOf( c ) ) );
  print( ( First index of c = + ( num .toString() ) ) );
  num .set( value , ( aList .lastIndexOf( b ) ) );
  print( ( Last index of b = + ( num .toString() ) ) );
  print( ( First item from list = + ( aList [0] ) ) );
  print( Note: The following is incorrect. );
  print( ( Last item from list = + ( aList .getLastItem() ) ) );
  print( Note: Calling removeLast causes runtime error. );
  print( Remove at index 2. );
  aList .remove( 2 ); duration = 0 seconds
  world.printList ( theList = aList );
  print( Remove at index 0. );
  aList .remove( 0 ); duration = 0 seconds
  world.printList ( theList = aList );
  print( Remove at index 1. );
  aList .remove( 1 ); duration = 0 seconds
  world.printList ( theList = aList );
  print( Clear the list. );
  aList .clear(); duration = 0 seconds
  world.printList ( theList = aList );
  print( The End );
  }


  public void printList ( String[] theList) {
    String printString = ;
       // Copyright 2007, R.G.Baldwin
  // Displays contents of a list of type String.
  for (int index=0; index< ( theList .size() ) ; index++) {
       // Concatenate list elements into a string
  // separated by spaces for printing.
  printString .set( value , ( printString + ( theList [ index ] ) ) ); duration = 0 seconds
  printString .set( value , ( printString + ) ); duration = 0 seconds
  }
  // Print string containing concatenated list contents
  print( printString );
  }

 

Listing 2. Source code for the program named Alice0185b.

Alice0185b's Code

Created by: Dick Baldwin

world

Events

When the world starts
Do:
world.main ( );

Methods

  public void main ( ) {
    Object[] aList = ;
       // Copyright 2007, R.G.Baldwin
  // Illustrates forAllInOrder and forAllTogether.
  doInOrder {
       // Add existing objects to the list.
  // Be sure to start with an empty list.
  aList .add( penguin ); duration = 0 seconds
  aList .add( cow ); duration = 0 seconds
  aList .add( hare ); duration = 0 seconds
  aList .add( monkey ); duration = 0 seconds
  aList .add( tortoise ); duration = 0 seconds
  }
  For all aList , one item_from_aList at a time {
       // Make all objects turn in sequential order.
  item_from_aList .turn( LEFT , 1 revolution );
  }
  For all aList , every item_from_aList together {
       // Make all objects move forward together.
  item_from_aList .move( FORWARD , 0.5 meters );
  }
  penguin .say( That's all, Goodbye ); duration = 5 seconds
  }

 


Copyright

Copyright 2007, Richard G. Baldwin.  Faculty and staff of public and private non-profit educational institutions are granted a license to reproduce and to use this material for purposes consistent with the teaching process.  This license does not extend to commercial ventures.  Otherwise, reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.

About the author

Richard Baldwin is a college professor (at Austin Community College in Austin, TX) and private consultant whose primary focus is a combination of Java, C#, and XML. In addition to the many platform and/or language independent benefits of Java and C# applications, he believes that a combination of Java, C#, and XML will become the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas.  He is the author of Baldwin's Programming Tutorials, which have gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.

In addition to his programming expertise, Richard has many years of practical experience in Digital Signal Processing (DSP).  His first job after he earned his Bachelor's degree was doing DSP in the Seismic Research Department of Texas Instruments.  (TI is still a world leader in DSP.)  In the following years, he applied his programming and DSP expertise to other interesting areas including sonar and underwater acoustics.

Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.

Baldwin@DickBaldwin.com

-end-