Skip to content

Commit

Permalink
Put code under ```fsharp code quotes
Browse files Browse the repository at this point in the history
  • Loading branch information
smoothdeveloper committed Mar 1, 2016
1 parent a3b24a6 commit bb56035
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 75 deletions.
19 changes: 14 additions & 5 deletions RFCs/FS-1001-StringInterpolation.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,32 @@ There is an approved-in-principle [proposal](http://fslang.uservoice.com/forums/

### Proposal

Proposed syntax:
"%(**embedded expression**)"
Proposed syntax:

```fsharp
"%(**embedded expression**)"
```

Initial implementation prototype has been [submitted][3]. Prototype accepts arbitrary F# expression as **embedded expression**.
In prototype source string literal is split into chunks containing text and embedded expressions. Then chunks are joined using [String.Concat][4].

Initial string literal:

"%d%(foo)%d%(bar.bar)"
```fsharp
"%d%(foo)%d%(bar.bar)"
```

After splitting:

Text("%d"); Expression(foo); Text(%d); Expression(bar.bar)
```fsharp
Text("%d"); Expression(foo); Text(%d); Expression(bar.bar)
```

Final result

String.Concat([| "%d"; box foo; "%d"; box (bar.baz) |])
```fsharp
String.Concat([| "%d"; box foo; "%d"; box (bar.baz) |])
```

### Open questions:

Expand Down
4 changes: 3 additions & 1 deletion RFCs/FS-1002-cartesian-product-for-collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ This RFC covers the detailed proposal for this suggestion.

It's often useful to compute the Cartesian product (cross join) of two collections. Today users up writing something like this:

let cross xs ys = seq { for x in xs do for y in ys -> x, y }
```fsharp
let cross xs ys = seq { for x in xs do for y in ys -> x, y }
```

It would be useful to have this in the FSharp.Core standard collection modules. It would be added to
the Seq, List and Array modules in FSharp.Core.
Expand Down
55 changes: 29 additions & 26 deletions RFCs/FS-1005-underscores-in-numeric-literals.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ This is a popular feature in other languages. Some other languages with a simila

just to name a few...


# Detailed design
[design]: #detailed-design

Expand All @@ -41,34 +40,38 @@ You can place underscores only between digits. You cannot place underscores in t

Taken from the Java documentation, the following examples demonstrate valid examples:

let creditCardNumber = 1234_5678_9012_3456L
let socialSecurityNumber = 999_99_9999L
let pi = 3.14_15F
let hexBytes = 0xFF_EC_DE_5E
let hexWords = 0xCAFE_BABE
let maxLong = 0x7fff_ffff_ffff_ffffL
let nybbles = 0b0010_0101
let bytes = 0b11010010_01101001_10010100_10010010
```fsharp
let creditCardNumber = 1234_5678_9012_3456L
let socialSecurityNumber = 999_99_9999L
let pi = 3.14_15F
let hexBytes = 0xFF_EC_DE_5E
let hexWords = 0xCAFE_BABE
let maxLong = 0x7fff_ffff_ffff_ffffL
let nybbles = 0b0010_0101
let bytes = 0b11010010_01101001_10010100_10010010
```

Taken from the Java documentation, the following examples demonstrate valid and invalid underscore placements (which are highlighted) in numeric literals:

let pi1 = 3_.1415F // Invalid cannot put underscores adjacent to a decimal point
let pi2 = 3._1415F // Invalid cannot put underscores adjacent to a decimal point
let socialSecurityNumber1 = 999_99_9999_L // Invalid cannot put underscores prior to an L suffix

let x1 = _52 // This is an identifier, not a numeric literal
let x2 = 5_2 // OK (decimal literal)
let x3 = 52_ // Invalid cannot put underscores at the end of a literal
let x4 = 5_______2 // OK (decimal literal)

let x5 = 0_x52 // Invalid cannot put underscores in the 0x radix prefix
let x6 = 0x_52 // Invalid cannot put underscores at the beginning of a number
let x7 = 0x5_2 // OK (hexadecimal literal)
let x8 = 0x52_ // Invalid cannot put underscores at the end of a number

let x9 = 0_52 // OK (octal literal)
let x10 = 05_2 // OK (octal literal)
let x11 = 052_ // Invalid cannot put underscores at the end of a number
```fsharp
let pi1 = 3_.1415F // Invalid cannot put underscores adjacent to a decimal point
let pi2 = 3._1415F // Invalid cannot put underscores adjacent to a decimal point
let socialSecurityNumber1 = 999_99_9999_L // Invalid cannot put underscores prior to an L suffix
let x1 = _52 // This is an identifier, not a numeric literal
let x2 = 5_2 // OK (decimal literal)
let x3 = 52_ // Invalid cannot put underscores at the end of a literal
let x4 = 5_______2 // OK (decimal literal)
let x5 = 0_x52 // Invalid cannot put underscores in the 0x radix prefix
let x6 = 0x_52 // Invalid cannot put underscores at the beginning of a number
let x7 = 0x5_2 // OK (hexadecimal literal)
let x8 = 0x52_ // Invalid cannot put underscores at the end of a number
let x9 = 0_52 // OK (octal literal)
let x10 = 05_2 // OK (octal literal)
let x11 = 052_ // Invalid cannot put underscores at the end of a number
```

For QZRNG literals, the string passed to the library routine has underscores removed.

Expand Down
133 changes: 90 additions & 43 deletions RFCs/FS-1006-struct-tuples.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,34 +45,44 @@ to consider whether F# will import, produce and/or propagate this metadata.

The syntax of types, expressions and patterns is extended to include a struct annotation like this:

type = struct (type * ... * type)
| ...
```fsharp
type = struct (type * ... * type)
| ...
```

```fsharp
expr = struct (expr, ..., expr)
| ...
```

expr = struct (expr, ..., expr)
| ...

pat = struct (pat, ..., pat)
| ...
```fsharp
pat = struct (pat, ..., pat)
| ...
```

e.g.

```fsharp
let origin = struct (0,0)

