Nice TWiki > Dev > StandardLibrary (r1.1 vs. r1.16) TWiki webs:
Dev | Doc | Main | TWiki | Sandbox
Dev . { Changes | Index | Search | Go }
 <<O>>  Difference Topic StandardLibrary (r1.16 - 03 Feb 2004 - DanielBonniot)
Added:
>
>

There are still reasons why we would want to modify the collection hierarchy (not necessarily the implementation, but make it have a different hierarchy structure) so that it would have no unsupported operations. That's a different project, of course.

-- DanielBonniot - 03 Feb 2004


 <<O>>  Difference Topic StandardLibrary (r1.15 - 02 Feb 2004 - BrynKeller)
Added:
>
>

These days, if you want this sort of thing, you just use the generator library in nice.functional. If you want to break out of a map/filter/etc. you just call stop() and that's equivalent to breaking. So:

import nice.functional;

let foo = naturals().filter(
              int i => {if (i == 53) { stop(); } return odd(i);
          ).map(int i => i.toString);

gives you a generator which starts with all the naturals, filtered down to only the odd ones, converted to strings. Except the method passed to filter calls stop() when it hits i == 53, so the whole chain ends at that point. It turned out to be a lot simpler than rewriting the entire collection hierarchy and so on.

-- BrynKeller - 02 Feb 2004


 <<O>>  Difference Topic StandardLibrary (r1.14 - 08 Aug 2003 - ArjanB)
Added:
>
>

see also StandardLibraryMethods


 <<O>>  Difference Topic StandardLibrary (r1.13 - 29 Jun 2003 - ArjanB)
Added:
>
>

Can you give a preview of what you have? If you are short in time, I could help implementing the additions.

Have you considered the addition/overloading of operators for common operations on collections? I think of an operator for creating ranges.

-- ArjanB - 29 Jun 2003


 <<O>>  Difference Topic StandardLibrary (r1.12 - 12 Jun 2003 - BrynKeller)
Added:
>
>

Hmm, that's a good point. I would say it's definitely useful - I seem to recall often wanting to break out of maps and filters in the past. Clean is another question - as you pointed out, handling Break in some cases could make things less efficient - for instance map for arrays would have to be written something like this:

<C,T,U> map(a@Array, f)
{
  List<U> list = new ArrayList(); //or maybe LinkedList
  list.foreach(T elem => { res.add(f(elem)); });  
  return list.toArray();
}

which is clearly going to be slower than the current implementation. Is it worth it? I'm not sure. What if we kept foreach the way it is now, but added forbreak as a foreach where you could throw a Break , and then added new methods like mapbreak, filterbreak and so on? Another approach that would be a little odd but would clutter the namespace less would be to define foreach like this:

<T> foreach(c@java.util.Collection, f, allowBreak = false) 
{
  if (allowBreak)
    try 
      {
        for (java.util.Iterator<T> i = c.iterator(); i.hasNext();)
          f(i.next());
      } 
    catch (Break b)
      {
        //Ignore
      }
  else
    for (java.util.Iterator<T> i = c.iterator(); i.hasNext();)
      f(i.next());
   
}

and then we could write other methods with allowBreak parameters too:

<C,T,U> map(a@Array, f, allowBreak)
{
  if (allowBreak)
    List<U> list = new ArrayList(); //or maybe LinkedList
    list.foreach(T elem => { res.add(f(elem)); }, allowBreak = true);  
    return list.toArray();
  else
    return fill(new U[a.length], int i => f(a[i]));
}
but maybe this is all getting too far-fetched.

-- BrynKeller - 12 Jun 2003


 <<O>>  Difference Topic StandardLibrary (r1.11 - 12 Jun 2003 - DanielBonniot)
Added:
>
>

That would at least break the implementation of map on arrays (file arrays.nice):

<C,T,U> map(a@Array, f) = fill(new U[a.length], int i => f(a[i]));
If f is allowed to throw Break, then we cannot assume that the result will have the same size as the argument. We could of course adapt the implementation. My question is: is it useful, and clean, to allow to break during map, filter, ...

-- DanielBonniot - 12 Jun 2003


 <<O>>  Difference Topic StandardLibrary (r1.10 - 11 Jun 2003 - BrynKeller)
Added:
>
>

Zero, I'd say. Actually, the current definition of foldLeft would already work:

<Any T, Any U> U foldLeft(java.util.List<T> l, (U, T)->U f, U init)
{
  U res = init;
  l.foreach(T elem => { res = f(res, elem); });
  return res;
}

assuming that foreach looks something like this:

<T> foreach(c@java.util.Collection, f) 
{
  try 
    {
      for (java.util.Iterator<T> i = c.iterator(); i.hasNext();)
      f(i.next());
    } 
  catch (Break b)
    {
      //Ignore
    }
}

Oh, it seems everything's already implemented with foreach, so we should be all set:

<C,T,U> map(c, f)
{
  C<U> res = c.similarEmptyCollection();
  c.foreach(T elem => { res.add(f(elem)); });
  return res;
}

<C,T> filter(c, test)
{
  C<T> res = c.similarEmptyCollection();
  c.foreach(T elem => { if(test(elem)) res.add(elem); });
  return res;
}

-- BrynKeller - 11 Jun 2003


 <<O>>  Difference Topic StandardLibrary (r1.9 - 11 Jun 2003 - DanielBonniot)
Added:
>
>

Unlike foreach, those functions return a value. What would be the semantics of breaking inside those? For instance, what does [1,2,3].foldLeft((int i, int j) => throw new Break(), 0) return? -- DanielBonniot - 11 Jun 2003


 <<O>>  Difference Topic StandardLibrary (r1.8 - 11 Jun 2003 - BrynKeller)
Added:
>
>

Are the methods in the StdLib? a complete set of additions to the collections api or do we need more?

I think there's room for a lot more collections methods in the standard library - in fact I'm working on some now, hopefully I'll be ready to circulate them for comments some time in the next two weeks.

-- BrynKeller - 11 Jun 2003

Added:
>
>

I think it would be a perfectly acceptable solution. The try/catch overhead probably isn't worth worrying about, since it's only getting set up once. It also has the advantage that if we implement map, filter, foldLeft, etc. in terms of this new foreach, then you can throw new Break() out of any of those as well, which could be handy.

-- BrynKeller - 11 Jun 2003


 <<O>>  Difference Topic StandardLibrary (r1.7 - 10 Jun 2003 - DanielBonniot)
Added:
>
>

I added contains and retain in CVS, and made has and keep deprecated. We will remove them in the future, preferably waiting some time after the compiler starts emiting warning when using deprecated methods. I also renamed findIndex into indexOf, do we agree on that too?

About find (and findLast), there are two versions. One works only on collections of non-null values, and it returns null if no element was found. The other one works on any collection, but throws java.util.NoSuchElementException is no element was found. So you can choose your style: either checked the returned value, or handle an exception. The advantage is that there is never confusions between a null element in the list passing the test and no element being found. What is the problem with this approach?

It might be practical to give the two versions different names, so one can really choose which one to use in every case. I thought about find and search. The idea is that find is expected to always return a value. If it doesn't, it is exceptional, so it throws and exception. On the other hand, search is merely searching for something, which might not be there (in which case it returns null). Comments?

-- DanielBonniot - 10 Jun 2003


 <<O>>  Difference Topic StandardLibrary (r1.6 - 06 Jun 2003 - DanielBonniot)
Changed:
<
<

We need a documentation for the standard library. The best way would be to write a tool nicedoc, similar to javadoc. There are already documentation comments in the library.

>
>

We need a documentation for the standard library. The best way would be to write a tool NiceDoc, similar to javadoc. There are already documentation comments in the library.


 <<O>>  Difference Topic StandardLibrary (r1.5 - 06 Jun 2003 - DanielBonniot)
Added:
>
>

%META:TOPICMOVED{by="DanielBonniot" date="1054927070" from="Dev.StdLib" to="Dev.StandardLibrary"}%


 <<O>>  Difference Topic StandardLibrary (r1.4 - 06 Jun 2003 - DanielBonniot)
Changed:
<
<

%META:TOPICPARENT{name="NiceDiscussions"}% The standard library needs work. One area is the collection hierarchy. There are so far few implementations. It is a question whether to add new ones, or make java.uil.* collections part of it, with polymorphic types. Something to look at could be how GJ retrofits polymorphic types on java.util. Would it be legal, techinacally possible and good to resuse this work, more or less automatically? There has been some discussions with BrynKeller about this subject.

>
>

%META:TOPICPARENT{name="CurrentDiscussions"}% TOC: No TOC in "Dev.StandardLibrary"

Changed:
<
<

I think that implementing the import of java.util.Collection and friends might be made easier by some change in the compiler, so I suggest to wait about that part, I will have a look.

>
>

Documentation for the standard library

Changed:
<
<

-- DanielBonniot - 31 Jul 2002

>
>

We need a documentation for the standard library. The best way would be to write a tool nicedoc, similar to javadoc. There are already documentation comments in the library. Writing nicedoc is a project in search of a volunteer to start it!

Unsupported operations in Java collections

Another thing I've been struggling with, is that the current collection hierarchy is somewhat imprecise - Collection specifies a number of operations which commonly appear together, but which might not always be appropriate (e.g., it's debatable whether LazyVector? should have a size method), and the same is true of sequence. I'm toying with a much more granular hierarchy at the moment, which I'll detail later. It also has two hierarchies, one for collections which allow in-place modification, and one for collections which do 'functional update', that is, return copies of themselves with the changed values. More later. -- BrynKeller - 05 Aug 2002

