These are chat archives for ramda/ramda

12th
Apr 2016
Hardy Jones
@joneshf
Apr 12 2016 02:17
Given expressive enough types it could be.
But we rarely get that in practice because people complain that the types are too hard.
Hardy Jones
@joneshf
Apr 12 2016 02:37
@BorePlusPlus how about const splitInHalf = xs => R.splitAt(xs.length / 2, xs)?
@ram-bot
const splitInHalf = xs => R.splitAt(xs.length / 2, xs);
splitInHalf(R.range(1, 10))
ram-bot
@ram-bot
Apr 12 2016 02:39
[ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8, 9 ] ]
Hardy Jones
@joneshf
Apr 12 2016 02:39
@ram-bot
const splitInHalf = xs => R.splitAt(xs.length / 2, xs);
splitInHalf(R.range(1, 11))
ram-bot
@ram-bot
Apr 12 2016 02:39
[ [ 1, 2, 3, 4, 5 ], [ 6, 7, 8, 9, 10 ] ]
Lewis
@6ewis
Apr 12 2016 03:43
can I use R.evolve to add a new key that depends on other key
@Bradcomp *
David Langford
@That-David-Guy
Apr 12 2016 03:50
@joneshf Do you normally mix ramda methods and js object methods? e.g. you used xs.length /2 instead of R.divide(R.length(xs), 2)
So something like
const findHalfIndex = o => R.divide(R.length(o), 2)
const splitInHalf = xs => R.splitAt(findHalfIndex(xs), xs);
splitInHalf(R.range(1, 11))
Or is that just overkill?
David Chambers
@davidchambers
Apr 12 2016 04:49
@ram-bot
S.lift2(R.splitAt, S.compose(S.C(S.div, 2), R.length), S.I)([1, 2, 3, 4, 5, 6])
ram-bot
@ram-bot
Apr 12 2016 04:49
TypeError: S.C is not a function
David Chambers
@davidchambers
Apr 12 2016 04:51
@raine, how do we update the Sanctuary version used by ram-bot?
Nick Brown
@nick-brown
Apr 12 2016 06:47

Could anyone help me understand why

var getFromStorage = function(key) { return function() { return localStorage[key]; }; };

Differs from:

var getFromStorage = function(key) { return localStorage[key]; }

is there something significant about the former's use of a closure?
David Langford
@That-David-Guy
Apr 12 2016 06:52
@nick-brown The first one returns a function waiting to be called. The second one returns a value
To use the first one you would have to go getFromStorage(key)()
To use the second one you would have to go getFromStorage(key)
Nick Brown
@nick-brown
Apr 12 2016 06:52
ah so localStorage's values are going to be locked in place when I call getFromStorage the first time?
or am I misreading that
David Langford
@That-David-Guy
Apr 12 2016 06:53
In the first instance? I don't think that is a guarantee
This message was deleted
Nick Brown
@nick-brown
Apr 12 2016 06:54
hmm
David Langford
@That-David-Guy
Apr 12 2016 06:54
@ram-bot
var data = ['hello']
var getFromStorage = function(key) { return function() { return data[0]; }; };
var data = ['world']

getFromStorage()()
ram-bot
@ram-bot
Apr 12 2016 06:54
'world'
David Langford
@That-David-Guy
Apr 12 2016 06:54
Notice it prints world and not hello

In our chapter about purity we saw a peculiar example of a pure function. This function contained a side-effect, but we dubbed it pure by wrapping its action in another function. Here's another example of this:

//  getFromStorage :: String -> (_ -> String)
var getFromStorage = function(key) {
  return function() {
    return localStorage[key];
  };
};

