fsharp / fslang-suggestions

The place to make suggestions, discuss and vote on F# language and core library features
345 stars 21 forks source link

A normative immutable array type #619

Open dsyme opened 6 years ago

dsyme commented 6 years ago

For people coming to this thread afresh, the RFC is here: https://github.com/fsharp/fslang-design/blob/main/RFCs/FS-1094-immarray.md

I propose we work out how to make one particular immutable array type normative in F# programming "in the box", including in Fable programming.

The existing way of approaching this problem in F# is to use a user-supplied package of collections such System.Collections.Immutable

Description

One particular thing that is a hole in our library is the lack of an immutable array data structure in regular F# coding. There are lots of use cases for this and it is easy enough to implement efficiently, e.g. here (originally from the compiler codebase) though there are other approaches.

I’m particularly aware that Fable and the Elmish design pattern is popularizing the use of immutable data for important model descriptions more and more and we should be helping improve the situation for that kind of programming

The main question is to how to make on immutable array type normative in F# coding

  1. Add a bespoke immutable array to FSharp.Core.

  2. Encourage people to take a dependency on System.Collections.Immutable and add a reference to it to our standard templates. However we would still presumably want an FSharp.Core module making it look and feel like a normal F# collection, but we wouldn't want FSharp.Core to have a dependency on System.Collections.Immutable.

Probably the hardest thing is to decide its name.

Related questions are

  1. Would want a bespoke functional update syntax “{ arr with 3 = expr }” or “{ arr with n = expr } or “arr.[n=expr]”.
  2. Would the type feel right from F# code – good ergonomics etc
  3. What library dependencies would the type induce
  4. How do other collections from System.Collections.Immutable feel to use from F#?

Extra information

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

Affidavit (please submit!)

Please tick this by placing a cross in the box:

Please tick all that apply:

ianrussellsoftwarepark commented 3 years ago

Did anyone suggest calling it Norm?

TomasEkeli commented 3 years ago

i like "block"

what're you doing?

playing with my blocks

dsyme commented 3 years ago

Did anyone suggest calling it Norm?

No, though what is that short for?

playing with my blocks

😆

nosami commented 3 years ago

I know this is bikeshed painting but what about [! 1;2;3 !] instead of [: 1;2;3 :]. The ! looks like it is emphasizing something. Also, it isn't too dis-similar looking to |

dsyme commented 3 years ago

I know this is bikeshed painting but what about [! 1;2;3 !] instead of [: 1;2;3 :]. The ! looks like it is emphasizing something.

This is a breaking change, or at least harder to make work, e.g. [!refcell]. Technically we could probably do it by special-casing on the matching ]. But ! also already has meanings too - let! most particularly. And, putting aside !refcell (which I wish we could deprecate in favour of refcell.Value), we may want to reserve it for future use for "computation expression bind in middle of other expression", e.g.

async { return [ !Async.AwaitTask(t1); !Async.AwaitTask(t2) ] } 
nbevans commented 3 years ago

ilist IndexList ?

I think the word array should be reserved for mutable arrays only. Immutable arrays aren't really arrays anymore in my mind. Maybe I'm weird though.

vzarytovskii commented 3 years ago

When I think of "block" it conveys both the shape (array-like) and the properties (can't be changed, it's a block, which sort of sounds like something immutable)

Block sounds good to me, and easy to grasp, however, I can see how it can be confusing for some people, especially coming from other languages/platforms.

vzarytovskii commented 3 years ago

ilist

List, at least for me, would imply specific implementation (i.e. no index-based access, List a = Nil | Cons a (List a) structure, etc.), it may confuse people I think.

dsyme commented 3 years ago

I think the word array should be reserved for mutable arrays only. Immutable arrays aren't really arrays anymore in my mind. Maybe I'm weird though.

I used "FlatList" initially but it's also unsatisfying

List, at least for me, would imply specific implementation (i.e. no index-based access, x :: xs structure, etc.). It may confuse people.

