These are chat archives for ramda/ramda

27th
Jan 2017
David Chambers
@davidchambers
Jan 27 2017 01:16

That happens because Ramda's ap is compatible with FantasyLand 1.0, whereas Fluture follows 3.0.

The argument order of ap was flipped in FL 2.0

Actually, @Avaq, the ap change was part of the 1.0.0 release. Ramda is currently compatible with fantasy-land@0.3.0.

James Forbes
@JAForbes
Jan 27 2017 02:26
I must be misunderstanding something @kedashoe, I don't see how that would affect this behaviour.
Rick Medina
@rickmed
Jan 27 2017 03:50
anyone used typescript of flow? any preference?
James Forbes
@JAForbes
Jan 27 2017 04:28

@rickmed I've used typescript extensively with ramda and my conclusion is, it doesn't work well for functional programming, its built for a different style of programming, it can't detect types of first class functions. There's no higher kinds. Doing standard ramda compositions in typescript is painful. There's no notion of currying, so if you want accurate definitions, prepare to write a lot of overloads...

Common FP typing idioms really slows down builds, things like union types add up compile times (With TS my initial compile was 165s without its 5s). It might be ok on smaller projects, but it was just untenable for us.

I also found the bugs we get aren't the ones typescript could catch. Maybe things will improve, but I think its best not to stick with JS, or use a different language entirely. And I'm not sure how much it can improve, I think typescript's model is almost diametrically opposed to FP. Writing FP code with --noImplicitAny makes composition pretty ugly, coding without it means your opening up the flood gates for all kinds of type errors. Non nullable types are great, but there's escape hatches like !. accessors, and so its sort of self defeating.

And I'm sad saying this, I was really excited about TS 2.0, non nullable types, more literals for unions, discriminated switches, its all sounded great. But if I could go back in time and tell myself not to adopt it, I would.

I get a lot of value out of sanctuary, and I find myself leaning on it more and more. I'm tempted to experiment with sweetjs to make the whole sanctuary experience a lot less verbose.

I have no experience with flow types, but I assume its much the same.

Also worth noting you can get a lot of value out of the typescript ecosystem without actually using typescript. VSCode for example automatically acquires type definition files for npm modules, so if you require('ramda') you get code completion and inline documentation without doing any setup at all. The same is true for your project's module.exports or es6 exports. The typescript language service can be of use to you in a vanilla JS project. I'm sure the above is possible in any editor as well.

Gabe Johnson
@gabejohnson
Jan 27 2017 04:37
@JAForbes if you wanted to play around w/ sweet.js I would suggest the master branch. Lot’s of bug fixes. There’s a few breaking changes from v2 but all for the better
Rick Medina
@rickmed
Jan 27 2017 05:17
@JAForbes wow, awesome response thanks!
Rick Medina
@rickmed
Jan 27 2017 05:29
@JAForbes "I also found the bugs we get aren't the ones typescript could catch." Which ones? Are you talking about functional style js or "traditional"?
Rick Medina
@rickmed
Jan 27 2017 05:34
Kevin Wallace
@kedashoe
Jan 27 2017 05:54
@JAForbes I've updated the PR to include either
James Forbes
@JAForbes
Jan 27 2017 07:16

@gabejohnson thanks for the advice! :D I'll give that a go

@rickmed my pleasure

Re: bugs

I think the features Typescript has are designed to make imperative code a lot less dangerous. Most of the bugs Typescript would catch are the sort of bugs you already don't have if your writing in a functional style. The way we write code seems to already prevent the bugs Typescript would catch.

1 example would be handling possible undefined values. Possibly undefined values are common in JS because a lot of api's have optional parameters, or variadic signatures that are all considered valid. But if you keep different functionality in different functions, and you ensure your data structures are consistent, and you use functions like S.get or R.propOr - there aren't any possibly undefined values left.

