I see similar evidence of structural sharing when I switch it to vector
(ins)user=> (def big-load (into [] (range 1000)))
#'user/big-load
(cmd)user=> (count (to-bytes big-load))
14934
(ins)user=> (count (to-bytes (into [] (repeat 100 big-load))))
15555
@seancorfield Neat! Iβll have to check out βRevealβ since Iβm back on the Clojure scene.
@noisesmith thanks for that breakdown
from glancing at the code, that is what I'd expect - it's just relying on normal Java serialization of object graphs, without any specialized read/write mods
I have this macro
(let [x 1 y 3]
(m x y))
that will evaluate to {:x 1 :y 3}
and also this one
(let [x 1 y 2]
(m+ x y | :z (+ x y)))
that will evaluate to {:x 1 :y 2 :z 3}
that's pretty cool π
Hey Folks.. I have a talk about Clojure 101 for Javascript devs.. I have some sintax comparison code samples and now i'm struggling to come out with some good idea to show some code .. real thing. I'm thinking in some httpserver with http-kit vs expressJS... sounds like a good example for clojure begginers?
Not a direct answer to your question about comparing code samples but I guess it's syntax related at least! Building up to a lisp-y syntax from a Javascript perspective, there's a clojure snippet at the end https://clojurians.slack.com/archives/C8NUSGWG6/p1603700061197400
the only way to extend a java interface in clojure is through gen-interface, right? in particular, definterface doesn't seem to allow that
what do you mean by extend?
declare a new interface that extends
an existing one
for background, I'm trying to create a custom redis command spec using a java library, as explained here: https://lettuce.io/core/release/reference/index.html#redis-command-interfaces
related question: how would I declare a varargs method in gen-interface?
When I once did a similar talk, I showed how Clojure's core library gave much more succinct and readable code than JS. Would that be of interest?
Hi all - I recently came across a Clojure library for representing regexes as data structures, and now I can't remember what it was called nor have had any luck finding it using google. Any ideas what it might have been?
FYI #find-my-lib
I think that's correct
i bet its https://github.com/lambdaisland/regal
that's the one! thanks!
A colleague is having regex problems of the "now you have two problems" variety, and I wanted to dangle this in front of them
you can use a Java array type string, like "[Ljava.lang.String;"
where you'll replace java.lang.String with your type
so something like this I think would make a String foo(String...)
for example:
(gen-interface
:name my.Foo
:methods [[foo ["[Ljava.lang.String;"] java.lang.String]])
That sounds really good
Is there a limit to the number of multimethods available in a namespace? I am assuming no. I have this really weird issue in which I have several mms in a ns. Everything is working fine and then I just added a new one and when I invoke it it throws an NPE. As a test, I literally duplicated one that works and renamed it. When I invoke it I get a NPE. Does this sound at all familiar to any existing issues?
I wear that cone all the time π @markbastian
How many mms do you have in that ns? What's the stacktrace of the NPE?
And maybe this is not relevant, but are you starting a new JVM from scratch after modifying the Clojure code, or trying to add the new multimethod to a running JVM with other Clojure code previously loaded?
9 previous. This is number 10.
Execution error (NullPointerException) at my.api/eval37134 (api.clj:63).
null
nrepl.middleware.interruptible-eval/evaluate/fn interruptible_eval.clj: 82
...
clojure.core/with-bindings* core.clj: 1973 (repeats 2 times)
clojure.core/apply core.clj: 665
...
nrepl.middleware.interruptible-eval/evaluate/fn/fn interruptible_eval.clj: 82
clojure.core/eval core.clj: 3214
...
my.api/eval37134 api.clj: 63
...
java.lang.NullPointerException:
@andy.fingerhut - tried both. It was in a longer running session, but i restarted to ensure there wasn't any old state hanging around, like an older definition or something.
And what's at api.clj:63
?
(froob {} {})
^the mm that blows up.
Can you create and share a minimal reproducible example?
(defmulti froob)
^the definition
(defmethod froob :default [this & _] (log-no-dispatch "froob" this))
^default implementation
(defn log-no-dispatch [fn-name dispatch-key]
(timbre/errorf
"No dispatch function for multimethod '%s' with dispatch key:\n%s."
fn-name
(with-out-str (pp/pprint dispatch-key))))
That's the whole thing.And as I said, this is just a copy+paste+rename of an existing mm that works fine.
Hold on. (defmulti froom)
is not valid.
There has to be a dispatch-fn
.
dumb me
of course
didn't copy that line
simple repro:
So not really a copy-paste then. :)
user=> (defmulti thing)
#'user/thing
user=> (defmethod thing :default [x] :hi)
#object[clojure.lang.MultiFn 0x7b60c3e "clojure.lang.MultiFn@7b60c3e"]
user=> (thing :hello)
Execution error (NullPointerException) at user/eval144 (REPL:1).
null
user=>
This is one of those dumb user error things. Thanks guys!
The one above it (defmulti put-file afs-api-dispatch-fn). <- yep
https://ask.clojure.org/index.php/9737/signal-an-error-on-mulimethod-without-a-dispatch-function
I need to wear the cone of shame on this one.
Alright, I'll dump the code examples I used. My talk was more about teaching FP, so I used Clojure functions in C-style syntax, but you can easily translate them back.
{ teamA: { ..., commits: [ { ..., date: "2017-12-17T03:24:00" }, ... ] },
teamB: { ..., commits: [ { ..., date: "2018-12-17T03:24:00" }, ... ] } }
=> [ { ..., date: "2018-12-17T03:24:00" },
{ ..., date: "2017-12-17T03:24:00" } ]
// Functional example
function teamToCommits(team) {
return threadLast(team,
vals(),
mapcat(:commits),
sortBy(:date,
comp(-, compare)),
take(25)
);
}
// Procedural example
function teamToCommits(team) {
var commits = [];
for (var key in team) {
var repoCommits = team[key].commits;
for (var i = 0; i < repoCommits.length; i++) {
commits.push(repoCommits[i]);
}
}
commits.sort(function(a, b) {
return b.date - a.date;
});
return commits.slice(0, 25);
}
i put in that http://ask.clojure.org question that there's some feedback already so wondering if this might also get a consideration. and honestly it's an easy to overlook problem either way
Conway's Look-and-say sequence
1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, ...
// Functional example
function lookAndSay(seq) {
return mapcat(
juxt(count, first),
partitionBy(identity, seq)
);
}
// We have extra space; let's
// turn it into a lazy sequence!
var lookAndSaySeq =
iterate(lookAndSay, [1]);
// The 100th member
lookAndSaySeq[99];
// Procedural example
function lookAndSay(seq) {
var result = [];
var lastChar = seq[0];
var times = 0;
for (var i = 0; i < seq.length+1; i++) {
var nextChar = seq[i];
if (nextChar === lastChar) {
times++;
} else {
result.push(times, lastChar);
lastChar = nextChar;
times = 1;
}
}
return result;
}
Yeah, I was so convinced I was following the pattern of my bank of defmultis and totally missed the missing dispatch fn.
https://clojure.atlassian.net/browse/CLJ-2584 alex promoted it to jira. so good on you for asking the question.
thank you!
Oh @borkdude ... https://github.com/borkdude/grasp ... You're a genius ;)
@l0st3d There is a binary available now: There's also a binary available now:
https://github.com/borkdude/grasp#binary
I experimented with a simpler DSL, but it didn't ago anywhere. I decided to expose spec as it is on the command line as well. For longer specs you can use the -f
option
π ... it looks great .... many thanks. I think it's difficult to define a simpler dsl without losing too much functionality ... grasp looks really useful π
@l0st3d speaking of which, I just added some convenience macros: https://github.com/borkdude/grasp#convenience-macros
π
Do you have plans to compile this for graalvm?
Thanks. Probably at some point. Not sure what the command line API should look like
No ... Me either ... Look forward to finding out ;)
@l0st3d Initially I was inspired by grape which has a less sophisticated pattern matching language and I came up with this:
"($cat reify ($+ ($symbol ($* $list))"
but not sure if it's worth doing this. one could also post their spec in a file which can then be fed as an argument