These are chat archives for ramda/ramda

28th
Apr 2017
Cody
@Condell
Apr 28 2017 00:38 UTC
this is kind of a dumb question I guess, but are composed functions supposed to be unit tested? Even though we know each individual part works if those functions pass unit tests?
Rick Medina
@rickmed
Apr 28 2017 00:56 UTC
@Condell why not test just the composed one?
Cody
@Condell
Apr 28 2017 00:57 UTC
Because if I wanted to reuse one of the functions that was inside of the R.compose(), then I would know that function itself is good to go
Rick Medina
@rickmed
Apr 28 2017 01:01 UTC
@Condell I usually don't extract functions from a composition for reusability, just readability. I would keep them as internal in modules and unit test them only when exporting them (ad-hoc when needed), otherwise it seems premature work
Brad Compton (he/him)
@Bradcomp
Apr 28 2017 01:01 UTC
You want to test the highest level units you can (who cares if you call it a 'unit test'). When you test the composition, you are testing not just the individual functions, but also that they fit together how you think
So like, if you pass in an edge case does it break the composition
Cody
@Condell
Apr 28 2017 01:03 UTC
sigh ok, i've been going about this all wrong then lol. I always thought it was a best practice to test all your functions...
Rick Medina
@rickmed
Apr 28 2017 01:04 UTC
remember semantically h = g ∘ f ∘... it does not matter what h is composed of (pure functions of course)
Cody
@Condell
Apr 28 2017 01:05 UTC
so then how would you go about writing code in a test driven way if you're writing a bunch of little functions where errors could pop up anywhere, but you're not testing them to make sure you're getting what you want?
Brad Compton (he/him)
@Bradcomp
Apr 28 2017 01:05 UTC
Cody
@Condell
Apr 28 2017 01:05 UTC
yep that me hahaha
Brad Compton (he/him)
@Bradcomp
Apr 28 2017 01:07 UTC
You definitely want to write tests for any function that is potentially a source of bugs, but your main focus should be on your interfaces - at the module level, route level, etc.
Rick Medina
@rickmed
Apr 28 2017 01:07 UTC

where errors could pop up anywhere

?

Cody
@Condell
Apr 28 2017 01:09 UTC
If I write 5 different functions, and compose them like
const someName = R.compose(funct5, funct4, func3, funct2, funct1), and i didnt write unit tests for any of those functions, how would I know where the bug was?
If I didnt get back what i was expecting from someName*
Brad Compton (he/him)
@Bradcomp
Apr 28 2017 01:11 UTC

Say you have a function that inserts a new member into the database, and you have various functions that validate whether the member you are inserting is valid (email validation, required fields, max length requirements, etc.)

You want to start by writing a bunch of tests for inserting members, including trying to insert members who are missing fields, have an invalid email, etc. So then when you run the should return an error if you insert a record with an invalid email test you are testing the email validation function, even if your test is running the entire set of functions and not just the individual validation function

And from a TDD perspective, you can write that test before you even know if you are going to write an email validation function.
Rick Medina
@rickmed
Apr 28 2017 01:14 UTC
@Condell In an ideal world ramda would tell you helpful hints where you messed up :) Otherwise, I think is really personal (and your team) how you work with ramda. But is not that different from imperative, if you have a huge imperative function, how would you debug it?
I'm talking about pure data transformation functions though
Brad Compton (he/him)
@Bradcomp
Apr 28 2017 01:17 UTC
Yeah, sorry my goto example is impure :(
Cody
@Condell
Apr 28 2017 01:17 UTC
@Bradcomp so then you would have a bunch of little tests, and functions, along with the "big" test and composed function? I'm trying to make sure each my functions return a monad
so for each function its going to give back an Either, or a Future
or am i doing this completely wrong? lol
Rick Medina
@rickmed
Apr 28 2017 01:19 UTC
for side effect stuff I normally model with Tasks (as simple as they could get), and consider each one of them as a unit test
anything that involves chain, I consider (arguably) an integration test
but I'm really confident in composing them bc the behavior of the composition operators are really predictable in fp
which is part why laws are really important :)
Brad Compton (he/him)
@Bradcomp
Apr 28 2017 01:24 UTC

