fp-ts icon indicating copy to clipboard operation
fp-ts copied to clipboard

What's the difference between Map and Record?

Open geofflittle opened this issue 4 years ago • 9 comments

📖 Documentation

As the title asks, what's the difference between Map and Record?

I noticed that Record at https://gcanti.github.io/fp-ts/modules/Record.ts.html had more functions under "utils" than does Map at https://gcanti.github.io/fp-ts/modules/Map.ts.html, but that's about it.

How do I know when I want to use Map or Record?

geofflittle avatar Aug 02 '20 02:08 geofflittle

Record is the module about what in TypeScript is named Record and it's a plain object.

Map is the module about this Map.

How do I know when I want to use Map or Record?

This has very little to do with TypeScript or fp-ts, it has to do with what problem you have to solve, so I don't thin this is the right place do discuss it. Anyway, both can be used as key-value stores. With Map you can use any object as key (lookups have to use the same reference though) and the insertion order is maintained. On the other hand, plain object are faster (if performance is a concern for your use case).

DenisFrezzato avatar Aug 02 '20 07:08 DenisFrezzato

Just to add to what @DenisFrezzato wrote, I don't believe the operations for Map are immutable either. So, if you wanted to use them in pure manner then you'd have to write wrappers around them to always return a new Map.

TheWix avatar Aug 03 '20 19:08 TheWix

@TheWix actually they are all immutable cause Map is just a signature extension over ReadonlyMap.

There are actually no mutable operations in fp-ts. If you need one you should use IORef and implement the mutable operations by yourself.

mlegenhausen avatar Aug 04 '20 05:08 mlegenhausen

@mlegenhausen Oops, sorry. I was referring to The built in JS Map rather than the fp-ts one.

TheWix avatar Aug 05 '20 11:08 TheWix

Does the Map in the docs refer to the js or fp-ts Map?

geofflittle avatar Aug 06 '20 00:08 geofflittle

@TheWix Actually fp-ts Map module is built on top of native Map

raveclassic avatar Aug 06 '20 11:08 raveclassic

What are the differences in use-cases between

  • the js Record,
  • the fp-ts Record (assuming this exists),
  • the js Map, and
  • the fp-ts Map

Thanks for your time, sorry if these are simple questions, I'm a little lost.

geofflittle avatar Aug 08 '20 18:08 geofflittle

What are the differences in use-cases between

  • the js Record
  • the fp-ts Record (assuming this exists),
  • the js Map, and
  • the fp-ts Map

First of all, there is no Record in js, so not sure what you mean there. Are you referring to the Record type in Typescript?

There is no difference between Record in TS and Record in fp-ts except that fp-ts provides some nicer utilities for working and interacting with Records. For example, accessing a property directly versus using lookup from fp-ts will give you different behaviour:

import * as R from 'fp-ts/Record'

declare const myRecord: Record<string, string>

// x will be typed as a string, even though myRecord may not have the 'someKey' property
const x = myRecord.someKey

// x will be typed as Option<string>, correctly reflecting the fact that myRecord may not have the
// 'someKey' property
const y = R.lookup("someKey", myRecord) 

In terms of when to use a Map vs a Record, there's no right answer it depends on what you are trying to do in your program as one data structure might be more optimal than another (as @DenisFrezzato already mentioned). For example, a Map can have keys of any type including objects or functions. There are many articles online talking about when you might wish to use a Map such as https://dmitripavlutin.com/maps-vs-plain-objects-javascript/

Once again, fp-ts Map gives you nice utilities for interacting with a map which are safer than what the native Map functions will give you in Typescript. So if you are looking for better type-safety in your codebase then you can always look into using fp-ts to interact with your Maps rather than using the native JS methods

Hope that helps! :)

cdimitroulas avatar Mar 27 '21 18:03 cdimitroulas

Would be interesting to have real world examples where a Map is more superior than a Record in a functional programming context. In my 10 years programming exclusively JS I never had the need for a Map.

The advantage of using complex objects as keys comes at the cost that each lookup seems to be O(n) (in fp-ts) where as it is O(log n) or even O(1) for a Record.

We normally solve the problem with complex keys by defining a io-ts type that converts the object to a string representation that can then be used as lookup key.

mlegenhausen avatar Apr 06 '21 13:04 mlegenhausen