These are chat archives for ramda/ramda

19th
Sep 2015
Raine Virta
@raine
Sep 19 2015 13:39
hm.
> [ R.head([]), R.head('') ]
Array [ undefined, '' ]
Martin Algesten
@algesten
Sep 19 2015 15:13
it would be reasonable for them to be the same. but which is better?
Hardy Jones
@joneshf
Sep 19 2015 15:14
neither?
Martin Algesten
@algesten
Sep 19 2015 15:15
you want an error thrown?
Hardy Jones
@joneshf
Sep 19 2015 15:15
nope
Martin Algesten
@algesten
Sep 19 2015 15:16
but you do want consistency?
is this equivalent to head?
> [[][0], ''[0]]
[undefined, undefined]
Alexey Khristov
@AlexeyKhristov
Sep 19 2015 15:22
Hi all,
how can I implement analog lodash.defaults with ramda?
Martin Algesten
@algesten
Sep 19 2015 15:23
ask @jdalton ;)
Scott Sauyet
@CrossEye
Sep 19 2015 15:24
What are analog defaults?
Martin Algesten
@algesten
Sep 19 2015 15:24
Hardy Jones
@joneshf
Sep 19 2015 15:26
@CrossEye I think there was a word or two missing.
i imagine @AlexeyKhristov wanted what @algesten linked to.
@algesten I want this:
[S.head([]), S.head('')] //=> [Nothing(),Nothing()]
David Chambers
@davidchambers
Sep 19 2015 15:31
R.head('') should evaluate to '', in my view. Its type in this case is String -> String. Those disturbed by the handling of empty inputs (as I am) can use S.head instead.
Alexey Khristov
@AlexeyKhristov
Sep 19 2015 15:36

thanks @algesten, yes, with lodash I use defaults function

imagin I have 3 objects

let a = {prop1: ‘a', prop2: ‘a'}
let b = {prop1: ‘b'}
let c = {prop2: ‘c'}

how implement next transformation: f(a, c) -> a' and f(b, c) -> b' and get

a' = {prop1: ‘a', prop2: ‘a’}
b' = {prop1: ‘b', prop2: ‘c’}
Scott Sauyet
@CrossEye
Sep 19 2015 15:37
Ramda has made the decision to not attempt to force on JS users such foreign-to-js concepts as Maybe, even if they are clearly helpful. I think having Sanctuary as well for those who want it is a great compromise.
wait, that's not right.
at least from your given output.
maybe?
Martin Algesten
@algesten
Sep 19 2015 15:43
@davidchambers isn't R.head('') -> '' sort of also an expression of you being disturbed by empty inputs? .. i mean a why shy away from undefined? ;)
Scott Sauyet
@CrossEye
Sep 19 2015 15:44
@joneshf: note that there's a button in the REPL to let you create a nice short link. It usually works. :smile:
David Chambers
@davidchambers
Sep 19 2015 15:47

I would rather the types be

head :: [a] -> a?
head :: String -> String

than

head :: [a] -> a?
head :: String -> String?

One can view head(s) as taking a slice of s from index 0 to index 1, which gives '' when s is ''.

That's my justification, at any rate. ;)

Martin Algesten
@algesten
Sep 19 2015 15:53
@davidchambers and the asymmetry between string and array is not upsetting to you? ... i find that a bit jarring.
David Chambers
@davidchambers
Sep 19 2015 15:53
I do too!
The fact that in one case we have [a] -> a and in the other case we have a -> a is very odd!
Martin Algesten
@algesten
Sep 19 2015 15:54
yes. the unwrapping.
hm. dual purpose functions.
David Chambers
@davidchambers
Sep 19 2015 15:55
But there's no way for us to pretend that String is really [Char], since we don't even have Char.
Martin Algesten
@algesten
Sep 19 2015 15:56
if we had char, would you argue head for string is string -> char?
David Chambers
@davidchambers
Sep 19 2015 15:57
Sure.
Hardy Jones
@joneshf
Sep 19 2015 15:58
You don't view it as head working with an interface?
David Chambers
@davidchambers
Sep 19 2015 15:58
What do you mean by that?
Martin Algesten
@algesten
Sep 19 2015 15:59
[R.head(''), R.tail(''), R.last('')] // => ["", "", ""]
[R.head([]), R.tail([]), R.last([])] // => [undefined, [], undefined]
Hardy Jones
@joneshf
Sep 19 2015 16:00
okay, that is hella confusing.
like, jquery level of confusing.
Martin Algesten
@algesten
Sep 19 2015 16:01
@joneshf go on...
Hardy Jones
@joneshf
Sep 19 2015 16:01
i mean, give it a more generic type.
David Chambers
@davidchambers
Sep 19 2015 16:01
The problem is that String is both an atom and a collection of atoms.
Hardy Jones
@joneshf
Sep 19 2015 16:02
that's only a problem if you think the interface needs to work on collections.
David Chambers
@davidchambers
Sep 19 2015 16:02
Break a string into pieces, and what are the pieces? Strings!
What are you suggesting, @joneshf? I'm intrigued.
Hardy Jones
@joneshf
Sep 19 2015 16:03
If the interface has head, tail, cons as the things you need to implement, then you have certain laws, cons(head(xs), tail(xs)) == xs or whatever.
Martin Algesten
@algesten
Sep 19 2015 16:03
but you could perhaps argue that undefined, as a value, is as much part of the type string as it is part of the type array.
Hardy Jones
@joneshf
Sep 19 2015 16:03
so string should satisfy that.
along with array.
then you dont worry about how it's implemented
just whether it will satisfy the laws.
or maybe a differnt formulation of operations and laws
Martin Algesten
@algesten
Sep 19 2015 16:05
so to satisfy those rules cons(undefined, []) really should be []
in which case cons(undefined, '') should be ''
David Chambers
@davidchambers
Sep 19 2015 16:06
That's a nice way to view the situation, Hardy!
Martin Algesten
@algesten
Sep 19 2015 16:14
so. i'm obviously being dense here. but @joneshf are you happy or not happy with the current situation of R.head/tail/last? i don't know if there's a R.cons to arbitrate whether those rules are upheld.
David Chambers
@davidchambers
Sep 19 2015 16:16

