Forums

Custom list class

General discussion about Cobra. Releases and general news will also be posted here.
Feel free to ask questions or just say "Hello".

Custom list class

Postby Charles » Tue Aug 21, 2012 7:30 pm

Stimulated by recent discussion regarding inclusive/exclusive for loops, ranges, etc., I made a custom list class to play around with "going against the grain" with a base index of 1. I also wanted to play with creating a .change method so the elements could be transformed in place without even needing a for loop. Other than that, I haven't used it for anything or fleshed it out completely. Here it is for you to review or play around with if you like:
"""
test with:

cobra -test MyList.cobra
"""


class MyList<of T> implements IEnumerable<of T>
# to-do? implements IList<of T>
"""
Allows for a custom base index and
also has an inclusive range readily available through .maxIndex.
"""

var _items as T[]
var _count = 0
var _capacity = 8
var _minIndex = 1 # fixed for now. always 1

invariant
.minIndex >= 0
(.count == 0) == (.maxIndex < .minIndex)

cue init
base.init
_items = T[](_capacity)

get minIndex from var

get maxIndex as int
ensure result >= 0
return _minIndex + _count - 1

get count from var

pro [index as int] as T
get
require index >= .minIndex and index <= .maxIndex
return _items[index - _minIndex]
set
require index >= .minIndex and index <= .maxIndex
_items[index - _minIndex] = value

def add(item as T)
ensure
this[.maxIndex] == item
.count == old .count + 1
.maxIndex >= .minIndex
body
if _count == _capacity
_capacity <<= 1
newItems = T[](_capacity)
_items.copyTo(newItems, 0)
_items = newItems
_items[_count] = item
_count += 1

def getEnumerator as IEnumerator<of T>
for i in _count, yield _items[i]

def getEnumerator as System.Collections.IEnumerator
implements System.Collections.IEnumerable
return .getEnumerator

def change(changer as ChangeMethod)
"""
Change each element in the list. By using this method you don't even have to loop
through the indexes.
"""
ensure .count == old .count
for i in _count, _items[i] = changer(_items[i]) to T

sig ChangeMethod(item) as dynamic # to-do: put this in MyList and make strongly typed


class TestMyList

test basics
t = MyList<of int>()
assert t.count == 0
assert t.minIndex == 1
assert t.maxIndex == 0
counter = 0
for item in t, counter += 1
assert counter == 0

test add
t = MyList<of int>()
t.add(3)
assert t.count == 1
assert t[1] == 3
expect Exception, assert t[0] == 3
expect Exception, assert t[2] == 3
counter = 0
for x in t
assert x == 3
counter += 1
assert counter == 1

test exceedCapacity
t = MyList<of int>()
for i in 1 : 16+1, t.add(i)
assert t.count == 16
for i in t.minIndex : t.maxIndex+1, assert t[i] == i

test toList
t = MyList<of String>()
t.add('a')
t.add('b')
assert t.toList == ['a', 'b']

test change
t = MyList<of String>()
t.add('a')
t.add('b')

t.change(do(item)=item.toUpper)
assert t.toList == ['A', 'B']

t.change(do(item))
return item.toLower
assert t.toList == ['a', 'b']
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Custom list class

Postby Charles » Tue Aug 21, 2012 7:32 pm

I suppose to make for loops nicer, we could provide a .stopIndex that returns .maxIndex + 1:
for i in 1 : t.stopIndex
print t[i]

Or .indexes:
for i in t.indexes
print t[i]

Or .indices, if you prefer.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Custom list class

Postby Charles » Tue Aug 21, 2012 7:46 pm

Yeah, forget .stopIndex, .indexes keeps your for loop simple. You don't have to remember to start it with "1 :" and if MyList is generalized to have any .minIndex, it still works:
class MyList...

def indexes as int*
"""
Convienient for numeric for-loops:
for i in t.indexes, print t[i]
Note that if you just need the elements, you can use the common enumerable for loop:
for i in t, print t
And if you need to change each element, you can use .change:
t.change(do(item)=2*item)
"""
for i in .minIndex : .maxIndex + 1, yield i
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Custom list class

Postby DelphiGuy » Wed Aug 22, 2012 8:23 pm