Another example union types can be used to notify you when your not covering all possible branches in a given domain. And this works really well in ML influenced languages. But TS' union types are both slow to compile and awkward to use. I assume their slow because most people using TS aren't using unions often enough for optimization to become a priority. They're awkward because if your not just using string literals you need to rely on a shared key on each possible subtype in order to discriminate, which can limit its usage and prevents it from being a general pattern you can employ again and again. So when we did have a bug for not handling every possible case, it was impossible, or impractical to use typescripts discriminated unions to do so. It also encourages you to use switch statements (in order to discriminate unions), and despite eslint making switches less dangerous, I still avoid them.

I find if your writing code point free almost exclusively, and keeping each function's type signature as simple as possible, its actually quite challenging to end up in the problematic situations that would warrant typescript's poor performance, verbosity and awkward syntax/requirements.

SO I think types are great, but typescript itself, from my experience has limited returns if your writing functional code. And even worse I find typescript inhibits writing FP code, because you need to give it type hints so often that you give up and write code manually/imperatively so it can implicitly detect the correct type without the noise of annotations.

If you want typed code, I'd recommend checking out purescript, or F# (via fable), or Elm.

I should also state, I'm not at all saying typescript isn't a great project, it is. It's just got a particular target audience, and its made concessions to maximise the benefits for that target audience. I think the target audience is OO with nested conditionals, variadic apis, optional arguments and inheritance. If your writing code that way, typescript is a powerful/useful tool.

Its really helpful for me to keep a record of what bugs you encounter at work, categorise them and then think of programming practices that could prevent or decrease the chances of that bug occurring. Sort of like Crockford's good part's.

E.g. I found coworkers were using template literal syntax, but with the wrong quotation mark when calling rest endpoints. It was infrequent but it came up often enough that we created static functions to call each endpoint, and removed all manual string construction from the app. Now that bug can't happen.

Another example would be in virtual dom, having a trailing comma, or accidentally creating a sparse array. We adopted comma first style to make it painfully obvious when a comma was missing or when there was 1 too many commas. This also prevented a lot of merge conflicts when different branches were iterating on the same view.

So they are the kind of bugs we were getting, and typescript could not help with those bugs. But TS is still a valuable project in other contexts I think.

Kevin Wallace
@kedashoe
Jan 27 2017 07:23
great stuff @JAForbes , we were considering typescript at work but i wasn't super excited about it. feel much better about not going with it now :)
Keith Alexander
@kwijibo
Jan 27 2017 07:43
:point_up: January 27, 2017 4:28 AM Really valuable @JAForbes thanks
@ZaoIsmael
const getLeaf = ( startID, node) => 
    node.leaf.reduce((accum,child)=> 
                     node.id==startID? 
                     [...accum, child.id, ...getLeaf(child.id, child)] :
                     [...accum, ...getLeaf(startID, child)]
       , [])
