Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] FsharpForFunAndProfit (GitBook): "Why use F#?" series #29

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
4700b12
Добавлены исходники оригинала
ArtemyB Oct 10, 2017
f626dec
Перевод "Why use F# on one page" + содержание цикла статей (1-я версия).
ArtemyB Oct 10, 2017
f5e28b2
Небольшие исправления
ArtemyB Oct 10, 2017
c045749
Оформил исходный (англ.) текст в виде цитат
ArtemyB Oct 11, 2017
aec157b
Подправил форматирование в фрагментах F#-кода
ArtemyB Oct 11, 2017
ce4e393
Подготовка к переводу "F# syntax in 60 seconds"
ArtemyB Oct 12, 2017
53e4294
1-я версия перевода "F# syntax in 60 seconds"
ArtemyB Oct 13, 2017
c6d179b
Подготовка к переводу "Introduction to the 'Why use F#' series"
ArtemyB Oct 15, 2017
f455b26
1-я версия перевода "Introduction to the 'Why use F#' series"
ArtemyB Jan 10, 2018
4097402
Подготовка к переводу "Comparing F# with C#: A simple sum"
ArtemyB Jan 10, 2018
260702f
Завершение перевода "Comparing F# with C#: A simple sum". Нужна проверка
ArtemyB Apr 11, 2018
5f4b8bf
Подготовка к переводу "Comparing F# with C#: Sorting"
ArtemyB Apr 11, 2018
05d5f8b
Завершение перевода "Comparing F# with C#: Sorting"; нужна проверка
ArtemyB Apr 12, 2018
4bcc21e
Подготовка к переводу "Comparing F# with C#: Downloading a web page"
ArtemyB Apr 12, 2018
33f881d
Завершение перевода "Comparing F# with C#: Downloading a web page"; н…
ArtemyB Apr 12, 2018
7141b99
Подготовка к переводу "Four Key Concepts"
ArtemyB Apr 12, 2018
9143a60
Завершение перевода "Four Key Concepts"; нужна проверка
ArtemyB Apr 12, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Why use F#/origin/assets/img/ShoppingCart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
240 changes: 240 additions & 0 deletions Why use F#/origin/posts/completeness-anything-csharp-can-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
---
layout: post
title: "Anything C# can do..."
description: "A whirlwind tour of object-oriented code in F#"
nav: why-use-fsharp
seriesId: "Why use F#?"
seriesOrder: 29
categories: [Completeness]
---

As should be apparent, you should generally try to prefer functional-style code over object-oriented code in F#, but in some situations, you may need all the features of a fully fledged OO language ? classes, inheritance, virtual methods, etc.

So just to conclude this section, here is a whirlwind tour of the F# versions of these features.

Some of these will be dealt with in much more depth in a later series on .NET integration. But I won't cover some of the more obscure ones, as you can read about them in the MSDN documentation if you ever need them.

## Classes and interfaces ##

First, here are some examples of an interface, an abstract class, and a concrete class that inherits from the abstract class.

```fsharp
// interface
type IEnumerator<'a> =
abstract member Current : 'a
abstract MoveNext : unit -> bool

// abstract base class with virtual methods
[<AbstractClass>]
type Shape() =
//readonly properties
abstract member Width : int with get
abstract member Height : int with get
//non-virtual method
member this.BoundingArea = this.Height * this.Width
//virtual method with base implementation
abstract member Print : unit -> unit
default this.Print () = printfn "I'm a shape"

// concrete class that inherits from base class and overrides
type Rectangle(x:int, y:int) =
inherit Shape()
override this.Width = x
override this.Height = y
override this.Print () = printfn "I'm a Rectangle"

//test
let r = Rectangle(2,3)
printfn "The width is %i" r.Width
printfn "The area is %i" r.BoundingArea
r.Print()
```

Classes can have multiple constructors, mutable properties, and so on.

```fsharp
type Circle(rad:int) =
inherit Shape()

//mutable field
let mutable radius = rad

//property overrides
override this.Width = radius * 2
override this.Height = radius * 2

//alternate constructor with default radius
new() = Circle(10)

//property with get and set
member this.Radius
with get() = radius
and set(value) = radius <- value

// test constructors
let c1 = Circle() // parameterless ctor
printfn "The width is %i" c1.Width
let c2 = Circle(2) // main ctor
printfn "The width is %i" c2.Width

// test mutable property
c2.Radius <- 3
printfn "The width is %i" c2.Width
```

## Generics ##

F# supports generics and all the associated constraints.

```fsharp
// standard generics
type KeyValuePair<'a,'b>(key:'a, value: 'b) =
member this.Key = key
member this.Value = value

// generics with constraints
type Container<'a,'b
when 'a : equality
and 'b :> System.Collections.ICollection>
(name:'a, values:'b) =
member this.Name = name
member this.Values = values
```

