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:

dsyme commented 3 years ago

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.

This is true, though is also the connatation that associates with immutability. It's quite useful to have a word that represents all of

Chunk and block seem to be the candidates here if we're looking for a single word rather than a combination of words (e.g. immutable array). For me "chunk" has the problem that it's a constituent part of something else, whereas "block" doesn't necessarily have that.

charlesroddie commented 3 years ago

rectangular linear

Block conveys something 2D or 3D to me, i.e. rectangular, but isn't linear more appropriate? What is rectangular about an array?

dsyme commented 3 years ago

For people coming to this thread afresh, current round of voting is here:

https://github.com/fsharp/fslang-suggestions/issues/619#issuecomment-759428584

dsyme commented 3 years ago

Block conveys something 2D or 3D to me, i.e. rectangular, but isn't linear more appropriate? What is rectangular about an array?

I think it's neutral - could be 1D, 2D, 3D e.g. "block booking" denotes a booking for 50 people, not 1 person (though arguably over a second dimension of time). For immutable arrays the second dimension is sort of the size of each element.

But that's ok, since it would lead to Block2D, Block3D etc. as dimensioned versions of the same. Of course the same would apply to ImmArray2D, ImmArray3D, ImmTensor etc.

ReedCopsey commented 3 years ago

I personally do like block, but there's also similar words like "slab" that may have less existing connotations and could work, be a meaningful word, and short/easy to type.

dsyme commented 3 years ago

I personally do like block, but there's also similar words like "slab" that may have less existing connotations and could work, be a meaningful word, and short/easy to type.

Yup. Any suggestions welcome. Something about Slab sounds problematic for me, not sure what - I think it's that "Sl" has a lot of words with very negative connotation in English - I won't list them all of course but consider "slap, slag, slam, slash, slip".

object commented 3 years ago

rectangular linear

Block conveys something 2D or 3D to me, i.e. rectangular, but isn't linear more appropriate? What is rectangular about an array?

I never associate a block with rectangle. And the non-computer definition says "a large solid piece of hard material, especially rock, stone, or wood, typically with flat surfaces on each side." I like especially "solid piece of hard material", sounds like immutable, doesn't it?

The more I compare options, the more I become in favor of block. Developers tend to be attached to names, so having a single simple short word known to everyone gives a better encouragement to use it. If I have to choose between array and ImmutableArray without knowing much about them, I will treat shortness of "array" as a hint of a default choice. "array" and "block" are equally short and simple. "imarray" is a tiny bit more complicated because it's compound. So "block" is my choice at the moment.

ReedCopsey commented 3 years ago

Other random ideas (just throwing them out there): Hunk, strip, band, course (maybe to esoteric)

[I still would vote for block of everything so far, though]

dsyme commented 3 years ago

I will treat shortness of "array" as a hint of a default choice. "array" and "block" are equally short and simple. "imarray" is a tiny bit more complicated because it's compound. So "block" is my choice at the moment.

Yes, I like that block is not penalising devs for going immutable in any way except slight unfamiliarity.

  1. It's not forcing them to use an abbreviation at all (a form of penalty, making code harder to read)
  2. It's not adding characters to their code (so just as succinct)
  3. It's not adding characters to their code (so no indentation changes)

So moving to "block" would be "all goodness".

lfr commented 3 years ago

consider "slap, slag, slam, slash, slip"

So many great candidates, so little time

davedawkins commented 3 years ago

As a recent newcomer to F#, I think I'd have found myself intuitively understanding a variant spelling of array over anything else. If I'd seen xarray or arrayx (for most x) I'd have enough information to understand the code and then google "fsharp arrayx" (later). I have to say I dislike x being more than 1 character. There's just enough infromation there to tell me it's different, and my brain is thinking "array behviour". The Im variants that try to be a long word but aren't just look like add-ons to my eye.

rv-17 commented 3 years ago

There is also the term Pad like One-time Pad, meaning a block.

IltaySaeedi commented 3 years ago

Since it would lead to Block2D, Block3D etc. as dimensioned versions of the same.

So chain and catena are not appropriate because they look single line.

dsyme commented 3 years ago

There is also the term Pad like One-time Pad, meaning a block.

To me that says something you can mutate (write on), that's why "one time" is needed :-)

IltaySaeedi commented 3 years ago

Cling or Clench. 🤔

Happypig375 commented 3 years ago

I hope that there are no more blocking issues blocking blocks from making it to F# vNext. Blocks will be important building blocks for my next project. 🚀

vilinski commented 3 years ago

this blog is about the code blocks which are blocked by the lock on the block of blocking collection of clocks

Happypig375 commented 3 years ago

@vilinski Bollocks!

jackfoxy commented 3 years ago

column

charlesroddie commented 3 years ago

@jackfoxy that is that is getting warm

I think Row is perfect

Short, one-dimensional

lfr commented 3 years ago

This Row looks pretty good I must say, perhaps less descriptive of the immutability of it but that's somewhat balanced by it being more descriptive of the single dimensional aspect of it

realparadyne commented 3 years ago

