fsharp / fsharp/fslang-suggestions

Allow defining custom literal syntax for creating collections

Open
#625 30 comments 34 reactions 0 assignees View on GitHub
area: lists-arrays-sequences
Dominant language
No language data
Stars
373
Forks
21
PR merge metrics
No merged PRs in 30d

Description

I propose we allow custom literal syntax to be defined for creating user-defined collections. E.g., the syntax `[ ... ]`, which currently is reserved for creating lists, could be declared to build an array, or a mathematical vector, or a PersistentVector from FSharpx.Collections, as long as the appropriate type (and how to construct the literal) can be determined at compile-time.

The existing way of approaching this problem in F# is to use `[| ... |]` syntax for arrays, and to use something like `Vector.ofList [ 1; 2; 3 ]` for other types, which tends to be uglier and/or harder to type than plain `[ 1; 2; 3 ]`.

## Rationale

In https://github.com/fsharp/fslang-suggestions/issues/619#issuecomment-345557586, @piaste made an interesting observation:

> I think one major reason people currently use Lists by default, even when they don't need a linked list at all and it just hurts performance, is that it has the cleanest literal syntax available in F#.
>
> Notably, both Fable-React and Websharper go with lists. In their HTML DSLs, every element is followed by two collections (attributes and inner HTML) and even using a basic array would start to look 'noisy' really fast (`div [||] [| foo |]` versus `div [] [ foo ]`) ...

This triggered a discussion which let to @dsyme [suggesting the following](https://github.com/fsharp/fslang-suggestions/issues/619#issuecomment-346669831) as a possible approach:

> Have the `[ ... ]` syntax resolved in a type-directed way (e.g. "if the target type is known to be a collection C with a builder pattern or IEnumerable constructor, then treat the syntax as if it is constructing a C, otherwise treat it as a regular F# list")) ...

Many people seemed to like the idea, so I've created this issue to track that particular suggestion.

## Pros and Cons

The advantages of making this adjustment to F# are that many user-defined data types will appear a lot "cleaner" to use. For example, if someone adds a [Relaxed Radix-Balanced vector type](http://hypirion.com/thesis) to FSharpx.Collections, creating one would be as simple as:

```fsharp
let vec : RRBVector<_> = [ 1; 2; 3 ]
```

Then if the primary constructor for RRBVector takes an array, then the `[ 1; 2; 3 ]` syntax would be turned into an array at compile-time and then passed to the RRBVector constructor at runtime. (In many cases, the type of `vec` would be determinable by type inference and it wouldn't be necessary to specify its type explicitly like this).

The disadvantages of making this adjustment to F# are twofold: first, there would be a significant amount of effort involved. Second, the `[ ... ]` syntax would become more "generic" and more cases like value restriction could be created. E.g., `let coll = []` would now not only need to determine the type of the *contents* of `coll`, but also the type of the collection itself, before that code could compile.

This would be a **breaking change** to F#.

## Extra information

Estimated cost (XS, S, M, L, XL, XXL): L

Related suggestions: #49 is a subset of this idea, and #619 is the discussion that led to this idea.

## 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:
* [ ] This is not a breaking change to the F# language design
* [ ] 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

Start by reading the discussion linked from #619 and the related suggestion #49, then review the proposal's examples and stated breaking-change concerns. A useful outcome would be a settled language-design direction that specifies how custom collection literals are resolved and what compatibility implications must be addressed.

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
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.