## Structs ##

F# supports not just classes, but the .NET struct types as well, which can help to boost performance in certain cases.

```fsharp

type Point2D =
struct
val X: float
val Y: float
new(x: float, y: float) = { X = x; Y = y }
end

//test
let p = Point2D() // zero initialized
let p2 = Point2D(2.0,3.0) // explicitly initialized
```

## Exceptions ##

F# can create exception classes, raise them and catch them.

```fsharp
// create a new Exception class
exception MyError of string

try
let e = MyError("Oops!")
raise e
with
| MyError msg ->
printfn "The exception error was %s" msg
| _ ->
printfn "Some other exception"
```

## Extension methods ##

Just as in C#, F# can extend existing classes with extension methods.

```fsharp
type System.String with
member this.StartsWithA = this.StartsWith "A"

//test
let s = "Alice"
printfn "'%s' starts with an 'A' = %A" s s.StartsWithA

type System.Int32 with
member this.IsEven = this % 2 = 0

//test
let i = 20
if i.IsEven then printfn "'%i' is even" i
```

## Parameter arrays ##

Just like C#'s variable length "params" keyword, this allows a variable length list of arguments to be converted to a single array parameter.

```fsharp
open System
type MyConsole() =
member this.WriteLine([<ParamArray>] args: Object[]) =
for arg in args do
printfn "%A" arg

let cons = new MyConsole()
cons.WriteLine("abc", 42, 3.14, true)
```

## Events ##

F# classes can have events, and the events can be triggered and responded to.

```fsharp
type MyButton() =
let clickEvent = new Event<_>()

[<CLIEvent>]
member this.OnClick = clickEvent.Publish

member this.TestEvent(arg) =
clickEvent.Trigger(this, arg)

// test
let myButton = new MyButton()
myButton.OnClick.Add(fun (sender, arg) ->
printfn "Click event with arg=%O" arg)

myButton.TestEvent("Hello World!")
```

## Delegates ##

F# can do delegates.

```fsharp
// delegates
type MyDelegate = delegate of int -> int
let f = MyDelegate (fun x -> x * x)
let result = f.Invoke(5)
```

## Enums ##

F# supports CLI enums types, which look similar to the "union" types, but are actually different behind the scenes.

```fsharp
// enums
type Color = | Red=1 | Green=2 | Blue=3

let color1 = Color.Red // simple assignment
let color2:Color = enum 2 // cast from int
// created from parsing a string
let color3 = System.Enum.Parse(typeof<Color>,"Green") :?> Color // :?> is a downcast

[<System.FlagsAttribute>]
type FileAccess = | Read=1 | Write=2 | Execute=4
let fileaccess = FileAccess.Read ||| FileAccess.Write
```

## Working with the standard user interface ##

Finally, F# can work with the WinForms and WPF user interface libraries, just like C#.

Here is a trivial example of opening a form and handling a click event.

```fsharp
open System.Windows.Forms

let form = new Form(Width= 400, Height = 300, Visible = true, Text = "Hello World")
form.TopMost <- true
form.Click.Add (fun args-> printfn "the form was clicked")
form.Show()
```

22 changes: 22 additions & 0 deletions Why use F#/origin/posts/completeness-intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
layout: post
title: "Completeness"
description: "F# is part of the whole .NET ecosystem"
nav: why-use-fsharp
seriesId: "Why use F#?"
seriesOrder: 27
categories: [Completeness]
---

In this final set of posts, we will look at some other aspects of F# under the theme of "completeness".

Programming languages coming from the academic world tend to focus on elegance and purity over real-world usefulness, while more mainstream business languages such as C# and Java are valued precisely because they are pragmatic; they can work in a wide array of situations and have extensive tools and libraries to meet almost every need. In other words, to be useful in the enterprise, a language needs to be *complete*, not just well-designed.

F# is unusual in that it successfully bridges both worlds. Although all the examples so far have focused on F# as an elegant functional language, it does support an object-oriented paradigm as well, and can integrate easily with other .NET languages and tools. As a result, F# is not a isolated island, but benefits from being part of the whole .NET ecosystem.

The other aspects that make F# "complete" are being an official .NET language (with all the support and documentation that that entails) and being designed to work in Visual Studio (which provides a nice editor with IntelliSense support, a debugger, and so on). These benefits should be obvious and won't be discussed here.

So, in this last section, we'll focus on two particular areas:

* **Seamless interoperation with .NET libraries**. Obviously, there can be a mismatch between the functional approach of F# and the imperative approach that is designed into the base libraries. We'll look at some of the features of F# that make this integration easier.
* **Full support for classes and other C# style code**. F# is designed as a hybrid functional/OO language, so it can do almost everything that C# can do as well. We'll have a quick tour of the syntax for these other features.
Loading