These are chat archives for ramda/ramda

6th
Jun 2016
Scott Christopher
@scott-christopher
Jun 06 2016 00:27
@aknuds1: You could also use a lazy right fold/reduce which passes the accumulator as a thunk that must be evaluated if you want to continue.
So it would look something like:
const lazyFoldR = (fn, acc, xs) =>
  xs.length === 0 ? acc : fn(xs[0], () => lazyFoldR(fn, acc, xs.slice(1)));

const mapFind = (mapFn, predFn, defaultVal, xs) =>
  lazyFoldR((x, acc) => {
    const mapped = mapFn(x)
    return predFn(mapped) ? mapped : acc()
  }, defaultVal, xs)
Arve Knudsen
@aknuds1
Jun 06 2016 00:28
Thanks @scott-christopher !
Hardy Jones
@joneshf
Jun 06 2016 01:42
didn't like my lazy idea eh? ;)
I thought it was pretty good.
@ram-bot
const Nil = {
  find: _ => null,
  map: _ => Nil,
};

const Cons = x => force => ({
  find: p => p(x) ? x : force().find(p),
  map: f => Cons(f(x))(() => force().map(f)),
});

const lazy = xs => xs.length === 0 ? Nil : Cons(xs[0])(() => lazy(xs.slice(1)));

R.find(R.lt(2), R.map(R.inc, lazy([1,2,3])))
ram-bot
@ram-bot
Jun 06 2016 01:42
3
Hardy Jones
@joneshf
Jun 06 2016 01:44
You should probably also note that find(p, map(f, x)) == find(compose(p, f), x)
if you're concerned about efficiency.
erm...
find(p, map(f, x)) == f(find(compose(p, f), x))
assuming you actually find something.
if not finding something is a possibility, S.find is a better thing to look towards.
Brad Compton (he/him)
@Bradcomp
Jun 06 2016 01:49
@joneshf I liked it! but I also like messing with transducers
Hardy Jones
@joneshf
Jun 06 2016 01:50
:+1:
Another option is extending ramda with something like (a -> Maybe b) -> [a] -> Maybe b
Hardy Jones
@joneshf
Jun 06 2016 01:55
or sanctuary probably is more appropriate
Brad Compton (he/him)
@Bradcomp
Jun 06 2016 01:57
Yeah, currently Ramda doesn't ever give back Maybes
Scott Sauyet
@CrossEye
Jun 06 2016 01:59
Although that may be changing soon... #1786
Hardy Jones
@joneshf
Jun 06 2016 02:08
cool
Brad Compton (he/him)
@Bradcomp
Jun 06 2016 02:25
I know I said this in the PR, and I am not trying to flame, but I still don't understand why Ramda is exposing a custom data type that isn't used internally, and isn't returned by any of the other functions in the library.
Tim Navrotskyy
@dypsilon
Jun 06 2016 07:53
Hi, is there a version of concat which accepts multiple arguments?
@ram-bot
R.concat([1,2], [3,4], [5,6]);
Aldwin Vlasblom
@Avaq
Jun 06 2016 08:07
@ram-bot R.reduce(R.concat, []) /***/ ([[1,2,3], [4,5,6], [7,8,9]])
ram-bot
@ram-bot
Jun 06 2016 08:07
[] does not have a method named "concat"
Aldwin Vlasblom
@Avaq
Jun 06 2016 08:07
-,-
Tim Navrotskyy
@dypsilon
Jun 06 2016 08:09
oh, right, reduce
thanks @Avaq
Stefano Vozza
@svozza
Jun 06 2016 09:16
Bear in mind that using concat with reduce will mean that you will clone every intermediary array too.
Tim Navrotskyy
@dypsilon
Jun 06 2016 10:41
@svozza thanks, I have concat method on my objects though
Ronn
@ronnross
Jun 06 2016 12:08
Hi I have a function that takes in a param that might not be there. It seems like this would be a great case for maybe, but I'm unable to really find docs on maybe.
for example, Can I use a maybe in this case if win is not there R.assoc('os_name', getOsName(getUserAgent(win))),
Aldwin Vlasblom
@Avaq
Jun 06 2016 12:31
It's more common to use Maybe in cases where a function might not return something, as apposed to using it as input for a function. Mind showing what win is and how you acquire it?
Ronn
@ronnross
Jun 06 2016 12:32
When the function is initially called window is passed in.
Aldwin Vlasblom
@Avaq
Jun 06 2016 12:43
//`S` is Sanctuary

