fantasyland / static-land

Specification for common algebraic structures in JavaScript based on Fantasy Land
MIT License
772 stars 41 forks source link

Implement Static Land module with ECMAScript module #47

Closed paldepind closed 6 years ago

paldepind commented 6 years ago

Hello @rpominov. Thank you for the great work on this project.

This PR is half question half PR.

From reading the module spec it seems that we can implement a Static Land module simply as an ECMAScript module? I.e. where instead of exporting an object with the Static Land functions the ECMAScript module is itself the Static Land module. The code in the PR shows what I mean.

Is that a correct way to implement Static Land? Is that a good way to implement Static Land?

rpominov commented 6 years ago

Hey! Yeah, as long as users are able to acquire the module object it's correct. But I'm not 100% sure users always will be able to import the object if it's exposed in that way. Can't think of an actual example, and almost certain it should be fine, but you never know with all the tools involved with managing ES modules nowadays.

gcanti commented 6 years ago

@paldepind @rpominov I can attest (several months of usage) that it works fine, at least with TypeScript

import { lift } from 'fp-ts/lib/Functor'
import * as option from 'fp-ts/lib/Option'

// mapOption: <A, B>(f: (a: A) => B, fa: option.Option<A>) => option.Option<B>
const mapOption = option.map

// lift accepts a Functor static dictionary as first argument:
// function lift<F>(F: Functor<F>): <A, B>(f: (a: A) => B) => (fa: HKT<F, A>) => HKT<F, B>
const liftedDouble = lift(option)((n: number) => n * 2)

// x: option.Option<number>
const x = liftedDouble(option.of(1))
paldepind commented 6 years ago

@rpominov Thank you for answering. That is quite nice I think. For some libraries, it can be a very simple and easy way to implement Static Land. In my case, I was looking into implementing Static Land in an immutable JavaScript list I've been working on. But since the library already exports equals, map, reduce, etc. it already implements Static Land by "accident". I have to write literally zero lines of additional code to implement Static Land 😄

But I'm not 100% sure users always will be able to import the object if it's exposed in that way.

As far as I'm aware, for any importer/bundler that supports the standardized ES6 modules format, it should be possible.

Do you think this PR should maybe be merged?

@gcanti Thank you for sharing your experience. I'll take that approach as well then. And by the way, really great work on fp-ts 👍

rpominov commented 6 years ago

have to write literally zero lines of additional code to implement Static Land

Haha, this happened before. "Static Land — specification you probably already implement" 😅

I'll merge this. If there are any problems, I guess the only way to find out is for many people to try this in their particular setups.