From bb56035c0a3ef6218d77e268842e8c813aeb144b Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Tue, 1 Mar 2016 16:09:05 +0100 Subject: [PATCH] Put code under ```fsharp code quotes --- RFCs/FS-1001-StringInterpolation.md | 19 ++- ...-1002-cartesian-product-for-collections.md | 4 +- ...FS-1005-underscores-in-numeric-literals.md | 55 ++++---- RFCs/FS-1006-struct-tuples.md | 133 ++++++++++++------ 4 files changed, 136 insertions(+), 75 deletions(-) diff --git a/RFCs/FS-1001-StringInterpolation.md b/RFCs/FS-1001-StringInterpolation.md index 93b77532..e974dd43 100644 --- a/RFCs/FS-1001-StringInterpolation.md +++ b/RFCs/FS-1001-StringInterpolation.md @@ -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: diff --git a/RFCs/FS-1002-cartesian-product-for-collections.md b/RFCs/FS-1002-cartesian-product-for-collections.md index 9b7ee8ce..1b4b145c 100644 --- a/RFCs/FS-1002-cartesian-product-for-collections.md +++ b/RFCs/FS-1002-cartesian-product-for-collections.md @@ -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. diff --git a/RFCs/FS-1005-underscores-in-numeric-literals.md b/RFCs/FS-1005-underscores-in-numeric-literals.md index 85a37aac..00b13ea2 100644 --- a/RFCs/FS-1005-underscores-in-numeric-literals.md +++ b/RFCs/FS-1005-underscores-in-numeric-literals.md @@ -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 @@ -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. diff --git a/RFCs/FS-1006-struct-tuples.md b/RFCs/FS-1006-struct-tuples.md index e30e519b..d33c5729 100644 --- a/RFCs/FS-1006-struct-tuples.md +++ b/RFCs/FS-1006-struct-tuples.md @@ -45,26 +45,34 @@ 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)``. @@ -72,7 +80,9 @@ 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. @@ -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. @@ -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 @@ -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. @@ -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 @@ -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. @@ -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