I also have concerns with this UnsupportedOperationException. It seems that the interface hierarchy was not well designed. Anybody interested to propose a fixed hierarchy?

-- DanielBonniot - 09 Sep 2002

Here a page discussing this problem: http://jinx.swiki.net/87

see also FlagInterfaces for an experimental approach to solve this problem -- ArjanB

Additional collection methods

Are the methods in the StdLib? a complete set of additions to the collections api or do we need more?

A few names of the methods could be could changed to fit better the java parts of the api. has->contains, keep->retain and "find" shouldn't throw an exception. -- ArjanB

Support for 'break'ing in foreach

Changed:
<
<

Another thing I've been struggling with, is that the current collection hierarchy is somewhat imprecise - Collection specifies a number of operations which commonly appear together, but which might not always be appropriate (e.g., it's debatable whether LazyVector? should have a size method), and the same is true of sequence. I'm toying with a much more granular hierarchy at the moment, which I'll detail later. It also has two hierarchies, one for collections which allow in-place modification, and one for collections which do 'functional update', that is, return copies of themselves with the changed values. More later. -- BrynKeller - 05 Aug 2002

>
>

-- BrynKeller - 05 Aug 2002

Changed:
<
<

Generic Java There is a new version of the Nice compiler that understands Generic Java type signatures. This allows in particular to use java.util.* collections with parameterized types (e.g. List). These replace the previous (very partial) collections from nice.lang. Functionals on collections (foreach, map, has, ...) are applicable to java.util Collections. import java.util.*; is not necessary, it is always made implicit (like for java.lang).

