This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: Support Iterable in for-each
- From: Jamison Hope <jrh at theptrgroup dot com>
- To: kawa at sourceware dot org
- Date: Fri, 27 Feb 2015 12:35:53 -0500
- Subject: Re: Support Iterable in for-each
- Authentication-results: sourceware.org; auth=none
- References: <CAOTvmokU5J0Gy58iCa_UgU7FhvYLT6Ba7Z8C6W1yA7DBA44G_w at mail dot gmail dot com> <52D048D4 dot 2080803 at bothner dot com> <54EFD57D dot 9060808 at bothner dot com>
On Feb 26, 2015, at 9:25 PM, Per Bothner <per@bothner.com> wrote:
> [This is a follow-up to a discussion from January 2014.]
>
> I've checked in code to generalize map, for-each, and vector-map
> so the sequence arguments can be "generalized sequences":
> * any java Iterable, which includes Scheme lists, vectors, uniform
> vectors, and any java.util.List;
> * any primitive array;
> * and any CharSequence, including java.lang.String and Scheme strings.
Very cool. I see that map always returns a list, regardless of the
type(s) of the sequence argument(s).
So if I've got an ArrayList of numbers
#|kawa:1|# (define arraylist (java.util.ArrayList 1 2 3 4 5))
and I want to produce another ArrayList containing the squares of
those numbers, I can do..
#|kawa:2|# (java.util.ArrayList @(map square arraylist))
[1, 4, 9, 16, 25]
or
#|kawa:3|# (apply java.util.ArrayList (map square arraylist))
[1, 4, 9, 16, 25]
That was too painless. :-)
Which is more idiomatic, (apply type list) or (type @list) ?
> vector-for-each is generalized to any java.util.List, using the
> get and size methods. (I.e it assumes the List is RandomAccess.)
> Thus it performs poorly on Scheme lists. (Perhaps we should compile
> in a cast to RandomAccess to guard against quadratic behavior on Scheme lists.)
>
> Note that a CharSequence is considered a sequence of Unicode scalar values
> (a surrogate pair is converted to a single character). OTOH a native
> Java char array is considered a sequence of 16-bit char values. I think
> it makes most sense this way.
>
> If the sequence type is known as compile-time then the Kawa compiler
> well generate custom code for that sequence type (see the scanner-for
> procedure and the ScanHelper class in compile_map.scm). Otherwise
> it will use an Iterator, selecting the Iterator kind at run-time (see the
> static getIterator method in gnu/lists/Sequences.java).
>
> Regardless, if the mapped-over procedure is a lambda it will
> get inlined.
>
> The splice operator @ now also handles strings:
> (string #\X @"abc" #\Y) ==> "XabcY"
> (However, this has not been optimized as well as I'd like yet.)
BTW, I had to define a remove() method for CharacterIterator in
gnu/lists/Sequences.java to build with Java 1.7, which doesn't have
these newfangled "default" methods.
I also had to add
<include name="kawa/Source*.java"/>
to the java-classes target in build.xml.
--
Jamison Hope
The PTR Group
www.theptrgroup.com