These are chat archives for ramda/ramda

19th
Oct 2015
Niloy Mondal
@niloy
Oct 19 2015 09:26
Whats wrong with just sub classing Error?
Raine Virta
@raine
Oct 19 2015 09:29
I want to add custom data to the Error objects for logging purposes, if you create a custom constructor for each error type it's not very DRY
Julien Goux
@jgoux
Oct 19 2015 09:36
General JS question, how would you alias two modules (one is internal to your app, the other is a third party one) when you want to use them both in one file, and you don't want to import each bit explicitly because it would be too long
Example
import T from "tcomb" and import Types from "./types"
Raine Virta
@raine
Oct 19 2015 09:37
does the example continue? I don't understand the problem
Julien Goux
@jgoux
Oct 19 2015 09:38
@raine I'm not sure about importing with global alias is good for code readability, but import explicitly can be very annoying too, so I don't know what to choose :p
and also if there is a good notation to distinct external module from internal ones
when you choose the global alias way
@raine For example here I'll have alias everywhere : https://gist.github.com/jgoux/9ac790a1dc2d420b3232
I don't know if it's a good thing
Niloy Mondal
@niloy
Oct 19 2015 09:42
you want to import all without using alias?
Julien Goux
@jgoux
Oct 19 2015 09:43
@niloy Yes this could work, and alias just the possible collisions
But I'm not sure if it's possible ?
import from "./foo" ?
Raine Virta
@raine
Oct 19 2015 09:44
you can't import all properties
I might have use for tcomb
Julien Goux
@jgoux
Oct 19 2015 09:49
This is an awesome lib :D
Raine Virta
@raine
Oct 19 2015 09:53
can you make a struct on the fly to validate an object?
I suppose why not
Julien Goux
@jgoux
Oct 19 2015 10:02
@raine I think yes
Aldwin Vlasblom
@Avaq
Oct 19 2015 10:03
@jgoux tcomb looks awesome. You could do something like compose or inherit tcombs types from your own types export:
//types.js
import tcomb from 'tcomb';

//compose
export default Object.assign({}, tcomb, {
  MyType
})

//or inherit
export default Object.assign(Object.create(tcomb), {
  MyType
})


