Forums

MultiList

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

Re: MultiList

Postby Charles » Tue Jul 31, 2012 11:09 pm

I just did a "sudo bin/install-from-workspace -net4" on an updated workspace and it choked on a MultiList test. I had to comment out line 442 which failed to throw an exception:
#           expect AssertException, ml3[1,1,1] = 5

I realize the problem is that the installer builds the Cobra.Core lib with -turbo which turns off contracts:
class Matrix

pro [indices as vari int] as T
get
require
indices.length == .numDims
body
return _data[_address(indices)]
set
require
indices.length == .numDims
not .isReadOnly
body
_data[_address(indices)] = value

Seems to me that contracts should be enabled by default but then we need an easy way to turn them off in libraries with no run-time overhead (or as little as possible).

I guess I'll have to ponder this some more after 0.9. It's really a contracts+lib issue, not a MultiList.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: MultiList

Postby jaegs » Sat Aug 04, 2012 11:38 am

I submitted a patch for MultiList
http://cobra-language.com/trac/cobra/ticket/288

I changed .v to .view and removed .t
I suppose someone could always make an extension method called .t if necessary
Since the last commit to Cobra.Core there is a lot more documentation.

In the past, I have used verbs in the present tense and past tense for distinguishing modifying in place vs. returning a copy that leaves the original unmodified

Past tense verbs makes sense to me. However, creating an out of place version for every in place method will dramatically increase the total number of methods. Additionally if someone wants to perform a sequence of operations out of place, only one view needs to be made.
ml.reshaped(shape).permute(order) #versus
ml.view.reshape(shape).permute(order)



I realize the problem is that the installer builds the Cobra.Core lib with -turbo which turns off contracts. Seems to me that contracts should be enabled by default but then we need an easy way to turn them off in libraries with no run-time overhead (or as little as possible).

I can see this being a big issue. The only options I'm seeing to let the user decide whether or not to use contracts is lots and lots of "if" statements in the .cs code or an additional .dll

I don't have too much experience with contracts but it seems to me that requirements should never be turned off. require is different from ensure or invariant in that a failed requirement is the caller's fault, while the other contracts are the library's fault.

Now consider a user making a concurrent program. With contracts, the everything works. Since performance is important, the user then turns off contracts. A race conditions causes a (unchecked) requirement to be violated. The library maker relied on requirements to alert the caller about improper use of their method. For example, instead of throwing an InvalidOperationException, a requirement is used. The library will crash inside of a method and probably won't give a good reason why it crashed.
jaegs
 
Posts: 58

Re: MultiList

Postby Charles » Sat Aug 04, 2012 5:17 pm

Re: contracts, we do in fact have a run-time flag to turn them off and hence the obligatory if-statements to check the flag. But we also have a compile-time option to completely exclude all the code related to contracts.

I'm leaning now towards leaving them in the library and if someone uses -include-contracts:none, turning off the flag so they won't run in the library. This will leave the library running slightly slower, but in practice it should be negligible. If someone needs even more speed (in other words getting rid of the if-statements) then they can use -embed-run-time.

However, this could be a large change depending on what we discover, so it will be post 0.9.

This part is wrong: "The library maker relied on requirements to alert the caller about improper use of their method." Your code should not rely on contracts for normal software operations. Also the contracts should have no side effects.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: MultiList

Postby Charles » Sat Aug 04, 2012 8:26 pm

I have applied the patch you provided for MultiList.

-- I changed the generic var from A back to the original T. This is a convention in the .NET community that generic args--which are always types--start with cap T. For example, if you look up the docs for Dictionary you'll find the args are called TKey and TValue. Sometimes I screw around with other conventions in tests and programs, but the Cobra std lib, I try to be more consistent.

-- I noticed all the changes from "dimension" to "axis" and "axes" for terminology:

+           """ Shape is the size of each axis in the view """
+ Maps the order of the axes stored internally to
...

I wondered if this came from Boost's multi_array, but when I go to:
http://www.boost.org/doc/libs/1_50_0/li ... /user.html

I get 0 browser find hits for "axi" and 52 for "dimension". Although I did not check Python, Ruby and MATLAB.

Why the change?

-- Regarding comments like "Syntactic placeholder ...", even if we add more syntactic sugar in support of MultiList, it's not a bad idea to have the methods. They can be invoked via reflection and the class can even be vended out to other .NET languages (C#, VB, etc.) which would need them.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: MultiList

Postby jaegs » Sun Aug 05, 2012 6:59 pm

axis is a Numpy term. MultiList technically only has one dimension, in memory that is. The word dimension is overloaded since it can refer to either the memory layout or to the shape of the MultiList. Hopefully, axis makes the situation more clear.

Here is where I am unclear about contracts. Let's say you're implementing the .add method in C#'s Dictionary class. The item to add cannot already be in the dictionary. Which of these options best align with good Cobra coding practices?
#Option 1: What exists currently in the .NET library, but written in Cobra
def add(key as TKey)
if .containsKey(key)
throw ArgumentException()
...

#Option 2:
def add(key as TKey)
require not .containsKey(key)
...

#Option 3:
def add(key as TKey)
require not .containsKey(key)
if .containsKey(key)
throw ArgumentException()
...


I'm never programmed in Eiffel, but going off of the Wikipedia page
Exception handling in Eiffel is based on the principles of design by contract. For example, an exception occurs when a routine's caller fails to satisfy a precondition, or when a routine cannot ensure a promised postcondition. In Eiffel, exception handling is not used for control flow or to correct data-input mistakes.

it sounds like only option 2 is correct for an Eiffel coder. Exceptions should only be used for unpredictable events like network errors. Furthermore, it doesn't seem like Eiffel contracts can be turned off - so here is where Cobra differs. The Cobra library writer should choose option 3 to account for the caller turning contracts off.
jaegs
 
Posts: 58

Re: MultiList

Postby Charles » Mon Aug 13, 2012 12:59 am

The comment about MultiList's memory having one dimension is true of computer memory in general (ignoring the segmented architecture used in some smaller processors). All multi-dimensional memory is an illusion. Anyway I'm fine with axis if NumPy is using it.

Re: contracts,

Option 1 hides the contract in the implementation of the method where it will not be picked up by a doc tool and not inherited in method overrides, nor identified in any way as part of the API.

Option 3 duplicates code which is the next greatest sin after premature optimization.

Option 2 is the correct form for Cobra.

I have consistently read that Eiffel does allow contracts to be turned off including your choice of preconditions, postconditions and invariants. Since their standard library is loaded with fairly thorough contracts, turning them off can be a necessity for projects that need better performance. This is typically done when shipping the software or releasing to a production environment.

There is then the idea of striking some balance where you leave one of these in place to act as a quality control while turning off the others to improve performance. Which one to leave on? They say preconditions:
Based on this knowledge, we can say that it is most practical first to turn off runtime checking of postconditions and invariants as we gain confidence in a class. Meaning of course, that we feel confident that any calls that meet preconditions will be properly processed. Then our only worry is that some deranged client will, with total disregard for our carefully crafted preconditions, make calls to our routines from invalid states. So, maybe we will leave precondition checking turned on for a while.

from http://docs.eiffel.com/book/platform-sp ... assertions

I read somewhere else, but don't have the reference, that this approach was learned through the experience of using Eiffel.

Interestingly, this fits in with your example about turning off preconditions which can lead to undetected misuse of a class.

Cobra does not have a compile-time option to turn these off in a granular fashion, but it does have run-time properties in CobraCore to do so:
class CobraCore

shared

pro willCheckInvariant from var
pro willCheckRequire from var
pro willCheckEnsure from var
pro willCheckAssert from var
pro willCheckNil from var

set willCheckAll as bool
.willCheckInvariant = value
.willCheckRequire = value
.willCheckEnsure = value
.willCheckAssert = value
.willCheckNil = value

Which means you could even set these based on config values or command line args.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Previous

Return to Discussion

Who is online

Users browsing this forum: No registered users and 117 guests

cron