Had we not surrounded its guts in another function, getFromStorage would vary its output depending on external circumstance. With the sturdy wrapper in place, we will always get the same output per input: a function that, when called, will retrieve a particular item from localStorage. And just like that (maybe throw in a few Hail Mary's) we've cleared our conscience and all is forgiven.

err
but I don't see how wrapping it in that function changes anything
other than, like you said, requiring two invocations to get your value back
oh, I guess because the key only gets used the first time the function is called, not later
David Langford
@That-David-Guy
Apr 12 2016 06:57
reading chapter
I think it's saying it is a pure function because it will always return a method, not that the method it returns is pure
David Langford
@That-David-Guy
Apr 12 2016 07:03
So
Nick Brown
@nick-brown
Apr 12 2016 07:03
gotcha - thanks!
David Langford
@That-David-Guy
Apr 12 2016 07:04
getFromStorage1('bananas') // -> Always returns a method that will get bananas from local storage. Is pure
getFromStorage2('bananas') // -> Return bananas value (can change, not pure)
I could be wrong though
Baqer Mamouri
@bmamouri
Apr 12 2016 07:04
Hey peeps, I am trying to figure out how exactly R. works but not have much success. My basic function:
const removeEmptyItems = R.filter(
  R.both(
    R.complement(R.isNil), 
    R.complement(R.isEmpty)
  )
)
const joinItems = R.compose(R.join(R.__), removeEmptyItems)

joinItems([1, 2, 3], ', ')
Nick Brown
@nick-brown
Apr 12 2016 07:05
@That-David-Guy no I think you're correct, 'bananas' gets 'locked in' so to speak.
David Langford
@That-David-Guy
Apr 12 2016 07:06
@nick-brown, locked in as an argument. Yes I believe so
David Langford
@That-David-Guy
Apr 12 2016 07:13

@bmamouri I'm new to ramda so I may be reading it wrong, but are you trying to do this?

@ram-bot

const addCommas = R.intersperse(', ')
const arrayToString = R.reduce((a, b) => a.toString() + b.toString(), '')
const joinItems = R.compose(arrayToString, addCommas)
joinItems([1, 2, 3]) // -> "1, 2, 3"

Or even simpler

@ram-bot

R.join(', ', [1, 2, 3])  // -> "1, 2, 3"
ram-bot
@ram-bot
Apr 12 2016 07:15
TypeError: [1, 2, 3] does not have a method named "join"
David Langford
@That-David-Guy
Apr 12 2016 07:15
ram-bot lies
Baqer Mamouri
@bmamouri
Apr 12 2016 07:17
@That-David-Guy I want to create a new function that accept two parameters.
I am jus trying to understand how the parameters to the function passed to composed functions.
I think I'd like to learn how exactly R.__ works. The sample in docs is very simplistic.
David Langford
@That-David-Guy
Apr 12 2016 07:19
Ahh ok. As a side note, if you use R.reject instead of R.filter you don't have to use R.complement
James Forbes
@JAForbes
Apr 12 2016 07:19

@bmamouri

R.reject will negate the need to complement the predicates:

const removeEmptyItems = R.reject(
  R.both(R.isNil, R.isEmpty)
)

But you could probably just do const removeEmptyItems = R.filter(Boolean)

Beat me to it @That-David-Guy! :)
David Langford
@That-David-Guy
Apr 12 2016 07:21
My understanding of R.__ is that normally in curried methods it is the last argument that it's waiting for. With R.__ you can move it to the first, or second, etc
@JAForbes :)
e.g.
@ram-bot
const add2 = R.add(R.__, 2);

add2(1)
ram-bot
@ram-bot
Apr 12 2016 07:21
3
David Langford
@That-David-Guy
Apr 12 2016 07:22
@ram-bot
const subtract2 = R.subtract(R.__, 2);

subtract2 (1)
ram-bot
@ram-bot
Apr 12 2016 07:22
-1
James Forbes
@JAForbes
Apr 12 2016 07:22
Also, even if there wasn't reject, you could negate the output of both
R.filter(
  R.complement(
    R.both(R.isNil,R.isEmpty)
  )
)
Baqer Mamouri
@bmamouri
Apr 12 2016 07:23
Thanks @That-David-Guy and @JAForbes I totally forget about reject. Much simpler:
const removeEmptyItems = R.reject(
    R.either(R.isNil, R.isEmpty)
)
James Forbes
@JAForbes
Apr 12 2016 07:23
:)
David Langford
@That-David-Guy
Apr 12 2016 07:24
@bmamouri so in your original example
const joinItems = R.compose(R.join(R.__), removeEmptyItems)

joinItems([1, 2, 3], ', ')

// IS THE SAME AS 

R.compose(R.join([1, 2, 3]), removeEmptyItems)(',')
Which doesn't return a proper result btw
James Forbes
@JAForbes
Apr 12 2016 07:25
@bmamouri you may want to use useWith or converge
David Langford
@That-David-Guy
Apr 12 2016 07:25
I have to head off, but hopefully I have told any furphies! Good luck @bmamouri :)
Baqer Mamouri
@bmamouri
Apr 12 2016 07:27
Thank you both @That-David-Guy, @JAForbes. You guys game much lot to learn about.
@JAForbes converge sounds great. I try to write it with converge
James Forbes
@JAForbes
Apr 12 2016 07:27
var joinItems = R.useWith(R.join, [R.identity, R.filter(Boolean)])

joinItems(',', [1,,2,3, false]) // => 1,2,3
Which is kind of like:
R.join(R.identity(','), R.filter(Boolean, [1,,2,3,false]))
There is some special combinator in Sanctuary I think that is essentially useWith with identity as one the transformers. But that is still on my learning todo list :)
Baqer Mamouri
@bmamouri
Apr 12 2016 07:29
Wooooooow @JAForbes I love this Ramda. Much better than lodash. useWith is amzing
Thanks heaps~
Any better way to learn Ramda than going through the functions one by one?
James Forbes
@JAForbes
Apr 12 2016 07:30
Careful, what you say about Lodash, you never know who's watching :P
Baqer Mamouri
@bmamouri
Apr 12 2016 07:30
I am planning to learn Haskell to get the fundamentals, but before that it would be great if I can find a learning material for ramda
Hahahahha Lodash is great, but it is not reusable like Ramda. Ramda is clean and I can put these functions in my library and use them in all other projects.
James Forbes
@JAForbes
Apr 12 2016 07:32
My mode of learning is going about your day to day trying to solve problems with small generic functions, and then checking the Ramda docs to see if they already have that function. They nearly always do.
I actually went through each function 1 by 1 back when I first learned underscore, and I tried to implement each function for myself. By the time I had finished doing that, that really helped with the whole " solve problems with small generic functions" thing
So its hard to say what the best way to learn is. Hanging out here certainly helps.
James Forbes
@JAForbes
Apr 12 2016 07:38
Also, reading code from companion projects is really helpful
e.g. https://github.com/paldepind/functional-frontend-architecture this is a pretty thought provoking read
But yeah, its a really good question. I don't think Ramda is easy to learn at all.
Denys Mikhalenko
@prontiol
Apr 12 2016 07:42
@bmamouri have you tried lodash/fp?
Baqer Mamouri
@bmamouri
Apr 12 2016 07:50
Thanks @JAForbes for the links. I add the book to my Kindle Library. :)

@prontiol lodash/fp looks interesting. I am actually converting an old project that was written with lodash to Ramda. Almost I removed majority of lodash functions.

I think lodash has its own strength. For example lodash is much better in dealing with objects. Lots of functions to support object traversing, manipulation, etc. But with Rambda you have to convert between objects and array with toPairs and fromPairs.

James Forbes
@JAForbes
Apr 12 2016 07:55

Lodash's focus is a fast stdlib that closely follows ecmascript's conventions. lodash/fp is another way to use Lodash. But if you want to focus on writing data structure independent code that focuses on composition above all else, then it's just not the best tool. There are so many weird edge cases and surprises in /fp that, in my opinion, it isn't worth it.

Here's why:

Many functions in Lodash are variadic, and their behaviour changes based on the arguments it receives. It dispatches based on arity and type. So 1st of all that clashes with generic data structures because you have to know the data structure head of time. But it also requires a lot of fp's functions to be capped at 2 args to prevent incorrect usage in composition.

This capping behaviour breaks basic use cases. And that isn't ever going to change. Because /fp is really just the output of a build process.

@bmamouri

Lots of functions to support object traversing, manipulation, etc. But with Rambda you have to convert between objects and array with toPairs and fromPairs.

I used to think this, but I think its just a documentation issue.
R.map returns an object if give it an object. There's also R.merge, objOf, evolve ...

To be clear, I think Lodash is great. And I think people should use it instead of native es6 array methods. Because it is more stable, and performant
But for fp, it's a bit clumsy. And I don't see how that can be fixed in an update because of what I said just above about focus
I think its a good thing for different libraries to have different focuses. I want Lodash to not be everything to everyone. I want it to be the default stdlib for JS. And in that sense, the decisions it makes in FP make a lot of sense. It all depends on your target audience. Every decision has trade offs
Lewis
@6ewis
Apr 12 2016 13:04
@ram-bot
R.join(',', R.filter(Boolean, [1,,2,3,false]))
ram-bot
@ram-bot
Apr 12 2016 13:04
'1,2,3'
Lewis
@6ewis
Apr 12 2016 13:05
@bmamouri ^^
Hardy Jones
@joneshf
Apr 12 2016 13:31
@That-David-Guy yeah, I do. It doesn't seem like you really get much from pulling out findHalfIndex. For me, ramda is a library, not a language. So I use it where it makes sense, instead of overusing it..
I mean, you can go off the deep end pretty easily.
@ram-bot
const findHalfIndex = xs => R.divide(R.length(xs), 2);
const splitInHalf = R.chain(R.splitAt, findHalfIndex);
splitInHalf(R.range(1,11);
ram-bot
@ram-bot
Apr 12 2016 13:34
SyntaxError: missing ) after argument list
Hardy Jones
@joneshf
Apr 12 2016 13:34
@ram-bot
const findHalfIndex = xs => R.divide(R.length(xs), 2);
const splitInHalf = R.chain(R.splitAt, findHalfIndex);
splitInHalf(R.range(1,11));
ram-bot
@ram-bot
Apr 12 2016 13:34
TypeError: monad.call(...).apply is not a function
Hardy Jones
@joneshf
Apr 12 2016 13:34
beh, well you could...
λ: let findHalfIndex xs = length xs `div` 2
λ: (findHalfIndex >>= splitAt) [1..10]
([1,2,3,4,5],[6,7,8,9,10])
Hardy Jones
@joneshf
Apr 12 2016 14:26
Nice!
Risto Stevcev
@Risto-Stevcev
Apr 12 2016 14:27
Nice
Lewis
@6ewis
Apr 12 2016 14:27
@ram-bot
const objectSplitNames = {firstName: "Lewis", lastName: null}
const fullName = (object) => R.assoc('concatenated_name', 
                                                 `${object.firstName || ''}
                                                  ${object.lastName || ''}`)(object);

fullName(objectSplitNames)
ram-bot
@ram-bot
Apr 12 2016 14:27
{ firstName: 'Lewis',
  lastName: null,
  concatenated_name: 'Lewis\n                                                  ' }
Lewis
@6ewis
Apr 12 2016 14:27
Do you guys have a better way to write that? especially object.firstName || '' (check for null)
Also anyone know how to ignore \n in es6? I tried String.raw
Dalibor Novak
@BorePlusPlus
Apr 12 2016 14:29
@6ewis
R.propOr
R.propOr
Lewis
@6ewis
Apr 12 2016 14:31
@BorePlusPlus can you read those arguments for me? @Bradcomp did it over and over but it just doesn't sink yet hehe
@BorePlusPlus also how were you thinking about using R.prop , it doesnt seem to be it's going to do what you expect
Dalibor Novak
@BorePlusPlus
Apr 12 2016 14:34

well it is a bit funky due to currying so explaining args would take some time:

propOr is a function that takes something of type a and returns a function
that takes String and returns a fucntion....

at least that's how I read it
but documentation explains this function quite well http://ramdajs.com/0.21.0/docs/#propOr
essentially - provide a default value, name of prop and object. if object has the requested prop its value is returned otherwise default value is returned
all of it curried
Lewis
@6ewis
Apr 12 2016 14:36
@BorePlusPlus it returns the value of a given property - not a function
Dalibor Novak
@BorePlusPlus
Apr 12 2016 14:36
R.propOr('', 'firstName');
due to power of curry all it does is return functions until you provided all of the parameters...
Lewis
@6ewis
Apr 12 2016 14:37
@BorePlusPlus I can't read those stuff without expanding the parameters list :package:
@Bradcomp I know what it does, I'm trying to read args better when I see them without having to expand the params list
Dalibor Novak
@BorePlusPlus
Apr 12 2016 14:39
function that takes a and returns function that takes String and returns function that takes object and returns a
Lewis
@6ewis
Apr 12 2016 14:39
@BorePlusPlus yea pretty much as ugly as what I wrote, and I'd still have to pass the object, wouldn't I
Dalibor Novak
@BorePlusPlus
Apr 12 2016 14:39
I don't know how else to describe it - sorry I am not functional wiz kid
Lewis
@6ewis
Apr 12 2016 14:39
@BorePlusPlus no worries
Brad Compton (he/him)
@Bradcomp
Apr 12 2016 15:15