//index.js
import T from './types';
Julien Goux
@jgoux
Oct 19 2015 10:05
@Avaq Why not, but I link to think as my types separate from the tcomb's one (the building blocks of my types)
And I have many types files :D
I split them across my entities
The only thing I would remove from tcomb is this part : https://github.com/gcanti/tcomb/blob/master/GUIDE.md#updating-immutable-instances
Using ramda lenses is better IMO
The syntax is too coupled to immutablejs
Aldwin Vlasblom
@Avaq
Oct 19 2015 10:07
Yeah. I raised my eyebrow at that roo.
Julien Goux
@jgoux
Oct 19 2015 10:07
Maybe I could suggest to split this part out of the core
Raine Virta
@raine
Oct 19 2015 10:07
I don't really see the point with immutable stuff
Aldwin Vlasblom
@Avaq
Oct 19 2015 10:09
If tcomb types were functors you could update by map(over(lens(...))), maybe.
Julien Goux
@jgoux
Oct 19 2015 10:10
I made the suggestion in tcomb gitter room :D
We'll see
There is also a babel-plugin to integrate runtime checking with tcomb using flow syntax
Julien Goux
@jgoux
Oct 19 2015 13:03
Is there an implementation of the Either monad with ramda ?
boxofrox
@boxofrox
Oct 19 2015 13:07
not without using an external lib like sanctuary.
Julien Goux
@jgoux
Oct 19 2015 13:19
@boxofrox Just found https://github.com/ramda/ramda-fantasy , thanks ! :)
Hardy Jones
@joneshf
Oct 19 2015 13:31
@jgoux be careful with that. It's not actually a monad. It's just a functor.
boxofrox
@boxofrox
Oct 19 2015 13:32
even though the readme table marks Monad for Either?
@joneshf Ok I saw your issue about it ^^
Hardy Jones
@joneshf
Oct 19 2015 13:35
And it fails to be an Apply, thus isn't a Monad.
k
it's getting fixed
just be careful :)
Julien Goux
@jgoux
Oct 19 2015 13:36
Yes, I'll have it in mind ^^
thanks !
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:23
I have a program processing a stream, and piping the result to stdout. When I do ./my-program | head I get Error: write EPIPE after 10 lines of output. Any tips on how to deal with this EPIPE error? I expected the stream to end on its own, at which point I exit the process.
Hardy Jones
@joneshf
Oct 19 2015 15:27
@Avaq if you do ./my-program | head -n 5 does the error happen after 5 lines?
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:28
Yes. :P
Hardy Jones
@joneshf
Oct 19 2015 15:28
k
I don't have anything constructive to add, was just curios.
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:29
Hahaha, it's the stream triggering the error. I handle it with .on('error', handle) but if I don't its thrown as an "Unhandled error event".
Hardy Jones
@joneshf
Oct 19 2015 15:30
what stream are you using?
kind of a pain that it doesn't handle cleanup itself.
Martin Algesten
@algesten
Oct 19 2015 15:30
is it because the out stream closes before you expect it to be closed?
Hardy Jones
@joneshf
Oct 19 2015 15:30
^ sounds like that.
Martin Algesten
@algesten
Oct 19 2015 15:31
i found it really tricky to know which stream to listen to for ending.
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:31
Well, head makes it close, of course. But I would expect my entire pipeline to just stop streaming at that point and trigger an end event.
Hardy Jones
@joneshf
Oct 19 2015 15:31
is this a unix thing, or a node thing?
Martin Algesten
@algesten
Oct 19 2015 15:32
yes. a node thing. like i have a readstream and a writestream and which of them do i listen to for the end?
Hardy Jones
@joneshf
Oct 19 2015 15:32
yes
:)
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:33
I start the stream with fs.createReadStream() (Node 4.x), but will switch to request() later. I pipe it through feedparser and some transduce-streams before piping to process.stdout.
I'm only listening to events on process.stdout.
Martin Algesten
@algesten
Oct 19 2015 15:35
i still don’t know which one you should listen to. it’s all a blur :)
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:36
So:
fs.createReadStream()
.pipe(feedparser)
.pipe(transduceStream(compose(...)))
.pipe(process.stdout)
.on('end', ...)
.on('error', ...) //this is where the error is caught
Martin Algesten
@algesten
Oct 19 2015 15:37
at this point i’m also confused as to which ‘end’ and ‘error’ we’re listening to… i hope it is the readstream.
which means you can probably fix it by adding an ‘end’ listener to process.stdout.
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:37
I believe pipe returns its argument. So it's probably the writestream
Martin Algesten
@algesten
Oct 19 2015 15:37
:D
in that case i reverse what i just said.
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:40
Still might be relevant. What would you have your process.stdout.on('end') listener do?
Martin Algesten
@algesten
Oct 19 2015 15:42
xD … hm. shut down the readstream somehow.
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:44
Yeah. :\ - I thought streams in Node are kind of pull-based. If I don't consume the stream (not pipe it to stdout or listen to on('data')) my process completes after a few milliseconds (the input file is hardly processed). Yet once I pipe to stdout, the process takes five seconds. The odd thing is that when I pipe to head, (besides getting the error) is that the process still takes 4.5 extra seconds after the error occurs, as if the whole stream is still being processed, but not written anywhere.
Martin Algesten
@algesten
Oct 19 2015 15:48
so could the problem be that your output should be paused, but it just keeps spewing things out and some buffer eventually overflows?
Julien Goux
@jgoux
Oct 19 2015 15:49
@Avaq process.stdout cannot be closed
process.stderr and process.stdout are unlike other streams in Node.js in that they cannot be closed (end() will throw), they never emit the finish event and that writes are always blocking.
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:50
So who is complaining when I | head?
Julien Goux
@jgoux
Oct 19 2015 15:51
Did you try to put an error listener on each stream ?
The listener isn't for all the chain, you have to put one by stream
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:52
I haven't. That sucks a bit.
Julien Goux
@jgoux
Oct 19 2015 15:52
I agree
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:52
I'll do that thing.
Julien Goux
@jgoux
Oct 19 2015 15:53
I'm not sure it's the solution, but maybe you'll see the error :D
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:55
But shouldn't errors not handled by on('error') be thrown by the EventEmitter? So in theory I shouldn't have to listen to at least get an uncaught exception.
Julien Goux
@jgoux
Oct 19 2015 15:57
@Avaq I don't think so, as you're in an asynchronous style with events.
It's the same with promises, if you don't catch the promise chain you can't see the error
With node.js script like that I always put a global catch for my promises :p
Aldwin Vlasblom
@Avaq
Oct 19 2015 15:59
Yeah. I added .on('error', console.error) to every step in the pipeline, and didn't get any kind of new error.
No, "error" events are special. If you don't listen to them when they occur, Node throws them.
If I remove all of my .on('error', console.error) listeners (including the one at the end of the pipeline) I get:
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: write EPIPE
    at Object.exports._errnoException (util.js:874:11)
    at exports._exceptionWithHostPort (util.js:897:20)
    at WriteWrap.afterWrite (net.js:763:14)