let f (struct (x,y)) = x+y
```

The "structness" of tuple types would be propagated through
the F# type inference process through unification of structness annotations. So, for example

let origin2 = origin
```fsharp
let origin2 = origin
```

would infer that ``origin2`` has type ``struct (int * int)``.

Otherwise, wherever possible, the existing design of F# tuples applies.

No code would be generic over structness, so

let f (x,y) = x+y
```fsharp
let f (x,y) = x+y
```

would apply only to reference tuples, unless "f" has been applied to a struct tuple somewhere in the code. Multiple copies of tuple-related functions may be needed.

Expand All @@ -81,19 +91,27 @@ would apply only to reference tuples, unless "f" has been applied to a struct tu
Optionally, the "structness" of tuple expressions and patterns could be inferred through
the F# type inference process through the unification of structness annotations. So, for example

let (x0,y0) = origin
```fsharp
let (x0,y0) = origin
```

would be permitted, as the tuple pattern on the left is inferred to be a struct, rather than requiring

let (struct (x0,y0)) = origin
```fsharp
let (struct (x0,y0)) = origin
```

Likewise the structness of tuple expressions can be inferred:

let points : (struct (int * int)) list = [ (1,2); (3,4) ]
```fsharp
let points : (struct (int * int)) list = [ (1,2); (3,4) ]
```

rather than requiring a ``struct`` annotation on each struct expression:

let points : (struct (int * int)) list = [ struct (1,2); struct (3,4) ]
```fsharp
let points : (struct (int * int)) list = [ struct (1,2); struct (3,4) ]
```

At a technical level, every time a non-annotated tuple form is used, a structness inference parameter is created.
If structness can't be inferred for a structness inference variable, it will default to "not a struct", i.e. a reference type.
Expand All @@ -109,22 +127,30 @@ and may potentially confuse some users who prefer a high degree of type/expressi

C# 7.0 Named annotations already exist in the syntax of types like this:

type = idopt: type * ... * idopt: type
| ...
```fsharp
type = idopt: type * ... * idopt: type
| ...
```

and to expressions:

expr = (id=expr, ..., id=expr)
| ...
```fsharp
expr = (id=expr, ..., id=expr)
| ...
```

and to patterns:

pat = (id=pat, ..., id=pat)
| ...
```fsharp
pat = (id=pat, ..., id=pat)
| ...
```

e.g.

let f () = struct (x=1,y=1)
```fsharp
let f () = struct (x=1,y=1)
```

### Type equivalence

Expand Down Expand Up @@ -176,19 +202,27 @@ TBD: We must decide if this will also apply to struct tuples.

F# has a special rule that adds subtype-flexibility when a function value is used, e.g.

let f (x: IComparable) = ...

```fsharp
let f (x: IComparable) = ...
```

can be called using any value that supports IComparable, because each use of ``f`` is implicitly replaced by a coercing expression:

(fun (x: #IComparable) -> f (x :> IComparable))
```fsharp
(fun (x: #IComparable) -> f (x :> IComparable))
```

This also applies to tupled arguments, e.g.

let f (x1: IComparable, x2: IComparable) = ...
```fsharp
let f (x1: IComparable, x2: IComparable) = ...
```

becomes

(fun (x1: #IComparable, x2: #IComparable) -> f (x1 :> IComparable, x2 :> IComparable))
```fsharp
(fun (x1: #IComparable, x2: #IComparable) -> f (x1 :> IComparable, x2 :> IComparable))
```

TBD: We must decide if this will also apply to functions taking struct tuples, and whether this would be consistently applied to members taking struct tuples too.

Expand All @@ -197,21 +231,26 @@ TBD: We must decide if this will also apply to functions taking struct tuples, a
In F#, like most other ML langauges, some simple values can be generalized.
This means these values are given generic type rather than hitting the value-restriction error. e.g.

let x = null
val x : 'a when 'a : null

let x = []
val x : 'a list
```fsharp
let x = null
val x : 'a when 'a : null
let x = []
val x : 'a list
```

This extends to tuples of these values:

let x = ([], [])
val x : 'a list * 'b list
TBD: decide if this extends to struct tuples.
```fsharp
let x = ([], [])
val x : 'a list * 'b list
```

let x = struct ([], [])
TBD: decide if this extends to struct tuples.

```fsharp
let x = struct ([], [])
```

# Drawbacks
[drawbacks]: #drawbacks
Expand Down Expand Up @@ -249,13 +288,17 @@ it would be a breaking change to the binary compatibility of F# code.

The syntax above assumes that parentheses are needed:

struct (int * int)
struct (3,4)
```fsharp
struct (int * int)
struct (3,4)
```

rather than

struct int * int
struct 3,4
```fsharp
struct int * int
struct 3,4
```

This seems reasonable.

Expand Down Expand Up @@ -287,11 +330,15 @@ efficiently is this implemented?

The syntax chosen may induce ambiguities, e.g.

type X = struct val X : int end

```fsharp
type X = struct val X : int end
```

v.s. a type abbreviation:

type X = struct (int * int)
```fsharp
type X = struct (int * int)
```

This may be particularly problematic w.r.t. whitespace indentation rules, where ``end`` is meant to balance the ``struct`` token.
However it should be possible to lookahead one token after the "struct" and avoid the use of the relevant offside processing
Expand Down

0 comments on commit bb56035

Please sign in to comment.