//getWin :: () -> Maybe Win
const getWin = () => S.toMaybe(win) //The function that provides you with Win returns a Maybe

//getOsName :: Win -> OsName
const getOsName = R.compose(getOsName, getUserAgent) //Given a Win, returns an OsName

//maybeOsName :: Maybe OsName
const maybeOsName = getWin().map(getOsName); //Map `getOsName` over the result of `getWin`, leaving us with a Maybe OsName

//Using S.fromMaybe, we extract the Maybe OsName to an OsName (given that `<unknown>` be a member of OsName).
R.assoc('os_name', S.fromMaybe('<unknown>', maybeOsName))
This is usually how I'd go about it: Returning Maybe instances from functions, and mapping "normal" functions over my Maybe instances. Actually passing the Maybe instance into a function is only needed for much more specific use-cases.
Ronn
@ronnross
Jun 06 2016 12:57
Ah thank you very much
Martin Broder
@mrtnbroder
Jun 06 2016 14:36

Hey everyone, making this completely point-free is not possible, is it?
http://goo.gl/7Ddd5j

imagine the pointfreepls is a function called by some other function with the data I've setup there.

I'm basically mapping over an array of objects, form it into a useable array that filters out the differences.
Brad Compton (he/him)
@Bradcomp
Jun 06 2016 14:41
@mrtnbroder useWith can come in handy here: http://goo.gl/UxojWE
Aldwin Vlasblom
@Avaq
Jun 06 2016 14:42
You can make it point-free if you use a proper flip and compose: http://goo.gl/rC2nrb
Not that it makes the code any better. Any developer will look at that and go o.0. A general rule I like to follow is: If you find yourself asking "how do I make this point-free?", then don't make it point-free.
Martin Broder
@mrtnbroder
Jun 06 2016 14:48
that was quick, thanks!
Brad Compton (he/him)
@Bradcomp
Jun 06 2016 14:49
The easiest way to get a quick response is to say something's impossible ;)
Martin Broder
@mrtnbroder
Jun 06 2016 14:49
@Avaq true words :) I think this is still readable though in my case
hehe
Aldwin Vlasblom
@Avaq
Jun 06 2016 14:49

The easiest way to get a quick response is to say something's impossible

true that :D

