what are pros and cons to use ArrayList instead generic collection in NET 2.0
Generic collections are type-safe - you cannot put a string into a List<int> - and don't require constant boxing/unboxing from object.
ArrayList on the other hand can handle a mix of different elements - this can be a plus in certain cases.
My take: typically I always use List<T> - unless I really need something that can handle int, string, DateTime etc. at the same time (very rare occasions).
Related
F# has multiple ways to declare the same types. This is likely because of the dual lineage of F# as both a member of the ML family and a .NET language. I haven't been able to find any guidance on which style is more idiomatic.
Specifically, I want to know:
Which is more idiomatic for 64-bit IEEE 754 floating-point numbers in F#, float or double?
Which is a more idiomatic way in F# to declare an array type:
int[]
int array
array<int>
Sources:
https://learn.microsoft.com/dotnet/fsharp/language-reference/basic-types
https://learn.microsoft.com/dotnet/fsharp/language-reference/fsharp-types#syntax-for-types
Context: I'm working on some API documentation that is explaining how data in a data store maps to .NET types, along with how those types are typically declared in both C# and F#.
For doubles, it's pretty much always float. Unless you deal with both singles and doubles and need to ensure clarity I guess.
For generic types, the usual syntax I use and see people use is:
int option
int list
int[]
For all other types, including F#-specific ones like Async, Set, and Map, angle bracket syntax is used.
The only type that I feel has a significant split is seq (an alias for IEnumerable): I'd say the majority of people use seq<int> but a significant number of people write int seq. Either way, you should definitely use seq and not IEnumerable. Similarly, you should use the alias ResizeArray for System.Collections.Generic.List.
The F# Core Library reference, which seems like a good example to follow, seems to prefer float, int[] and seq<int>.
Why cannot we change the instance properties from within the instance methods in Swift for the Value Types like struct, enums? Why does the same thing works for reference types like Classes?
Doing mutating func in struct makes it act like a class instance method?
The design of Swift was heavily influenced by functional programming languages such as Haskell, F#, Scala, Erlang, etc. One of the core principles of functional programming is that data is immutable. Functions operate on the data and produce new values as a result rather than modifying the data in place which eliminates side effects. These influences are seen in many places in Swift such as immutable value types, the map function, lambda functions, optional values, and pattern matching (switch in Swift).
I am trying to port a small compiler from C# to F# to take advantage of features like pattern matching and discriminated unions. Currently, I am modeling the AST using a pattern based on System.Linq.Expressions: A an abstract base "Expression" class, derived classes for each expression type, and a NodeType enum allowing for switching on expressions without lots of casting. I had hoped to greatly reduce this using an F# discriminated union, but I've run into several seeming limitations:
Forced public default constructor (I'd like to do type-checking and argument validation on expression construction, as System.Linq.Expressions does with it's static factory methods)
Lack of named properties (seems like this is fixed in F# 3.1)
Inability to refer to a case type directly. For example, it seems like I can't declare a function that takes in only one type from the union (e. g. let f (x : TYPE) = x compiles for Expression (the union type) but not for Add or Expression.Add. This seems to sacrifice some type-safety over my C# approach.
Are there good workarounds for these or design patterns which make them less frustrating?
I think, you are stuck a little too much with the idea that a DU is a class hierarchy. It is more helpful to think of it as data, really. As such:
Forced public default constructor (I'd like to do type-checking and argument validation on expression construction, as
System.Linq.Expressions does with it's static factory methods)
A DU is just data, pretty much like say a string or a number, not functionality. Why don't you make a function that returns you an Expression option to express, that your data might be invalid.
Lack of named properties (seems like this is fixed in F# 3.1)
If you feel like you need named properties, you probably have an inappropriate type like say string * string * string * int * float as the data for your Expression. Better make a record instead, something like AddInfo and make your case of the DU use that instead, like say | Add of AddInfo. This way you have properties in pattern matches, intellisense, etc.
Inability to refer to a case type directly. For example, it seems like I can't declare a function that takes in only one type from the
union (e. g. let f (x : TYPE) = x compiles for Expression (the union
type) but not for Add or Expression.Add. This seems to sacrifice some
type-safety over my C# approach.
You cannot request something to be the Add case, but you definitely do can write a function, that takes an AddInfo. Plus you can always do it in a monadic way and have functions that take any Expression and only return an option. In that case, you can pattern match, that your input is of the appropriate type and return None if it is not. At the call site, you then can "use" the value in the good case, using functions like Option.bind.
Basically try not to think of a DU as a set of classes, but really just cases of data. Kind of like an enum.
You can make the implementation private. This allows you the full power of DUs in your implementation but presents a limited view to consumers of your API. See this answer to a related question about records (although it also applies to DUs).
EDIT
I can't find the syntax on MSDN, but here it is:
type T =
private
| A
| B
private here means "private to the module."
Which way is more idiomatic to use Nullable<'a> or to use Option<'a> for representing a nullable int?
Option is far more idiomatic in F# code.
It has far nicer syntax when used in match and has large amounts of support from the standard library.
However, if you plan to access the code from C# or some other language you should probably expose the interface with Nullable which is easier to use in C#.
As John said, Option<T> is definitely more idiomatic type in F#. I would certainly use options as my default choice - the Option module provides many useful functions, pattern matching works nicely on options and F# libraries are generally designed to work with options.
That said, there are two cases when you might want to use nullable:
When creating arrays of optional values - Nullable<T> is a value type (sort of) and if you create an array Nullable<T>[] then it is allocated as continuous memory block. On the other hand options are reference types and option<T>[] will be an array of references to heap-allocated objects.
When you need to write some calculations and propagate missing values - in F# 3.0, there is a module Microsoft.FSharp.Linq.NullableOperators which implements various operators for dealing with nullable values (see MSDN documentation) which lets you write e.g.:
let one = Nullable(1)
let two = Nullable(2)
// Add constant to nullable, then compare value of two nullables
(one ?+ 2) ?>=? two
I have implemented IEnumerable for a collection I built, and (although I have not tested them all) the Seq values appear to work correctly. Is it possible to override some Seq values, for instance "last", when the native performance of a value of my collection is better than using Seq's IEnumerable based function? I have not found any information on overriding Seq.
No -- the functions in the Seq module can't be overridden. However, some of them do try to optimize performance by checking their input value (the seq<'T> instance you pass them) to see if it's an instance of IList<'T> or 'T[]; if it is, the functions will take some optimized code path. For example, if you pass an array ('T[]) to Seq.length, it'll be able to quickly determine the length by using the .Length property of arrays.
If you're stuck on using the Seq module, the only performance optimization I can think of would be to have your collection also implement ICollection<'T> and/or IList<'T>. That may optimize some cases, but it won't be all cases.
As already said in the other answer, there is no way you can override the functions in the Seq module. If you're implementing a custom collection, then the best thing to do is to follow the standard pattern used by the core F# libraries.
The Seq module contains the most often used functions and functions that can be reasonably provided for any sequence.
Modules like Array or List provide more efficient implementations for a specific collection type and they add more functions (not available in Seq) that are specific to the collection (for example, functions List.tail and Array.get).
The best way when adding your own collection is to follow this pattern:
Implement IEnumerable<'T> so that the functions from Seq module work for your type
Create MyCollection module that contains efficient implementations of standard functions (at least those that matter to you) and adds more functionality that is specific to your collection.