>
>

And alternate design uses exceptions. You make the iterating function catch an exception called Break. In the anonymous function, it is possible to break by just throwing that exception. One advantage is that we can add that functionality to foreach itself, and clients don't need to do anything if they don't need breaking.

Deleted:
<
<

Testing and comments are welcome. The new (beta) version is available, as usual, at http://nice.sf.net/nice.jar

Example code:

Changed:
<
<

package test;

void main(String[] args)

>
>

foreach(c@java.util.Collection, f)

Changed:
<
<

java.util.List frenchNumbers = new ArrayList?(); frenchNumbers.add("Zero"); frenchNumbers.add("Un"); frenchNumbers.add("Deux"); frenchNumbers.add("Trois"); frenchNumbers.foreach(String s => println(s));

// Collections can be used on primitive types too (unlike Generic Java). java.util.List numbers = new ArrayList?(); numbers.add(0); numbers.add(1); numbers.add(2); numbers.add(3); numbers.foreach(int i => println("Number " + i + " is written " + frenchNumbers[i] + " in french."));

>
>

try { for (let i = c.iterator(); i.hasNext();) f(i.next()); } catch(Break ex) {}

Deleted:
<
<

One concern I have with java.util Collections is the UnsupportedOperationException?. It seems that the interface hierarchy was not well designed. Anybody interested to propose a fixed hierarchy?

-- DanielBonniot - 09 Sep 2002

Changed:
<
<

Here a page discussing this problem: http://jinx.swiki.net/87

see also FlagInterfaces for an experimental approach to solve this problem -- ArjanB

>
>

Usage:

List<String> l = [ "A", "B", "C" ];
l.foreach(String s => { println(s); if (s.equals("B")) throw new Break(); });
Changed:
<
<

Are the methods in the StdLib? a complete set of additions to the collections api or do we need more?

>
>

Does someone know (or can make experiments to find out) if the try block would cause a performance penalty, in case the client does not need to break?

Changed:
<
<

And I think we need at least some sort of javadocs for the stdlib soon.

>
>

Would foreach with Break exception support a good solution? Is forbreak still needed, because it is more general?

Changed:
<
<

A few names of the methods could be could changed to fit better the java parts of the api. has->contains, keep->retain and "find" shouldn't throw an exception. -- ArjanB

>
>

-- DanielBonniot - 06 Jun 2003


 <<O>>  Difference Topic StandardLibrary (r1.3 - 04 Jun 2003 - ArjanB)
Added:
>
>

Are the methods in the StdLib? a complete set of additions to the collections api or do we need more?

And I think we need at least some sort of javadocs for the stdlib soon.

A few names of the methods could be could changed to fit better the java parts of the api. has->contains, keep->retain and "find" shouldn't throw an exception. -- ArjanB


 <<O>>  Difference Topic StandardLibrary (r1.2 - 26 Apr 2003 - ArjanB)
