sestoft / C5

C5 generic collection library for C#/.NET
http://www.itu.dk/research/c5/
MIT License
1.03k stars 180 forks source link

Option type #1

Closed qbit86 closed 11 years ago

qbit86 commented 13 years ago

Why do you use deprecated out- and ref-parameters to return values? «Framework Design Guidelines» say: http://msdn.microsoft.com/en-us/library/ms182146.aspx http://msdn.microsoft.com/en-us/library/ms182131.aspx

In the methods like Find(...) a preferred interface is an option type (maybe monad): http://en.wikipedia.org/wiki/Option_type. This is a way it is done in standard libraries of functional programming languages. It really gives far more easy-to-use API!

sestoft commented 13 years ago

On Mon, 27 Jun 2011, Qbit86 wrote:

Why do you use deprecated out- and ref-parameters to return values?

This is a good idiom in imperative code. In functional code it obviously is a bad idea.

Peter

qbit86 commented 13 years ago

This is a good idiom in imperative code. In functional code it obviously is a bad idea.

But my C#-code is as functional as possible :) And out/ref + assignments are too imperative :(

You say: «The design has been influenced by the collection libraries for Java and Smalltalk and the published critique of these.» (http://www.itu.dk/research/c5/latest/ITU-TR-2006-76.pdf) It's probably worth looking at collection libraries in mixed-paradigm languages as F# (http://msdn.microsoft.com/en-us/library/ee353413.aspx). Exception-free search operations always return option as zero-or-one-element collection (in Haskell they return Maybe monad): http://msdn.microsoft.com/en-us/library/ee353739.aspx http://msdn.microsoft.com/en-us/library/ee353786.aspx etc. It's very handy (even if one cannot use pattern matching in C#): you don't need to divide initialization into declaration and assignment; your locals are immutable, their values are predictable. Compare current usage with suggested: // 1) K key = ... K actualKey = key; V value; if (dictionary.Find(ref actualKey, out value)) { /* Use actualKey, value. / } // 2) K key = ... KeyValueOption<K, V> result = dictionary.Find(key); if (result.HasValue) { / Use result.Key, result.Value. */ }

In C++ STL we've got similar pattern: get result handle (iterator—Option), compare it with sentinel (v.end()—Option.None), retrieve it from handle (dereferense—Option.Value).

Class Option can be implemented as in Elevate Library (http://elevate.codeplex.com/), for eaxmple.

ondfisk commented 12 years ago

Agreed the Option type of F# is a very neat solution.

However, C5 also tries to mimic the standard C# interfaces and programming styles and here the so called Try Get pattern is most often used. Cf. Krzysztof Cwalina, Brad Abrams: Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321246756).

C5 is currently littered with Try Get and it would be an enormous undertaking to convert these into Option type style - and also be a major breaking change it the old Try Get methods were not to remain in the library.