This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-09-11
Channels
- # announcements (18)
- # beginners (57)
- # calva (20)
- # cider (4)
- # cljdoc (15)
- # cljs-dev (14)
- # clojure (124)
- # clojure-europe (5)
- # clojure-italy (5)
- # clojure-nl (10)
- # clojure-spec (4)
- # clojure-uk (44)
- # clojurescript (4)
- # clojutre (18)
- # clr (2)
- # cursive (25)
- # datomic (53)
- # emacs (18)
- # events (1)
- # figwheel-main (1)
- # fulcro (34)
- # joker (6)
- # kaocha (13)
- # nrepl (3)
- # nyc (24)
- # off-topic (1)
- # pathom (16)
- # protorepl (4)
- # re-frame (1)
- # reitit (27)
- # rewrite-clj (5)
- # shadow-cljs (38)
- # spacemacs (25)
- # sql (20)
- # vim (28)
- # xtdb (20)
Anyone good at math? It’s funny. I’ve got myself (again) into stupid argument about how Lisp is not less readable because of prefix notation and I’ve been thrown a “challenge” in my face: > simple formula > Combined trip distribution:
f(t) = A (t^B) exp(Ct) where t = t (i,j)
Then t(i,j)=A(i) f(i,j,t) / Sum(A(i) f(i,j,t))
And I’m not familiar with this at all. Can someone help me to write a function for this in Clojure?I’ve tried to google and it’s not helping. I have found bunch of articles about trip distribution methods. Uniform factor method, Average factor method, Fratar method, Furness method, Gravity model, Tanner model, Intervening opportunities model, Completing opportunities model.. holy cow…
@ag I am not familiar with that formula, although I see there is a Wikipedia page for it. Before someone can help you write code for it, I think you (or someone) needs to identify what the parts mean, e.g. f(i,j,t), is that effectively a 3-d matrix/array indexed by integers i,j,t? Or are some of those things real numbers, not integers? The Sum, what is it summing over? j an integer ranging from 1 to N? If so, is N an input? The A(t^B) in the first line, is that the same A as the A(i) in the second line, or a different thing?
@andy.fingerhut @U05509S91 I really appreciate willingness to help . The person first presented the formula (just as I showed) and I said: “well it’s like giving someone an arbitrary verse from a Walt Whitman’s poem and ask to present a Latin translation to demonstrate how it is more “readable” than for example its translation to Mandarin.“. The person then posted the following C like code:
loat t[100,100];
float A[100];
float D[100];
float trips[100,100];
for i = 0 to 99 {
sum =0.0;
for j=0 to 99 {
friction = (t[i,j]^B)*pow(t[i,j]*C);
sum+=A[j]*friction;
}
for j=0 to 99 {
friction = (t[i,j]^B)*pow(t[i,j]*C);
trips[i,j]=D[i]*A[j]*friction/sum;
}
which to be honest confused me even more.I guess it is my own fault. I should’ve been more courteous and respectful. In my defense I can only say that I’m really tired of programmers (experienced and whatnot) spreading nonsense like “Lisp is not readable” etc. Here’s the full conversation: https://www.quora.com/What-is-the-most-brutal-truth-about-the-Clojure-programming-language/answer/Francis-King-5 if you solve this, feel free to post the solution, but please make sure that it is clean and reasonable enough to convince non-believer that Lisp code is not less readable.
I've seen pow(x,y) as a C library function that computes and returns x to the power y, but I do not know what a single-argument version does.
This whole thing kinda made me want to read more about trip distribution, and trip generation and in general to learn more about the problem. Not for the sake of winning the argument. Just for fun
yeah, pow
takes the base and a number:
https://www.programiz.com/c-programming/library-function/math.h/pow
but what’s above seems to be “C like pseudo code” I assume in that case perhaps it is pow2
FWIW - my interpretation
;; DATA
(defn t "trip cost" [from to] (if (= from to) 0 1))
(def size 100)
(def locations (range size))
(def A "trips attracted to `to`" (memoize (fn [to] (rand-int 100))))
(def D "trips from `from`" (memoize (fn [from] (rand-int 100))))
(def B "not sure what these are, assuming some constants" 1)
(def C "as above" 1)
;; CALCULATION
(defn a-friction
[from to]
(* (Math/pow (t from to) B)
(Math/pow (* (t from to) C) 2)
(A to)))
(defn trip
[from to]
(let [sum (reduce + 0 (map (partial a-friction from) locations))]
(-> (D from)
(* (a-friction from to))
(/ sum))))
;; OUTPUT
(def trips (into {}
(for [i locations
j locations]
[{:from i :to j} (trip i j)])))
Did the people giving the challenge give it in the form that you show there? Or did they just say "look up the Combined trip distribution formula and implement it"?
@andy.fingerhut is more positive than I would be presented with this. 🙂 it feels like as presented, it already hasn't been reduced into a form that is useful for computation, and it doesn't matter if it's in prefix or infix notation.
I mean, sometimes I like a challenge, but it helps if I know what is being asked first 🙂
A question related to reify
: As I understand reify
allows to create an anonymous record by extending an existing record.
Is there a way to to the same but non anonymously i.e. to create a record that extends an existing record?
>As I understand reify
allows to create an anonymous record by extending an existing record.
this is not correct
and there is no mechanism in clojure to extend a class to another class, so no to your question (well proxy
I guess, but it's not what you're asking for)
sorry I meant, reify allows to create an anonymous type
> While deftype and defrecord define named types, reify defines both an anonymous type and creates an instance of that type. from https://webcache.googleusercontent.com/search?q=cache:y8by8CHJKvgJ:https://clojure.org/reference/datatypes+&cd=3&hl=en&ct=clnk&gl=il
Is there a way to use deftype and provide a “base” type and extend it (like with reify)?
which is also discussed in that same page you linked above
@viebel Maybe you should describe the bigger problem you’re trying to solve by extending a base type?
I remember that once I used something (maybe in clojurescript) that allows to extend a record
yes. Exactly
Is there a good reason for that diff between clj and cljs?
specify
doesnt extend a record either, it provides additional implementations to a particular instance of a type IIRC, and in clojure we can do something similar to specify
now with extend-via-meta in protocols
In cljs, there is specify! and specify, the latter doesn’t mutate the base instance (it clones it).
important clarification. Thanks
There is a slight difference between extend-via-meta
and specify
when we override an existing method:
with extend-via-meta
, the original method takes precedence. See here:
http://app.klipse.tech/?eval_only=1&cljs_in=(defprotocol%20Component%0A%20%20%3Aextend-via-metadata%20true%0A%20%20(stop%20%5B_%5D)%0A%20%20(start%20%5B_%5D))%0A%0A(defrecord%20M%20%5B%5D%0A%20%20Component%0A%20%20(stop%20%5B_%5D%20%22stop%20the%20record%22))%20%0A%0A(def%20meta-component%20%0A%20%20(with-meta%20(M.)%20%0A%20%20%20%20%7B%60start%20(constantly%20%22start%20the%20meta%22)%0A%20%20%20%20%20%60stop%20(constantly%20%22stop%20the%20meta%22)%7D))%0A%0A%0A(dbg%20(start%20meta-component))%0A(dbg%20(stop%20meta-component))%0A%0A%0A(def%20spec-component%0A%20%20(specify%20(M.)%0A%20%20%20%20%20%20%20%20%20%20%20Component%0A%20%20%20%20%20%20%20%20%20%20%20(stop%20%5B_%5D%20%22stop%20the%20spec%22)%0A%20%20%20%20%20%20%20%20%20%20%20(start%20%5B_%5D%20%22start%20the%20spec%22)))%0A%0A(dbg%20(start%20spec-component))%0A(dbg%20(stop%20spec-component))%0A%0A
but it's not part of clojure's design, and it's not particularly easy to implement on the JVM
to leverage the host capabilities, I believe
although this is maybe a better question for #clojurescript or #cljs-dev
Hola, I'm struggling a bit to get zippers to do my bidding:
https://gist.github.com/devn/61b3690f4d6e059303874d547c21f803
What did I mess up here? I've tried a bunch of variations and can't seem to figure out why the (set? l)
branch in the loop
doesn't get hit.
l is a loc, which is the data structure a zipper uses to keep track of its traversal, so it is never a set
your child|branch? function only considers seqs to be branches if they have children
I seem to recall suggesting a recursive for to you for this kind of thing previously
((fn f [path parent-id item]
(let [id (java.util.UUID/randomUUID)]
(cons (assoc (dissoc item :children)
:id id
:path path
:parent parent-id)
(for [child (:children item)
i (f (conj path (:name item))
id
child)]
i))))
[]
nil
{:name "root",
:description "root",
:children
[{:name "Foo",
:description "foo",
:children
[{:name "Bar",
:description "bar",}
{:name "Baz",
:description "Baz",
:children [{:name "Qux",
:description "qux"}]}]}]})
you may also want to checkout a lens library (I haven't used any so I cannot recommend any), at least in theory with those the "path" you build will be directly usable to update sub values
@hiredman appreciate that, and yes, I seem to remember you recommending that approach previously as well 😄
@hiredman ok, just had a chance to run it, the only missing bit there is that some :children
can be sets, which means the path would need to be constructed as ("root" {:name "foo" :description "foo" :children ...} ...)
in some cases
and for vectors, it needs to be the index of the item in the vector for get-in/update-in reasons
(for anyone following along at home, I updated my gist and wound up getting my zipper-based solution working https://gist.github.com/devn/61b3690f4d6e059303874d547c21f803)
One question I have in light of this is: Is there any particular design reason why update-in
doesn't handle sets?
For instance, the ability to do:
(update-in {:a {:b #{{:c :d}}}} [:a :b {:c :d}] assoc :e :f)
update-in
is for "associative structures"
and inherently leans on assoc
Hey guys, i'm making a guide to people who already do web development and want to have a head start in clojure
Here is the draft: https://community.inkdrop.app/note/ede8cdf47aafb065ac7c0964d4fca7d5/note:krng7hycU
Ring isn't an HTTP server. What you're bringing there is Jetty as the HTTP server.
Thanks, i'll fix this 😅
Given what you cover in that, I'd say input validation is probably the next logical step but probably ought to be "part 2" rather than making "part 1" any longer...?
That's cool, i'll break this in two parts (or even more if i feel adding more content) thanks for the feedback
@U04V70XH6 could i describe Ring as an API for HTTP Server ? the description used on their github is "Clojure HTTP server abstraction "
Yeah, API is a good way to describe it. The readme confirms that "By abstracting the details of HTTP into a simple, unified API, Ring allows web applications to be constructed of modular components that can be shared among a variety of applications, web servers, and web frameworks." and you can use Ring with http-kit or Jetty or Immutant or...
We have apps that select Jetty or http-kit dynamically at startup -- and only the "start web server" logic cares: the entire rest of the app is unchanged by that decision (and I've tested that also works with Immutant, which can be used as a library the same way).
Awesome, good to know, i'll mess around with http-kit later, won't put those info in this guide because i want to avoid complexity and more stuff that a newcomer would have to deal with, but surely this is nice to know, thanks again!
Redacted into this: "Remember that the Ring library talks with a web server under the hood, in our case, the web server that we will use is [Jetty](https://www.eclipse.org/jetty/), because ring already has an adapter for jetty written and ready to use for us."
I want to know if i should mention data input validation or this is out of the subject of my guide
i would talk about input validation using Spec
a quick glance on the draft is enough to know what i am presenting on this guide
Hello all, what happen with lein repl with clojure 1.10.1? The repl is starting in 1 second with cider, is that correct?
@fabrao What do you think has changed from previous versions of Clojure with lein repl
and/or CIDER?
Can you be a bit more specific? And also which version of Clojure are you comparing this with? I can't think of anything that changed in Clojure. I believe CIDER's default middleware changed to be lazily loaded which may well improve startup time.
my guess is you have a user.clj file and you upgraded to a java version where it has the performance regression for code execute when running static inits
oh, sorry, I think 1.10.1 is just the work around for that performance issue, so likely not it
1.10.1 is starting faster for you -- so that's the workaround described in https://github.com/clojure/clojure/blob/master/changes.md
If it was 10-20 seconds before, on 1.10.0, then you probably hit that user.clj
loading issue yes.
Did you also update CIDER? (see my comment above about it switching to lazy loading middleware).
well, this is a HUGE performance increase, I´m very happy with result, I even thougth to buy Mac to speed up the stuffs
It's always better to update things one at a time and then you'll know exactly what caused any observable change.
Updating multiple parts of your tool chain at once is ... an exercise for the, er, brave 🙂
yes, I did not update some stuffs fearing breaking some, and I asked you just about this because it was breaking after update some libs
Why do you think there isn't?
Wait, ssecond
or second
?
@skuttleman What would ssecond
do? (second (second x))
?
Yes. Just like ffirst
or nnext
, only seconder.
REALLY!? Two second
s only no ssecond
!? https://clojuredocs.org/clojure.core/fnext
I knew about the various first
/`next` combo functions but never actually noticed these two docstrings were identical:
user=> (doc second)
-------------------------
clojure.core/second
([x])
Same as (first (next x))
nil
user=> (doc fnext)
-------------------------
clojure.core/fnext
([x])
Same as (first (next x))
nil
user=>
So I guess ssecond
would be fnfnext
🙂 🙂 and Clojure <> Lisp so we don't go down the caddadr
path...
I suspect the various first
/`next` combos all got in before the API was really being thought about? It would be interesting to hear from Stu or Rich on that...
ffirst
and nnext
are both actually used in clojure.core, so likely Rich considered them general purpose enough to include them in the API.
second is used in clojure.core, but not fnext