Wiki

Ticket #126 (accepted enhancement)

Opened 9 years ago

Last modified 9 years ago

Provide enumerate method (or similar) in CobraCore

Reported by: hopscc Owned by: Chuck
Priority: medium Milestone:
Component: Cobra Compiler Version: 0.8.0
Keywords: Cc:

Description

Once you have multi arg assignment in for loops it seems its a common idiom to want to walk an IEnumerable and get back an item and its offset in the IEnumerable

Currently to do this you need to wrap a counter around the IEnumerable forloop

i as int = 0
for item in mylist
    doSomethingWith(i, item)
    i += 1

While not difficult this is tedious and obscurative and generally 'clunky'

In python this is provided with an .enumerate function

myList = [ 'one", 'two', 'three']
for i, item in enumerate(myList)
    doSomethingWith(i, item)

I propose we add a similar method to CobraCore
allowing something like

myList = [ 'one", 'two', 'three']
for i, item in CobraCore.enumerate(myList)
    doSomethingWith(i, item)

Pending pure functions or some form of default method lookup to
a specified class ( CobraCore ) this is probably as simple as we can get....


Heres the implementation

	def enumerate(ie as IEnumerable) as IEnumerable<of IList>  is shared
		n=0
		for e in ie
			yield [n, e]
			n += 1
			
			
	def main is shared
		a = [1,2,3,4]	
		l = .enumerate(a)
		l1 =  for ii in l get ii 
		assert l1 == [[0,1],[1,2],[2,3],[3,4]]
		
		for i,item in .enumerate(['a','b','c'])
			assert i in [0,1,2]
			assert item in ['a', 'b', 'c']
			#print "[i]:[item]"
			
		kvpList = [KeyValuePair<of String, String>('x','aa'),
					KeyValuePair<of String, String>('y','bb'),
					KeyValuePair<of String, String>('z','cc') ]
		for i,kv in .enumerate({'x':'aa','y':'bb','z':'cc'})
			assert i in [0,1,2]
			assert kv in kvpList
			#print "[i]:[kv]"

Change History

Changed 9 years ago by Chuck

  • owner set to Chuck
  • status changed from new to accepted

Overall I agree with you. I was already planning this, but instead of the clunky Python approach where you have to switch between methods and functions, it would be done with an extension method instead:

for i, item in items.numbered
    print i, item

# or even:
for i, item in items.sorted.reversed.numbered
    print i, item

Also, the best return type for .numbered would be KeyValuePair<of int, T>.

Finally, nothing about the verb "enumerate" indicates that an integer comes along for the ride. In fact, Cobra will have a "cue enumerate" to make enumerating objects easier, e.g., implementing .NET IEnumerable<of T> / JVM Iterable<of T>.

Changed 9 years ago by Chuck

Btw in place of:

IEnumerable<of X>

You can say:

X*

Changed 9 years ago by Chuck

See also ticket:129

Changed 9 years ago by Chuck

Cobra does not recognize methods on streams that come from extending !IEnumerable<of T>. I will need to fix that.

Changed 9 years ago by hopscc

Coupla points

'clunky ... switching between functions and methods'

some things work well as methods, others as functions. I wonder about extension methods as being easily user discoverable (in addition to whatever the native .Net libs provide) and how implementable they will be on platforms other than .Net

as an extension ; fine if .numbered works seamlessly on everything that implements IEnumerable

KeyValuePair - best return type - huh ?

The enumerable isn't keyed by the count - different representation
return a 2 element list [count, item] and hey it just works with multivalue for loops

re 'enumerate' - one definition is 'to ascertain the number of; count'..

numbers and counts are usually integers...

the cue helps with implementing IEnumerable/Iterable not with consuming such implementations....

Maybe this needs opening as a discussion item...

Changed 9 years ago by Chuck

So len(x) "works better as a function" and append(x) "works better as a method"? Huh???

Regarding discoverability, in Python when I print the dir() of a list, I see "append", "extend" and others. But the only "len" I see is quadruple underscore len, which isn't the right approach for using a list. That's poor discoverability.

Regarding KeyValuePair<of T, U>, it's being used for its "pair"ness and it's strong typing.

Changed 9 years ago by hopscc

len/append() where did they come from?
as a totally different topic I can make an argument that len as a function does work better in that it can subsume both Array.length and List.count ( and whatever as yet undiscovered length/count variants are buried in any other parts of the .Net class libs)
still..

and with dir(list) in cobra we get ...... a syntax error so thats no help
crap discoverability in python doesnt need to be a excuse for different crap discoverability in cobra
Not that enumerate is ideal but at least its congruent with python if thats where you're coming from

For base .net libs you can use the MS doc, for cobra extensions you have to ....

a) already know it
b) spelunk existing src code hoping someone else has used it
c) wander the compiler/RTL src
d) search the forum and hope its been mentioned and the search mechanism doesnt discount your search pattern as too common

pending someone doing + maintaining the definitive cobra doc project..

Hmm makes me wonder if we need some tool to auto gen doc from the RTL/extensions
src files unless you already have an unmentioned idea for auto documenting the cobra-additions-over-the-base-platform...

....

The strong typing (for the item) is a reasonable point but so is a genericised
list type <int>, <whatever> if its needed... ( and its still not a Key+Value)

Changed 9 years ago by Chuck

Re: your "crap discoverability in python" comment, you're the one who brought up discoverability. I was the one pointing out that it's not any better when you switch between functions and methods.

And why you say "crap discoverability in cobra" is beyond me. If we put some List functionality in static/shared methods, how is that going to make for good discoverability over extension methods? You still have to look somewhere.

And you're a)b)c) list is a bit strange. We already have these types of docs for PrimitiveTypeMembers -- check it out. The only reason we don't have them for the new extension methods is that I just added them a couple days ago!

A yes, there's a "cobra -doc ..." option although it's likely in need of some TLC.

Changed 9 years ago by hopscc

yes I did bring up discoverability because i think its an issue for understanding the Cobra api especially given the current state of the info and doc and specifically wrt enumerate.... Sorry bout that

'you still have to look somewhere' and if you're familiar with python you'll be looking for the closest thing to a function that has a similar name to the python equiv
FTM thats all the stuff in CobraCore.
Assuming you're coming to this cold and realise such a thing as class extensions exist in cobra where would you go to see whats been provided?
( the second is probably a bigger hurdle than the first)

re the 'doc' PrimitiveTypeMembers

thats partly the point - I've been following this stuff and I didnt realise that page existed, partially complete though it may be
Also and unfortunately a long list of one liner method signatures (however nicely formatted) doesnt really cut it as 'doc'

Maybe if it was crosslinked to the .Net api doc somehow but that doesnt address
new functionality in extension methods (as opposed to converting existing static methods to instance ones)

Note: See TracTickets for help on using tickets.