Yes, it does feel like "array" and "list" both come with such heavy pre-existing connotations from both F# and other languages (functional or other) that we only get to where we want by adding words like "FlatList" or "ImmutableArray". These names are saying "it's like this other thing but it's also not like this other thing". Block seems to carry no other connotation.

realparadyne commented 3 years ago

This is definitely the hardest thing in computer science!

Arrays have arity, so the name makes some sense. Imray would combine immutable with array but it's making up a new word.

Block for 'block of data' is nice too. Short to type easy to say, descriptive and not a real word. A block of something solid is harder to change individual parts of so it hints at immutability too.

So I think I might go for block now instead.

achkasov commented 3 years ago

"Block", "chunk", "blob", "cache", "line", "row", "column" are all good, in my opinion.

IltaySaeedi commented 3 years ago

We have Norm in calculators when we don't want to specify how many numbers after floating point need to be shown we use Norm. It also has usage in Mathematical analysis and matrices, Norm is a function from vector space to the nonnegative real numbers. I've searched on the internet and asked from who loves Math.

achkasov commented 3 years ago

What about just a "Ray". It is concise and kinda like an "Array" but just shorter -- so easier to type for a lazy person like me 😃

nbevans commented 3 years ago

New suggestion safearray SafeArray

nbevans commented 3 years ago

I think out of dsyme's list of suggestions my most preferred is actually arr Arr. I like the conciseness of it and the fact it is shorter to type (will show up on Intellisense every time you reach for an array) than array Array which will encourage adoption of a safer data type.

When you're introducing a new type that, ideally, you would love to be a free upgrade of an existing type (array Array) but for back-compat reasons cannot be - then usually the next best thing is a name which is very similar but shorter than that existing type name. Hence arr Arr seems to fit the bill.

lfr commented 3 years ago

image

This is looking bad for my poor validation blocks... we hardly knew ya 😥

I don't just say this because I'm trying to save them, but blocks have an implicit promise of composition @dsyme, it's why I used it for my library because they really are built on top of each other, here it seems we're hijacking the term for lack of better options which saddens me. Why not "Slab" instead of "Block"? It feels just as immutable, but without any of the composition connotation.

lfr commented 3 years ago

BTW I do love the word block, I understand why it has so many votes, I just think that it's a shame to take it over from my (as well as any other potential libraries of real composable bocks) for this basic concept just because it sounds good and we can't find anything better.

dsyme commented 3 years ago

@lfr Yes worth considering ramifications for existing uses of block (code block , validator block, ...). The FSharp.Cores use of "set" and "map" have similar issues (e.g. Hash map, database data set, plus many others)

matthewcrews commented 3 years ago

Possibly silly suggestion, rar Rar. Why? Read Only Array. Very short. Zero precedent (which may or may not be bad). I'm trying to gauge from comments what is most important: Not overloaded with other language concepts, not conflicting with .NET concepts, short...? I really liked block Block but I understand the possible conflicts. I also liked arr Arr but I can see how that may not be beginner friendly.

dsyme commented 3 years ago

@matthewcrews The problem with readonly is discussed by @TIHan up above in this comment https://github.com/fsharp/fslang-suggestions/issues/619#issuecomment-565240089

matthewcrews commented 3 years ago

My apologies. I rescind my idea 😊

dsyme commented 3 years ago

I really liked block Block but I understand the possible conflicts

Any word will have conflicts, and I don't think these are yet significant enough to warrant exclusion. There are many factors to be taken into account.

lfr commented 3 years ago

@matthewcrews I love Rar/rar! I don't think that read-only is an issue, it's true that read-only doesn't mean immutable, but anything immutable is by definition also read-only so it's accurate enough imo.

Hardt-Coded commented 3 years ago

Did anyone suggest calling it Norm?

Or "Bob" ... Bob is a nice name for all thing. Like Planets or Star Systems ;)

lukesdm commented 3 years ago

image

This is looking bad for my poor validation blocks... we hardly knew ya 😥

I don't just say this because I'm trying to save them, but blocks have an implicit promise of composition @dsyme, it's why I used it for my library because they really are built on top of each other, here it seems we're hijacking the term for lack of better options which saddens me. Why not "Slab" instead of "Block"? It feels just as immutable, but without any of the composition connotation.

