Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Static Land compliance of the TypeRep exposed by Flutures module version #109

Merged
merged 2 commits into from
May 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions index.es.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
export {
Future,
Future as default,
isFuture,
reject,
of,
never,
isNever
} from './src/core';
export {default, default as Future} from './src/future';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure that ES specification allows to do export {default} from '...'. It maybe the case that it works with current tools by incident, and may not work in the future.

Copy link
Member Author

@Avaq Avaq May 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading through the spec, one rule is concerning:

For each IdentifierName n in ReferencedBindings of ExportClause: It is a Syntax Error if StringValue of n is a ReservedWord

In the spec for ReservedWord we see that default is actually a reserved word. This would mean that export {Future as default} from '...' also shouldn't work.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Maybe you should do import Future from './src/future'; export default Future; to be safe.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means I have to do it like this:

import _Future from './src/future';

export default _Future;
export const Future = _Future;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, ugly. But I would probably do it like this though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made the same mistake in other places of the code. I'll merge this PR as is, and create a separate issue to discuss the matter.

export {isFuture, reject, of, never, isNever} from './src/core';

export * from './src/dispatchers';

Expand Down
5 changes: 1 addition & 4 deletions src/chain-rec.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import {Future, Core} from './core';
import {Core} from './core';
import {Next, Done} from './internal/iteration';
import {Undetermined, Synchronous, Asynchronous} from './internal/timing';
import {show, showf, noop} from './internal/fn';
import {FL} from './internal/const';

export function ChainRec(step, init){
this._step = step;
Expand Down Expand Up @@ -47,5 +46,3 @@ ChainRec.prototype.toString = function ChainRec$toString(){
export function chainRec(step, init){
return new ChainRec(step, init);
}

Future[FL.chainRec] = chainRec;
21 changes: 1 addition & 20 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Denque from 'denque';
import {show, showf, noop, moop} from './internal/fn';
import {isFunction} from './internal/is';
import {error, typeError, invalidArgument, invalidContext, invalidFuture} from './internal/throw';
import {FL, $$type} from './internal/const';
import {$$type} from './internal/const';
import type from 'sanctuary-type-identifiers';

const throwRejection = x => error(
Expand All @@ -21,22 +21,6 @@ export function isFuture(x){
return x instanceof Future || type(x) === $$type;
}

Future.prototype[FL.ap] = function Future$FL$ap(other){
return other._ap(this);
};

Future.prototype[FL.map] = function Future$FL$map(mapper){
return this._map(mapper);
};

Future.prototype[FL.bimap] = function Future$FL$bimap(lmapper, rmapper){
return this._bimap(lmapper, rmapper);
};

Future.prototype[FL.chain] = function Future$FL$chain(mapper){
return this._chain(mapper);
};

Future.prototype.ap = function Future$ap(other){
if(!isFuture(this)) invalidContext('Future#ap', this);
if(!isFuture(other)) invalidFuture('Future#ap', 0, other);
Expand Down Expand Up @@ -641,6 +625,3 @@ Sequence.prototype._fork = function Sequence$_fork(rej, res){
Sequence.prototype.toString = function Sequence$toString(){
return `${this._spawn.toString()}${this._actions.map(x => `.${x.toString()}`).join('')}`;
};

Future['@@type'] = $$type;
Future[FL.of] = of;
31 changes: 31 additions & 0 deletions src/future.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {Future, of, reject} from './core';
import {FL, $$type} from './internal/const';
import {chainRec} from './chain-rec';
import {ap, map, bimap, chain} from './dispatchers';

Future['@@type'] = $$type;
Future[FL.of] = Future.of = of;
Future[FL.chainRec] = Future.chainRec = chainRec;
Future.reject = reject;

Future.ap = ap;
Future.prototype[FL.ap] = function Future$FL$ap(other){
return other._ap(this);
};

Future.map = map;
Future.prototype[FL.map] = function Future$FL$map(mapper){
return this._map(mapper);
};

Future.bimap = bimap;
Future.prototype[FL.bimap] = function Future$FL$bimap(lmapper, rmapper){
return this._bimap(lmapper, rmapper);
};

Future.chain = chain;
Future.prototype[FL.chain] = function Future$FL$chain(mapper){
return this._chain(mapper);
};

export default Future;
10 changes: 2 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import {
Future,
isFuture,
isNever,
never,
of,
reject
} from './core';
import Future from './future';
import {isFuture, isNever, never, of, reject} from './core';

import * as dispatchers from './dispatchers';

Expand Down
9 changes: 6 additions & 3 deletions test/7.compliance.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {expect} from 'chai';
import FL from 'fantasy-land';
import {Future, reject, ap, map, bimap, chain, chainRec} from '../index.es.js';
import Future from '../index.es.js';
import * as U from './util';
import jsc from 'jsverify';

Expand All @@ -11,8 +11,7 @@ describe('Compliance', function(){

const test = (name, f) => jsc.property(name, 'number | nat', o => f(o.value));
const eq = U.assertEqual;
const of = Future[FL.of];
const undetermined = x => Math.random() > 0.5 ? of(x) : reject(x);
const undetermined = x => Math.random() > 0.5 ? Future.of(x) : Future.reject(x);

const I = x => x;
const T = x => f => f(x);
Expand All @@ -23,6 +22,8 @@ describe('Compliance', function(){

describe('to Fantasy-Land:', () => {

const of = Future[FL.of];

describe('Functor', () => {
test('identity', x => {
const a = undetermined(x);
Expand Down Expand Up @@ -119,6 +120,8 @@ describe('Compliance', function(){

describe('to Static-Land:', () => {

const {of, ap, map, bimap, chain, chainRec} = Future;

describe('Functor', () => {
test('identity', x => eq(
map(I, of(x)),
Expand Down