Thanks for taking a stab at this code, Chuck. I'm reading it and trying to come up to speed, so it may be a little time before I respond more fully.

What's the "invariant" keyword for, please? Couldn't find it by Googling "invariant" and ".net", other than discussions of "invariant culture".

Here's a very perplexing (at least to a .Net beginner like me) article about covariance, contravariance and invariance. Is this even related to Cobra's "invariant" keyword? Any links to articles more on point would be appreciated.

http://www.readability.com/articles/plyezesv
DelphiGuy
 
Posts: 116

Re: Custom list class

Postby Charles » Wed Aug 22, 2012 8:49 pm

"invariant" comes from Eiffel and is part of Cobra contracts. The invariants of a class are a list of boolean conditions that should always be true upon returning from a method. If a method violates an invariant, an exception will be thrown and you will know that either that method is buggy or the invariant in question is.

You didn't find much for .NET because the concept is not baked into .NET or C# or VB. This is a Cobra add-on.

Other places to search:
-- "cobra invariant" on Google or Bing
-- If you don't get hits with that then try "cobra language FOO"
-- While viewing Cobra discussion forums, use the search box in the upper right hand corner to search discussions.
-- While viewing the Cobra wiki, use the search box in the upper right hand corner to search the wiki.
-- Search the filenames and the source code in Tests\ HowTo\ and Samples\ of a Cobra workspace
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Custom list class

Postby DelphiGuy » Wed Aug 22, 2012 9:21 pm

"invariant" will behave this way pursuant to all instances of every method in the class where the invariant lives?! that's quite amazing and powerful.
DelphiGuy
 
Posts: 116

Re: Custom list class

Postby Charles » Thu Aug 23, 2012 1:11 am

Yes, it's like an "ensure" for every method in the class.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Custom list class

Postby DelphiGuy » Tue Aug 28, 2012 1:57 pm

From Charles' "Custom list class" post, dated Tue Aug 21, 2012 10:32 pm:

Code: Select all
    get minIndex from var

    get maxIndex as int
        ensure result >= 0
        return _minIndex + _count - 1

    get count from var


Would someone please remind me why "get" is allowed (as above) independent of a "pro" declaration? Is this a Cobra add-on, or is just plain old .Net? I don't see a discussion of .Net allowing this in either of my .Net books.

I note that "maxIndex" is "get"-ed and declared in the same statement. There's no private version of maxIndex that I see.

Thanks.
DelphiGuy
 
Posts: 116

Re: Custom list class

Postby Charles » Tue Aug 28, 2012 3:07 pm

.NET has properties that can declared in classes, structs and interfaces. They can be get-only, set-only or get+set. This is true in the .NET type system and in the languages C#, VB and Cobra. Then there is the question of syntax:
# explicit syntax using pro keyword:

class X

var _a as int

pro a as int
get
return _a
set
_a = value


# you will get tired of typing that after awhile
# here is a shortcut:

class X

pro a from var as int


# Cobra won't complain if you declare the var explicitly.
# This was the original shortcut syntax implemented before the above

class X

var _a as int

pro a from var


# get-only properties are somewhat common, at least in my code, because
# I may not want to account in the implementation for certain things being
# changed, and/or it may simply not be necessary.
# Note the use of var initialization below:

class X

get children from var = List<of X>()

There is a wiki page on properties. I skimmed it and it looked correct, but possibly incomplete.

You'll note that like other declarations, properties start with a keyword (pro, get, set) followed an identifier.

We could probably come up with some steps like:

1. Decide if you want a get+set, get-only or set-only property.
2. Type the keyword pro, get or set.
3. Type an identifier for the property.
4. Decide if you will implement the property with code or from a variable.
5. If code, type the data type of the property with "as type"
etc.

HTH
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Custom list class

Postby DelphiGuy » Sun Apr 27, 2014 2:08 pm

Charles said:
There is a wiki page on properties. I skimmed it and it looked correct, but possibly incomplete.


That wiki page is incredibly helpful. Thanks for pointing me to it (long ago!).
DelphiGuy
 
Posts: 116

Next

Return to Discussion

Who is online

Users browsing this forum: No registered users and 4 guests