These are chat archives for ramda/ramda

9th
Jul 2016
Gabe Johnson
@gabejohnson
Jul 09 2016 02:14
@davidchambers

inverse:

R.gt(x,y) !== R.lte(x,y)

for all x,y

converse:

R.gt(x,y) === R.lt(y,x)

for all x,y

Gabe Johnson
@gabejohnson
Jul 09 2016 02:26
The discussion was concerning the confusing semantics of those functions. Currently R.gt(x,y) ~ x > y which I found intuitive but which, when used as a predicate can be confusing.
David Chambers
@davidchambers
Jul 09 2016 02:34
Thanks, @gabejohnson. So our current definition of positive :: Number -> Boolean, R.gt(R.__, 0) could be changed to R.lt(R.__, 0) via a mechanical transformation at upgrade time. One could then manually rewrite it as R.gt(0). Makes sense!
Gabe Johnson
@gabejohnson
Jul 09 2016 02:35
Correct
I knew them math classes would be worth something someday :smile:
Gabe Johnson
@gabejohnson
Jul 09 2016 02:40
@davidchambers, though I really like @CrossEye suggestion of aliasing better. R.lt === R.isGt
with extensive explanation in the docs
James Forbes
@JAForbes
Jul 09 2016 04:49

@CrossEye I was musing on your usage and I really wouldn't want to ruin such an elegant application. My opinion was based on the idea that the current gt api wasn't useful, and the benefits were entirely hypothetical.

I find the current API awkward and surprising, but, now I can see that gt is actually useful as a binary application like @gabejohnson, I am in favour of isGt being a unary predicate, and gt staying as is.

Like many things in ramda, it may seem more complex at first, but there is a "Rich Hickey simplicity" to having consistent operators. I can see the application being beneficial in graphics programming, which is a massive field and particularly relevant for front end JS.

@davidchambers I apologise for changing my mind on the brink of a potential merge of sanctuary-js/sanctuary#239

Jigar Gosar
@jigargosar
Jul 09 2016 06:58
@Bradcomp thanks brad, as my application is growing I am really suffering with too many debugging issues related to passing improper type, which in java I would get instant ide highlight and wouldn't make the mistake in the first place.
Hey folks, do any of you spend too much time debugging because of type mismatch? which in lang like java ide catched immediately?
I have started doing TDD but when my tests fail, I don't get any info whether it was type mismatch or some bug in code.
James Forbes
@JAForbes
Jul 09 2016 07:04

@jigargosar I do find that I am debugging problems that a type system could solve. But Typescript doesn't meet my needs. Structural typing seems antithetical to functional programming.

I want to try purescript but the docs make my head spin. I keep reading them and my head keeps spinning.

VSCode has some pretty incredible type inference for plain old javascript. But you need to write in a certain style to get the most benefit.