I like row. Short and simple. Immediately makes me think of a row in a spreadsheet which has a number of cells with arity just like an array.

I don't think the name has to say it's immutable. Array doesn't say it's mutable. You won't misread it while scanning code.

achkasov commented 3 years ago

Row and Ray are the best in my opinion. Also a "beam" maybe?

matthewcrews commented 3 years ago

I really like row. Short and suggests continuity.

IltaySaeedi commented 3 years ago

Row2D and Row3D are strange for me, however I am not native English speaker. If it is fine for you, there would not be any problem with Row.

matthewcrews commented 3 years ago

I agree that Row2D is strange but if you think about how the memory is laid out, it's not so strange. 2D and 3D Arrays are still long runs of memory. There's nothing 2D or 3D dimensional about their layout. The 2D and 3D refers to how to address the memory, not how it's stored. In that case I don't think that it's quite as strange. So far there are no perfect solutions, just less terrible ones.

brianrourkeboll commented 3 years ago

I don’t think anybody’s said it yet in as many words, but block has the advantage that people do refer to a “block” of memory, which is kind of what an array represents. Its main disadvantage is that it is not, to my knowledge, in common use as a name for an actual array-like type in any well-known language.

Arr/arr, on the other hand, has the advantage of being clearly not quite the same as “array,” shorter to type (and so first in autocomplete), and yet still close enough to “array” that everyone will know that it’s at least something like an array. It also has an old-school, hipster, Unixy terseness to it. Its main disadvantage becomes apparent only when you try to say int arr aloud 🙃—in practice, though, I think people would just say “array,” and they could fall back to whatever arr was actually abbreviating (e.g., ImmutableArray<_>) if the need arose.

@dsyme notes that using an abbreviated word-form like arr could incur some “penalty” or mental overhead, but it is perhaps noteworthy that we already have and are quite happy with the rather-ubiquitous seq. Of course, there isn’t a competing, similar-yet-different, expanded sequence type in that case, but I don’t think its terseness alone is an argument against arr.

Another consideration is that current (mutable) array type annotations in F# are usually and canonically written 'T []—that is, the type name is not even uttered, with [] in its place. The commonest use of any form of the word “array” in actual F# source code is probably only when the Array module is used.

So, all in all, I think my vote for now is for:

  1. module Arr, type 'T arr.
  2. And then, if need be, for Block/block.
pmbanka commented 3 years ago

I will treat shortness of "array" as a hint of a default choice. "array" and "block" are equally short and simple. "imarray" is a tiny bit more complicated because it's compound. So "block" is my choice at the moment.

Yes, I like that block is not penalising devs for going immutable in any way except slight unfamiliarity.

  • It's not forcing them to use an abbreviation at all (a form of penalty, making code harder to read)
  • It's not adding characters to their code (so just as succinct)
  • It's not adding characters to their code (so no indentation changes) So moving to "block" would be "all goodness".

I think the "all goodness" comment forgets about the objections mentioned in other comments, namely:

I just want to mention that I really like imray suggestion, because it is easily pronouncable (as opposed to most other suggestions that are not existing words - see e.g. immray), and it is a completely made-up word, so it won't clash with any existing meanings and usages. Sure, it may feel weird at the beginning, but this is a case for many neologisms - and as the time passes and the language evolves, these feeling naturally disappears. Most important, it has all the benefits that apply to "block" mentioned above.

Personally, I feel it is a trade off - block vs imray is familiarity vs avoiding clashes with existing code, all others being equal. Both would be a fine choice.

dsyme commented 3 years ago

the name block is associated with the ability to compose and combine them, which would be a bit misleading here

TBH I think this is a mistaken ascription of compositionality to the word "block".

In common usage (e.g. metal or wooden blocks) I don't expect to be able to compose two blocks and get a block unless I literally fuse them irreversably or make copies of them.

For example, when I compose 100 wooden blocks I get a pile of wooden blocks, or a wall, or a Jenga game, not a single wooden block.

So I feel immutable arrays are "compositional" (that is, via copying or as building blocks to something larger) in much the same way that "blocks" are in common usage.

dsyme commented 3 years ago

the name "block" may clash with already existing code due to the ubiquitous nature of the word

Yes, though I'm not yet aware of any existing use of the word in FSharp.Core or .NET Standard API surface area (besides disk blocks? are there others). That's not too bad all in all.

matthewcrews commented 3 years ago

I'm assuming Lego is out 😂. All this talk of blocks makes me think of Legos and they are featured in almost all of Scott Wlaschin's talks on composition.

It would be great for marketing. "Come write F#! We have fun and Lego built into the language!"

FYI: not a real suggestion. Just had a moment of whimsy

pmbanka commented 3 years ago

I'm assuming Lego is out 😂. All this talk of blocks makes me think of Legos and they are featured in almost all of Scott Wlaschin's talks on composition.

In seriousness, I think this might be the source of the discussed association in some commenters' minds. Then again, lego pieces are more commonly(?) referred to as "bricks", which would definitely mean composability. All in all, I 100% agree with https://github.com/fsharp/fslang-suggestions/issues/619#issuecomment-760950788

