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

Wishlist: AMD modules and Ramda.js #27

Open
semmel opened this issue Oct 3, 2015 · 1 comment
Open

Wishlist: AMD modules and Ramda.js #27

semmel opened this issue Oct 3, 2015 · 1 comment

Comments

@semmel
Copy link

semmel commented Oct 3, 2015

In the future will infernu analyse code written using Ramda.js (https://github.com/ramda/ramda) as functional library?
Their functions are all documented with type signatures, e.g. @sig a -> (* -> a) for the always or constant function:

_curry1(function always(val) {
  return function() {
    return val;
  };
})

The other thing is AMD modules. It would be nice to have those of course, since all my code is contained in such a module, infernu bails out immediately with

Unbound variable: 'define'

Greetings
Semmel

@sinelaw
Copy link
Owner

sinelaw commented Oct 5, 2015

Short answer: hopefully and yes.

Generally there are several things libraries like Ramda use that Infernu currently doesn't support:

  1. Optional arguments.
  2. The magical arguments value.
  3. More sane type signature printing.
  4. (probably) User-supplied type annotations (aka "type ascriptions").

All of the above are in the works, I'm currently looking at a major rewrite of the type checker (for many different reasons).

If we put aside _curry1, specifically the 'always' part is typed by infernu as: forall a. a -> (() -> a (it will print it as b -> (() -> b), but it's the same). Note that it requires zero arguments for the resulting function. We could have infernu allow arbitrary "trailing" arguments to all functions, but that makes cringe (not as safe).

Another function I looked at is _slice. It switches over arguments.length, so I had to remove that part and only check the default case (all args supplied). What I got was:

/*       _slice : (( { get length: Number
                     , get =[]: Rfq.(Number -> c) | d}
                  ,Number
                  ,Number) -> [c]) */

Translation: given any object that has a .length number property, and a [] accessor that, given numeric indexes returns a value of type c, and given two numbers, it returns an array of type [c]. That's interesting because the type signature here proves that _slice must be copying data into an array! It doesn't return the same type of object that it received.

So although the type is correct, the user may want to hide those details and limit it to a less general type: [a] -> Number -> Number -> [a] (when curried). For that we need (4) from above, user-supplied type annotations.


As for modules, yes, they should be supported in the future, and it should relatively straightforward to support them. I've prioritized that lower until the dust has settled on the type system.

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

No branches or pull requests

2 participants