(And VSCode's JS Intellisense is powered by typescript, so it is still pretty awkward writting FP with it)

Jigar Gosar
@jigargosar
Jul 09 2016 07:05
@JAForbes +1
@JAForbes +1 for both purescript and and typescript.
James Forbes
@JAForbes
Jul 09 2016 07:05
But I am pretty sure purescript is the answer. I just need to persist
:)
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:06
I've been trying out Purescript these past few weeks. They just updated the book to be compatible with the new version
James Forbes
@JAForbes
Jul 09 2016 07:06
@Bradcomp I think you are far ahead of me on the fp road
But how are you finding purescript?
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:07
Well, I am truly enjoying the intellisense and compiler errors I get with a well typed language
Jigar Gosar
@jigargosar
Jul 09 2016 07:07
@JAForbes am I missing something? Having a type system doens't counter FP. @Bradcomp @davidchambers right?
James Forbes
@JAForbes
Jul 09 2016 07:07
@jigargosar I'm specifically talking about Typescript's flavour of type system
Jigar Gosar
@jigargosar
Jul 09 2016 07:08
@JAForbes I am using scantuary and ramda, because it is plain old js. I want to keep it that way. don't want to get bound to TS or PS.
James Forbes
@JAForbes
Jul 09 2016 07:08
It's structural instead of nominal. Meaning if I have 2 types with different meaning, but they have the same shape, typescript will accept either interface as a valid input because they are structurally the same
@Bradcomp yeah I bet!
Jigar Gosar
@jigargosar
Jul 09 2016 07:08
@JAForbes you lost me ;)
no worries.
James Forbes
@JAForbes
Jul 09 2016 07:09
@jigargosar I explained it poorly, sorry
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:09
@jigargosar You are correct, but some type systems are better than others for FP. Typescript would help, but it doesn't allow for the kind of polymorphism you get from an HM style type system.
Jigar Gosar
@jigargosar
Jul 09 2016 07:10
I am vew new to FP just a 6 month old baby. And I am going to present my exp with Ramda/Scantuary at functional conf 2016 Bangalore :D
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:10
Awesome!
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:11
I've been struggling with it for the past couple years. I've tried Purescript and Haskell in the past, but to be honest it never really clicked until I was writing JavaScript on a daily basis.
Jigar Gosar
@jigargosar
Jul 09 2016 07:12
@JAForbes ooh, didn't know that types are just aliases in TypeScript. that is not right.
@JAForbes now I understand the structural similarity part, it's more like duck typing.
but I am sure for custom types it will give an error right?
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:13
Purescript has been stretching my brain a bit, but it's really cool. I'm using pux for my views, which is very similar to Elm or Redux.
James Forbes
@JAForbes
Jul 09 2016 07:14
@jigargosar nope, I'll make another example with a complex type
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:14
@JAForbes That's a bummer!
Jigar Gosar
@jigargosar
Jul 09 2016 07:15
@Bradcomp but what about lockin? I love all languages and frameworks, they teach me so much, but then I take those lessons, and write a tiny lib for my own purpose. All built using ramda ;)
react/FRP/streams/redux etc, I have mini versions of all. now these type errors are killing me.
@Bradcomp huge bummer!
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:17
@jigargosar Well, I'm not using Purescript at work, just at home as a learning exercise (also fun), so I'm not as concerned about lockin. I also tend towards small libraries that are easy to swap out / evolve over time, especially if I need to maintain a project for a long period.
Jigar Gosar
@jigargosar
Jul 09 2016 07:18
@Bradcomp +1
"flow" seems like a very minimalistic investment/lockin. Or I will borrow ideas from scantuary. and write my own helper functions for argument/return type validation. I already have function decorators which check for null arg, and null returns. Now I need few more decorators to check for validations. Hopefully that will be enough for now.
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:19
While it seems silly, have you tried putting type signatures at the top of your functions? Little ones like they have in the Ramda docs can be surprisingly helpful when you're trying to string the pieces together...
James Forbes
@JAForbes
Jul 09 2016 07:19