Rock?

jwosty commented 3 years ago

For what it's worth, Ruby and Smalltalk both use the word "block" to refer to certain kinds of lambdas. I still like that one though.

JaggerJo commented 3 years ago

Maybe this helps to imagine how each would look like in actual code.

Arr.map and int arr and [: 1;2;3 :] 👍 carbon-4

Block.map and int block and [: 1;2;3 :] 😄 carbon-3

ImmArray.map and int immarray and [: 1;2;3 :] ❤️ carbon-5

Imray.map and int imray and [: 1;2;3 :] 🎉 carbon-6

ImArray.map and int imarray and [: 1;2;3 :] 🚀 carbon-7

Vector is really nice also, but as @rmunn explained above it shouldn't be used for an immutable array implementation.

vilinski commented 3 years ago

can't understand excitement about block, this word has too wide usage to give it another confusing meaning. I like arr most - as shorter, immutable variant for array one should prefer

JaggerJo commented 3 years ago

can't understand excitement about block, this word has too wide usage to give it another confusing meaning. I like arr most - as shorter, immutable variant for array one should prefer

I can imagine that seeing array and arr in a piece of could would lead a beginner to think they are the same.

Voted for Block basically because it's better than the other options - but there isn't really a good one IMHO.

It's really hard because the best name (array) is already taken - otherwise it could be array & mutableArray or something.

rv-17 commented 3 years ago

Language-Ext also uses Arr, which is my favorite. It's the short(er) form fo Array which is also easier to type. The better type should be easier to type. (e. g. List of T vs. ArrayList) https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Arr_A.htm

dsyme commented 3 years ago

can't understand excitement about block, this word has too wide usage to give it another confusing meaning.

Could you list out some of the meanings please?

vilinski commented 3 years ago

it's like if I say interface anybody thinks about ISerializable and not about function signature (just as an example). Only because Sun and Microsoft have occupied this as a keyword :)

lfr commented 3 years ago
  • most prominent is a block as a grouped programming construct, regardless whether within curlies as in C languages { this is a block }, or indented as in ML languages,
  • so nested block is a block within block, not an array of arrays
  • block comment as opposite to line comment
  • any things like computation expression job {...} or lazy (), lock() {} etc.
  • in my current company the BuildnigBlocks is a bunch of internal NuGets used in all our microservices :)
  • for sure one can call a set of values grouped to an array also a block, but I can't remember the word block usually used like this

it's like if I say interface anybody thinks about ISerializable and not about function signature (just as an example). Only because Sun and Microsoft have occupied this as a keyword :)

Also @stephentoub's TPL Dataflow blocks from System.Threading.Tasks.Dataflow. Arcane? Yes. Awesome? Also yes. Should it disqualify block from this debate? Sadly, I fear not.

dsyme commented 3 years ago

@vilinski I'm listening, though TBH that doesn't yet make me think it's a mistake. It's a relatively short list. And all the other suggestions have distinct problems too.

As a humorous aside on collective nouns, people may remember that Stack<T> and Stack of T were synonymous with .NET Generics in the early days, leading to Cup<T> cups. Well, it turns out that in French Stack is Pile. Which rendered back to English leads to Pile of ... and you know how to instantiate that when you're in a bad mood :-) When I saw this first time I realised that "Pile" is by far the most underused collective noun in computing. I'm not however advocating its use here.

jwosty commented 3 years ago

After thinking about it for a little, I do like “chunk”. Even less commonly used than “block”, I would think.

jbeeko commented 3 years ago

What about irray and Irray? Starts with I yes but the I is not not really a prefix as it is in IArray. Easy to say and both the long and short 'I' sound like array but different.

I'd argue the name should have some sign-posting back to Array. Otherwise when encountered it reads as a new concept. I think is is especially true of Block.

zanaptak commented 3 years ago

block also calls to mind filesystem blocks or block-based IO in general, in which they are more analogous to array elements than an array, as fixed-size pieces of a larger whole.

block does not suggest immutability to me any more than other collective descriptors. A list/set/block/chunk of data, all are just bytes and we can change bytes, unless we have separately defined and enforced them to be immutable.

The plainly-named versions of other types (list, set) are immutable, block doesn't provide any hint that array is an exception to that.

Whatever the term, its definition will inevitably describe it as an immutable array, so I've kept my vote on imarray as self-descriptive and concise enough.

achkasov commented 3 years ago

Have other options been considered like:

 [<ImmutableArray>]
 let data: array = [|...|]

Or

 let data1 = [|...|] // this array is mutable

 #immutableArrays "on"
 let data2 = [|...|] // this and all other arrays below are immutable
lfr commented 3 years ago

Have other options been considered like:

 [<ImmutableArray>]
 let data: array = [|...|]

Or

 let data1 = [|...|] // this array is mutable

 #immutableArrays "on"
 let data2 = [|...|] // this and all other arrays below are immutable

I'm pulling this out of thin air, but I don't believe compiler services and directives should be required for ordinary code.

SamuelBerger commented 3 years ago

The name will be typed a lot, from day one of an F# journey. It should be short, easy to type and visually nice. I think it should be a proper name, not a compound name with two capitals. I like Block and Arr but I am also fine with something else, as long it is not compound. Even if naming is the hardest thing, it must be possible, no? Maybe it just needs a brain storming session? 😬 Here is mine: Solid, Rack, Tray, Chess, Piano, Arim, Arri, Arrim, Arrai, Arraim, Imar, Imarr, Irray, Imray, Ray

TomasEkeli commented 3 years ago

even though i personally like block i also see the problems with its name already being used for other things like "block of code"

but, what really bothers me is that as soon as i read the example code i found myself interpreting the "block" as a blocker or blockage. which is atotally different and quite frequently used meaning of a "block" in many domains.

therefore i'm no longer in favour of it

JaggerJo commented 3 years ago

How about Collection and collection ?

lfr commented 3 years ago

Here is mine: Tray, Chess, Piano, Arim, Arri, Arrim, Arrai, Arraim, Imar, Imarr, Irray, Imray, Ray

😂 Harp? Also, ♥ Arrim

einarwh commented 3 years ago

ImmerArray. It rhymes with "immer dabei", which is German for "always there". I am only half joking.

dsyme commented 3 years ago

ImmerArray. It rhymes with "immer dabei", which is German for "always there". I am only half joking.

I've decided on UnveränderlicherZusammenhängenderSammlung :-) With a special rule to allow with or without the umlauts.

UnveränderlicherZusammenhängenderSammlung.map, unveraenderlicherzusammenhaengendersammlung, [: 1;2;3 :]

vzarytovskii commented 3 years ago

ImmerArray. It rhymes with "immer dabei", which is German for "always there". I am only half joking.

I've decided on UnveränderlicherZusammenhängenderSammlung :-) With a special rule to allow with or without the umlauts.

UnveränderlicherZusammenhängenderSammlung.map, unveraenderlicherzusammenhaengendersammlung, [: 1;2;3 :]

I think we should enforce umlauts, makes it more consistent.

SchlenkR commented 3 years ago

I think we should enforce umlauts, makes it more consistent.

I think so, too. At least someone could understand how hard it can be writing special chars on keyboards that aren't US layouted. For example, writing a pipe-forward on a German keyboard, you have to strike 4 times: Alt-GR + (<|>), Shift + (<|>). Just this hustle makes it hard to convince people not to use dot-notation ;)

matthewcrews commented 3 years ago

I'm curious, how committed are we to having this name point it being an immutable array? Are we entertaining names that are new? If the desire is for the name to be short, we become limited in the character combinations. I'm not suggesting gibberish but I'm seeing this tensions between brevity, descriptiveness, and being an un-loaded term (as opposed to over-loaded).

dsyme commented 3 years ago

I'm curious, how committed are we to having this name point it being an immutable array?

TBH I'm open to any suggestion. We're not specifically committed to anything

IltaySaeedi commented 3 years ago

What about Catena. My english is not so good so I prefer to add an image.

Screenshot_20210114-184712_Edge.jpg