This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-17
Channels
- # aws (16)
- # beginners (82)
- # boot (29)
- # cider (43)
- # cljs-dev (90)
- # cljsrn (14)
- # clojure (79)
- # clojure-dev (12)
- # clojure-greece (4)
- # clojure-italy (12)
- # clojure-russia (81)
- # clojure-shanghai (1)
- # clojure-spec (39)
- # clojure-uk (28)
- # clojurescript (159)
- # consulting (1)
- # cursive (16)
- # data-science (6)
- # datomic (18)
- # devops (3)
- # emacs (22)
- # figwheel (1)
- # graphql (15)
- # hoplon (3)
- # jobs (1)
- # jobs-discuss (8)
- # leiningen (1)
- # luminus (6)
- # lumo (1)
- # off-topic (18)
- # om (6)
- # onyx (38)
- # pedestal (30)
- # perun (3)
- # re-frame (38)
- # reagent (8)
- # ring-swagger (2)
- # rum (2)
- # sql (2)
- # unrepl (14)
- # untangled (1)
- # vim (8)
How do you extend the IFn protocol to string? I tried (extend-protocol IFn string (-invoke [this] (.toUpperCase this))))
but then ("hi")
returns #object[TypeError TypeError: "hi".call is not a function]
instead of "HI"
@john I think in the primitive case you need to extend it to js/String
(this only applies to IFn
)
in Lumo:
cljs.user=> (extend-protocol IFn
#_=> js/String
#_=> (-invoke
#_=> ([this]
#_=> (.toUpperCase this))))
⬆
WARNING: Extending an existing JavaScript type - use a different symbol name instead of js/String e.g string at line 1
#object[Function "function (){
var this$ = this;
return this$.toUpperCase();
}"]
cljs.user=> ("hi")
"HI"
right but I don’t think you can get around it for the IFn
case
I could be wrong
also note you need to wrap the arity in an extra set of parens
Is there a way to "catch" a warning, so alarm bells in figwheel and elsewhere don't trigger?
Okay, thanks @anmonteiro. I'm going to forego this route. Don't want to break anything.
Hi, how can I send a POST request using cljs-ajax
library and specify its Content-Type
to application/x-www-form-urlencoded
? Thanks!
@cmal :headers
can be sent in the options map https://github.com/JulianBirch/cljs-ajax#getpostput
@bostonaholic Thank you. What should I use in the :format
field?
since it says :format
sets the Content-Type
header, then just send :format "application/x-www-form-urlencoded"
@bostonaholic Thank you! Need I add a :write
field and give it a function in :format
? The doc says that :format
should be a map in which there are two keys :write
and :content-type
, like this: https://github.com/JulianBirch/cljs-ajax/blob/29e5c57c916dac73007eeb117351f61e30c420c1/src/ajax/core.cljc#L260
@looveh server-side node.js ? require("my-module")
is sync by design, I think it's impossible to lazy-load stuff, unless they implemented System.loader
JS spec under node, which looks unlikely to me.
Hi everyone! I was writing asyncronus tests using the cljs.test macro's deftest, is, testing async ecc. I have had the need to binding a dynamic var to a different value and I have used the "binding" macro properly. Unfortunately if I place the binding before the async call, there is no binding and if I place it in the async block it is permanently rebounded. This problem is reported in cljs documentation of binding (last two examples): https://clojuredocs.org/clojure.core/binding. How can I work around this problem? I tried to use "with-redefs" but the situation is the same changing...
@giovaferra you will need to manually bind and restore probably via a test fixture
@dnolen thanks! I will try that way 🙂 I haven't looked at the code of "cljs.test/async" yet, but I was wondering why there is this problem with binding, I mean, why it shouldn't work in an asynchronous context? :thinking_face:
@dnolen nice, I have something good to watch later today 👍 I enjoy most of your talks. just in case another want to watch as well: https://www.youtube.com/watch?v=lzXHMy4ewtM
@giovaferra no bound-fn. See here: https://dev.clojure.org/display/design/Dynamic+Binding and here: https://groups.google.com/forum/#!topic/clojure/6cmnkHmHBNw
cgrand is braving the storm though: https://github.com/cgrand/dynvars
feasible yes, what’s still in flux is the impl and the API as bound-fn
is imo suboptimal in an async world. For three reasons: two minor (perf and verbosity) and one major (`bound-fn` captures a flat snapshot of vars while in CPS you’d like to capture the whole bindings stack)
@giovaferra bindings are established in a sync scope and they’ll be gone by the time the async code runs - this isn’t specific to ClojureScript btw
There is a solution, which is darwin's zones
, although it would probably need some perf test. It seems to be working fine but cgrand found out that the set walks the entire object and that could be a perf issue
aye, @giovaferra you could try zone's with the test/async https://github.com/binaryage/cljs-zones
So I'm sending a message to a worker. It's failing silently on the postMessage. I have an object that manages a pool of workers. If I define that object in another namespace, it works...
Perfect! Thank you guys! Your answers have been very usefull! I'm going to read all the documentations in order to understand the solution to this problem 😉
@giovaferra as an alternative to with-redefs
, to manually change var values you can also directly use set!
: https://cljs.github.io/api/cljs.core/setBANG
ClojureScript now has 7000 stars on GitHub https://github.com/clojure/clojurescript
I'm a bit confused about how to deal with properties of a foreign library object in advanced compilation mode. I'm trying to use phaser from http://cljsjs.io https://github.com/cljsjs/packages/blob/master/phaser/resources/cljsjs/phaser/common/phaser.ext.js but there don't seem to be any entries for properties, and I'm getting errors in advanced compilation mode, for example. the make
property of the game object, as documented here: http://phaser.io/docs/2.6.1/Phaser.Game.html#make
So, for example, if game
is my object, this line doesn't work (.make.sprite game ...)
. make is a property, and sprite is a method of the object stored at make.
So my first question is to figure out whether I'm misunderstanding externs/properties. Beyond that, I want to better understand how to more quickly debug or avoid externs using the new modes available in clojurescript.
this article has more info: http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html
so you can install phaser from npm and use :foreign-libs
to its path in the node_modules
directory
you'll get a lot of warnings from the closure compiler, but it should leave your properties in tact after advanced compilation
another option is to forgo externs altogether and use string based property accessors
this approach is outline here: http://blob.tomerweller.com/reagent-import-react-components-from-npm
perhaps, but it's not magic, you'll most likely still have to make edits to the externs file
@puzzler you just walked into ClojureScript fire swamps: https://www.youtube.com/watch?v=tpXfASdPteI
@danvingo I believe you only use .-
when the final thing in the series of dots is a property. Here it is a method, and the intermediate step is a property.
(let [game #js {:make #js {:sprite (fn [] (js/console.log "hi"))}}]
(.sprite (.-make game) "arg1"))
Has anyone had success with the pseudo-names
compilation option? I just tried it, and it didn't appear to change the error in any way.
Hey folks. Not ready to ANN this on the list yet, as this is a super experimental preview. But here's my new CLJS concurrency library I'm calling Tau: https://gitlab.com/johnmn3/tau
@puzzler I’m somewhat confused as to what you are doing, it seems like you need to make some kind of object and pass it to Phaser?
@puzzler here's some info externs: https://developers.google.com/closure/compiler/docs/api-tutorial3
Admittedly, the project is pretty dirty atm. Pushing it out now because I need advice on a number of pieces.
@dnolen In phaser, the first thing you do is create a game object. That part works. The game object has properties on it that are handles to a lot of different systems. For example, the make property leads to a object factory that has constructor methods for many different kinds of things. One of the methods in this factory is sprite
which creates new sprites.
@puzzler right so I understand, you need to provide something to Phaser that satisfies some interface
but the problem is this value is going to be exported to some foreign library outside of Closure compilation
@darwin I was thinking about putting that somewhere in the rationale: "Because, they said it couldn't be done." 😉
The game
object is successfully created, and satisfies the interface because it was created by Phaser. The problem is that all the property names are munged. I'm not sure what the syntax would be to add this to an extern file. The documentation says Foo.bar; but I'm not sure what the Foo
would be here.
@puzzler yes it should work, but in case it doesn’t, the other suggestion will definitely work
@puzzler also (.-make ^js/PhaserIface x ...)
should work if you want to go the externs inference route
I don't see any property externs in the file. The phaser externs on http://cljsjs.io was built with jmmk/javascript-externs-generator tool, according to the README. Is there a better way to get all the properties?
Is the trick of making a library its own extern file more likely to work than the tool used for the http://cljsjs.io file?
using the library as an externs is only going to work if the top level if sensible - which it usually isn’t
@puzzler in this case I think you can probably get away with externs inference to avoid writing your own file
My first choice would be to figure out how to generate a more robust externs file automatically (i.e., find a better generator tool) since the http://cljsjs.io one seems incomplete. But I can try to get up and running with extern inference. I'm not sure I'm on the latest clojurescript/figwheel, so I'll have to update those to give it a whirl. Thanks for the tips.
@puzzler the challenge with auto-generating externs is static analysis, JS libraries often dynamically create properties so this is an uphill battle
generating robust externs is a $1M task, you would make whole npm ecosystem google-closure-compatible over night
How much analysis is clojurescript doing during compilation to determine whether to munge? Does an extern that includes, e.g., a scale
method on any object prevent .scale
from ever munging on any object, or does clojurescript try to do some analysis to figure out whether this is a scale
that can be safely munged or not?
@puzzler Closure compiler does the analysis and munging. ClojureScript only flags certain functions with ^:export
to prevent munging.
I just got a million dollar idea, given a code which has tests passing in dev mode, you could write a loop compiling your sources in :advanced mode with :pseudo-names true, and running your tests - if they fail, you parse the js error message, identify the failed pseudo name and auto-generate an extern for it, rinse and repeat, until it starts passing the tests 😉
Here's what I'm getting at: it sounds like the Closure compiler doesn't really care what "type" the method or property name is on. So why can't the externs file simply be a list of method or property names not to munge. All the externs files I've seen have a whole bunch of hierarchy to them, and I don't see why that is necessary if it is being ignored.
@puzzler and no, declared externed properties must be associated with a particular object to prevent munging, afaik
@john I believe you can also specify externs on Object
which are effective on any js object
since most of clojusescript is untyped anyways it actually doesn't matter where properties in externs go
So when I do a call that corresponds to object.make.sprite()
How does the closure compiler know that the make
property is a type that has a corresponding extern for the sprite method? Nothing in the externs indicates the type of a given property, just that it exists, right? So how would the compiler be able to figure out not to munge sprite
?
I recall not being able to get externs to work without having the correct hierarchy, but it's been a while.
@puzzler basically just define Foreign.prototype.anyProperyYouWantToKeep;
in your externs
didn't release that yet but shadow-cljs
has a --check
option that will tell you about any undefined properties
@darwin how about this idea... instead of non-deterministic munging, deterministically munge names into base64 identifiers. Most words would probably shrink down to 2 or 3 chars. Then it's reversible 🙂
wait, how would base64 make anything smaller?
oh, sorry, I see what you mean
so you aren’t talking about base64 encoding, which always makes strings longer