This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-04-28
Channels
- # aws-lambda (2)
- # beginners (49)
- # boot (49)
- # cider (7)
- # clara (1)
- # cljsrn (4)
- # clojure (199)
- # clojure-android (49)
- # clojure-dev (1)
- # clojure-greece (4)
- # clojure-italy (3)
- # clojure-nl (4)
- # clojure-norway (5)
- # clojure-russia (78)
- # clojure-spec (22)
- # clojure-uk (18)
- # clojurebridge (2)
- # clojurescript (252)
- # core-typed (2)
- # cursive (11)
- # data-science (1)
- # datascript (2)
- # datomic (38)
- # devcards (1)
- # flambo (3)
- # hoplon (10)
- # immutant (2)
- # jobs (3)
- # luminus (1)
- # lumo (2)
- # off-topic (8)
- # om (3)
- # onyx (29)
- # parinfer (1)
- # pedestal (4)
- # portkey (13)
- # re-frame (13)
- # reagent (6)
- # ring (3)
- # ring-swagger (15)
- # schema (2)
- # spacemacs (4)
- # test-check (4)
- # untangled (46)
- # yada (2)
I’m using d3 (strokes) with rum , of all the examples I went through, HTML pages are accessing the compiled javascript files but not any of the clojure-script compoennets/ functions.
@ingared in venn-diagram do you draw d3 circle in did-mount
?
When you draw them like in example, the body element and such is already available. In the case of reactjs, you need to draw them in did-mount, since the dom element is only available then.
https://google.github.io/closure-library/source/closure/goog/demos/ <-- do we have cljs bindings for this UI library ?
@qqq it comes with goog
right? So you can just include it like any other goog
library.
what happens if you do (:require [goog.ui Dialog])
from inside your CLJS project?
@tbaldridge : good point; just to clarify: under this methd, I would be using the goog ui library in an "imperative" way and not in a "react" way right?
you can usually wrap an imperative UI in a React component with componentDidMount
/`componentWillUnmount` and then use it like a normal React component from the outside
@qqq the only draw back I've seen so far is those lib doesn't support server rendering. ( only if you need it )
I have a macro where I'm trying to test if the second parameter is a vector, but what I have is always returning true.
(defmacro with-vec [fname & x]
`(if (vector? ~(first x))
(ex.core/do-my-apply ...
I've tried moving the ~
behind x
and (vector?..
but the first then branch always executes.So I've got this awesome macro where you can do (def t (an.ex/thread))
and then (on t (println "hi") (println "from thread t"))
and I just upgraded the on
macro so that if the second arg is a vector, that vector is used as the binding arguments in the code that is passed. But then the actual values of those bindings within the vector are also passed "over the wire" as arguments, which get filled in on the other side, as arguments to the implicit function that executes the body.
So like, (def a {:a 1})
then (on t [a] (println (assoc a :b 2)))
will print {:a 1, :b 2}
in the worker thread.
and if a
is a TypedArray, it will transparently convert it to a Transferable and send it by reference.
Hello. Anybody know if there’s any way to change the pprint format for (pprint {:p1/a 1 :p1/b 2})
from #:p1{:a 1, :b 2}
to {:p1/a 1, :p1/b 2}
?
@darwin you might want to look into http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf
Ignore their silly bruteforce method of generating signed distance fields, you can do it in java efficiently if you look into proper algorithms
Say, anyone have a recommendation for a rich-text input component that is react/reagent friendly and generates Markdown?
@timgilbert I suggest look at https://github.com/ianstormtaylor/slate, you can define custom serializers, so depending of the content your users are writing it wouldn’t be too hard to generate markdown
@thheller that worked! That differs from the clojure syntax for multiple arity protocol methods though, doesn't it?
you can’t use multi-arity fn syntax with protocols
extend-protocol and extend-type use the same syntax as when embedded in defrecord/deftype
actually, maybe I’m wrong on that! (reading the docstring)
weird, didn’t remember that
anyone have an example project that uses boot and npm dependencies (node_modules)?
Heya, I just upgraded ClojureScript in a project from 1.9.293 to 1.9.521. For deployment, it builds an uberjar and puts the compiled cljs into it which is then served by a Clojure web server which is also bundled up in the uberjar. Thus, ClojureScript should not be required at runtime, and up until (at least) version 1.9.293 that was indeed possible by marking the ClojureScript dependency as provided
. Now with 1.9.521 I get java.lang.ClassNotFoundException: com.google.javascript.jscomp.CompilerOptions
when running the main class. Not marking it as provided
makes it work but blows up the uberjar's size by 10 MB. Before I file a bug report: is it reasonable to expect this to work in the first place?
Oh, the clojurescript compiler is of course not referenced anywhere in the Clojure part of the code.
@thheller Yeah, but I don't 😄
Trying again with 1.9.293 now just in case
I'll try to come up with a minimal repro case unless you talk me out of it 🙂
Yeah, it can only be the Clojure part
Maybe some other library is referencing the cljs compiler somehow
OK just verified: it works with the exact same code when depending on clojurescript 1.9.293 as provided
Sure, that's a red herring - it's not included in the uberjar after all
and the produced jar definitely does not contain any cljs/*
files? check wit jar -tvf uber.jar
Well there's cljs/core/match/macros.clj
for example but that's been there before, too
And of course it's not required anywhere in the Clojure code
Well, I'll just ship 10 more megs for now and will try to come up with an isolated reproduction case when I'm done with that
not sure about the :provided
part, I have everything in :dev
and that doesn't end up in the uberjar
Indeed, that's worth a try
Looks like it's not picked up by lein-cljsbuild
there
Using the leiningen.cljsbuild
Leiningen hook
Right, makes sense - the :dev
profile is not active when lein uberjar
runs after all
@thheller How are you building your cljs for the uberjar then?
Heh, nice
It does, just not with the uberjar build hook
@thheller Do you have a guide on how to set up shadow-devtools
for uberjar deployment as I described above?
Never mind, I think I found it
usually I don't put generated CLJS files into the uberjar but serve them from the fs
Can't you force inclusion with with-profile
? I always use :test
for my ClojureScript dependency, I don't actually even know why (probably it has to do with Maven's trnasitive dep rules)
:aliases
{"foo"
["do"
["run" "-m" "shadow.cljs.devtools.cli/release" "website"]
"uberjar"]}
generate into a dedicated directory that the :uberjar
profile has as a :resource-path
@thheller Yup, that's what I came up with
Thanks for the hint! Maybe I'll switch to shadow-devtools
indeed 🙂
while running inside a webpage, is there a reliable way to capture F1, F2, F3, ..., or should I assume the browser / OS owns all those keys ?
Is it possible to override the (.invoke ...
method on functions, such that if any arguments to the function return (-realized?...
= false
then said invocation will be queued up for later? Similar to promises, but transparently enabled on the IFn interface?
not really, since IFn is an interface that expects a response. Making a function async changes the return type. So if you have a IFn<Object, Object> now you would have a IFn<Object, Promise<Object>>
Right, but then if you modify IFn to also handle Promise<Object>, further queuing up invocations?
I guess I don't know what you mean by "expects a response." Is it impossible to alter IFn's invocation behavior based on the arg type? I was thinking, if any of the args are like MyPromise...
I looked a bit into seeing if it was possible to integrate JS yield
and generators with CLJS -realized?
but I couldn't grok it all. It seems like CLJS sequence abstraction is already pretty close to an Iterable, so creating yieldable sequences might be possible.
On a similar note, for a system I'm working on, I might want a promise like interface. But rather than forcing the user into the whole JS promise system, I was think about simply implementing a (-then..
method on my object, which simply queues the function call on a queue inside the object, if the object is still pending.
ok but ClojureScript users already have core.async if/when they need it - which is probably at this point more idiomatic
why bother with anything over Promises at all - unless this is just for interop in your own project or something?
I thought about core.async. It'd provide a number of solutions to my architectural problems. But as of right now, the whole system has zero dependencies. And it creates a fairly small minified artifact, which is nice.
Not sure if I want all of my objects returning chans. Using chans internally, I wouldn't mind so much.
When all that is really needed, for this particular use case, potentially, is a then
, which is trivial to implement on an object with an invocation queue
another alternative is that you write your main interface using callbacks and then your users can layer whatever they want over it
but if a user never uses a namespace that uses core.async - there won’t be any stuff at all in the final artifact
So, you're saying, provide an additional core.async interface to the objects in another ns and if that functionality isn't used, it won't be added to the deps. That makes sense
No, that changes the equation for me. If I can provide the user more options without forcing those options, I'll provide them.
Google Closure Library has a Promises thing I thought - not sure how “standard” it is though
But I'll probably focus on a plain, generic interface for the first iteration. probably with vanilla callbacks and -then
as an optional deftype method or something.
another high level design question: I haven't done much with deftypes and protocols yet. I tend to just use maps and vectors to model my data. In this current project, I'm storing most of the objects created in a map. Those objects have a deftype facade, but their methods generally don't operate on the deftypes initialized values passed in. My plan was to prototype everything out in regular data structures and once the semantics were somewhat figured out, bake those semantics directly into the deftype - move the state out of the object maps and into the deftyped objects and work on them there. But these objects aren't really cpu bound - most of their methods are asynchronous. They need coordination by data structures outside of themselves anyway, so why bother storing the object's values in the objects themselves? Is there any downside to using a deftype as just a facade over a system?
@john I'd start with looking at using defrecord
if you are concerned about hashmap performance. They look like maps, and act like maps, but any fields you declare up-front are stored in object fields and have the fast lookup you would expect from objects
I'll check it out. Do you know what I mean by facade though? As if all the getters and setters on the object just call out to values stored in a global map, which the system operates on. Rather than trying to operate over a collection of objects using their methods.
The downstream user doesn't need to use or know about the global map that backs all the data structures their using. But the library author can more easily operate on the global map of values and properties, rather than over a collection of opaque objects with method calls
I'm just wondering if that's a frowned upon design pattern. Or if it's used often with asynchronous method call situations
does that code turn k into sth dereffable? it creates an object implementing IDeref, no?
It most probably wouldn't be as efficient as lookup in an object, but if many of the operations you have on that object are asynchronous, you don't really care about cpu bound efficiency for lookup. The deref is probably happening after some delayed callback of some sort anyway.
But, recognize that you are mutating global state. So in that aspect I tend to avoid patterns like this.
You can do this functionally via something like cursors though
zippers work somewhat in the same way, your "thing" contains both state and a path into the state.
so, in effect, their own access to the object would act as a cursor over that global state
which wouldn't be any easier, as the author, if I'm just working with lots of little pieces of mutable state
because aren't the objects tossed around within a deftype just as mutable as some external maps stored in a global map?
@mobileink what do you mean?
working with mutable isn't much different than working with an external db is it? fwiw i wrap access to google datastore with deftype and protocols so it behaves just like a map.
Well, arguably, the values within a deftype are more mutable than those stored in a vanilla map, in an atom, right?
your facade-value just wraps get-in already, in IDeref, no? why that instead of sth else?
mostly because deref provides a uniform interface across many objects that allows objects to implement any necessary atomic operations in the background, prior to the return. Like a safe getter contract. So it's idiomatic.
That's a bit handwavy in cljs, since all data access is also protected by the non-reentrancy of the js thread... but once we start talking about cljs values within a distributed, asynchronous context, that safe getter/setter contract that clojure provides becomes important again.
ah, syntax. i tend to avoid @ for no particular reason. well, because it mucks up the functional model, i guess.
yeah, having @
littered everywhere is a code smell
the deref thing doesn't really matter. The point is that many of my deftype methods don't operate over internal values, but rather external values, coordinated by traditional Clojure coordination mechanisms.
they're mucking with mutable data though
my druthers: implement IFn so user can write (k) instead of @k. it's all about the functions! 😉
deftypes are immutable by default
no, deftype is 100% immutable by default
eh....
let's not go there
you can, but that's not default behavior
and in CLJ it's completely dis-allowed without special flags
But if I want to make a custom data structure in cljs, that's the behavior I need to implement, correct?
(deftype Cons [head tail])
custom data-structure and it's 100% immutable
I don't think it does.
But there's nothing in deftype that prevents someone from going (deftype MutableCons [head tail] Somthing (-mutate [_ state] (bang on state...
well that's true, you can always make your "mutation" op return a new object, is that what you mean?
Sure, but don't do that...as it goes against most of the design goals of Clojure
@mobileink exactly, you can have state + a path. Modifying state returns a new state + path.
moving to a new place returns state + a new path
but if my object has a value, a list of watchers, a list of validators, a list of queued actions, a list of queued callbacks, etc, etc... My object is going to have to mutate something somewhere, right?
i've rassled with this for my gae datastore wrapper. what do database wrappers usually do? returning a new ds after a put seems kinda smelly.
Datomic does that 🙂
the concept of a watch assumes mutability I think
So, I can either mutate the list of watchers, validators, callbacks, values etc within the object, or I can manage all that state in a coordinated system, outside the object.
why not use an atom with your object inside it?
it already has implementation for watchers etc.
or don't use clojure's watch system, use your own immutable watch system
@noisesmith Yeah, I've messed with that option as well.
@tbaldridge I'd be interested in hearing your take on what an immutable watch system would consist of
@noisesmith essentially, extending atoms with my necessary methods.
it's a system where (add-watch obj k f)
returns a new obj
I just find the objects deftypes create somewhat opaque - more difficult for me to inspect and understand. Though I may just be to dim about deftypes atm
They're more difficult to inspect for obvious performance reasons. But while I'm building the custom data type, I'd like all that data on the outside of the object first, where I can think about it like regular clojure data
agreed, so that's what's interesting, you could implement all this without using deftype
it's all just data, with functions that modify the data, returning new data
I'm only using the deftype as a facade so it looks like a traditional clojure data structure to the user.
And I'm thinking, later optimization efforts, can focus on wrapping some of the functionality into the type object itself, when necessary.
But it doesn't sound like this is a Clojure datastructure, and so forcing it to match existing interfaces may cause more problems than it would solve
what you're describing here is a combination of Clojure reference types and data
watches go on reference types, not data
right - but the suggestion implied there (worth noting) is the separation of data from mutation - using a mutable container not a mutable data
Anyway, I should work on a few refactors so I can get this code out so y'all can critque it directly, rather than just talk about the design.
@noisesmith I believe I'm achieving a better separation by placing the data in traditional clojure data structures and leveraging traditional clojure update semantics. All data type data is stored within persistent data structures and accessed behind derefs and updated via clojure's persistent ds update semantics. Otherwise, I'd be banging on the value directly within the deftype.
so for constructing a reference type, at least so far, it feels like doing it this way is more clojurey
Can some body suggest me coding exercises to get to speed with Clojure and Clojure Script ??
http://4clojure.com - though the exercises are out of order
someone should create an emailmvc -- showcase your newest ui library / framework by writing an email client in it
@ingared: i recommend you pick one to start. get clojure down before you move on to cljs.
I remember it being discussed here previously but I don't remember if there was any resolution to the question. Is there a way to determine at runtime whether a project was compiled with :advanced
mode or :none
?
open the code, if you see only single variable name inside functions, and it's all smashed together and makes no sense at all, it's :advanced