the name "block" may clash with already existing code due to the ubiquitous nature of the word

Yes, though I'm not yet aware of any existing use of the word in FSharp.Core or .NET Standard API surface area (besides disk blocks? are there others). That's not too bad all in all.

I guess it is indeed not too bad, but still worth considering. I thought it might be worthwile to check:

dsyme commented 3 years ago

I guess it is indeed not too bad, but still worth considering. I thought it might be worthwile to check:

Thanks, those are useful. Variations on "syntax block" and "block of code" are definitely the most common conflict revealed there

Happypig375 commented 3 years ago

What, "block of code" is not an immutable collection of code (instructions) at run time?

IltaySaeedi commented 3 years ago

Massif, a compact group of mountains.

achkasov commented 3 years ago

Massif, a compact group of mountains.

Also "massiv" is "array" in Russian.

IltaySaeedi commented 3 years ago

"Sprig", a small stem bearing leaves or flowers, taken from a plant.

red-swan commented 3 years ago

I feel obligated to suggest Irray. Makes more sense when spoken. As in, "In F# we have arrays and irrays." From this you can gather that I'm a fan of the Imray suggestion.

charlesroddie commented 3 years ago

@dsyme How many more rounds? :) Can we have top 3 from last round (Block, ImArray, Arr), and three new ones (row, irray, imray)? With voting for any number of options (since three of these are similar)?

laenas commented 3 years ago

If there is an intent that the new immutable Array type be used over the present Array type; either due to philosophical outlook or better default performance for "don't think about it" mechanics - then Arr seems to make more sense, as its brevity seems like it'll lead folks to 'just use it' until they need to think about it. Otherwise, I'm rather fond of the Irray terminology ahead of Imray (I'm not Ray, I'm Ryan, common mistake, though)

woojamon commented 3 years ago

book log journal album (also happens to be latin for "list") catalog index table

I think I prefer literary (printing/publishing?) terms, probably because something written down or printed generally has the notion of permanence (immutability), but people can still add something to the beginning or end of the printed/published work with relative ease (composition), i.e.: books, logs, journals, albums and catalogs can be all appended with additional content.

davedawkins commented 3 years ago

Going at it from the "written in stone" aspect then: "tablet". Quick look at synonyms led me to "bar". We could quite quickly arrive at "barry".

woojamon commented 3 years ago

Has series been suggested?

let sumEven (data: int series) =
    if Series.isEmpty data then
        0
    else
        data
        |> Series.filter isEven
        |> Series.sum

sumEven [: 1; 2; 3 :]
sumEven [::]
sumEven Series.Empty
lfr commented 3 years ago

In the middle of all this there's been a suggestion that:

If you haven't guessed by now, that suggestion is Beam, by @achkasov

woojamon commented 3 years ago
  • unlike block, doesn't have composition connotation

Ok I like Beam, but beams are also used compositionally to build things...

therefore I hereby propose shaft 😂

let sumEven (data: int shaft) =
    // ...

(other interesting beam synonyms are "strut", "joist"... edit: those are are also used to build things compositionally though 😓)

lfr commented 3 years ago

Well, sure, but a beam is usually not composed directly with itself like blocks are, they are usually components of more complex structures, not unlike arrays are used to build complex programs. Can't put my finger on why, but strut does have a ring to it as well.

woojamon commented 3 years ago

I felt the same ring with strut and wondered about it too. Maybe because it sounds like struct?

Anyways, if this new type is going to have the same collection-like usage semantics as Array, how important is it for the type name to have the notion of an ordered, collection-like thing as well?

Things like Bar.sum or Block.fold might be a bit awkward for the uninitialized. (no pun intended.) Although I wouldn't mind having a let data: foo bar every now and then ha

beyon commented 3 years ago

I vote Block or ImArray from the mentioned alternatives so far.

With ImArray it's clear what it is but a less elegant than list/array/map/seq/block.

For me block manages to feel both tangible and open enough to work as an immutable array even if there are other meanings. I can imagine having a block of [code/building/whatever] blocks just fine.

Biggest problem with block would be that it's used fairly frequently for other things. One being as (building)blocks of programs/websites.

However the alternatives brought up have even more specific meanings to me.

Ray - used in geometry and computer graphics, it has no end! I wouldn't want that with my immutable array!

Row - I associate it with a horizontal direction, to me an array might have a linear order but no specific spatial direction.

SamuelBerger commented 3 years ago

Block in French is "bloc" and in Dutch "blok". One character less and no clashing! "Diversity in tech" also for non English words in programming languages so to speak :)

realvictorprm commented 3 years ago

Brick

Charles Roddie notifications@github.com schrieb am Sa., 16. Jan. 2021, 18:57:

@dsyme https://github.com/dsyme How many more rounds? :) Can we have top 3 from last round (Block, ImArray, Arr), and three new ones (row, irray, imray)? With voting for any number of options (since three of these are similar)?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/fsharp/fslang-suggestions/issues/619#issuecomment-761606264, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGB4Z4CX5J6POBCGOIKQBQLS2HHRPANCNFSM4EDWZKWQ .