The EventEmitter throws the error.
Julien Goux
@jgoux
Oct 19 2015 16:02
ok
I think it's because of head behaviour
does it works without piping to hed ?
head
Aldwin Vlasblom
@Avaq
Oct 19 2015 16:03
Yeah. Works just fine.
So you can add a listener on your process to exit on this error :D
I never piped to head, good to know :D
Aldwin Vlasblom
@Avaq
Oct 19 2015 16:06
Oh I did try searching for something like that before I even resorted to asking you guys! I didn't expect it to be specific to head though. Now I have to catch errors that are specifically EPIPE and handle it as if it means stream#end. :\
Julien Goux
@jgoux
Oct 19 2015 16:06
or you have to tee it first
Aldwin Vlasblom
@Avaq
Oct 19 2015 16:06
Yeah. But then my process still goes and processes the whole file.
I want it to be lazy.
Julien Goux
@jgoux
Oct 19 2015 16:06
So catching EPIPE should work
Did you try ?
Aldwin Vlasblom
@Avaq
Oct 19 2015 16:07
Well, I'll probably have to inspect the error object, and pause the readstream when I find the EPIPE. I'll get on it now.
Julien Goux
@jgoux
Oct 19 2015 16:09
If you do a head on your script, isn't EPIPE the end of the execution ?
Aldwin Vlasblom
@Avaq
Oct 19 2015 16:11
No. After the stream ends I still persist some data.
Before exiting.
Aggregated throughout the stream.
Now that I've handled the EPIPE error, I'm getting Error: This socket is closed. from somehwere. t_t
I'll try some stuff. Thanks for your thoughts and help! :D
Julien Goux
@jgoux
Oct 19 2015 16:20
@Avaq you're welcome
Aldwin Vlasblom
@Avaq
Oct 19 2015 16:21
The "this socket is closed" happens when I try to console.log after piping 10 lines to head. :)
Makes sense.
Aldwin Vlasblom
@Avaq
Oct 19 2015 16:33
It works: .on('end', res).on('error', ifElse(propEq('code', 'EPIPE'), res, rej)). I just have to make sure I don't try to write anything else to stdout after res is called.
Julien Goux
@jgoux
Oct 19 2015 16:35
Cool ! Great job. :+1:
joneshf-work1
@joneshf-work1
Oct 19 2015 17:44
@Avaq you've reminded me why I never want to write javascript
Jethro Larson
@jethrolarson
Oct 19 2015 18:23
I used to be annoyed that js has map as a function and map as a data structure. Now that I understand this stuff better I'm less mad.
Martin Algesten
@algesten
Oct 19 2015 19:03
is this library built on interpreting the exact string output of a String(foo)?
joneshf-work1
@joneshf-work1
Oct 19 2015 19:30
thts' pretty cool
joneshf-work1
@joneshf-work1
Oct 19 2015 21:59
is there a safe version of find and head and all those array things?
that I might have missed
Scott Christopher
@scott-christopher
Oct 19 2015 22:14
@joneshf-work1 Not in Ramda. Sanctuary has typically been suggested to cover that gap – find, head
joneshf-work1
@joneshf-work1
Oct 19 2015 22:15
sounds like it's time to level up to sanctuary then.
Scott Christopher
@scott-christopher
Oct 19 2015 22:15
That said, it might be nice to consider offering findOr, headOr in Ramda.
A quick search for | undefined in the docs highlights all the functions that could offer *Or equivalents
Scott Sauyet
@CrossEye
Oct 19 2015 22:24

Ramda has always considered itself a lower-level library. When several of the principals were not interested in imposing something like Maybe on JS users who'd never seen anything of the sort, Sanctuary was started as a companion library that adds various sorts of higher-level safeties on top of Ramda, including safe versions of head and find and the like, as well as additional type-checking that Ramda is not interested in doing.

@buzzdecafe has recently suggested that maybe it's time to reconsider that decision for Ramda.

I'm not convinced, although I do find the combination of Ramda and Sanctuary better for much of my own use than Ramda alone.

joneshf-work1
@joneshf-work1
Oct 19 2015 22:29
yeah, I'm fine with using additional libraries
I just didn't know if I missed something
Frederik Krautwald
@Frikki
Oct 19 2015 22:35
If the entry level should be low for newcomers, I agree with @CrossEye , too much higher level can easily throw them off. Ramda is quite advanced already, compared to standard JS.
Scott Sauyet
@CrossEye
Oct 19 2015 22:41
The fear was creating something like Bilby -- elegant as can be, but not useful for most JS users.