Keith Alexander
@kwijibo
Jan 27 2017 07:48
Sudarsan Balaji
@artfuldev
Jan 27 2017 07:48
guys, any idea why R.tap was introduced, and any hints regarding the name? would really like to know
Ismael
@ZaoIsmael
Jan 27 2017 07:50
@kwijibo thx for the help
Keith Alexander
@kwijibo
Jan 27 2017 07:50
@artfuldev useful for eg, logging in the middle of a composition
Sudarsan Balaji
@artfuldev
Jan 27 2017 07:50
@kwijibo why the name tap, in particular?
kwijibo @kwijibo shrugs
Sudarsan Balaji
@artfuldev
Jan 27 2017 07:51
@kwijibo thanks, firstly
the reasons are kind of obvious, but the name is what intrigues me
I'm writing a similar library and the name Tap is what I'm using now, but it feels odd to use something without knowing why.
Keith Alexander
@kwijibo
Jan 27 2017 07:53
i always thought of it as like tapping into a flow without changing the flow
Sudarsan Balaji
@artfuldev
Jan 27 2017 07:53
That helps, thanks :)
Keith Alexander
@kwijibo
Jan 27 2017 07:53
i could be totally wrong!
Sudarsan Balaji
@artfuldev
Jan 27 2017 07:54
so it's mostly kind of a helper - to be used with composition or inside a forEach
Keith Alexander
@kwijibo
Jan 27 2017 07:54
you can use it inside a map, but inside forEach doesn't make sense since forEach doesn't return anything
Sudarsan Balaji
@artfuldev
Jan 27 2017 07:57
I thought R.forEach returned the original array
actually it says so in the docs: http://ramdajs.com/docs/#forEach
Keith Alexander
@kwijibo
Jan 27 2017 07:59
i thought you meant native forEach sorry
Sudarsan Balaji
@artfuldev
Jan 27 2017 07:59
Yeah, I guess I was confusing things.
Anyway, curious to know why Ramda avoids deferred execution etc.?
Keith Alexander
@kwijibo
Jan 27 2017 08:00
R.forEach(f) seems like R.map(R.tap(f))
Sudarsan Balaji
@artfuldev
Jan 27 2017 08:01
yes, my doubt exactly. But it isn't implemented that way. Why, I wonder?
It's implemented separately, without using either R.map or R.tap
Keith Alexander
@kwijibo
Jan 27 2017 08:03
iirc Ramda prefers not to implement ramda functions in terms of its public api
that may be why
Sudarsan Balaji
@artfuldev
Jan 27 2017 08:04
because the public api might change?
Keith Alexander
@kwijibo
Jan 27 2017 08:14
sounds plausible :)
Sudarsan Balaji
@artfuldev
Jan 27 2017 08:14
_ also has a tap function that allows it to 'tap into' method chains
I just googled it
thanks! :)
Matt McKellar-Spence
@MattMS
Jan 27 2017 09:21
@artfuldev re tap, maybe also https://en.m.wikipedia.org/wiki/Network_tap
There is also a Linux command that does the same thing in between piping commands.
Rick Medina
@rickmed
Jan 27 2017 12:47
@JAForbes really useful stuff thanks!
It would be amazing grouping gotchas, watch outs, etc when writing fp js somewhere
James Forbes
@JAForbes
Jan 27 2017 13:02

Thank you @rickmed. And I never tried ts-static-land btw, looks impressive! Gotchas are hard to write about I think because they're always context dependent and nuanced, but maybe in the limited context of FP in JS it could be ok?

@kedashoe thanks for adding that to your PR! That particular issue stumped for at least an hour yesterday :). And good luck with your tech stack choices at your work.

@kwijibo Thank you

Should note, I think the TS team is interested in FP, and they're looking into HKT (there are some issues bouncing around on their github) but I think there's just less demand for it than other things, and its so late in the game it may always feel awkward to write FP in TS.

Rick Medina
@rickmed
Jan 27 2017 14:03
yes (in the context of fp js) (not saying from you necessarily but the community I mean)
@JAForbes
Rick Medina
@rickmed
Jan 27 2017 14:23
would you mind sharing your library stack of choice when writing fp js? eg: ramda, sanctuary, fun-task, ramda fantasy, etc...fs, network libraries...daggy...?
Stefan Rimaila
@stuf
Jan 27 2017 14:24
ramda, partial.lenses, and kefir.atom along with static-land has been a very exciting combination lately.
esp. since partial.lenses works so well with ramda
Rick Medina
@rickmed
Jan 27 2017 14:27
@stuf for IO and async?
partial.lenses looks cool
Stefan Rimaila
@stuf
Jan 27 2017 14:28
For async I think I've just been using kefir, turning events and promises into streams and acting upon those.
The calmm.js "stack" is pretty exciting in that sense, especially kefir.atom when used in conjunction with karet.util (karet is something akin of a wrapper to React to embed observables into the VDOM). Worth checking out as well.
But partial.lenses has been a godsend, solved so many problems with handling arbitrary JSON data (and, well, data in general)
Rick Medina
@rickmed
Jan 27 2017 14:31
calmm seems sort of cyclejs with lenses?
Stefan Rimaila
@stuf
Jan 27 2017 14:32
yeah, a bit like that. more like a collection of some libraries that you can use together (or with something else too)
Rick Medina
@rickmed
Jan 27 2017 14:33
how do you use static-land? I thought it was only a spec
Stefan Rimaila
@stuf
Jan 27 2017 14:33
but definitely worth playing around with, esp. the lenses library.
ah yeah, not static-land per se, there are some operations in the lens library that works with static-land -compatible specs, as well as with the reactive library (kefir)
Rick Medina
@rickmed
Jan 27 2017 14:34
lenses are cool! good that partial.lenses is "performance oriented"
gotcha
Rick Medina
@rickmed
Jan 27 2017 14:39
@JAForbes Could you share this? It would be amazing "Its really helpful for me to keep a record of what bugs you encounter at work, categorise them and then think of programming practices that could prevent or decrease the chances of that bug occurring."
Rick Medina
@rickmed
Jan 27 2017 14:52
I'm specially interested in "ensure your data structures are consistent"
Jonah
@jonahx
Jan 27 2017 15:02
excuse the not ramda-specific question, but since i respect many people on this channel figured i’d ask: has anyone dealt with reading and writing large quantities of numeric data (gigabytes) to disk? ofc i could dump it as json, but i’d guess there are far more space efficient solutions. can anyone recommend one, either built in or an npm module?
Alex Deas
@alex-deas
Jan 27 2017 15:05

The first question you should be asking is, why are you using JavaScript to process Gb of data and write to disk?

It's difficult to give a recommendation without knowing what sort of data you're dealing with, how often will it need to be accessed etc

