crocks
crocks copied to clipboard
TS typings
Have you planned or thought about creating typings files to support us TS developers?
I have given it a lot of thought and will not support either TS or flow types officially. But if anyone makes and maintains them, I will gladly link to those libs.
EDIT: crocks is intended to be a Javascript lib, I think there are many other libs out there that do support TS and flow out of the box.
But out of curiosity, if you have any experience in building typings for ADTs...what would this translate to in T$?
https://github.com/evilsoft/crocks/blob/master/src/Pred/index.js
EDIT:
it is a Monoidal Contravarient functor that wraps a Predicate function that goes from anytype a
to Boolean
.... So a Pred a Boolean
. you can change it to another (or same type) b
by using contramap
that takes a function b -> a
, making it a Pred b Boolean
Unfortunately I'm the wrong person to ask as I don't have enough experience in writing complex typing files, somebody a lot smarter has to tackle this one.
EDIT:
I think this is a good example of typings that support mapping functions like a -> b
where both can be random types, etc.
Bummer sauce. Well if anyone ends up making typings for these Types and Functions, I will def throw a link in the docs and give you a shout out.
@evilsoft - Here are some typings for Pred
. I haven't really spent time on further enhancing this, but as it stands the compile-time checks and intellisense are promising.
type PredFn = (a: any) => boolean;
type TransformFn = (a: any) => any;
type Instance = {
runWith: (a) => boolean,
inspect: () => string,
toString: () => string,
concat: (a: Instance) => Instance,
empty: () => Instance,
contramap: (a: TransformFn) => Instance,
}
declare var Pred: {
(a: PredFn): Instance
empty: () => Instance
type: () => string
}
export = Pred;
Hmmm. okay. this is not as bad.
@karthikiyengar could you try Identity
.
Maybe this is something we can do.
@karthikiyengar @dalefrancis88 and @bennypowers and whoever.
What do you think about us doing this? For just the types?
@evilsoft - I think the biggest win from this would be the ease of API exploration and avoiding a large number of instantiation/usage errors.
If the above example (and our PoC with Identity
- I'll put it up soon) is anything to go by, we can have excellent type support for the crocks
and monoids
- the red squiggly lines makes me feel warm and fuzzy.
Pointfree functions are going to be a bit painful, and we will start hitting T$'s limitations. That being said, it is completely possible to type a boatload of functions we provide similar to Ramda (although they default to any
a lot, it still kind of works). And it does look like things are going to improve with https://github.com/Microsoft/TypeScript/pull/24897 - which will be released soon.
Well. Then with this being the fourth person asking, I think it is time we seriously explore this option.
@evilsoft - I've setup some types and tests for Identity
at https://github.com/karthikiyengar/crocks-types - could you please take a look? Failing tests are sections where the types can be improved - I'm afraid I don't have the smarts at the moment to do better. The lack of Higher Kinded Types makes things difficult.
Notable resources: https://gcanti.github.io/fp-ts - Looks like applicatives are partially working for them https://github.com/gcanti/fp-ts/blob/master/HKT.md - An excellent article on how to emulate HKTs. https://github.com/SimonMeskens/TypeProps - Another approach. https://github.com/cbowdon/TsMonad - Can draw inspiration from here https://www.cl.cam.ac.uk/~jdy22/papers/lightweight-higher-kinded-polymorphism.pdf - I can't bring myself to read this just yet. https://github.com/Microsoft/TypeScript/issues/1213 - T$ proposal for HKT
@karthikiyengar amazing. looks like I will be learning me some T$. (don't tell the people I work with tho, they will make so much fun of me)
^ that's not true! Tell us of your learnings. I've done some TS courses on egghead and am impressed by some bits of it.
FYI jsdoc comments will work with TS editor plugins
And es modules (which I haven't forgotten about) will help with static analysis.
I'd be super happy to kick things off on this one. I'm assuming that we aren't considering a full-fledged move to TS when it comes to the library itself. That leaves us with two options.
- Include
d.ts
definitions as a part of the library. This allows us to have autonomy over lint-rules, tests etc. - Fork DefinitelyTyped and PR crocks typedefs.
If we could decide on the approach, we can calculate next steps.
https://github.com/Microsoft/dts-gen can generate the starting template and you can build up from there. I'm heavily interested in this as well and would like to contribute when I can. TS is no bullshit, you'll appreciate the cognitive de-load once you start using all the tooling surrounding it.
I think, the last frontier for TS is this: https://github.com/Microsoft/TypeScript/issues/5453 (most of the primitives are already implemented), with that done TS will fully encompass the strongly typed fp/frp in js.
Thanks for looking into this!
I'd like to give a +1 for including a d.ts
definition in the library (option 1 from @karthikiyengar) as this will make crocks support TS "out of the box".
DefinitelyTyped is great, but is more of a fix for libraries that does not support TS.
If @evilsoft can give us a go ahead on this one, I'd be happy to kick-start a PR!
On Sat, Aug 4, 2018, 12:19 PM Kjell-Morten [email protected] wrote:
Thanks for looking into this!
I'd like to give a +1 for including a d.ts definition in the library (option 1 from @karthikiyengar https://github.com/karthikiyengar) as this will make crocks support TS "out of the box".
DefinitelyTyped is great, but is more of a fix for libraries that does not support TS.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/evilsoft/crocks/issues/286#issuecomment-410439226, or mute the thread https://github.com/notifications/unsubscribe-auth/AH4Kb5AMLGdDFvkdZ-8AMJZaAtDW74Fyks5uNXUvgaJpZM4U4nze .
@kjellmorten I would much prefer it not being in the lib, this is a Javascript, not a T$ lib as such I would only :corn:sider adding on these conditions:
- No code will ever be modified to account for T$ types .
- T$ works with composition of curried variadic functions (do not think it does at this point).
- T$ can handle adhoc type unions, So if I want to have a type
A
be aString
or aNumber
, the typeString + Number
(not a union type, but the union of 2 or more types), it needs to account for this. - HKTs can hold curried, variadic functions as their values. (things like
ap
must type check)
While as @zdrr stated, T$ is not bull-poop, I really do not think it is ready for actual Functional Programming without removing the power that Javascript has to offer in the functional space. All of the code I have seen using T$ the way you can use Javascript functionally requires a lot of specialization and compromises to things that are super simple in JS. That specialization (that I have seen) leads to many brittle definitions in the application domain.
Once those (4) conditions are met, then I am okay with it being officially supported in the lib, otherwise I am okay someone adding them to that typings repo, with the understanding that under no circumstance will any code be modified to accommodate those typings. I have seen a couple really good ADT libs lose so much power to accommodate T$ and I would rather not degrade crocks the same way.
My hope is, that as a functional community we stop trying to make something that was built for Object Oriented Programming work in a functional paradigm, and focus on something that works for functional javascript.
[end "make people angry" rant]
All that said tho, @karthikiyengar if we can hit those (4) things, I will happily merge it in.
@evilsoft - Roger. It's easily possible to achieve 1 and 3 at the moment. Typescript has some really kick-ass support for discriminated unions.
With regards to 2 and 4, I think there's been some progress made in the 3.0 release. Allow me to perform some experiments before I get back to you on this one.
There is an open issue for Variadic Kinds in the TypeScript https://github.com/Microsoft/TypeScript/issues/5453 It's currently listed under the "Future" for the TS roadmap https://github.com/Microsoft/TypeScript/wiki/Roadmap However things like curried functions is still possible, just a little verbose in the definition file.
@eddiemoore that is great news! So by verbose, do you mean for a ternary function would that mean accounting for
-
a -> b -> c -> d
-
(a, b) -> c -> d
-
a -> (b, c) -> d
-
(a, b, c) -> d
Also without knowing what compose
means is it able to capture the composition for the function we provide here or would we have to change that to accommodate?
@karthikiyengar just looked into the union types for T$. That is pretty awesome!
@evilsoft Yeah, so you can define overloads in TypeScript if a function can take different params in different ways. It's a little annoying at the moment having to write it out 4 times, however it does give you the nice code hints and type safety plus more.
~~As for compose, not sure if this is the best way or not, but it seems to work:~~
function compose<A>(fn: (...x: any[]) => A, ...fns: Array<(...y: any[]) => any>): A
// use:
const x = compose(() => 42) // type of x will be a number
const y = compose(() => 'something', () => 42) // type of y will be a string
Update: Ignore the compose stuff.... I realise it's wrong lol.
Ok better way is probably to use the overloads:
export type Arity1<A, B> = (a: A) => B;
export function compose<A, B>(f: Arity1<A, B>): Arity1<A, B>;
export function compose<A, B, C> (g: Arity1<B, C>, f: Arity1<A, B>): Arity1<A, C>;
export function compose<A, B, C, D> (h: Arity1<C, D>, g: Arity1<B, C>, f: Arity1<A, B>): Arity1<A, D>;
export function compose<A, B, C, D, E> (i: Arity1<D, E>, h: Arity1<C, D>, g: Arity1<B, C>, f: Arity1<A, B>): Arity1<A, E>;
export function compose<A, B, C, D, E, F> (j: Arity1<E, F>, i: Arity1<D, E>, h: Arity1<C, D>, g: Arity1<B, C>, f: Arity1<A, B>): Arity1<A, F>;
source: https://github.com/TylorS/typed-compose/blob/master/src/compose.ts
@eddiemoore - Great! Libs like ramda use some form of codegen to minimize manual typing for compose/curry
. I was wondering if you think https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#generic-rest-parameters (or other new 3.0 features) helps in typing curry
/compose
.
I've been trying to wrap my mind around it, but I've run into a dead end.
An interesting thread here: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/27715#thread-subscription-status
@karthikiyengar it might help. Haven't dug into it enough though.
The only problem with the overloads, is that unlike ramda, we do not stop at 10. you can make a composition as big as you need.
@evilsoft - Sure, you can extend it via codegen to an arity of n, but it comes with a performance cost AFAIK.
https://github.com/types/npm-ramda/blob/master/templates/compose.ts
On Fri, Aug 10, 2018, 7:22 PM Ian Hofmann-Hicks [email protected] wrote:
The only problem with the overloads, is that unlike ramda, we do not stop at 10. you can make a composition as big as you need.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/evilsoft/crocks/issues/286#issuecomment-412149498, or mute the thread https://github.com/notifications/unsubscribe-auth/AH4Kb5jgY7LgI5NnbSEPqqJBM74Z69j6ks5uPcFbgaJpZM4U4nze .
Spent some time digging deeper into this. Here's some stuff that I've uncovered.
- We need to decide if the typings are going to be a separate repository (like https://github.com/types/npm-ramda/) or be a part of the crocks main codebase. There are arguments for and against this.
- https://github.com/ikatyang/dts-element-fp does a great job of code-generating definitions for curry/compose.
- Since we'd have to rely on codegen, we have to set up some serious infrastructure that allows us to develop and test the final
.d.ts
file to template and interpolate the final module declaration.
I'd really appreciate direction from someone more experienced with this than myself, although I'm willing to put the time in.
@ikatyang - Could you please share some of your thoughts about this with us?
- Declaration files shouldn't be placed in non-TS projects, placing the declaration files in the main repo means it should be responsible for it, that is, you may have to release a new version just because of the TS declaration bugfixes, and if there're PRs for new functions or something, you can't ask people to write declaration for it since this is a JS project, which means it's easy to be out of sync.
- It should be fine to use it, though I didn't document it well.
- It should be just a matter to setup the codegen and
dts-jest
, the complexity innpm-ramda
is just because I'd like to use them in the watch mode and a lot of custom usage to suit the ramda case.