We have R.prepend, which for some reason does this:

> R.prepend('', '')
['']

It's not supposed to accept a string as its second argument, of course.

Martin Algesten
@algesten
Sep 19 2015 16:18
Yes. Not optimal.
> R.prepend('a', 'bc')
["a", "b", "c"]
Hardy Jones
@joneshf
Sep 19 2015 16:32
@algesten sure, but i'd like to hope there are more laws than just that one.
@algesten laws that would make what you stated not be true.
I'd hope that length(cons(x, xs)) == length(xs) + 1
in which case, that definition of cons you gave above would not be true any longer.
also, to be clear, I'm not suggesting any changes to ramda.
Martin Algesten
@algesten
Sep 19 2015 16:42
@joneshf got ya
hemanth @hemanth here is link to my talk https://www.youtube.com/watch?v=gLmYJM28fnQ :)
David Chambers
@davidchambers
Sep 19 2015 17:46
@hemanth, your definition of currying is imprecise. My understanding is that currying is the process of transforming (a, b, c) => … into a => b => c => ….
hemanth.hm
@hemanth
Sep 19 2015 17:56
@davidchambers :) Thanks. Yeah as you mentioned it's (a, b, c) => into a => b => c => the crowd there was very new to FP, so was trying to simplify.
hemanth.hm
@hemanth
Sep 19 2015 18:15
there were like 400 devs in the crowd, out of them even if 40 picks up FP, it's a win for me.
David Chambers
@davidchambers
Sep 19 2015 18:16
Absolutely! Thank you for sharing FP!
hemanth.hm
@hemanth
Sep 19 2015 18:18
MP. Thank you all for Ramda!
BTW I am trying to define all the FP jargons at https://github.com/hemanth/functional-programming-jargons
It would great to get PRs from this room :shipit:
David Chambers
@davidchambers
Sep 19 2015 18:40
"Jargon" is a mass noun, so you should remove the "s" from the name unless there's a reference I'm missing (which could easily be the case).
The repo is a great idea! I'll look at it later today.
Scott Sauyet
@CrossEye
Sep 19 2015 19:42

@joneshf: I'm a little confused by the types of what you'd want: You made two suggestions very close together. You want

head([]); //=> Nothing

which presumably implies:

head :: [a] -> Maybe(a)

But cons, as I've always thought of it, is something like

cons:  a -> [a] -> [a]

So with those two, I can make little sense of your proposed law that

cons(head(xs), tail(xs)) == xs

It's not that I don't like the law, but I can't see how it works with Maybe(a) for its first parameter. Am I missing something simple?

Hardy Jones
@joneshf
Sep 19 2015 19:56
nope, you're not missing anything.
I conflated my concerns.
Sorry about that.
So, going with the primitive types, it'd be nice for that law to hold, but with more complex types, then the law cannot hold as stated.
Scott Sauyet
@CrossEye
Sep 19 2015 20:14
NP. I'd actually like to see if we can support a law like that.
Raine Virta
@raine
Sep 19 2015 20:40
his way of currying with just lambdas in the example is cool
Scott Sauyet
@CrossEye
Sep 19 2015 20:44
It's by far the simplest way to write such curried functions, but then it only allows you to call the function as fn(a)(b)(c)(d), and never as fn(a, b, c, d) or fn(a, b)(c)(d), etc.
Raine Virta
@raine
Sep 19 2015 20:47
yep. definitely going to explore that library
Scott Sauyet
@CrossEye
Sep 19 2015 21:12
definitely want to look into his coroutine stuff!