These are chat archives for ramda/ramda

4th
Jun 2018
Dennie de Lange
@tkvw
Jun 04 2018 12:46
I see code like this: type => not(contains(type,['something'])), am I correct to say this is an antipattern (because the composed function is created each time)?
Urban
@UrKr
Jun 04 2018 13:17
Do the new additions to Typescript enable any improvements to the typings here ?
https://github.com/types/npm-ramda
Selwyn
@Siilwyn
Jun 04 2018 13:18
@UrKr not a Typescript user but that sounds like a vague question...
Urban
@UrKr
Jun 04 2018 13:20
It is a vague question. But there are some issues that are pointed out by the maintainers of npm-ramda, and I'd be surprised if the new additions don't solve any of them. It might be too general a question though.
Brad Compton (he/him)
@Bradcomp
Jun 04 2018 15:28

@tkvw I would agree it's an antipattern, but not for the reason you specify.

x => not(f(x)) can always be rewritten to complement(f), which is preferable to me.

Brad Compton (he/him)
@Bradcomp
Jun 04 2018 15:42
@UrKr You might get better answers in their gitter rather than here. I don't think any of the core team works with Typescript, but there are some who frequent these parts that do...
Stephen Ely
@reallyely
Jun 04 2018 17:00

Hey gang, I have a case that I'm not able to find information on through searching because I'm not really clear on how to articulate it succinctly, but I'm certain this is a solved/ not uncommon case.

I have one data structure, fairly large, that I need to derive different sets of values from.

Currently I'm map/filter/reducing this one data set three times, but that, of course, is not ideal. Is there a way with Ramda that I can save unnecessary iterations, and still derive these three sets of data?

Brad Compton (he/him)
@Bradcomp
Jun 04 2018 17:03
@reallyely Often times a single reduce will do the trick. In reality though, the devil is in the details. Is there a succinct example you might be able to provide?
Stephen Ely
@reallyely
Jun 04 2018 17:04
I have some notion of how I would write a function to handle this case using reduce, but didn't want to reinvent the wheel. Lemme write up a succinct example.
Stephen Ely
@reallyely
Jun 04 2018 17:07
Riggght transducers!
const uom = 'in'
const data = [
  {id, name, value}, ...
]

const dataIds = map(prop('id'), data)
const dataValues = map(toValueWithUnitOfMeasure(uom), data)
const maxValue = reduce(toMaxValue, 0, data)
Mike Lambert
@lax4mike
Jun 04 2018 17:15
how large is your data? this code is clear, and i wonder how readable it would be to accomplish this in 1 iteration...
ie. is this the bottleneck of your application?
Stephen Ely
@reallyely
Jun 04 2018 17:19
I'm not sure if I'm noticing a performance hit, it's still in the milliseconds.
Data can be anywhere from 1 - dozens of arrays of ~1000 objects, so I'm estimating around 10,000 as being on the higher end, maybe more like 5,000
For the average case
Stephen Ely
@reallyely
Jun 04 2018 17:27
You may be right. It may not be worth fretting over until we notice issues as I'm happy with the clarity, too.
I'll look at transducers as an option. Thanks for your feedback
Mike Lambert
@lax4mike
Jun 04 2018 17:28
yeah, transducers or a single reduce, let us know what you find out!
Brad Compton (he/him)
@Bradcomp
Jun 04 2018 17:31
I think it's clearer there than with a single reduce, but it could certainly be done.
Keep in mind that you're still dealing with linear time with one or 3 iterations. Often times it is better to optimize where you can get improvements in your big O rather than just single digit multipliers.
Dennie de Lange
@tkvw
Jun 04 2018 17:39
@Bradcomp : you say my reasoning is flawed? (i.e. the function being generated each time)
or should I just not care?
Brad Compton (he/him)
@Bradcomp
Jun 04 2018 17:39
I agree the function is being generated each time, but that isn't always an anti-pattern
Dennie de Lange
@tkvw
Jun 04 2018 17:40
ok, just checking my assumption, I understand your other comment; thanks :+1:
Brad Compton (he/him)
@Bradcomp
Jun 04 2018 17:40
:+1:
Daniel Rodríguez Rivero
@danielo515
Jun 04 2018 17:57
From my point of view you should always prefer to not create functions on the fly. Building them beforehand gives the compiler the chance to optimize them
One small question. How do you extract values from ADTs when you need to interact with the outside world? Sure you can lift any third party functions, but what about serialization and RPC?
For anyone interested here is a small benchmark about how performant transducers are, which is huge : https://danielorodriguez.com/nodejs-benchmarks/transducers.html
The code difference is not much complex
Brad Compton (he/him)
@Bradcomp
Jun 04 2018 18:14
@danielo515 as a general rule I agree, but always is a strong term. There are times (ramda/ramda#2491) where it can lead to some tricky bugs.
Brad Compton (he/him)
@Bradcomp
Jun 04 2018 18:25
Do you want to serialize the whole ADT, or just the value inside it?
In general it depends on the library. Daggy uses the cata method which lets you pass in the extraction method for each constructor. Sanctuary has functions like fromMaybe and either to get the values out. Typically Futures and Tasks with have a fork method or function.