@jigargosar So patterns you use in FP ( e.g. Elm's Action types), are possible but awkward in typescript. You need to ensure if something is semantically different, that is also structurally different

You can probably see that being useful in OOP system where different classes have very different structures. But it is so painful in FP where many things have the same interface (e.g. Monads), but very different semantics.

+1 to type signatures in comments
Jigar Gosar
@jigargosar
Jul 09 2016 07:21
@JAForbes thanks for all this info, TS really sucks. I am better of with writing my helper functions that validate structure using R.applySpec
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:21
Sanctuary is really nice. It gives you good error messages when you get a type mismatch, which can be really helpful
James Forbes
@JAForbes
Jul 09 2016 07:22

A lot of my tests could be completely replaced by a nominal type system. So it is a little sad that typescript took the structural path. Because you definitely could have a nominal form of typescript that worked with Javascript.

I think Typescript's mandate was to make typing existing weird dynamic JS code possible (e.g JQuery), and that meant very flexible interfaces.

It would be great to have a sister project that didn't worry about flexible interfaces.

Jigar Gosar
@jigargosar
Jul 09 2016 07:22
@Bradcomp no I haven't because when writing code I know the type expected. Its just that I forgot some map/flatten/ using merge instead of concat.
and returned a different type .
James Forbes
@JAForbes
Jul 09 2016 07:23
I'm enjoying Sanctuary as well. I'm pretty excited about it honestly.
Jigar Gosar
@jigargosar
Jul 09 2016 07:24
@Bradcomp I plan to use type signatures, but for now they are not adding any value, since I am the sole code doctor.
quick question, in the very first scantuary example of creating a Identity type.
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:24
@jigargosar That makes sense. That can be killer when you just miss some little thing (map instead of chain is a fun one).
James Forbes
@JAForbes
Jul 09 2016 07:24
I wrote my own private tsd for part of ramda, and I made R.pipe type definitions. It was really cool to get a type error within a composition. So typescript isn't a complete waste of time. But I could see Sanctuary giving ever more helpful type errors.
Jigar Gosar
@jigargosar
Jul 09 2016 07:25
;)
quick question, in the very first scantuary example of creating a Identity type. the constructor function is not using any type safe methods.
James Forbes
@JAForbes
Jul 09 2016 07:26
which example?
when defining a type, I will be able to use other types right? I was wondering because the S module is created after creating the type. bit confusing for mw.
James Forbes
@JAForbes
Jul 09 2016 07:30
Sorry @jigargosar, I've completely stayed away from create. I have not added sanctuary definitions to any of my functions, I am just using the provided functions.
Brad Compton (he/him)
@Bradcomp
Jul 09 2016 07:32
Yeah, I can't help you there either... Sorry.
Jigar Gosar
@jigargosar
Jul 09 2016 07:32
ok, thanks @davidchambers is working on some guide, maybe then I will be able to understand stuff. I did take a look at scantuary website building code, it was of little help. since it was all in single file, and didn't define any custom type afaik. Thanks a lot @JAForbes and @Bradcomp for taking the time. Back to coding ;)
James Forbes
@JAForbes
Jul 09 2016 07:33

@Avaq is there a way to map over the success and rejection simultaneously in fluture? I've got an endpoint and it ends with

.bimap(JSON.stringify, JSON.stringify)

Which is fine, just wondering if there is something I'm missing akin to:

mapBoth(JSON.stringify)

@jigargosar :) anytime
sourcevault
@sourcevault
Jul 09 2016 08:44
Aldwin Vlasblom
@Avaq
Jul 09 2016 13:49

@JAForbes Good question. You're not missing it. It's not there. I can never decide whether including it in the library is overhead. It's quite easy to create:

const mapBoth = f => Future.bimap(f, f);

Or with the duplication combinator:

const mapBoth = W(Future.bimap);

I recommend using functional pipelining over method chaining (so static functions) in order to mix in your own functions into the workflow more easily.

David Chambers
@davidchambers
Jul 09 2016 15:52
@jigargosar, the reason create needs to exist is that polymorphic functions such as I are very strict. They will complain if they receive a value which is not a member of any known type. For example:
@ram-bot
S.I(['my', 1337, 'triplet'])
ram-bot
@ram-bot
Jul 09 2016 15:53
Type-variable constraint violation

I :: a -> a
     ^
     1

1)  ["my", 1337, "triplet"] :: Array ???

Since there is no type of which all the above values are members, the type-variable constraint has been violated.
David Chambers
@davidchambers
Jul 09 2016 15:53
But perhaps my application makes use of lots of (string, number, string) triplets.
I'd like to tell Sanctuary that these are valid values. I would do so by first defining a Triplet type, then creating a Sanctuary module which knows about this type:
const {create, env} = require('sanctuary');
const $ = require('sanctuary-def');

//    Triplet :: Type
const Triplet = ...;

const S = create({checkTypes: true, env: env.concat([Triplet])});
David Chambers
@davidchambers
Jul 09 2016 16:00

Or I will borrow ideas from scantuary. and write my own helper functions for argument/return type validation.

Have you considered using sanctuary-def, @jigargosar? If so, what draws you towards rolling your own solution? I understand that sanctuary-def is very slow currently. I hope to improve this over the next month or two, but we do at least have the checkTypes: false escape hatch.

sourcevault
@sourcevault
Jul 09 2016 23:52
what ramda function is opposite of unnest/flatten ?
I remember seeing it being defined but forgot the name
oh right, its splitEvery :D, how does someone summon ramda bot ?
@ram-bot splitEvery