@6ewis a -> String -> Object -> a

a can be any type, but they have to match. In other words, the first parameter is the same type as what is returned.

String -> Object -> a is the same type signature as R.prop, although it's notated differently in the docs :(.

So it takes three parameters, where the last two are the same as what gets passed into R.prop. Does that help?

Brad Compton (he/him)
@Bradcomp
Apr 12 2016 15:20
@ram-bot
var fullName = R.converge(R.join(' '), [R.propOr('', 'firstName'), R.propOr('', lastName)]);
fullName({firstName: 'Brad', lastName: 'Comp'});
ram-bot
@ram-bot
Apr 12 2016 15:20
ReferenceError: lastName is not defined
Brad Compton (he/him)
@Bradcomp
Apr 12 2016 15:21
@ram-bot
var fullName = R.converge(R.join(' '), [R.propOr('', 'firstName'), R.propOr('', 'lastName')]);
fullName({firstName: 'Brad', lastName: 'Comp'});
ram-bot
@ram-bot
Apr 12 2016 15:21
TypeError: "Brad" does not have a method named "join"
Brad Compton (he/him)
@Bradcomp
Apr 12 2016 15:21
Argh!
@ram-bot
var fullName = R.converge(R.unapply(R.join(' ')), [R.propOr('', 'firstName'), R.propOr('', 'lastName')]);
fullName({firstName: 'Brad', lastName: 'Comp'});
ram-bot
@ram-bot
Apr 12 2016 15:23
'Brad Comp'
Brad Compton (he/him)
@Bradcomp
Apr 12 2016 15:29
@ram-bot
var fullName = R.converge(R.unapply(R.join(' ')), [R.propOr('', 'firstName'), R.propOr('', 'lastName')]);
var me = {firstName: 'Brad', lastName: 'Comp'};

R.converge(R.assoc('fullName'), [fullName, R.identity])(me)
ram-bot
@ram-bot
Apr 12 2016 15:29
{ firstName: 'Brad', lastName: 'Comp', fullName: 'Brad Comp' }
Brad Compton (he/him)
@Bradcomp
Apr 12 2016 15:33
R.converge
Raine Virta
@raine
Apr 12 2016 15:37

@raine, how do we update the Sanctuary version used by ram-bot?

updated it in hubot-eval-js just now @davidchambers

David Chambers
@davidchambers
Apr 12 2016 15:38
Thanks!
LeonineKing1199
@LeonineKing1199
Apr 12 2016 17:01
Would pick ever work for nested props? Sort of like how Mongoose does it now where you can query based on this:
Query.findOne({'propA.propB.propC' : 'some_random_snake_case_data'});
Could I do a R.pick(['part.of.the.nested.path'], obj);?
My bad, MongoDB does that, not Mongoose
Lewis
@6ewis
Apr 12 2016 17:08
How can i pass the param that i want R.map(foo, object).. i want foo to receive both (key, 'myParam')
@Bradcomp thank you - it does help
basically what index does
R.addIndex(R.map)
Brad Compton (he/him)
@Bradcomp
Apr 12 2016 17:16
@6ewis Map won't do that for you, but check out
R.toPairs
LeonineKing1199
@LeonineKing1199
Apr 12 2016 17:18
Alright, I wimped out and used merge with path and pick to get the behavior that I desired. I would, however, like to formally troll for incorporating Mongo's approach into Ramda and say that if people name their properies "like.this" then they deserve what they get!
Lewis
@6ewis
Apr 12 2016 17:27
@Bradcomp thanks ill take a look.
R.isEmpty("                         ");
Lewis
@6ewis
Apr 12 2016 17:33
Is there something similar that return true?
Brad Compton (he/him)
@Bradcomp
Apr 12 2016 17:34

@ram-bot

var onlySpace = R.compose(R.isEmpty, R.trim)
onlySpace("                     ")

@6ewis

