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

Rewrite #41

Merged
merged 11 commits into from
Apr 18, 2017
Merged

Rewrite #41

merged 11 commits into from
Apr 18, 2017

Conversation

rpominov
Copy link
Member

@rpominov rpominov commented Apr 15, 2017

Fixes #32
Fixes #34
Fixes #9

docs/spec.md Outdated
@@ -113,20 +96,30 @@ For example:
- Two promises are equivalent when they yield equivalent values.
- Two functions are equivalent if they yield equivalent outputs for equivalent inputs.

Note that these examples are not universal, in some cases differnet

Choose a reason for hiding this comment

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

s/differnet/different/

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks!

Copy link
Contributor

@dead-claudia dead-claudia left a comment

Choose a reason for hiding this comment

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

Appologies for the splattering of comments, but I thought I'd go through the spec and offer a few suggestions, primarily in how the types are presented in code.

README.md Outdated
Specification for common algebraic types in JavaScript
based on [Fantasy Land](https://github.com/fantasyland/fantasy-land).
Specification for common algebraic structures in JavaScript
based on [fantasy-land](https://github.com/fantasyland/fantasy-land).
Copy link
Contributor

Choose a reason for hiding this comment

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

The spec's name is actually spelt "Fantasy Land".

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I'm going back and forth with this. I like how lower case "static-land" looks (except in titles), but if I use lower case "static-land" then "Fantasy Land" next to it looks off.

README.md Outdated

In Static Land a type is just a collection of static functions, and instances
In static-land we use static functions, and instances
Copy link
Contributor

Choose a reason for hiding this comment

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

In static-land, we use ...

Note the added comma.

README.md Outdated

Simply expose some [Type Objects](docs/spec.md#type) that work with types that your library provides or with types defined in another library or with native types like Array.
Simply expose some [module](docs/spec.md#module) that work with types that your library provides or with types defined in another library or with native types like Array.
Copy link
Contributor

Choose a reason for hiding this comment

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

Simply expose some a module ...

Note the edit.

@@ -1,104 +1,87 @@
# Static Land Specification
Copy link
Contributor

Choose a reason for hiding this comment

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

You should either change this to "static-land specification" or change all the instances of "static-land" elsewhere to "Static Land", for consistency. Otherwise, it looks very off.

docs/spec.md Outdated
@@ -1,104 +1,87 @@
# Static Land Specification

This is a specification for common algebraic types in JavaScript based on
[Fantasy Land Specification](https://github.com/fantasyland/fantasy-land).
This specification describes JavaScript interfaces and laws
Copy link
Contributor

Choose a reason for hiding this comment

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

Try something like this:

This specification describes a set of JavaScript interfaces and algebraic laws that are common in some other functional languages like Haskell.

I feel this could also be improved, but I think you might see what I'm getting at.

Foldable<T> {
reduce: ((a, b) => a, a, T<b>) => a
}
```
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this?

interface Foldable<T<*>> {
  reduce: ((a, b) => a, a, T<b>) => a;
}

Extend<T> {
extend: (T<a> => b, T<a>) => T<b>
}
```
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this?

interface Extend<T<*>> {
  extend: (T<a> => b, T<a>) => T<b>;
}


#### Methods
```js
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this?

interface Comonad<T<*>> extends Functor<T>, Extract<T> {
  extract: (T<a>) => a;
}

docs/spec.md Outdated

#### Methods
In the following signature `Applicative<U>` means that a value must
not only match `Applicative` signature, but also fully support `Applicative` algebra.
Copy link
Contributor

Choose a reason for hiding this comment

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

How about this? Probably not optimal, but it's a little more specific, and ties to my suggestion below.

In the following signature, U<*> extends Applicative<U> means that values of that type must be modules that both implement the Applicative signature and follow its laws. U itself represents the type of such values.

Traversable<T> {
traverse: (Applicative<U>, a => U<b>, T<a>) => U<T<b>>
}
```
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this?

interface Traversable<T<*>, U<*> extends Applicative<U>>
    extends Functor<T>, Foldable<T> {
  traverse: (U, a => U<b>, T<a>) => U<T<b>>;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Here U is a function level variable, we don't want to make it signature level variable. There is an important distinction:

Also notice that signature level type variables are fixed for a module, while a function level variable can be substituted with a different concrete type in each function application. In other words we must choose what T stands for when we create a module, and we must choose what a stands for only when we apply baz to some value.

Although maybe U should be lower case then 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

Then this?

interface Traversable<T<*>>
    extends Functor<T>, Foldable<T> {
  traverse: <U<*> extends Applicative<U>>(U, a => U<b>, T<a>) => U<T<b>>;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

This doesn't seem right. U<*> extends Applicative<U> suggest that U is a module, then a => U<b> and U<T<b>> are wrong, these functions are not returning modules.

To clarify, in my current version U is a type like Array, e.g. if second argument of traverse() is a function that returns arrays, then first argument must be a module that supports Applicative with T=Array.

Copy link
Contributor

Choose a reason for hiding this comment

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

To clarify, I mean U represents the module, but U<a> is an instance. Similarly, Maybe is a type class, and Maybe a is an instance's type.

Copy link
Member Author

@rpominov rpominov Apr 17, 2017

Choose a reason for hiding this comment

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

Yeah, I understand your point of view. I just don't think we should use a module name as a type name. If I have a module called Maybe, the values it's working with won't be automatically of types Maybe<number>, Maybe<boolean> etc. It could use arrays for example under the hood ([1] for some, and [] for nothing), so the values that module works with would be of family of types Array<something>. Or it could be working with instances of class Maybe {...} then, values would have types Maybe<something> after all, but that name "Maybe" will refer to a class name, not to a module name.

This way of thinking seems more correct to what we're dealing with. Modules are not types. In principal some methods of a module can work with different types from another. Or we even may have an algebra which signature parametrized with two or more types.

Copy link
Member Author

@rpominov rpominov Apr 17, 2017

Choose a reason for hiding this comment

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

Btw, current version of the spec calls modules "types", that was a mistake, and to fix it was the initial inspiration for this rewrite 🙃

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm now starting to see why you use Applicative<U> instead - the value's type would be Maybe<T>, while the module type would be Monad<Maybe<T>>. So I'll go with it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Well because in notation that I made up Applicative<U> in that position means "a module that matches Applicative signature for type U" :)

Check out section that describes the notation.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah. I caught that, but I didn't read it as such. I'd read it as "a module that implements Applicative<U> for type U".

@rpominov
Copy link
Member Author

Ok, I'm going to merge this. Thanks for help @isiahmeadows and @polytypic !

@rpominov rpominov merged commit ecb743f into master Apr 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants