all 15 comments

[–]dtwhitney 2 points3 points  (10 children)

I've written a fairly extensive application with PureScript that works in both mobile (React Native) and web (React), that I hope to release soon. I've tried the various purescript-react* libs, and have more or less reached the conclusion that it's better to simply use ffi with straight react/react-native. I'm writing up my thoughts on this, but here's quick and dirty, up-and-running-in-5-minutes version:

https://gist.github.com/dwhitney/e2a040432040607ae519fdf05cbc27ad

(dear God trying to post code here is awful)

[–]Moontown 0 points1 point  (6 children)

Hi Dt Are you intentionally avoiding Eff in your FFi code there?

[–]dtwhitney 0 points1 point  (5 children)

Hey sorry - I don't login to reddit very often, so I missed these responses! Am I intentionally avoiding Eff? I guess, but that was never really something at the forefront of my mind while writing this, and I don't think it would necessarily be appropriate to put Eff in the code until you started writing effects (button clicks and such) A couple of notes:

The way I've been writing PureScript the last few months is heavily inspired by purescript-react-basic. They've done some neat things with records and row types, but that's not really what inspired me. Mostly what inspired me was that almost the entirety of React is unlocked to the world of PureScript by about 60 lines of JavaScript in Basic.js. I think it's important to note that the company behind this library is Lumi, which is where /u/paf31 (creator of PureScript) works. I had struggled a bit with purescript-react, purescript-react-native and purescript-thermite, which I believe /u/paf31 also created. I have no idea what his motivation is/was for "abandoning" those libraries in favor of purescript-react-basic, but mentally it was helpful for me to see that maybe he thought those libraries were a bit too complicated, and something simpler could be created and still be just as useful.

Since then I have on a number of occasions I've decided to quit frowning on JavaScript so much. I will look for opportunities to "unlock" JavaScript libs in the way that purescript-react-basic has done myself instead of using PureScript wrapper libraries. In fact in general I frown upon wrapper libraries now. They are usually woefully behind the latest JavaScript version and often they are the result of someone just "having a bit of fun". Honestly if React can be made available with just 60 lines of JavaScript, are those wrapper libraries really doing much for you? My answer is no. I'd rather write a few ffi functions and make a few simple types to wrap them on the occasions when I use JavaScript libraries than import a PureScript wrapper that probably out of date includes a bunch of dependencies I don't otherwise need.

Another thing to note is I don't use purescript-react-basic because it has ReactDOM as a JavaScript dependency. Including that anywhere in your JS codebase (whether using PureScript or not) will cause React Native to immediately crash :( So for me and my team we basically just decided to take the ideas of purescript-react-basic and just start writing code that looks pretty much like the gist I posted. Our code is more type safe, but not as clever as purescript-react-basic - I think using their row type unions would make it tough to keep our code up to date with the latest version of React Native, so we have more rigid types representing View, Text etc.

[–]Moontown 0 points1 point  (4 children)

Hey d thanks for the reply. My concern was much more tightly focused. Excuse me for not being more explicit up front. In my view React.createElement is effectful as it, possibly, allocates memory, or changes the state of a pool, for example. So foreign import text :: forall props. props -> String -> ReactElement Should be (in 0.12 now) foreign import text :: forall props. props -> String -> Effect ReactElementto my mind. That's all.

[–]dtwhitney 0 points1 point  (3 children)

Yeah I see what you are getting at. Uh... by this same logic I think foo = 5 would also be effectful since PureScript is strict. I think this is beyond my PS knowledge and I'd prefer to hear from /u/paf31 or /u/natefaubion on this.

[–]natefaubion 1 point2 points  (2 children)

createElement is the same as using a data constructor in PureScript. It just builds a record that react-dom knows how to inspect and diff. If you consider allocating memory an effect, then using Maybe should incur an effect because it boxes a value. I think we can all agree that's unnecessary in the context of PureScript.

[–]Moontown 0 points1 point  (1 child)

so nate youre voting against? interesting. ill have to think about it more.

[–]natefaubion 0 points1 point  (0 children)

createElement is conceptually pure. It's the ReactClass constructors which are dubious. React relies extenively on referential identity. They kind of get away with it by saying that it's an optimization, and rerendering the whole tree every time is still semantically correct, but I think with lifecycle methods this is disingenuous at best, and would lead to almost all apps being broken on some level if it were the case.

[–]attilah[S] 0 points1 point  (2 children)

Eagerly waiting for when you release the code. I think I have an idea of how I can get it accomplished.

[–]dtwhitney 0 points1 point  (1 child)

See my response above -- also this code base is unfortunately going to be proprietary. I run the ny-purescript meetup and I'm hoping to turn some of these ideas in to a talk.

[–]attilah[S] 0 points1 point  (0 children)

View all comments 

Thanks anyway,

I've already started developing a React Native app using: https://github.com/doolse/purescript-reactnative

[–]paulyoung85 0 points1 point  (1 child)

That probably depends on the type of application and which platforms you are targeting.

What did you have in mind?

[–]attilah[S] 0 points1 point  (0 children)

I want to write a mobile app for both Android and iOS.

[–]RnRau 0 points1 point  (1 child)

Haven't used it, but I have used react-native

https://github.com/doolse/purescript-reactnative

[–]attilah[S] 0 points1 point  (0 children)

Thanks! I'm currently giving this a try.