@Condell It depends on your goals. If you're writing a library, it makes sense to test every public function. If you're writing an application you want to verify the behavior of the application. If one of your functions is complicated, I would write a bunch of tests to verify that function, along with integration tests to verify the behavior of code that uses the function.

Remember the goal in writing the tests is to catch bugs before the code goes live (whatever that means), and to ensure future changes to the code don't break the existing functionality. If you write tests too granularly, it can make it difficult to change the code in the future.

Brad Compton (he/him)
@Bradcomp
Apr 28 2017 01:37 UTC
I should say that the fact that you are writing tests at all is fantastic, and will make your life better in the long run!
Cody
@Condell
Apr 28 2017 01:40 UTC
Thanks! I'm trying haha. I was struggling writing tests for Futures, but I looked at your egghunt-server repo and got some ideas. @Bradcomp
thats what I'm working on now, but I just refactored my tests similar to how you had them in egghunt so im gonna push that in a second
Stefano Vozza
@svozza
Apr 28 2017 05:50 UTC
I always write tests for the smaller functions too, more so because it's easier to find out what function is breaking than if you've one big test for a composition. No messing about with R.tap etc.
Stefano Vozza
@svozza
Apr 28 2017 06:24 UTC
anyone see the V8 javascript survey? of the proposed features half are OO focussed and none help with FP. make your voice heard:
https://docs.google.com/forms/d/e/1FAIpQLSegrt21-vrtT10OsZgSF5THwz8s30JNi6lrm_WoNigUjmZvzA/viewform?c=0&w=1e
Just RAG
@justrag
Apr 28 2017 06:26 UTC
And what are actually the things missing from JS now that would be useful for FP?
Stefano Vozza
@svozza
Apr 28 2017 06:30 UTC
Compose operator, ability to define infix functions
Something like the underscore character in scala for easy partial application
Stacksafe composition
Compiler optimisations for nested functions
Of course, none these will ever happen. Lol
But it never hurts to ask!
James Forbes
@JAForbes
Apr 28 2017 06:40 UTC
I think they will, but first C# has to do it, then we have to wait 5 or 6 years :)
I bet C# will get |> operators from F#, and then JS will get it, but it will be the year 2025
Just RAG
@justrag
Apr 28 2017 06:57 UTC
|> is the compose operator?
James Forbes
@JAForbes
Apr 28 2017 07:51 UTC
pipeline operators
like an eager backwards compose
Stefano Vozza
@svozza
Apr 28 2017 08:00 UTC
"I think they will, but first C# has to do it, then we have to wait 5 or 6 years" :D
James Forbes
@JAForbes
Apr 28 2017 08:04 UTC
:)
Denis Stoyanov
@xgrommx
Apr 28 2017 08:45 UTC
Will be better to have infix operators in js with priority and associativity like in haskell (of course u can to try livescript)
James Forbes
@JAForbes
Apr 28 2017 08:51 UTC
Yeah I can get behind infix :thumbsup:
Just RAG
@justrag
Apr 28 2017 08:51 UTC
@ram-bot var obj = {key1: {k1: 1, k2: 2, k3: 3}, key2: {k1: 4, k2: 5, k3: 6}} R.evolve({key2: {k2: R.always(10), k3: R.always(11)}},obj)
ram-bot
@ram-bot
Apr 28 2017 08:51 UTC
{ key1: { k1: 1, k2: 2, k3: 3 },
  key2: { k1: 4, k2: 10, k3: 11 } }
Just RAG
@justrag
Apr 28 2017 08:52 UTC
Is there a better way to replace multiple deep properties without touching others?
(I want to replace .k2 and .k3 in key2.)
Denis Stoyanov
@xgrommx
Apr 28 2017 08:53 UTC
Lens
Envolve
Or evolve :smile:
I forgot
Just RAG
@justrag
Apr 28 2017 08:54 UTC
I'm using evolve above, but in a kinda-hacky way ;)
Denis Stoyanov
@xgrommx
Apr 28 2017 08:54 UTC
Map + lens
Rick Medina
@rickmed
Apr 28 2017 12:31 UTC

I think they will, but first C# has to do it, then we have to wait 5 or 6 years :)