Brad Compton (he/him)
@Bradcomp
Jun 06 2016 14:50
I often find I learn quite a bit in the process of refactoring something to be point-free, but it's usually better as a learning exercise, rather than for production code that has to be read by others.
Martin Broder
@mrtnbroder
Jun 06 2016 14:52
the whole file is basically point-free, this would have been the first function that wasn't
so I thought, dayum, how can I make this point-free
Brad Compton (he/him)
@Bradcomp
Jun 06 2016 14:53
That's fun
Martin Broder
@mrtnbroder
Jun 06 2016 14:53
bugged me quite a bit :shipit:
Tim Navrotskyy
@dypsilon
Jun 06 2016 20:59
Hi, everyone, so I'm at this place again where I have an array of Futures. This time I want to run a reduce on it, though because I need to find the biggest value (R.max). Do you have a hint for me how to proceed? My intuition is to use traversable, but it's so so weird...
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:12
Is there a Promise.all for Futures?
Aldwin Vlasblom
@Avaq
Jun 06 2016 21:12
I think you could reduce(lift(max), Future.of(0)) (futures) or compose(reduce(max, 0), sequence(Future.of)) (futures)
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:12
I'm reading the docs now and it doesn't seem like it.
Aldwin Vlasblom
@Avaq
Jun 06 2016 21:12
@LeonineKing1199 Fluture has Future.parallel
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:13
This message was deleted
Aldwin Vlasblom
@Avaq
Jun 06 2016 21:14
But with Futures that have parallel ap, which all do now, you can use sequence(Future.of) like Promise.all
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:14
@Avaq I'm trying parallel right now, but I have a feeling that there is a more elegant way. Lifting looks just like it.
@Avaq by the way, thank you for Fluture, I'm using it right now. Very nice implementation.
Aldwin Vlasblom
@Avaq
Jun 06 2016 21:15
:D Awesome
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:17
What are the pros and cons in R.sequence vs Fluture.parallel? They seem identical to me on the surface...
Aldwin Vlasblom
@Avaq
Jun 06 2016 21:18
Future.parallel is a bit more specialized, in that it has built-in throttling. It might also have a small performance benefit, but I'm saying that purely on intuition, so you might wanna' doublecheck. ^^
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:19
Microoptimization is not that important to me right now.
Aldwin Vlasblom
@Avaq
Jun 06 2016 21:21
Nah, so it's just the throttling that makes the difference. Other than that they each turn an Array Future a into a Future Array a, maintaining ordering.
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:30
@Avaq great, thank you for help!
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:31
This Future stuff seems neat. I'm a co fanboy but, dang, Futures seem cool.
Would it be possible to somehow combine the amazingness of generator-based async control flow with some of the Fantasyland stuff?
Or are they diametrically opposing ideologies?
Aldwin Vlasblom
@Avaq
Jun 06 2016 21:38
@LeonineKing1199 https://github.com/Avaq/Fluture#do or more general: https://github.com/russellmcc/fantasydo, which, unlike co, you can use on any Monad.
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:38
afaik they are, generators are iterators and iterators are imperative by nature, but there is "fantasy do" which marries the both worlds happily
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:39
Yay! Someone's combined them and it's glorious!
Thank God.
Omg.
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:40
also i'm not there yet to use "do", it's still a mystery for me right now, like T Monads
I'm trying to write a monadic shell wrapper right now, and having pretty hard time, but even in the current form it rocks. Just by applying some functional programming principles the benefits are huge.
maybe I should write some haskell, but damn, it's time consuming!
Aldwin Vlasblom
@Avaq
Jun 06 2016 21:44

Cases where do is really nice is when you find yourself building the pyramid because you need access to variables at multiple stages along your chain:

thing().chain(x =>
  something(x).chain(y =>
    somethingElse(x, y).chain(z => ...)
  )
)

Turns into:

Future.do(function*(){
  const x = yield thing();
  const y = yield something(x);
  const z = yield somethingElse(x, y);
  ...
})
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:45
oh, that's actually awesome
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:45
I was gonna say, it's funny that you mention functional principles helping when I'm the opposite, I think functional combined with imperative is one of the best combos out there.
It's like Reese's Peanut Butter Cup good.
TM
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:46
well, I see functional programming more as an architecture pattern lately
nobody cares if the insides of your function are imperative, only the input and output matters
but truly functional programs are only possible with the right architecture around those functions
like virtual dom or cycle.js
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:48
Well, I'm under the mindset that any language that isn't multi-paradigm is relatively useless.
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:48
as in "any function without side effects is useless"?
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:48
No, I mis-typed and meant programming language :P
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:49
oh, well, I can't tell till I work with haskell
or at least clojure
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:50
A lot of languages are adopting functional things as well. Java/C++ now have lambdas and both those languages have always support immutability.
The only thing you can't actually stop is variable capture.
But that's okay.
I don't know much Haskell but I think you could literally create C++ versions of all their types.
And the Haskell runtime is implemented in C, I believe. Well, the GHC runtime.
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:54
imho it's not so easy to implement the types without using them for a while
and the ecosystem is just there
that's what scares me in functional javascript right now: people just don't understand/care to understand
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:55
Well, whose fault is that, really?
Languages are tools and if people don't care to learn the tool, is it the person's fault or the tool's?
People don't like tools that they can't figure out how to use.
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:56
i fear, that javascript is meant to be used imperatively, at least thats what 95% of devs are doing in the current ecosystem
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:56
That's true but to a degree. Everything in JS is an object, meaning functions are as well.
That's a huge first step towards functional code.
JS' biggest problem is its lack of typing and immutability.
Chet Harrison
@ChetHarrison
Jun 06 2016 21:57
@dypsilon it's got all the goods it needs to go FP
so it's a hybrid
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:57
sure, it's possible to write pure functional code, but that's not what the ecosystem is doing right now
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:57
And I think it's indicative of how powerful combining those paradigms is.
Chet Harrison
@ChetHarrison
Jun 06 2016 21:57
you can use a little of both OO and FP
LeonineKing1199
@LeonineKing1199
Jun 06 2016 21:57
You shouldn't be writing pure anything, imo.
All imperative = awful. All OO = awful. And by that token, yes, even all FP = awful.
The ability to shift paradigms is incredibly powerful and adaptive. We live in a good age of programming, I think.
Tim Navrotskyy
@dypsilon
Jun 06 2016 21:59
tbh I don't want to write any of this: FP or OOP. All I want is to manage the side effects and reuse the code more. OOP+impreative is weak for both of this wishes.
Chet Harrison
@ChetHarrison
Jun 06 2016 21:59
:+1:
LeonineKing1199
@LeonineKing1199
Jun 06 2016 22:00

