fsharp / fsharp/fslang-suggestions
Define properties using `let public`
- Dominant language
- No language data
- Stars
- 373
- Forks
- 21
- PR merge metrics
- No merged PRs in 30d
Description
# Define properties [edit: and public fields] using `let public`
An example class with current syntax:
```fsharp
type A() =
let u = 0
static let v = 1
member _.U = u
member t.W(i) = t.X + i + v
member t.X(i) = if i = 0 then 1 else t.X(i-1) * v
static member Y(i) = i + v
```
I propose we add `let public` syntax to expose properties. The class could then be rewritten as:
```fsharp
type A() =
let public U = 0
static let v = 1
let rec public X(i) = if i = 0 then 1 else X(i-1) * v
let public W(i) = X + i + v
static let public Y(i) = i + v
```
## Pros and Cons
### Pros:
1.
a) The common pattern `let u = ...` followed by `member _.U = u` can be replaced by the single line `let public u = ...`.
b) The cumbersome `_.` unused bindings are not present. (They would also be removed if https://github.com/fsharp/fslang-suggestions/issues/626 is implemented.)
2. Sequential ordering with explicit recursion is enforced, as usual in F# code, with the usual benefit of being able to understand code by reading it in sequentially. (Note that the second version swaps W and X and is easier to understand as a result.)
Current F# class code is a tradeoff between 1. and 2. If you use more `let u = ...; member _.U = u` you get the benefits of code order at the expense of verbosity. This suggestion would remove that tradeoff.
### Cons:
1. The public API of a class can no longer be found by looking at the bottom of the class definition.
2. It's another way of doing the same thing, and properties with setters would still need to be implemented with the current `member...` syntax.
## Notes
`let public U = f()` would be equivalent to `let u = f()` followed by `member _.U = u`, so `f()` is only evaluated once.
There would be no way to replicate `member _.SayHello = printf "hello world"` using this syntax, although `member _.SayHello() = printf "hello world"` could be done as `let public SayHello() = ...`. Arguably this is an advantage as the fact that properties without arguments execute their bodies whenever called is a fact that can surprise beginners and catch out experienced users.
## Extra information
Estimated cost (XS, S, M, L, XL, XXL):
L
## Affidavit (please submit!)
Please tick this by placing a cross in the box:
* [ x ] This is not a question (e.g. like one you might ask on [stackoverflow](http://stackoverflow.com)) and I have searched stackoverflow for discussions of this issue
* [ x ] I have [searched both open and closed suggestions on this site](http://github.com/fsharp/fslang-suggestions/issues) and believe this is not a duplicate
* [ x ] This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.
Please tick all that apply:
* [ x ] This is not a breaking change to the F# language design
* [ x ] I or my company would be willing to help implement and/or test this
Contributor guide
No contributing guide indexed for this repository
Research direction
No implementation files, tests, or entry points are named in the issue. Before picking it up, establish where F# class `let` and `member` syntax is parsed and tested; done would require an accepted design, implementation, and tests for the proposed forms.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- fsharp
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100