Changed:
<
<

Found a backup of this page. -- ArjanB - 25 Apr 2003

>
>

Here a page discussing this problem: http://jinx.swiki.net/87

see also FlagInterfaces for an experimental approach to solve this problem -- ArjanB


 <<O>>  Difference Topic StandardLibrary (r1.1 - 25 Apr 2003 - ArjanB)
Added:
>
>

%META:TOPICINFO{author="ArjanB" date="1051276103" format="1.0" version="1.1"}% %META:TOPICPARENT{name="NiceDiscussions"}% The standard library needs work. One area is the collection hierarchy. There are so far few implementations. It is a question whether to add new ones, or make java.uil.* collections part of it, with polymorphic types. Something to look at could be how GJ retrofits polymorphic types on java.util. Would it be legal, techinacally possible and good to resuse this work, more or less automatically? There has been some discussions with BrynKeller about this subject.

I think that implementing the import of java.util.Collection and friends might be made easier by some change in the compiler, so I suggest to wait about that part, I will have a look.

-- DanielBonniot - 31 Jul 2002

I've noticed that there's a need for another basic method on Collection, which is a method that's like foreach, but provides the client code with some way to stop the iteration. I'll call this method forbreak, because it's foreach with a break. It looks something like this:

<Any T> void forbreak(Collection<T> coll, (()->void)->T->void func);

forbreak(s@Sequence, func) {
  boolean breakFlag = false;
  T->void each = func(()->void esc =>{breakFlag = true;});
  for(int i=0;!breakFlag; i++) {
    each(s[i]);
  }
}
So the function passed to forbreak takes an 'escape continuation', so-to-speak, and returns a function to iterate with. Then the iterator function can use the escape continuation to break off the iteration when desired. Foreach can be implemented trivially on top of forbreak:
foreach(c@Collection, func) = c.forbreak(()->void esc=>func);
and it seems like a more generally useful building block for functions on collections which may or may not be sequences, or support size(), or what have you. For instance, find() is currently defined on Sequence, but with forbreak installed, it could be promoted up to Collection. If we added a method mkEmpty, which would produce an empty collection (i.e., much like a no-args constructor) to Container, then we could define foldLeft, map, filter, etc. top of forbreak. So for collections to get all that great functionality, they only have to define mkEmpty and forbreak. Actually, mkEmpty plus either forbreak or fold would do. Maybe we should make fold the base operation, and forbreak can easily be built on that as well.

Another thing I've been struggling with, is that the current collection hierarchy is somewhat imprecise - Collection specifies a number of operations which commonly appear together, but which might not always be appropriate (e.g., it's debatable whether LazyVector? should have a size method), and the same is true of sequence. I'm toying with a much more granular hierarchy at the moment, which I'll detail later. It also has two hierarchies, one for collections which allow in-place modification, and one for collections which do 'functional update', that is, return copies of themselves with the changed values. More later. -- BrynKeller - 05 Aug 2002

Generic Java There is a new version of the Nice compiler that understands Generic Java type signatures. This allows in particular to use java.util.* collections with parameterized types (e.g. List). These replace the previous (very partial) collections from nice.lang. Functionals on collections (foreach, map, has, ...) are applicable to java.util Collections. import java.util.*; is not necessary, it is always made implicit (like for java.lang).

Testing and comments are welcome. The new (beta) version is available, as usual, at http://nice.sf.net/nice.jar

Example code:

package test;

void main(String[] args)
{
  java.util.List<String> frenchNumbers = new ArrayList();
  frenchNumbers.add("Zero");
  frenchNumbers.add("Un");
  frenchNumbers.add("Deux");
  frenchNumbers.add("Trois");
  frenchNumbers.foreach(String s => println(s));

  // Collections can be used on primitive types too (unlike Generic Java).
  java.util.List<int> numbers = new ArrayList();
  numbers.add(0);
  numbers.add(1);
  numbers.add(2);
  numbers.add(3);
  numbers.foreach(int i => println("Number " + i + " is written " + frenchNumbers[i] + " in french."));
}
One concern I have with java.util Collections is the UnsupportedOperationException?. It seems that the interface hierarchy was not well designed. Anybody interested to propose a fixed hierarchy?

-- DanielBonniot - 09 Sep 2002

Found a backup of this page. -- ArjanB - 25 Apr 2003


Topic StandardLibrary . { View | Diffs | r1.16 | > | r1.15 | > | r1.14 | More }
Revision r1.1 - 25 Apr 2003 - 13:08 GMT - ArjanB
Revision r1.16 - 03 Feb 2004 - 09:46 GMT - DanielBonniot
Copyright © 1999-2003 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback.