Skip to content

Commit a438dd2

Browse files
authored
Apply Markdown lint (#43)
Just a small attempt to make all markdown files consistent and formatted in line with the current best practices. I've also added a lint GHA job to prevent drifting away from this baseline in the future.
1 parent a0d0ffb commit a438dd2

24 files changed

+2967
-1322
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Markdown Lint
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
lint:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v4
10+
with:
11+
fetch-depth: 0
12+
- uses: tj-actions/changed-files@v45
13+
id: changed-files
14+
with:
15+
files: '**/*.md'
16+
separator: ","
17+
- uses: DavidAnson/markdownlint-cli2-action@v19
18+
if: steps.changed-files.outputs.any_changed == 'true'
19+
with:
20+
globs: ${{ steps.changed-files.outputs.all_changed_files }}
21+
separator: ","

.markdownlint-cli2.jsonc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
// Enable all rules by default
3+
"default": true,
4+
5+
// Line length: increase default from 80
6+
"MD013": {
7+
"line_length": 100,
8+
"code_blocks": false,
9+
"tables": false
10+
},
11+
12+
// Allow duplicate headers in different nested sections
13+
"MD024": {
14+
"allow_different_nesting": true
15+
},
16+
17+
// Allow inline HTML
18+
"MD033": false,
19+
20+
// First line in a file doesn't need to be a top-level header
21+
"MD041": false,
22+
}

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# fslang-spec
2+
23
F# Language Specification
34

45
## Overview
@@ -8,6 +9,7 @@ This is an initiative to create a more complete and community-maintainable F# sp
89
This will be no small task, but we believe it is worthwhile and we count on community contributions.
910

1011
We foresee three phases:
12+
1113
1. Convert the [latest official spec](https://fsharp.org/specs/language-spec/4.1/FSharpSpec-4.1-latest.pdf) to markdown and create the structure and tools to make it community-maintainable. This is done.
1214
2. Add the post-4.1 features as documented in the [RFCs](https://github.com/fsharp/fslang-design/) to the spec. Our goal: a complete F# 10 spec.
1315
3. Make spec update part of new feature development so that an up-to-date spec can be released with every new major compiler release.
@@ -151,4 +153,3 @@ The sources are the markdown files for the chapters (clauses) in the `spec` dire
151153
Run `build` to create a new complete spec (including ToC and updated reference links) in your `artifacts` directory.
152154

153155
At certain points, releases are created and published in the `releases` directory.
154-

releases/FSharp-Spec-4.1.2024-10-02.md

Lines changed: 946 additions & 412 deletions
Large diffs are not rendered by default.

releases/FSharp-Spec-latest.md

Lines changed: 946 additions & 414 deletions
Large diffs are not rendered by default.

spec/basic-grammar-elements.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,33 @@ active-pattern-op-name :=
2222
| | ident | ... | ident |
2323
| | ident | ... | ident | _ |
2424
```
25+
2526
In operator definitions, the operator name is placed in parentheses. For example:
2627

2728
```fsgrammar
2829
let (+++) x y = (x, y)
2930
```
31+
3032
This example defines the binary operator `+++`. The text `(+++)` is an `ident-or-op` that acts as an
3133
identifier with associated text `+++`. Likewise, for active pattern definitions (§ 7), the active pattern
3234
case names are placed in parentheses, as in the following example:
3335

3436
```fsgrammar
3537
let (|A|B|C|) x = if x < 0 then A elif x = 0 then B else C
3638
```
39+
3740
Because an `ident-or-op` acts as an identifier, such names can be used in expressions. For example:
3841

3942
```fsgrammar
4043
List.map ((+) 1) [ 1; 2; 3 ]
4144
```
45+
4246
The three character token `(*)` defines the `*` operator:
4347

4448
```fsgrammar
4549
let (*) x y = (x + y)
4650
```
51+
4752
To define other operators that begin with `*`, whitespace must follow the opening parenthesis;
4853
otherwise `(*` is interpreted as the start of a comment:
4954

@@ -149,6 +154,7 @@ long-ident-or-op :=
149154
| long-ident '.' ident-or-op
150155
| ident-or-op
151156
```
157+
152158
## Constants
153159

154160
The constants in the following table may be used in patterns and expressions. The individual lexical
@@ -178,6 +184,7 @@ const :=
178184
| false | true -- Boolean constant of type "bool"
179185
| '(' ')' -- unit constant of type "unit"
180186
```
187+
181188
## Operators and Precedence
182189

183190
### Categorization of Symbolic Operators
@@ -215,10 +222,12 @@ prefix operators include the `~` character:
215222
// To completely redefine the prefix + operator:
216223
let (~+) x = x
217224
```
225+
218226
```fsgrammar
219227
// To completely redefine the infix + operator to be addition modulo- 7
220228
let (+) a b = (a + b) % 7
221229
```
230+
222231
```fsgrammar
223232
// To define the operator on a type:
224233
type C(n:int) =
@@ -229,6 +238,7 @@ let n = n % 7
229238
static member (+) (x1:C,x2:C) = C(x1.N+x2.N)
230239
static member (-) (x1:C,x2:C) = C(x1.N-x2.N)
231240
```
241+
232242
The `::` operator is special. It represents the union case for the addition of an element to the head of
233243
an immutable linked list, and cannot be redefined, although it may be used to form infix expressions.
234244
It always accepts arguments in tupled form — as do all union cases — rather than in curried form.
@@ -284,7 +294,8 @@ For example, consider the following token stream:
284294
```fsharp
285295
a + b * c
286296
```
287-
In this expression, the `expr infix-op expr` rule for `b * c` takes precedence over the
297+
298+
In this expression, the `expr infix-op expr` rule for `b * c` takes precedence over the
288299
`expr infix-op expr` rule for `a + b`, because the `*` operator has higher precedence than the `+` operator. Thus, this
289300
expression can be pictured as follows:
290301

@@ -293,18 +304,21 @@ expression can be pictured as follows:
293304
// _________
294305
// _____
295306
```
307+
296308
rather than
297309

298310
```fsharp
299311
a + b * c
300312
// _________
301313
// _____
302314
```
315+
303316
Likewise, given the tokens
304317

305318
```fsharp
306319
a * b * c
307320
```
321+
308322
the left associativity of `*` means we can picture the resolution of the ambiguity as:
309323

310324
```fsharp

spec/custom-attributes-and-reflection.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ attribute-target :=
2525
constructor
2626
event
2727
```
28+
2829
## Custom Attributes
2930

3031
CLI languages support the notion of _custom attributes_ which can be added to most declarations.
@@ -41,6 +42,7 @@ expressions. Attributes on parameters are given as follows:
4142
```fsharp
4243
let foo([<SomeAttribute>] a) = a + 5
4344
```
45+
4446
If present, the arguments to a custom attribute must be _literal constant expressions_ , or arrays of the
4547
same.
4648

@@ -60,6 +62,7 @@ type Foo1 [<System.Obsolete("don't use me")>] () =
6062
type Foo2 [<System.Obsolete("don't use me")>] private () =
6163
member x.Bar() = 1
6264
```
65+
6366
Custom attributes are mapped to compiled CLI metadata as follows:
6467

6568
- Custom attributes map to the element that is specified by their target, if a target is given.
@@ -71,8 +74,8 @@ Custom attributes are mapped to compiled CLI metadata as follows:
7174
that is named `_F`.
7275
- A custom attribute on a union case `ABC` for a type `T` is compiled to a custom attribute on a static
7376
method on the CLI type definition `T`. This method is called:
74-
- `get_ABC` if the union case takes no arguments
75-
- `ABC` otherwise
77+
- `get_ABC` if the union case takes no arguments
78+
- `ABC` otherwise
7679
- Custom attributes on arguments are propagated only for arguments of member definitions, and
7780
not for “let”-bound function definitions.
7881
- Custom attributes on generic parameters are not propagated.
@@ -147,7 +150,6 @@ In addition:
147150
`System.Type` object, although the `System.Type` object is not accessible by using the `typeof`
148151
operator.
149152

150-
151153
However:
152154

153155
- Internal and private function and value definitions are not guaranteed to be given corresponding
@@ -158,5 +160,3 @@ However:
158160
abbreviations and F# unit-of-measure annotations.
159161
- The definition of new units of measure results in corresponding compiled CLI type declarations
160162
with an associated `System.Type`.
161-
162-

0 commit comments

Comments
 (0)