This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-05-02
Channels
- # admin-announcements (4)
- # aleph (10)
- # arachne (1)
- # beginners (66)
- # boot (19)
- # cider (6)
- # cljs-edn (2)
- # cljs-site (32)
- # cljsjs (4)
- # cljsrn (32)
- # clojure (116)
- # clojure-austin (6)
- # clojure-belgium (2)
- # clojure-dusseldorf (1)
- # clojure-russia (16)
- # clojure-uk (5)
- # clojurescript (178)
- # community-development (2)
- # cursive (28)
- # datascript (16)
- # datomic (16)
- # dirac (13)
- # editors (2)
- # emacs (1)
- # error-message-catalog (30)
- # events (3)
- # garden (2)
- # hoplon (27)
- # jobs (4)
- # ldnclj (4)
- # liberator (3)
- # off-topic (6)
- # om (49)
- # onyx (24)
- # parinfer (9)
- # re-frame (59)
- # reagent (46)
- # remote-jobs (1)
- # rethinkdb (4)
- # rum (2)
- # slack-help (11)
- # untangled (13)
Out of curiosity, has anyone ever tried to use cljs to generate JavaScript for apple's "JavaScript for automation" applescript alternative?
@gowder: interesting, haven’t played with it. haven’t heard anyone trying that yet
@gowder: what are you using it for?
@shaunlebron: Right now, nothing at all, I was just kicking around the idea.
@gowder: ah, was just wondering what’s possible with it that might compel more people here to try or look into it
@shaunlebron: people do all kinds of interesting stuff with AppleScript... obvious possibilities include stuff like feeding the text of Apple notes into a machine learning pipeline...
What's the best way to make this more idiomatic?
(defonce messages (atom []))
(.forEach (.watch (.limit (.order chat "datetime" "descending") 8))
(fn [x] (->> (js->clj x :keywordize-keys true)
(reset! messages))))
(-> chat
(.order "datetime" "descending")
(.limit 8)
(.watch)
(.forEach
(fn [x] (->> (js->clj x :keywordize-keys true)
(reset! messages)))))
(.. chat
(order "datetime")
(limit 8)
(watch)
(forEach
(fn [x] (->> (js->clj x :keywordize-keys true)
(reset! messages)))))
seems to work. Any reason to pick one over another?@gowder: I did this for kicks once https://github.com/slipset/applescript
There is also https://github.com/mfikes/planck/issues/122 which kind of explains why this is pain IIRC
cljsfiddle fun gist of the day http://cljsfiddle.com/#gist=9f886e53e7b96d9db056c3edd76a5a65
This (binding [*out* *err*] ...)
gives me a Use of undeclared Var my-ns/*err*
error. Is *err*
not a thing in clojurescript? I don't see it listed in https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure.
Looking closer, I see *out* is currently not implemented
listed tho. So that answers my question at least.
hmm, your environment must be broken somehow, for some reason cljs.core is not recognized as your implicit namespace
such as when I run a node app and there's a runtime error, have it display the clojurescript trace
also, how do you require nodejs modules? I can't seem to find much info on that. I looked at [this](https://github.com/bodil/clojurescript-all-the-way-down), but it's throwing "No such namespace, js" when I do (def source-maps (js/require "source-map-support"))
@slipset: interesting! Actually doesn't look like it would be too hard for basic scripting, judging by your example plus the one posted in the gh issue. Maybe time to play around with this. (I wouldn't necessarily believe hhas's gripes in that issue, though ---I think this is someone with an axe to grind; judging by that comment plus a response to a tweet of mine, s/he just regularly searches for everything relating to AppleScript to complain and link to his/her own libs)
@gowder What sort of bummed me out was that javascriptcore didn’t seem to have access to the osascript thingy. It would have been so nice being able to do (def mail (js/Application "Mail”))
from planck
@martinklepsch: About :closure-defines
, I can’t get it to work with leiningen in project.clj
. Is it supposed to be in :builds :my-build
or :builds :my-build :compiler
? Neither worked for me. It is supposed to override values set with goog-define
right?
@vikeri: yes. It's a compiler option so you need to make sure it's passed to the compiler
also in project.clj no quoting is necessary.
@martinklepsch: Ok, that’s what I did. The issue might be related to my RN setup.
@vikeri: if you look at the main file generated by the compiler it should have appropriate lines for the closure-defines you passed to the compiler
@vikeri: I assume you use none?
Well the output is target/ios/not-used.js
so maybe that has something to do with the error 😛
haha. the closure-defines stuff works by prepending a little thing to the main file so if you're not using the main file it won't work
how do people feel about global state management in clojurescript compared to a backend clojure application? Over the past months i've fully adopted Component on the server side and thoroughly enjoy the repl experience it allows. It has influenced the way I am now building up a client side app. I'm passing local state down the ladder everywhere, taking state as args instead of referring to a global. While this keeps things a little organized, it's also seeming to put a strain on front end api, having to pass around resources everywhere where it would be easier just to silently depend on something like a singleton async channel, and the gains are less pronounced because on the frontend my workflow is based around page refreshes instead of resetting the repl (and i'm fine with this). Basically, is it common for state management to be less strict on client side applications?
Independetly if you will use it or not, take a look on https://github.com/tonsky/rum
in the front end, I like using EntityDB http://keechma.com/04-entitydb.html
I'm getting more at this: When you use EntityDB for example do you pass around the reference to the DB in all your functions that use it? Or just have it defined globally somewhere and refer to it throughout all your functions
On the server I kind of adapted the passing it as an arg everywhere and along with Component I feel this was beneficial to my workflow, but now going back to client stuff, I'm seeing less benefits to that style, but it's still kinda drilled in my head that "global state is bad"
I’ve only used it with keechma, and there is no need to pass it around because of the way it is architected. I would probably try to emulate the way it is done there if I weren’t keechma: Separate the components(views) from the controllers, and the only way they can communicate is via messaging.
@jjttjj While JS and not CLJS, I would really take a hard look at how Redux does state management.
@jjttjj: if you're getting started in this space, the re-frame readme is a pretty good intro to redux (plus you'll learn re-frame and start applying it!): https://github.com/Day8/re-frame
It has a dispatch & subscription mechanism that neatly side-steps needing to pass around your db
Also: posh (https://github.com/mpdairy/posh) is a take on re-frame but using datascript for querying/updating your app db (datascript, that thing that looks like datomic)
I saw a presentation of someone that made mobile apps with clojurescript, but dropped Datascript because it was a little slow on mobile
Ah, gotcha. Still I am planning on using it (Datascript) in my current app to try it out, my users for that will just be my colleagues and they'll be on browsers (rather than native).
@jjttjj: the problem you have outlined is a real one. A common way how to “pass implicit parameters” is via dynamic bindings. Clojure core library itself relies on this technique a lot. When going from Clojure to ClojureScript this technique is not that useful because it breaks with introduction of async code. Dynamic bindings are not “inherited” by callbacks (or code scheduled asynchronously and we don’t have anything like bound-fn
in ClojureScript). This issue has been raised multiple times over time but no acceptable solution was proposed (yet). I would recommend following this JIRA issue where we will discuss possible solutions: http://dev.clojure.org/jira/browse/CLJS-1634
keechma makes the URL the source of global state, which isn't a terrible idea if you are interested in SEO or server side rendering for performance reasons
I don’t have an issue with passing in the dependency into a function. It makes things much clearer when reading. I’d rather be able to reason about a function later, than save some keystrokes today.
@roberto: right, but there is some limit to that I believe, for example would you explicitly pass a logger service reference into all functions in your system?
or would you want to pass “db” reference through functions which don’t care about db, but want to call other functions which possibly need access to the db?
I once did a rewrite of quite complex cljs code to component model “without global vars", and it wasn’t a pleasant experience...
ended up passing “context” parameter as explicit bag of deps into basically all functions
I’m not a Haskell guy, but the problem we are talking about is real. And there exists research papers about it Haskell people came up with a language extension for it: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/other-type-extensions.html#implicit-parameters
if a function needs to call another function that queries the db, then that function depends on db
I have a REST application where I pass the db into the handler functions, that way it's very explicit
I also agree that it is better to pass deps explicitely in parameters but there is a limit to that when it becomes impractical.
how would you do that logging use case? I don’t want one global logger, I want to pass loggers explicitly down as a “service"
i would pass down the logger, since it is a dependency. If for some reason I want to avoid that, then I’d pour some holy water on me and use a global var.
in combination with datomic for example you really don't want to have your db in a dynamic var or weird things will happen when you query the db as of some time
laziness? I don’t get it, going for explicit arg passing is the right thing to do, but verbose and prone to heavy maintenance
you have to be careful with dynamic vars when doing multi-threaded development, must be aware of bound-fn
(in Clojure)
@darwin: example, we had this: (binding [db (db/as-of ...)] (map #(db/q '[....]) ...) or something. We got the results of the default binding, because evaluation was lazy
so, I don’t have a good solution for my logging case. I want to do it right. But I cannot pass logger into every single function in my code base. I cannot use dynamic binding because it won’t survive async call boundaries. I’m left with no other options.
the same arguments as against global db reference or any other global thing. I want to be able to pass my own version of logger into functions at any level.
i have wanted to have individual loggers because certain things I’ve wanted to log differently, but couldn’t figure out how to do that with timbre
. If I could do that, I would still pass it down as a dep tho.
why would you ever wanted to do (binding [*out* something-special] …)
in Clojure code?
you want to redirect functions like println and similar and capture their output for example
no, he proposed bindings and I outlined above why bindings don’t work for me under some circumstances
good discussion guys, I have to run and do some work now, if you want to help solve my issue, follow http://dev.clojure.org/jira/browse/CLJS-1634
I wrote a blog post about using Protocols in ClojureScript, specifically how it is involved with JavaScript interop: http://blog.altometrics.com/2016/05/protocols-in-clojurescript/
@fenton: you can use a library like storage-atom: https://github.com/alandipert/storage-atom
under the hood it uses transit to encode and decode your data structures into strings that can be put into local storage
I wonder why the session-storage doesn't appear to work in my clojure-script repl...hmmm
@kingoftheknoll: deps conflicts are tricky, I would first try to include fipp dependency in your top-level project.clj, probably using the latest 0.6.4, hopefully puget will be able to work with this “future” version
including fipp explicitely in your project should have precedence over deps declarations in libraries
I’ll give that a try, I’m surprised others haven’t reported this since it’s the stock reagent template… could it be referencing deps outside of my project?
hummm… nope
does lein deps :tree
really confirm it is using fipp 0.6.4? (see the last section where it lists the effective deps tree)
[venantius/ultra "0.3.4"] -> [mvxcvi/puget "0.8.1"] -> [fipp "0.5.2"]
overrides
[lein-figwheel "0.5.2"] -> [figwheel-sidecar "0.5.2"] -> [fipp "0.6.4”]
I even tried
[lein-figwheel "0.5.2" :exclusions [fipp]]
and explicitly required fipp 0.6.4
:exclusions [fipp] on figwheel will fail, because your problem is that puget brought old version of fipp and figwheel chokes on it
try :exclusions [fipp] on ultra lib, that should leave fipp 0.6.4 as effective version
ultra lib?
for some reason this old version wins over figwheel’s request to require 0.6.4 versio of fipp (assuming this one is newer)
I’m not requiring that lib
not sure what is
cd to my project dir, then lein deps
you have to do lein with-profile +dev deps :tree
to see merged deps from your root :dependencies and :dev :dependencies
good news is that doesn’t give me any warnings
does that mean I need to run figwheel using with-profile
?
leiningen implemented some implicit magic that some “known” profiles are merged under some circumstances
so it highly depends what commands are you trying to call if that :dev profile will be effective or not
read the docs here: https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md
lol I understand. Is there a nuclear option like blowing away my .m2 dirs?
to make sure your :dev profile gets included simply add with-profile +dev
to your lein calls
sure thing
thanks for helping