-
Notifications
You must be signed in to change notification settings - Fork 842
Update Tutorial Script #2122
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
Update Tutorial Script #2122
Conversation
|
|
||
|
|
||
| /// First some basics on integers and numbers | ||
| /// Modules are the primary way to organize functions and values in F#. This module contains some |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we explain the difference between // comments and triple-slash comments? It looks like a mix has been used in this document which could be confusing as to what the 'defacto' comment style is, and when/where each type should be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Called out the different comment types up top.
saul
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a really great addition to ease beginners into F#, especially if they're from an imperative background 👍
| printfn "The result of squaring the integer 4573 and adding 3 is %d" result1 | ||
|
|
||
| /// When needed, annotate the type of a parameter name using '(argument:type)' | ||
| /// When needed, annotate the type of a parameter name using '(argument:type)'. Parenthesis are required. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be using the plural of parenthesis (parentheses).
|
|
||
| /// Strings can also use @ to create a verbatim string literal | ||
| let string3 = @"c:\Program Files\" | ||
| /// Strings can also use @ to create a verbatim string literal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe explain that verbatim strings will ignore escape sequences such as \n, \t etc. It may also be useful to demonstrate the logical equivalent: "C:\Program Files\"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
| printfn "%s" (showPlayingCard card) | ||
|
|
||
| // Single-case DUs are often used for domain modeling. This can buy you extra type safety | ||
| // over primitive types such as strings and ints. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...as they cannot be implicitly cast to/from the type they wrap. For example, a function that takes a parameter of type Address will not accept a value of type string (and vice versa).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed (heh, that was a pun).
| elif item < x then Node(x, insert item left, right) // Call into left subtree. | ||
| else Node(x, left, insert item right) // Call into right subtree. | ||
|
|
||
| /// Discriminated Unions can also be represented as structs via the 'Struct' attribute. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When would you use this? Why would you prefer to use a struct DU over a reference DU?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed this with a basic statement. There should be some documentation somewhere where we could point to about structs v. reference types for performance, but since it's a bit of a tricky area that's subject to that specific code, I've opted not to explain anything here.
smoothdeveloper
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice showcase of the syntax for main constructs.
| /// | ||
| /// The second line below will fail to compile because of this. Uncomment it to see what happens. | ||
| let sampleStructTuple = struct (1, 2, 3) | ||
| //let thisWillNotCompile: (int*int) = struct (1, 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding
//let thisWillCompile: struct (int*int) = struct (1, 2)?
| /// A record is a collection of data items brought together into one object. | ||
|
|
||
| /// Records are an aggregate of named values, with optional members (such as methods). | ||
| /// They are immutable and have structural equality semantics. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// They are immutable by default and have structural equality semantics.| /// | ||
| /// This represents a Binary Search Tree, with one case being the Empty tree, | ||
| /// and the other being a Node with a value and two subtrees. | ||
| type 'T BST = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use BST<'T> notation to match dotnet syntax?
| // https://docs.microsoft.com/en-us/dotnet/articles/fsharp/ | ||
| // | ||
| // To see this tutorial in documentation form, see: | ||
| // https://docs.microsoft.com/en-us/dotnet/articles/fsharp/tour |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this URL stable?
|
|
||
| // Open namespaces using 'open' | ||
| // Open namespaces using the 'open' directive. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
directive? Maybe use "keyword" ?
forki
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great. only couple of minor suggestions
| /// Modules are the primary way to organize functions and values in F#. This module contains some | ||
| /// basic values involving basic numeric values computed in a few different ways. | ||
| /// | ||
| /// To learn more, see: https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/modules |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here. we need to make sure it's a stable url
| /// Conditionals use if/then/elid/elif/else. | ||
| /// | ||
| /// Note that F# uses whitespace indentation-aware syntax like Python. | ||
| /// Note that F# uses whitespace indentation-aware syntax, similar to languages like Python or Ruby. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC Ruby is not whitespace sensitive - then have things like end keywords. http://stackoverflow.com/a/17052327/145701
| let string4 = """The computer said "hello world" when I told it to!""" | ||
|
|
||
| /// String concatenation is '+'. Also see String.concat, System.String.Join and others. | ||
| /// String concatenation is normally done with the '+' operator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the normally should be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
normally seems fine here. There are after all other ways of concatenating strings..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It pretty much depends on context. If you do it in a big loop you "normally" want to use a string builder. But I'm fine with keeping it.
| /// Many other collection types are available in System.Collections.Generic, | ||
| /// System.Collections.Immutable and other libraries. | ||
| module ListsAndArrays = | ||
| /// Lists are ordered, immutable, singly-linked lists. They are eager in their evaluation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
immutability is a concept that is not used in many languages yet. Can we link to a definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually something covered in the documentation: https://docs.microsoft.com/en-us/dotnet/articles/fsharp/tour#functions-and-modules
letbindings are also how you bind a value to a name, similar to a variable in other languages.letbindings are immutable by default, which means that once a value or function is bound to a name, it cannot be changed in-place. This is in contrast to variables in other languages, which are mutable, meaning their values can be changed at any point in time. If you require a mutable binding, you can uselet mutable ...syntax.
I'm a bit wary about copying in that text (or something like it) into comments, but I agree that it should probably be mentioned near the beginning here and a link to some documentation ought to be provided.
| let list1 = [ ] | ||
|
|
||
| /// This is a list with 3 elements. | ||
| /// This is a list with 3 elements. ';' is used to separate elements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or line breaks. Please add a sample with line breaks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good feedback
| yield System.DateTime(2012, month, day) ] | ||
|
|
||
| // Print the first 5 elements of 'daysList' using 'List.take'. | ||
| printfn "The first 5 days of 2017 are: %A" (daysList |> List.take 5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did we already introduce the pipe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about this, and it's kind of difficult to introduce piping (and composition with >>) without also having Lists/Arrays/etc, since those are some of the most natural data structures to process data via a pipeline. I think that if we have pipelines prior to this section with some basic lists then it should be okay.
|
@cartermp
Thanks Kevin |
|
Awesome job! |
|
FYI the links are stable - both the docs.ms and MSDN links are backed by a redirect system, so if documents get moved around then it'll get handled appropriately. I'll prepare a module for mutability v. immutability and pipelines. |
|
That would be the first time Microsoft links are considered stable. ;-) But I trust you on this. |
| open Microsoft.FSharp.Data.UnitSystems.SI.UnitNames | ||
|
|
||
| /// Define a unitized constant | ||
| let sampelValue1 = 1600.0<meter> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a typo here sampelValue1
I've made quite a few changes to the Tutorial project to align it a bit more with the Tour of F# document. That means a few things:
|>pipelines and changing from%Ato a more concrete format type when possibleWhen this is merged (pending changes), I'll be updating the Tour document so that the backing code samples pull from this same source file. I'll probably be modifying a bit of the text, but there shouldn't be too much to change in that document.
I may also push another change which endeavors to add more
printfnstatements.cc @dsyme