Oberon Community Platform Forum
November 19, 2017, 03:23:40 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News:
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: init for arrays?  (Read 4173 times)
gub
Newbie
*
Posts: 9


« on: July 12, 2008, 06:45:04 PM »

Hi,

I'm looking for the most conveniert way for assigning a number of values to an array, a list or something similar in Zonnon.

Expressed in C# it might look like this:
Code:
int[] dimensions = { 200, 400, 500, 800, 900 };
foreach( int dim in dimensions )
// do something with dim

In Pythom you probably would:
Code:
for dim in [ 200, 400, 500, 800, 900 ]:
# do something with dim

Sets don't seem to work since the numbers involved are to big. Any hints?

greetings
gub
Logged
cfbsoftware
Full Member
***
Posts: 106


WWW
« Reply #1 on: August 06, 2008, 02:35:06 PM »

As far as I know, Zonnon is no different from Oberon or Modula-2 in this respect. i.e. assigning separate random constant values to an array requires an assignment statement for each constant.

However, this is rarely an issue in real world applications as there is usually more than one way to express an algorithm - an array might be one of many different potential solutions.

e.g. if we focus on the possible task-specific (rather than implementation-specific) requirements that might have led to the given example in the original question:

Code:
int[] dimensions = { 200, 400, 500, 800, 900 };
foreach( int dim in dimensions )
// do something with dim

Noting that there are only five items and no obvious pattern to the values the use of an array would not be a logical choice. A valid equivalent implementation could well be:

Code:
  DoSomething(200);
  DoSomething(400);
  DoSomething(500);
  DoSomething(800);
  DoSomething(900);

The best actual approach to take in any specific case would depend on many factors: the complexity of the array, the number of elements involved, any sort of logical pattern in the values, how the list of values were to be accessed etc. etc.

I recently responded to a similar question about array-initialisation facilities on the BlackBox mailing list with something like this:

Keep in mind that initialised arrays are not necessarily 1-dimensional arrays of basic items. If that were the case an array initialisation feature might well have been implemented. In the general case they can be multi-dimensional arrays of complex data structures. The consequential additional complexity to the language and compiler to implement a workable and clear scheme to handle this would be quite significant.

Here is an example of an alternative approach to a task that might have been implemented using a structured constant facility (if it had existed).  It's a real-world example that I was actually working on just a few months ago. It's written in Modula-2 but the syntax should be readily understandable.

The application is a Motorola MC68K assembler and I was tackling the problem of initialising the OpCode data. The original code read the initialisation data from a file. I wanted to eliminate the file and 'hard-code' the data. The OpCode table is a 1-dimensional array with elements consisting of a reasonably complex record:

Code:
  Table68K : ARRAY [FIRST..LAST] OF TableRecord;

where:

Code:
  TableRecord = RECORD
    Mnemonic : TOKEN;
    Op : BITSET;
    AddrModeA : ModeA;
    AddrModeB : ModeB;
  END;

where:

Code:
  TOKEN = ARRAY [0..TokenSize] OF CHAR;
  ModeA = SET OF ModeTypeA;
  ModeB = SET OF ModeTypeB;

Using a helper procedure to initialise a single record:

Code:
  PROCEDURE Add(Mnemonic : TOKEN; Op : BITSET; AddrModeA : ModeA; AddrModeB: ModeB);
  VAR
    tr: TableRecord;
  BEGIN
    tr.Mnemonic := Mnemonic;
    tr.Op := Op;
    tr.AddrModeA := AddrModeA;
    tr.AddrModeB := AddrModeB;
    INC(index);
    Table68K[index] := tr
  END Add;

The initialisation code then just became a simple series of procedure calls:

Code:
  Add("ABCD", {15, 14, 8},   ModeA{Rx911, RegMem3, Ry02},  ModeB{});
  Add("ADD",  {15, 14, 12},  ModeA{OpM68D},                ModeB{EA05y});
  Add("ADDA", {15, 14, 12},  ModeA{OpM68A},                ModeB{EA05a});
  Add("ADDI", {10, 9},       ModeA{},                      ModeB{Size67, EA05e, Exten});
  Add("ADDQ", {14, 12},      ModeA{Data911},               ModeB{Size67, EA05d});
  ...
  ...
Logged

Chris Burrows
Astrobe v6.0 (Jun 2016): Oberon for ARM Cortex-M4 and Cortex-M3 Microcontrollers
http://www.astrobe.com
gub
Newbie
*
Posts: 9


« Reply #2 on: August 17, 2008, 05:40:02 PM »

Noting that there are only five items and no obvious pattern to the values the use of an array would not be a logical choice. A valid equivalent implementation could well be:

Code:
  DoSomething(200);
  DoSomething(400);
  DoSomething(500);
  DoSomething(800);
  DoSomething(900);
Yes this is the easiest solution, and it seems to fit your example pretty well. I'm not happy with the copy-and-paste programming style induced by the repetition of code, but my real problem is that my code in the loop is too short to define a new procedure for it:
Code:
writeln( dim[i]:4, " " , measureSeconds( dim[i] ):6:2, "s" );
In this case it would be possible to place the output inside the measureSeconds-procedure, but I don't feel it belongs there. In the end this is again the question in how far a programming language should limit the possible solutions.

Quote
Keep in mind that initialised arrays are not necessarily 1-dimensional arrays of basic items. [...] The consequential additional complexity to the language and compiler to implement a workable and clear scheme to handle this would be quite significant.
Honestly, since there exist compilers which can handle this, this should be handled by the compiler and not by the programmer. On the other hand I confess to expecting the convenience of a scripting language from a programming language which seems to be developed with rather limited human resources.

Why not use the tools the .NET libraries offers. For instance:
Code:
module Main;
import
   System.Collections as SysCol;
var
   dim: SysCol.ArrayList;
   i: integer;
begin
   dim := new SysCol.ArrayList();
   dim.Add( 900 ); dim.Add( 800 );
   dim.Add( 500 ); dim.Add( 400 );
   dim.Add( 200 );
   for i:=0 to (dim.Count-1) do
      (* do something with dim[i] )
   next;
end Main.
Unfortunately I don't know how to use the conctructor ArrayList(ICollection) might make the code sufficiently short and expressive for my tastes. Any ideas?

Btw, is it possible to use generic collections like System.Collections.Generic.List<(Of <(T>)>) in Zonnon?
« Last Edit: August 17, 2008, 05:43:37 PM by gub » Logged
danp
Newbie
*
Posts: 37


« Reply #3 on: August 17, 2008, 08:14:01 PM »

Hi gub,

This could be another solution:

Code:
module Test;

import System;

type
CharArray = array * of char;
StringArray = array * of string;

var
s : string;
sa : StringArray;
i, j : integer;
sep : CharArray;
begin
s := "200,400,500,800,900";
sep := new CharArray(1);  sep[0] := ",";
sa := StringArray(s.Split(sep));
for i:=0 to len(sa)-1 do
j := System.Int32.Parse(sa[i]);
writeln(j:0)
end;
readln
end Test. 

Greetings,
Dan
« Last Edit: August 17, 2008, 08:21:26 PM by danp » Logged
cfbsoftware
Full Member
***
Posts: 106


WWW
« Reply #4 on: August 18, 2008, 12:46:25 AM »

Quote
but my real problem is that my code in the loop is too short to define a new procedure for it:
Do not be afraid of writing one-line procedures if it makes the code easier to comprehend and consequently more reliable to maintain. If you have been advised against this technique make sure that the advice was not just based on bad experiences using other languages. They may well have been implemented with inefficient parameter passing mechanisms.
Logged

Chris Burrows
Astrobe v6.0 (Jun 2016): Oberon for ARM Cortex-M4 and Cortex-M3 Microcontrollers
http://www.astrobe.com
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!