tbh I don't want to write any of this: FP or OOP. All I want is to manage the side effects and reuse the code more. OOP+impreative is weak for both of this wishes.

OO got popular exactly because it manages flow and side-effects so well. I mean, what is a Monad if not a C++ class that takes functions in some of the arguments for its methods?

Tim Navrotskyy
@dypsilon
Jun 06 2016 22:02
I spent my 7+ years in the trenches with OOP and I still couldn't find a way to write concise code after all those books and refactorings. FP looks much better in this regard after half a year.
Chet Harrison
@ChetHarrison
Jun 06 2016 22:02
btw I just got my hands on the best js FP book I have ever read. I highly recommend it https://www.manning.com/books/functional-programming-in-javascript
LeonineKing1199
@LeonineKing1199
Jun 06 2016 22:03
Well, the real question becomes, were you writing only OO code?
OO can't solve everything by itself.
Granted, in a language like Java, you kind of don't really have a choice
And OO stuff in JavaScript is the worst, I've found.
Tim Navrotskyy
@dypsilon
Jun 06 2016 22:05
@LeonineKing1199 type classes like functors, monoids and monads are strictly speaking not OO. But seriously, looking at the Command Pattern from GoF I don't really know what OO is anymore.
@ChetHarrison thanks for recommendation, looks promising
Chet Harrison
@ChetHarrison
Jun 06 2016 22:06
trust me It has taken me years to compile all the information that book contains
you will read it in a day
Tim Navrotskyy
@dypsilon
Jun 06 2016 22:07
@ChetHarrison after glancing at the TOC I'm a bit disappointed there are no type classes.
Chet Harrison
@ChetHarrison
Jun 06 2016 22:08
it covers a hand full of the most usefull monadic types
plus lenses
and combinators
Tim Navrotskyy
@dypsilon
Jun 06 2016 22:10
oh, oh, that sounds interesting
thank you
Chet Harrison
@ChetHarrison
Jun 06 2016 22:10
:+1:
Stefano Vozza
@svozza
Jun 06 2016 22:52
i'm a bit surprised at how enthusiastic he is about lodash's chain function in chapter 3
Rob Halff
@rhalff
Jun 06 2016 22:56
How do I create something like composeP(neverRunResultAlreadyGiven, iKnowTheAnswer, noIdea) where all promises receive the same input object.
the only thing I can think of is to write the functionality from scratch.
Tim Navrotskyy
@dypsilon
Jun 06 2016 23:00
@rhalff that's a bit of a hack but you could partially apply all your functions with the value, this way they will ignore the value passed down through compose
Rob Halff
@rhalff
Jun 06 2016 23:05
@dypsilon I will still need the halt on success logic, it seems them being promises also complicates it, only composeP and pipeP are aware of them I think. e.g. can't use something like anyPass.
Tim Navrotskyy
@dypsilon
Jun 06 2016 23:06
@rhalff what do you mean by "halt on success logic"?
Brad Compton (he/him)
@Bradcomp
Jun 06 2016 23:07
@rhalff If you know the result of two of the functions, can you use something like Promise.all?
Tim Navrotskyy
@dypsilon
Jun 06 2016 23:09
have to go now, see you all tomorrow
Rob Halff
@rhalff
Jun 06 2016 23:11
ok have to rethink this, using promise all means not using ramda.