Fork me on GitHub
#clojure
<
2020-10-28
>
Matias Francisco Hernandez Arellano14:10:14

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?

samoleary15:10:49

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

💪 3
herald16:10:24

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?

herald20:10:09

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.

herald20:10:41

{ 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);
}

herald20:10:58

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;
}

euccastro16:10:39

the only way to extend a java interface in clojure is through gen-interface, right? in particular, definterface doesn't seem to allow that

Alex Miller (Clojure team)17:10:11

I think that's correct

thanks2 3
dpsutton16:10:47

what do you mean by extend?

euccastro16:10:51

declare a new interface that extends an existing one

euccastro16:10:09

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

euccastro16:10:14

related question: how would I declare a varargs method in gen-interface?

Alex Miller (Clojure team)17:10:26

you can use a Java array type string, like "[Ljava.lang.String;"

Alex Miller (Clojure team)17:10:46

where you'll replace java.lang.String with your type

Alex Miller (Clojure team)17:10:55

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]])

robertfw17:10:42

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?

robertfw17:10:42

that's the one! thanks!

👍 3
robertfw17:10:08

A colleague is having regex problems of the "now you have two problems" variety, and I wanted to dangle this in front of them

markbastian19:10:44

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?

p-himik20:10:33

How many mms do you have in that ns? What's the stacktrace of the NPE?

andy.fingerhut20:10:51

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?

markbastian20:10:20

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: 

markbastian20:10:07

@U0CMVHBL2 - 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.

p-himik20:10:35

And what's at api.clj:63?

markbastian20:10:44

(froob {} {})

markbastian20:10:53

^the mm that blows up.

p-himik20:10:38

Can you create and share a minimal reproducible example?

markbastian20:10:38

(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.

markbastian20:10:31

And as I said, this is just a copy+paste+rename of an existing mm that works fine.

p-himik20:10:33

Hold on. (defmulti froom) is not valid.

p-himik20:10:44

There has to be a dispatch-fn.

markbastian20:10:08

didn't copy that line

dpsutton20:10:08

simple repro:

p-himik20:10:11

So not really a copy-paste then. :)

dpsutton20:10:12

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=>

markbastian20:10:05

This is one of those dumb user error things. Thanks guys!

markbastian20:10:18

The one above it (defmulti put-file afs-api-dispatch-fn). <- yep

markbastian20:10:10

I need to wear the cone of shame on this one.

dpsutton20:10:16

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

markbastian20:10:32

Yeah, I was so convinced I was following the pattern of my bank of defmultis and totally missed the missing dispatch fn.

dpsutton20:10:05

https://clojure.atlassian.net/browse/CLJ-2584 alex promoted it to jira. so good on you for asking the question.

👍 3
Lone Ranger19:10:06

I wear that cone all the time 🌀 @U0JUR9FPH

Ed22:10:57

Do you have plans to compile this for graalvm?

borkdude22:10:06

Thanks. Probably at some point. Not sure what the command line API should look like

Ed22:10:37

No ... Me either ... Look forward to finding out ;)

borkdude22:10:42

@U0P0TMEFJ Initially I was inspired by grape which has a less sophisticated pattern matching language and I came up with this:

"($cat reify ($+ ($symbol ($* $list))"

borkdude22:10:38

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

borkdude21:10:26

@U0P0TMEFJ 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

Ed17:11:44

👍 ... it looks great .... many thanks. I think it's difficult to define a simpler dsl without losing too much functionality ... grasp looks really useful 🙂

borkdude17:11:35

@U0P0TMEFJ speaking of which, I just added some convenience macros: https://github.com/borkdude/grasp#convenience-macros