Jonah
@jonahx
Jan 27 2017 15:19
@alex-deas basically, large arrays of floats. i’ll be reading them in from a system process, and then saving them to disk. later they’ll be read back from disk, and some computations will be done. so “not often” to your question about accessing them. GBs is probably an overestimate. It was more a shorthand way of saying “disk space matters in this case” so a serialization method that’s half as big as JSON would be a win. to answer your first question, i’m using JS because the project has a frontend component and i’d rather just use the same language for everything, because while i’d like efficiency when saving, i don’t think speed matters so much that i need to use a system language. ie, “JS should be fine"
Rick Medina
@rickmed
Jan 27 2017 15:45
@jonahx I'm far from an expert but an alternative to json would be a database (one that adjusts to your data shape/needs) and use any of npm's client libraries. The problem with dumping to json (almost 100% sure) is that whenever interacting with it you will load all the data into memory (GBs), a DB will not. If you are worried about disk usage you could compress/uncompress on each interaction (minding the cpu overhead) but the memory issue would stand.
Keith Alexander
@kwijibo
Jan 27 2017 15:53
regarding serialising arrays of floats, csv or tsv would of course be more efficient than JSON
Jonah
@jonahx
Jan 27 2017 16:13
@rickmed that’s a good point, and probably where this leads, but i’m in the playing around stage atm, so a db probably adds more complexity than it’s worth.
Kurt Milam
@kurtmilam
Jan 27 2017 16:15
@jonahx I don't have any experience with it, but this could be an interesting solution: http://msgpack.org/index.html
Jonah
@jonahx
Jan 27 2017 16:15
@kwijibo i think the problem with csv is that it’s still a text format, so i’m spending a byte for each digit of every float, as opposed to 8 bytes for storing the JS float at full accuracy. or only 4 if im willing to give up some precisoin. correct me if i’m wrong.
Sudarsan Balaji
@artfuldev
Jan 27 2017 16:16
@MattMS thanks! :)
Jonah
@jonahx
Jan 27 2017 16:17
@rickmed that looks promising, thanks
Kurt Milam
@kurtmilam
Jan 27 2017 16:18
@jonahx msgpack stores floats in either 5 or 9 bytes, depending on whether the float is single or double precision.
Keith Alexander
@kwijibo
Jan 27 2017 16:21
@jonahx JSON is just stored as Unicode
Rick Medina
@rickmed
Jan 27 2017 16:21
@jonahx maybe this will fit you https://github.com/louischatriot/nedb
Keith Alexander
@kwijibo
Jan 27 2017 16:22
so while it could encode floats in a more space efficient manner, it just encodes everything as a sequence of unicode characters doesn't it?
Rick Medina
@rickmed
Jan 27 2017 16:22
(re: there is a way to read json/compress/uncompress as streams but that depends on what will you do (read/write) with your data
Jonah
@jonahx
Jan 27 2017 16:25
@kwijibo yes i believe that’s correct, which is the problem.
@rickmed thx for nedb link
Keith Alexander
@kwijibo
Jan 27 2017 16:27
oh sorry i misread you - JS as JSON
Alex Deas
@alex-deas
Jan 27 2017 16:41
A large number of arrays, you could store it as vectors? Possibly with one file providing your vector map. After you've loaded the map you can load the rest of the files asynchronously
Gabe Johnson
@gabejohnson
Jan 27 2017 17:09
@JAForbes :thumbsup: there’s a gitter community. feel free to ping me or disnet w/ any questions
Rob Halff
@rhalff
Jan 27 2017 18:00
would it be fairly save if I point to a function directly. e.g. 'ramda/src/curry' to avoid loading the whole ramda lib? I see src/ is available in the npm package.
Rob Halff
@rhalff
Jan 27 2017 18:08
Nevermind, lodash.curry is a better option in this case.
Ken Aguilar
@piq9117
Jan 27 2017 20:52
hello
so how do you bundle ramda-fantasy with system.js?
James Forbes
@JAForbes
Jan 27 2017 21:17

@rickmed its all on issue/pull request threads on a private repo :(

From here on in I'll keep the notes in a gist and try to turn it into a blog post though.

Rick Medina
@rickmed
Jan 27 2017 21:50
@JAForbes awesome! Also, would you mind sharing your library stack of choice when writing fp js? eg: ramda, sanctuary, fun-task, ramda fantasy, etc...fs, network libraries...daggy...?
James Forbes
@JAForbes
Jan 27 2017 21:52
Sure, I tend to use fluture, union-type, sanctuary, ramda, flyd and mithril.
For fs/network stuff I just futurize the node api.
Jonah
@jonahx
Jan 27 2017 22:03
@JAForbes hadn’t heard of union-type before, looks nice. per @rickmed’s question about fun-task, how do you deal with error handling?
Rick Medina
@rickmed
Jan 27 2017 22:04
@JAForbes thanks!
@jonahx I recommend this https://vimeo.com/113707214, it is f# but the ideas apply
Jonah
@jonahx
Jan 27 2017 22:07
@rickmed yes, i’ve seen that before. good video.
Stefan Rimaila
@stuf
Jan 27 2017 22:07
sanctuary is nice, a shame it's out of the box just Maybe and Either, more or less :(
James Forbes
@JAForbes
Jan 27 2017 22:09
@stuf I think sanctuary is aiming to interop with other libraries, and even remove maybe/either from its core in future. That's what projects like https://github.com/sanctuary-js/sanctuary-type-classes and https://github.com/sanctuary-js/sanctuary-type-identifiers are about
@jonahx yeah great video. That's how I handle errors too.
Stefan Rimaila
@stuf
Jan 27 2017 22:09
Was too fast too fast to hit enter, realized that just as I was writing it.
Friday etc.
But Sanctuary's Maybe already is a huge help for taking in data for transformation and chaining the transformation steps through Maybes
James Forbes
@JAForbes
Jan 27 2017 22:22
Yeah its brilliant
Stefan Rimaila
@stuf
Jan 27 2017 22:24
repeating myself probably, but partial.lenses has been a lifesaver lately, esp. since it works together with ramda so well
Rick Medina
@rickmed
Jan 27 2017 22:35
@JAForbes any tips on unit testing? (sorry for the question bombarding)