lumo

:lumo: Standalone ClojureScript environment. Currently at version 1.9.0
mattford 2017-06-10T14:48:00.147535Z

Hi, i’m failing to understand some code.

mattford 2017-06-10T14:48:22.148975Z

#!/usr/bin/env lumo

(require '[cljs.pprint :as pp :refer [pprint]])

(def github (js/require "github"))
(def githubapi (github.))

(.. githubapi (authenticate #js {:type "netrc"}))

(-> (.. githubapi -users (getOrgs {}))
    (.then #(:data (js->clj % :keywordize-keys true)))
    (.then #(map :login %))
    (.then #(println %)))

mattford 2017-06-10T14:48:33.149735Z

I wrote the above and when I run I get

mattford 2017-06-10T14:48:49.150833Z

(madedotcom MastodonC Callitech MissGuided)

mattford 2017-06-10T14:49:27.153151Z

But if I change the last line of the code

mattford 2017-06-10T14:49:38.154040Z

to a map it doesn’t work

mattford 2017-06-10T14:50:14.156451Z

(-> (.. githubapi -users (getOrgs {}))
    (.then #(:data (js->clj % :keywordize-keys true)))
    (.then #(map :login %))
    (.then #(map println %)))

pesterhazy 2017-06-10T14:51:49.162743Z

which npm package is that?

pesterhazy 2017-06-10T14:51:53.162974Z

"github"?

mattford 2017-06-10T14:51:55.163099Z

yeah

mattford 2017-06-10T14:52:43.166140Z

uses promises (I dont’ know much about node or promises) I’m just playing with Lumo as a script env at the mo.

pesterhazy 2017-06-10T14:53:43.169624Z

I get UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: ~/.netrc authentication type chosen but no credentials found for '<http://api.github.com|api.github.com>'

mattford 2017-06-10T14:54:05.170861Z

hmmm yeah you need a ~/.netrc to authenticate to github

pesterhazy 2017-06-10T14:54:11.171185Z

how do I do that?

mattford 2017-06-10T14:54:39.172798Z

You’d have to create a personal access token in github and then setup the ~/.netrc file

mattford 2017-06-10T14:54:48.173395Z

Let me do it on a public method so you don’t have to faff.

pesterhazy 2017-06-10T14:56:02.178136Z

got it to work

mattford 2017-06-10T14:56:13.178777Z

ah cool

pesterhazy 2017-06-10T14:56:41.180675Z

replace the maps with mapvs

mattford 2017-06-10T14:57:01.181942Z

I tried doall

pesterhazy 2017-06-10T14:57:13.182783Z

doall should work as well

pesterhazy 2017-06-10T14:57:25.183599Z

alternatively, the last one could use run! instead of map

pesterhazy 2017-06-10T14:57:56.185502Z

it works for me then - I get one organization back

mattford 2017-06-10T14:58:29.187951Z

hmm weird

pesterhazy 2017-06-10T14:58:43.188875Z

what does it print for you with run!?

pesterhazy 2017-06-10T15:01:12.200189Z

(doall (map println %)) also works for me

mattford 2017-06-10T15:01:39.202244Z

ah my bad

mattford 2017-06-10T15:01:49.202964Z

replace map with doall instead of wrapping it

mattford 2017-06-10T15:02:01.203781Z

been puzzling over that for a good whilst!

mattford 2017-06-10T15:02:16.204922Z

😞 and then 🙂

pesterhazy 2017-06-10T15:02:19.205158Z

hehe yeah laziness gets everyone, now and then

pesterhazy 2017-06-10T15:02:38.206571Z

btw not sure about the wisdom of those consecutive promises if the steps aren't async

pesterhazy 2017-06-10T15:03:05.208486Z

although I've seen this frequently in node code, so not picking on you

mattford 2017-06-10T15:03:29.210133Z

hmmm

mattford 2017-06-10T15:03:42.211036Z

the whole github api is promised based

mattford 2017-06-10T15:04:00.212293Z

and I cant’ extract the values of promises (as I understand it)

mattford 2017-06-10T15:04:08.212831Z

what else can I do?

pesterhazy 2017-06-10T15:04:20.213604Z

I mean you could use a single .then step no?

mattford 2017-06-10T15:04:51.215536Z

ah yes

mattford 2017-06-10T15:05:12.217043Z

that map doesn’t actually print but calls other promises

mattford 2017-06-10T15:06:00.220197Z

which could be combined into a single .then

mattford 2017-06-10T15:06:40.223213Z

I kinda liked the monadic nature of multiple .thens but if that’s not good Clojure style I shall change 🙂

pesterhazy 2017-06-10T15:07:48.227818Z

don't know about that, but it just seems pointless to me (in js as well as in cljs)

pesterhazy 2017-06-10T15:09:13.233874Z

node programmers in general seem to be seeking asynchrony like the moth seeks the flame... I just don't understand why

mattford 2017-06-10T15:09:27.234744Z

I was wondering about a then-&gt; threading thingy

pesterhazy 2017-06-10T15:11:16.242157Z

interesting idea

pesterhazy 2017-06-10T15:11:37.243524Z

although that could encourage the async step where it's not needed I suppose?

mattford 2017-06-10T15:11:53.244645Z

yeah

mattford 2017-06-10T15:12:03.245275Z

hmmm

mattford 2017-06-10T15:12:13.246038Z

I have to confess the async nature of the node github api has put me off somewhat.

pesterhazy 2017-06-10T15:12:35.247383Z

all io in node is async, give or take

mattford 2017-06-10T15:12:35.247386Z

Seems as soon as I use it i’m trapped.

pesterhazy 2017-06-10T15:12:46.248095Z

at least all network io for sure

pesterhazy 2017-06-10T15:12:55.248711Z

agree, it's contagious

mattford 2017-06-10T15:13:32.251146Z

Was porting a script I use to clone all my repos across all orgs to Lumo as an experiment.

mattford 2017-06-10T15:14:59.256892Z

Those async steps which aren’t really needed.

mattford 2017-06-10T15:15:10.257812Z

Do they just resolve immeadiately?

pesterhazy 2017-06-10T15:15:27.259083Z

i feel cljs macros could help mitigate the pain, with the right syntax

mattford 2017-06-10T15:15:31.259420Z

i.e how bad is it?

pesterhazy 2017-06-10T15:15:42.260172Z

but not sure what that syntax would look like

mattford 2017-06-10T15:17:59.268897Z

Might have a play later 🙂 thanks for the help

mattford 2017-06-10T17:04:48.705158Z

Any thoughts on this style

mattford 2017-06-10T17:40:18.925718Z

#!/usr/bin/env lumo

(require '[cljs.pprint :as pp :refer [pprint]])

(def github (js/require "github"))
(def githubapi (github.))

(defn then-&gt;
  "Promise threading"
  [promise &amp; callbacks]
  (reduce (fn [promise callback] (.then promise callback))
          promise
          callbacks))

(.. githubapi (authenticate #js {:type "netrc"}))

(defn getReposForOrg
  "Get all the repos for an Org"
  [org]
  (then-&gt; (.. githubapi -repos (getForOrg #js {:org org}))
          #(:data (js-&gt;clj % :keywordize-keys true))
          #(map :ssh_url %)
          #(pprint %)))

(defn getOrgs
  "Get the organisations for an authenticated user"
  []
  (then-&gt; (.. githubapi -users (getOrgs {}))
          #(:data (js-&gt;clj % :keywordize-keys true))
          #(map :login %)))

(then-&gt; (getOrgs)
        #(mapv getReposForOrg %))

dominicm 2017-06-10T17:41:04.929673Z

I wonder if it would be difficult to "promisify" callback style code by using a canary for where the callback would go?

dominicm 2017-06-10T17:41:32.931423Z

obviously, the macro would essentially just generate that tree structure, but still

anmonteiro 2017-06-10T17:53:58.983069Z

^ this will be in the next Lumo

dominicm 2017-06-10T17:54:43.985958Z

Bluebird had this, didn't get much use, it's a bit of a 80% solution

richiardiandrea 2017-06-10T18:49:16.257619Z

then-&gt; still reads better imho, I like the above

mattford 2017-06-10T21:01:03.835330Z

hmmm I’ve written some macros in lumo repl

mattford 2017-06-10T21:01:11.835847Z

Struggling to debug.

mattford 2017-06-10T21:01:12.835939Z

macroexpand doesn’t seem to do anything?

anmonteiro 2017-06-10T21:33:41.945920Z

@mattford not sure what problem you’re having but this post may help: http://blog.fikesfarm.com/posts/2015-09-07-messing-with-macros-at-the-repl.html

anmonteiro 2017-06-10T21:33:55.946645Z

macros in self-hosted ClojureScript behave a little differently

mattford 2017-06-10T21:35:12.951169Z

ah I hadn’t appreciated that