ram-bot
@ram-bot
Apr 12 2016 17:34
true
Lewis
@6ewis
Apr 12 2016 17:35
@Bradcomp the reason why I was asking for my own param is to refactor this https://gist.github.com/6ewis/a2403779cd5dd7446585599c3a2e7540 . How can i apply R.toPairs there
@Bradcomp basically passing regaddr, mailaddr, and divaddr to a single function that concatenate
Lewis
@6ewis
Apr 12 2016 18:08
This message was deleted
This message was deleted
unrelated to previous post
@ram-bot
const arrayOfNull = [null, null, null, null]; //should return true
const arrayOfEmptyStrings = ["  ", "", "", ""]; //should return true
const emptyArray = []; //should return true

const notValid = R.all(R.compose(R.or(R.isNil, R.isEmpty), R.trim));
R.map(notValid, [arrayOfNull, emptyArray, arrayOfEmptyStrings]);
Lewis
@6ewis
Apr 12 2016 18:30
@ram-bot
const notValid = R.compose(R.or(R.isNil, R.isEmpty), R.map(R.trim));
R.map(notValid, arrayOfEmptyStrings);
ram-bot
@ram-bot
Apr 12 2016 18:30
ReferenceError: arrayOfEmptyStrings is not defined
Lewis
@6ewis
Apr 12 2016 18:31
@ram-bot

const arrayOfEmptyStrings = ["  ", "", "", ""]; //should return true
const notValid = R.compose(R.or(R.isNil, R.isEmpty), R.map(R.trim));
R.map(notValid, arrayOfEmptyStrings);
ram-bot
@ram-bot
Apr 12 2016 18:31
[ false, false, false, false ]
Brad Compton (he/him)
@Bradcomp
Apr 12 2016 18:39
@6ewis http://goo.gl/dAVRpQ is this what you're looking for?
Lewis
@6ewis
Apr 12 2016 19:18
@Bradcomp thanks you're the man
Lewis
@6ewis
Apr 12 2016 19:46
anyone can take a look at the code above id like to return true instead
Aldwin Vlasblom
@Avaq
Apr 12 2016 19:48
@6ewis I think you should use R.either rather than R.or.
Aldwin Vlasblom
@Avaq
Apr 12 2016 19:55
@ram-bot R.or(R.isNil, R.isEmpty) === R.isNil
ram-bot
@ram-bot
Apr 12 2016 19:55
true
Lewis
@6ewis
Apr 12 2016 19:56
@Avaq the problem is with the R/trim
Aldwin Vlasblom
@Avaq
Apr 12 2016 19:57
I believe I just demonstrated the problem. :)
Brad Compton (he/him)
@Bradcomp
Apr 12 2016 19:58
@ram-bot
const arrayOfEmptyStrings = ["  ", "", "", ""]; //should return true
const notValid = R.compose(R.either(R.isNil, R.isEmpty), R.map(R.trim));
R.map(notValid, arrayOfEmptyStrings);
ram-bot
@ram-bot
Apr 12 2016 19:58
[ false, true, true, true ]
Brad Compton (he/him)
@Bradcomp
Apr 12 2016 19:59
@ram-bot
const arrayOfEmptyStrings = ["  ", "", "", ""]; //should return true
const notValid = R.compose(R.either(R.isNil, R.isEmpty), R.trim);
R.map(notValid, arrayOfEmptyStrings);
ram-bot
@ram-bot
Apr 12 2016 19:59
[ true, true, true, true ]
Brad Compton (he/him)
@Bradcomp
Apr 12 2016 20:00
R.trim didn't need to be wrapped in map, also R.or should have been R.either
Lewis
@6ewis
Apr 12 2016 20:11
@Avaq Thank you.
@Bradcomp thanks again
@ram-bot
const arrayOfNull = [null, null, null, null]; //should return true
const arrayOfEmptyStrings = ["  ", "", "", ""]; //should return true
const emptyArray = []; //should return true

const notValid = R.all(R.compose(R.either(R.isNil, R.isEmpty), R.when(R.is(String), R.trim)));
R.map(notValid, [arrayOfNull, emptyArray, arrayOfEmptyStrings]);
ram-bot
@ram-bot
Apr 12 2016 20:11
[ true, true, false ]
Lewis
@6ewis
Apr 12 2016 20:13
weird - it returns tue, true, true in the repl
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:14
I see. That is quite weird. o.0
Paul
@pauloliver
Apr 12 2016 20:15
rambot could be on an older version? REPL is on 0.21.0
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:15
@ram-bot R.is(String)(" ")
ram-bot
@ram-bot
Apr 12 2016 20:15
false
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:15
...
This message was deleted
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:24

Never mind it's not the VM it seems:

> vm.runInNewContext('(function(val){return val != null && val.constructor === String || val instanceof String})("")')
true

Very odd..

Lewis
@6ewis
Apr 12 2016 20:26
@Avaq woot woot! I found my first bug on ramda lol
@Avaq I think the repl doesn't evaluate it as a string
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:28
R.is(String)("") returns true in the REPL, but false in ram-bot.
@ram-bot String
ram-bot
@ram-bot
Apr 12 2016 20:32
[Function: String]
Lewis
@6ewis
Apr 12 2016 20:32
I meant ram-bot
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:33
@ram-bot String(1)
ram-bot
@ram-bot
Apr 12 2016 20:33
'1'
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:33
@ram-bot "".constructor === String
ram-bot
@ram-bot
Apr 12 2016 20:33
true
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:34
What?
Lewis
@6ewis
Apr 12 2016 20:34
@Avaq should i file an issue?
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:35
I think @raine is aware by now. ;)
Lewis
@6ewis
Apr 12 2016 20:35
@ram-bot "".constructor === Object
@Avaq too bad, the history of @ram-bot will forget me :)
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:38
@ram-bot R.is.toString()
ram-bot
@ram-bot
Apr 12 2016 20:38
'function f2(a, b) {\n            switch (arguments.length) {\n            case 0:\n                return f2;\n            case 1:\n                return _isPlaceholder(a) ? f2 : _curry1(function (_b) {\n                    return fn(a, _b);\n                });\n            default:\n                return _isPlaceholder(a) && _isPlaceholder(b) ? f2 : _isPlaceholder(a) ? _curry1(function (_a) {\n                    return fn(_a, b);\n                }) : _isPlaceholder(b) ? _curry1(function (_b) {\n                    return fn(a, _b);\n                }) : fn(a, b);\n            }\n        }'
Tobias Pflug
@gilligan
Apr 12 2016 20:39
hm, I am wondering about the type signature of R.groupWith right now
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:39
Everything seems fine! Why does it do this?!
Tobias Pflug
@gilligan
Apr 12 2016 20:39
@ram-bot R.groupWith
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:39
R.groupWith
ram-bot
@ram-bot
Apr 12 2016 20:39
Error: No such function groupWith
Tobias Pflug
@gilligan
Apr 12 2016 20:40
@ram-bot groupWith
ram-bot
@ram-bot
Apr 12 2016 20:40
[Function: f2]
Lewis
@6ewis
Apr 12 2016 20:40
@ram-bot "".constructor === Object
@ram-bot typeof( "".constructor );
Tobias Pflug
@gilligan
Apr 12 2016 20:42
why is it groupWith :: (a, a -> Bool) -> [a] -> [[a]] and not more like (a -> ( a -> Bool)) -> [a] -> [[a]] ?
Lewis
@6ewis
Apr 12 2016 20:42
@ram-bot
typeof( "".constructor );
ram-bot
@ram-bot
Apr 12 2016 20:42
'function'
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:44
Let's teach him.
@ram-bot R.is(String)("") = true
ram-bot
@ram-bot
Apr 12 2016 20:44
ReferenceError: Invalid left-hand side in assignment
Aldwin Vlasblom
@Avaq
Apr 12 2016 20:44
Ahw
Tobias Pflug
@gilligan
Apr 12 2016 20:53
so can anyone tell me something about(a, a -> Bool) versus (a -> a -> Bool) ? @CrossEye or @scott-christopher or anyone else? :)
Raine Virta
@raine
Apr 12 2016 20:57
@avaq @6ewis it's that long standing issue
can't remember the specifics anymore, @davidchambers probably knows
Aldwin Vlasblom
@Avaq
Apr 12 2016 21:01
@gilligan I believe a, a is meant to indicate that those two arguments must be provided together. So the function is not curried.
Scott Sauyet
@CrossEye
Apr 12 2016 21:03
Exactly
Tobias Pflug
@gilligan
Apr 12 2016 21:06
that makes perfect sense
thanks folks :)