then, damn it, where is the c# survey?? @JAForbes

James Forbes
@JAForbes
Apr 28 2017 12:32 UTC
ooo nice strategy!
Denis Stoyanov
@xgrommx
Apr 28 2017 12:32 UTC
?
F# > C#
Almost all features C# was stolen from F# :smile:
James Forbes
@JAForbes
Apr 28 2017 12:33 UTC
@xgrommx I was joking that tc39 is heavily influenced by C# language design, and if we want functional features in JS we need to wait until they get implemented in C#, so @rickmed is suggesting we find the C# survey and speed things up :)
Rick Medina
@rickmed
Apr 28 2017 12:34 UTC
I put all 1 :) and stated all the functional optimizations I could think of (I'd think they are more probable since they don't need a spec)
James Forbes
@JAForbes
Apr 28 2017 12:35 UTC
Yeah its not a bad strategy, honestly
Gabe Johnson
@gabejohnson
Apr 28 2017 12:37 UTC
Function.prototype.curry
With the semantics of curry in Ramda/Lodash
Denis Stoyanov
@xgrommx
Apr 28 2017 12:40 UTC
@JAForbes don't wait - elm, purescript,ghcjs and maybe livescript :smile:
James Forbes
@JAForbes
Apr 28 2017 12:43 UTC
@xgrommx purescript / elm I agree, but its pretty hard to move from an existing codebase into that ecosystem. Never used ghcjs, but I assume its even more the case. Livescript's tooling is pretty disappointing, I like the language, I use it a lot for build scripts. But its painful for anything bigger I've found at least.
The great thing about livescript is it immediately works with the JS ecosystem, which isn't true of most other FP compile to languages
Alexander Fell
@enzuguri
Apr 28 2017 12:48 UTC
Hello all, I was wondering if anybody can help me with a toy example, specifically with operator choice?
let asyncRequest = (url) => {
  return Promise.resolve(`${url}-response`);
};

let outgoingRequests = {
  requestA: 'http://example.com?q=a',
  requestB: 'http://example.com?q=b'
};

let magicReduce = (acc, value) => {
  return [
    R.append(value[0], acc),
    asyncRequest(value[1])
    ];
}

let promiseAll = (x) => Promise.all(x);

let requester = R.composeP(
  // convert [['key', ...], ['response', ...]] to obj
  R.apply(R.zipObj),
  R.compose(
    // convert to Promise.all(keys, Promise.all)
    promiseAll,
    // convert to [['key', ...], Promise.all]
    R.adjust(promiseAll, 1),
    // convert to [['key', ...], [Promise, ...]]
    R.mapAccum(magicReduce, []),
    // convert obj into [['key', 'query'], ...]
    R.toPairs
  ));

requester(outgoingRequests)
  .then(x => console.log(x))
// prints { requestA: '${url}-response', ...}
Specifically, I'm unsure about the use of mapAccum here, and whether there can be a better choice?
Gabe Johnson
@gabejohnson
Apr 28 2017 12:53 UTC
Function.pipe w/ compiler support
Galileo Sanchez
@galileopy
Apr 28 2017 16:57 UTC

do any of you have any suggestion on how could I change my front end file distribution preserving the following properties?

  • Should have the ability to use commonJS require with npm modules on my front-end files
  • Should be able to compile the whole application to only one file
  • Should have a way to explicitly tell the compilation system which files to include and in which order
  • There should be a way to explicitly tell when each module should be executed.

Right now I have a client folder with a an index.js file which requieres the files that I need manually
This index file is built using browserify, and each module has a guard statement that prevents further execution
in case some predicate is false

if(not (theContentsOfThisFileShouldBeExecuted())) return;

or another common situation

if(not  (current route matches the route this file is intended to run on)) return;

What bothers me of this setup is mainly that if I forget the ward I will have unnecessary stuff running on the background.

Rick Medina
@rickmed
Apr 28 2017 20:32 UTC
unrelated: can I get some opinions about graphql? :)
Vasili Sviridov
@vsviridov
Apr 28 2017 21:38 UTC
@rickmed graphql is really nice
some things are non-trivial, like access control
and caching, potentially