These are chat archives for ramda/ramda

27th
Mar 2015
Nate Wildermuth
@wildermuthn
Mar 27 2015 00:04
Is there a reason I'd use R.clone over something like .slice(0)?
I went from 800ms of processing to 1ms.
Raine Virta
@raine
Mar 27 2015 00:05
clone is deep clone
Nate Wildermuth
@wildermuthn
Mar 27 2015 00:05
deep vs shallow... ok
Raine Virta
@raine
Mar 27 2015 00:05
yeah
Nate Wildermuth
@wildermuthn
Mar 27 2015 00:05
is there a faster way to do a deep clone? ;)
Immutable data?
Raine Virta
@raine
Mar 27 2015 00:06
no idea, heh, maybe parse . stringify if your data is just primitives
Nate Wildermuth
@wildermuthn
Mar 27 2015 00:06
I feel like I run into so many performance issues with Ramda, because I'm not using immutable data.
Raine Virta
@raine
Mar 27 2015 00:07
why do you need the deep clone?
Scott Sauyet
@CrossEye
Mar 27 2015 01:42
What sort of data structure took 800ms to clone?
Raine Virta
@raine
Mar 27 2015 08:24
has anyone used IO monad for side effects in javascript?
Scott Christopher
@scott-christopher
Mar 27 2015 10:02
I have been messing around with a Haskell style "do" notation for fantasyland monads, with an example of using a State IO monad here: https://gist.github.com/scott-christopher/5069a91b924e7e182caa
Raine Virta
@raine
Mar 27 2015 10:04
Option is like data.maybe, I guess
Scott Christopher
@scott-christopher
Mar 27 2015 10:04
exactly
Raine Virta
@raine
Mar 27 2015 10:09
very interesting. what is the purpose of StateT?
Raine Virta
@raine
Mar 27 2015 10:10
heh, I've somehow managed to avoid monad transformers so far
or mabye StateT is something else? =)
Scott Christopher
@scott-christopher
Mar 27 2015 10:15
StateT is a transformer of the State Monad
Ludwig Magnusson
@TheLudd
Mar 27 2015 10:16
ok
But while on the topic. What is the porpose of IO in a JavaScript context?
Raine Virta
@raine
Mar 27 2015 10:18
great question
Scott Christopher
@scott-christopher
Mar 27 2015 10:19
It mainly allows for confining the execution of IO such that unsafePerform() is only called in the applications main
with the absence of a static type system, it becomes less useful in something like JS
Raine Virta
@raine
Mar 27 2015 10:21
in your experience, does it make side effects easier to reason about?
in JS, that is
Scott Christopher
@scott-christopher
Mar 27 2015 10:22
my experience in using them is lacking, to be honest :)
Raine Virta
@raine
Mar 27 2015 10:22
anyway, I will play around with your examples this weekend, thank you very much
Scott Christopher
@scott-christopher
Mar 27 2015 10:23
you're welcome :)
^ is the IO monad package that is used in the gist
Raine Virta
@raine
Mar 27 2015 10:24
ramda-fantasy has its own, I noticed
Scott Christopher
@scott-christopher
Mar 27 2015 10:24
https://github.com/fantasyland/fantasy-examples is where I sourced most of the examples from in the gist
I'll have to check it out
Has there been any discussion about adding support in ramda for ES6 features?
Simon Friis Vindum
@paldepind
Mar 27 2015 12:06
@TheLudd, sorry for the late reply. Nope, not any more. I'm currently fooling around with my own FRP library and a companion view layer. Why do you ask?
Ludwig Magnusson
@TheLudd
Mar 27 2015 12:07
I was curious about using flyd as a base for flux architecture
Simon Friis Vindum
@paldepind
Mar 27 2015 12:07
@CrossEye: I've been working/thinking about the library for converting 3rd party libraries to a functional style. Take a look at what I've got here: https://github.com/paldepind/functionize
@TheLudd, that is certainly possible! A flyd stream can very easily serve the purpose of a flux action!
And you can use FRP idioms to transform the actions in your stores.
Ludwig Magnusson
@TheLudd
Mar 27 2015 12:10
I did some experimental coding with flyd. I think the only thing I seem to be missing is a listening feature, to be notified when a stream changes. Is there support for this or is it planned? I am new to FRP so I am not sure what is standard and what is not
Simon Friis Vindum
@paldepind
Mar 27 2015 12:12
Cool! If I understand you correctly you can use 'map' and/or a dependent stream for that. Like this: flyd.map(function(x) { console.log('Im called whenever the stream changes'; }, sourceStream);
@TheLudd, if there is anything I can do to make the tutorial more clear about this please tell me :)
Ludwig Magnusson
@TheLudd
Mar 27 2015 12:14
nice
that was what I wanted
Raine Virta
@raine
Mar 27 2015 12:15
how does flyd compare to bacon
Ludwig Magnusson
@TheLudd
Mar 27 2015 12:15
@raine in size? :D
Simon Friis Vindum
@paldepind
Mar 27 2015 12:16
@raine, flyd is WAY WAY smaller. Modular from the bottom up. More functional: argument order similar to Ramda and soon everything will be curried.
Ludwig Magnusson
@TheLudd
Mar 27 2015 12:17
I looked at bacon and RXJS. Again, I am new to FRP so I don't know what requirements such a library would have but I thought they were way bigger than they needed
Simon Friis Vindum
@paldepind
Mar 27 2015 12:17
@raine: flyd aims for simplicity and extendability. It has a small but powerful documented core on top of which additional functionality can be built.
Raine Virta
@raine
Mar 27 2015 12:18
I'm not sure if that's a good thing for someone who's new to FRP, like myself
Ludwig Magnusson
@TheLudd
Mar 27 2015 12:20
I have a similar feeling with promises which I currently use. Take bluebird for instance. It is a good library but very big. I think you could acheive the same stuff it has with ramda + Future
Simon Friis Vindum
@paldepind
Mar 27 2015 12:20
@raine, when Flyd (hopefully) gets more extensions it should be just as usable for people new to FRP. But currently I agree with you since it's a very early state.
Flyd is also compatible with fantasy land and transducers btw.
Raine Virta
@raine
Mar 27 2015 12:21
TheLudd: I'm also considering switching bluebird to data.task, but haven't yet
Ludwig Magnusson
@TheLudd
Mar 27 2015 12:23
@raine I'd love to get feedback on my PR in ramda-fantasy about Future.ap and parallel execution. Right now I wouldn't know how to run several async tasks in parallel and react when they are all done with data.taks or ramda-fantasy
but my PR supposedly changes that
have you tried that?
Ludwig Magnusson
@TheLudd
Mar 27 2015 12:27
I have not
Ludwig Magnusson
@TheLudd
Mar 27 2015 12:31
Looks like parallel and lift are specific versions of functions that already exist in libraries like ramda?
Btw @paldepind "flyd" is "flow" in danish?
Raine Virta
@raine
Mar 27 2015 12:40
TheLudd: I'm looking at your PR, could it be written without redefining variable references?
Simon Friis Vindum
@paldepind
Mar 27 2015 12:41
@TheLudd, :D Yes, indeed it does! I'm a dane.
Ludwig Magnusson
@TheLudd
Mar 27 2015 12:42
@raine Not sure perhaps with currying?
I have an Idea that I will try out
Ludwig Magnusson
@TheLudd
Mar 27 2015 12:51
@raine better now?
inappropriate word yeah! I dig that change.
Raine Virta
@raine
Mar 27 2015 13:02
do you happen to have an example of using that?
Ludwig Magnusson
@TheLudd
Mar 27 2015 13:03
the test pass with it. but yes, let me paste in one
Ludwig Magnusson
@TheLudd
Mar 27 2015 13:10
hmm ok, so there was some trouble. I assumed it worked since there was tests for ap. My ugly implementation did work with example code. I'll look into it
No ofc it doesn't work since the calls to doResolve returns a new function that needs to be called by the last fork to be resolved.
Simon Friis Vindum
@paldepind
Mar 27 2015 13:49
@TheLudd: Regarding your question about a listening feature in Flyd. Do you think I could make that part easier to understand in the tutorial?
Ludwig Magnusson
@TheLudd
Mar 27 2015 13:51
Well. I'd expect a section with that header. While this section is perhaps technically correct I don't understand that I can use it to subscribe to stream events.
Another thing: is the reduce documentation correct? I'd expect the callback to be given two arguments.
Simon Friis Vindum
@paldepind
Mar 27 2015 13:56
What about the section about dependent streams? https://github.com/paldepind/flyd#dependent-streams Does that make sense to you?
Ludwig Magnusson
@TheLudd
Mar 27 2015 13:57
Yes I tried that but the way I understood it was that the dependent stream was only evaluated when it was called.
Simon Friis Vindum
@paldepind
Mar 27 2015 13:57
@TheLudd Yes, it is correct. But showing an example where only the accumulator is actually used is was a bad idea. I'll change that.
Ludwig Magnusson
@TheLudd
Mar 27 2015 13:59
A general point about documentation would be to always specify all parameters that functions receive with clear names. Even if you don't use them in your examples.
@paldepind How much FRP have you done?
Raine Virta
@raine
Mar 27 2015 14:03
do you guys have any simple use case in mind for FRP, I might try flyd over the weekend
seems like it works in browser
Ludwig Magnusson
@TheLudd
Mar 27 2015 14:04
I want to use it to keep track of entities that are created, updated, deleted
so... todo? =)
Simon Friis Vindum
@paldepind
Mar 27 2015 14:09
@TheLudd: Yes. That is a good point. I've just slightly updated the documentation of dependent streams, map and reduce. Does it make more sense now?
Thanks a lot for your comments :)
I've used both Elm and Bacon.js.
@raine, my own use case is keeping HTML in sync with data and handling browser events. Bacon has a pretty good tutorial that shows some of the benefits to FRP: http://baconjs.github.io/tutorials.html
Ludwig Magnusson
@TheLudd
Mar 27 2015 14:11
what was disappointing about them? As I take it you were dissapointed in order to write your own...
Simon Friis Vindum
@paldepind
Mar 27 2015 14:12
Here is a splendid introduction to FRP btw: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
@TheLudd Elm is very neat! But it's a language on it's own, so it's an entirely different beast.
Raine Virta
@raine
Mar 27 2015 14:12
paldepind: awesome. thanks for sharing
Simon Friis Vindum
@paldepind
Mar 27 2015 14:15
@TheLudd, with Bacon.js it was mainly the size, the argument order and that it doesn't do currying. But mostly it was that I think I've found a very elegant way to implement the core of a FRP library.
Ludwig Magnusson
@TheLudd
Mar 27 2015 14:15
cool
I did the same thing with dependency injection. Wrote a lib in 100 LOC. Pretty cool what you can do when you realize that less is more.
Simon Friis Vindum
@paldepind
Mar 27 2015 14:19
Sounds cool. I'll take a look :)
Ludwig Magnusson
@TheLudd
Mar 27 2015 14:22
if you can stand coffeescript =)
Simon Friis Vindum
@paldepind
Mar 27 2015 14:41
I can :)
Ludwig Magnusson
@TheLudd
Mar 27 2015 15:00
@paldepind Have you figured out how to use ap from fantasy-land with the streams?
Ludwig Magnusson
@TheLudd
Mar 27 2015 16:08
@davidchambers @buzzdecafe Is there a defined behavior for calling a binary curried function with only __?
var whatAmI = R.append(R.__);
or perhaps @CrossEye
joekillian
@joekillian
Mar 27 2015 19:08
Does Ramda go well with scijs/ndarray? I ask because functional javascript PLUS multidimensional arrays in the right combination seems like an easy way to move away from APL/J like very easy functional/matrix programming to exactly the same thing with Javascript. Only it will be "on average" much more readable and of course near universally acceptable - compared to APL. So instead of a compile from APL to Javascript and there is one of those why not just Ramda and Ndarray playing well in an APL like fantasyland?
Simon Friis Vindum
@paldepind
Mar 27 2015 19:21
@TheLudd, as far as I can see the main usage is that you can use any lift implementation based on fantasy land.
joekillian
@joekillian
Mar 27 2015 19:30
I mean some kind of domain specific language where merged Ramda plus Ndarray provides if anything a lot more application than APL which still is used quite a bit. That's basically what APL is: a compact functional matrix language. It and its cousin ascii J are just too compact. Nobody likes reading those long one liners. I program in J and used to in APL and like the idea of easy functional Javascript with Ramda merged with Ndarray to provide all the ease of programming I get with J and then I have easy access to web programming with thousands of Javascript libraries.
Scott Sauyet
@CrossEye
Mar 27 2015 20:20
@paldepind. Functionalize looks great. I think it would be helpful if the user API could be simplified a bit. This would look cleaner to me:
var S = fz.convert(
    String.prototype,
    {
        sliceFrom: fz.mapFieldTo('slice', fz.apply(fz._, [fz._, undefined])),
        sliceTo: fz.mapFieldTo('slice', fz.apply(fz._, [undefined])),
        uppercase: fz.dupTo('toUpperCase')       
    }
);
@TheLudd passing only R.__ should give you back an equivalent of the original function.
Scott Sauyet
@CrossEye
Mar 27 2015 20:32
@joekillian: I've never used ndarray. There don't look to be to many direct touch-points with Ramda. I'd love to hear more about exactly what you're trying to do.
Simon Friis Vindum
@paldepind
Mar 27 2015 21:27
@CrossEye: Hm. My idea was that the "specification" was actually just a huge function consisting of a bunch of functions composed together. Also you're not including the part of the example that created an invoker out of every function in String.prototype (fz.methods, fz.map(fz.fnInvoker)).
You're proposal certainly looks more readable at a glance. But what if the transformation of one function depended on an earlier one? Conceptually the keys in a hash/object doesn't have order?
Simon Friis Vindum
@paldepind
Mar 27 2015 21:37
I got an idea: Instead of the *To functions (mapFieldTo and dupTo). You could have a single function taking an object with property names as keys and transformations as values. The function would then write the result of the transformations into the object according to their key. Something like this:
var converter = fz.pipe([
  fz.methods, fz.map(fz.fnInvoker),
  fz.to({
    sliceFrom: fz.pipe(fz.get('slice', fz.apply(fz._, [fz._, undefined])),
    sliceTo: fz.pipe(fz.get('slice', fz.apply(fz._, [undefined])),
    uppercase: fz.get('toUpperCase'),
  })
]);
var S = converter(String.prototype);
Scott Sauyet
@CrossEye
Mar 27 2015 22:46
@paldepind: I didn't get into the implementation at all, and didn't really entirely understand everything in your demo code, which is part of the reason I thought a simplification was in order. I may be way off-base. Your second version definitely looks cleaner than the example in the repo, but I do still feel as though to use it requires more detailed knowledge of the implementation that might be desired. Remember though, that I'm just an outsider playing around with an entirely foreign API, without worrying at all about how it might be implemented; my ideas might have no basis in reality.
Scott Sauyet
@CrossEye
Mar 27 2015 23:14

Perhaps something like this:

var S = fz.convert(
    String.prototype,
    fz.allBut(['anchor', 'big', 'blink', 'bold', 'fixed', 'fontcolor',
               'fontsize', 'italics', 'link', 'small, 'strike', 'sub', 'sup']),
    fz.and({
        sliceFrom: fz.mapFieldTo('slice', fz.apply(fz._, [fz._, undefined])),
        sliceTo: fz.mapFieldTo('slice', fz.apply(fz._, [undefined])),
        uppercase: fz.dupTo('toUpperCase')       
    })
);

Or of course it might be fz.all() instead of fz.allBut(...). This is still not ideal, as .and would not be a good name if you don't include a version of all. But it might be close.