Posts on Twitter:

JAVA SOFTWARE DEVELOPER ENGINEER - VA Boot Apply here










Use the code "ctwlambdadays19" to get a 40% discount from our partner . Also check out your account to join the raffle and win a free copy of "Get Programming with " by .













Stackoverflow trends of JVM languages. is first with a strong growth during the last 2 years.



Retweet Retweeted Like Liked












πŸ’» 2019 is the year you can become proficient in , , and ! πŸ“’ Attention attention! πŸ“’ brings you the best Java talks by experts and amazing workshops. Purchase your ticket now!
















2 hours on the train from Salzburg to Vienna were very productive. So now I can do an admirable trick: run server with ALPN to accept HTTP/2 and HTTP/1.1 reusing the handler. Next stop = expose a conn stream as a Manifold stream to get new protocol features



Retweet Retweeted Like Liked





Posts on Tumblr:

wish people would stop making serious LISP clones

Valuable Things in Clojure
  • dpsutton: immutable datastructures, a repl, and an alex. all features i value in Clojure
  • alexmiller: tell your friends :)
  • christian767: I do that too :slightly_smiling_face:
youtube

Every Clojure Talk Ever - Alex Engelberg and Derek Slager

Side-effects may include side-effects.

Clojure

   (.setFeedSubmissionIdList request (.setId (IdList.) ids))
   ;; これは下記のようにも書ける
   ;;(-> request
   ;;    (.setFeedSubmissionIdList (.setId (IdList.) ids)))
   ;;
   ;;(-> request
   ;;    (.setFeedSubmissionIdList (-> (IdList.)
   ;;                                  (.setId ids))))

Syndicode Digest #65 – Modest genius

When you’re modest, nobody will know how much you do. But when people claiming too much, they’re not taken seriously as talented ones. Because talent comes with modesty and thoughts that your achievement will be evaluated sooner or later. Better sooner, of course. However, sometimes …

Why I Love Macros

Macros are one of those weird things that programmers sometimes hear about, but unless they’re using a language that has them, they might think macros are weird, archaic, and/or useless. If their only prior exposure to macros have been through C/C++, I can kinda see where they’re coming from.

Like most other features from Lisp, metaprogramming (aka macros) is slowly starting to creep into modern day programming languages. Scala has it, Clojure has it (being a Lisp dialect and all that), Haskell has it (through Template Haskell), JavaScript has it (through Sweet.js), and of course Rust has it.

Coming from a background of C/C++, macros are nothing but a simple text-replacement system, where the preprocessor runs through your code and replaces the text almost verbatim, a good example of a C macro that I’ve used a fair bit is this one:

#define foever for(;;)

so that I can write

forever {
  /* do repeat this forever */
}

All the macro really does, is have the preprocessor go in and replace every occurrence of the word forever, and replacing it with for(;;) (which is the same as while(true) for those uninitiated).

That’s all great and all, but C/C++ macros are just text replacement macros, which means they don’t have the power of “true” macros. If we take good ol’ Lisp for example: since everything in Lisp is a list, that means the data within a macro definition is itself a list, which means we can do list manipulation on the program code itself! List concatenation, iteration, mapping, reducing, all that good stuff becomes possible when macros are data rather than simple preprocessor text!

Now, Lisp syntax is a bit too obtuse to give decent examples in without confusing people too much, so let’s use Rust instead. Fair warning: I haven’t used Rust enough to know if it has quite the same expressive power as Lisp macros, but it’s certainly up there, judging by the lazy_static! macro.

A common example of Rust macros is the vec! macro, since it’s very easy to implement and very easy to explain, so here we go.

The vec! macro is defined as follows:

macro_rules! vec {
  ($($x:expr),*) => ({
    let mut vec = Vec::new();
    $(vec.push($x);)*
    vec
  })
}

I’ll explain what each line does in a moment, but let’s first see it in action: if I write

let v = vec![1, 2, 3, 4];

the macro will actually expand that expression to this:

let v = {
  let mut vec = Vec::new();
  vec.push(1);
  vec.push(2);
  vec.push(3);
  vec.push(4);
  vec
};

That is to say, it creates a new scope, then an empty vector, pushes each value into it one by one, and then returns the vector out of the scope and into v.

Let’s break down how this works then: on the first line we have macro_rules! vec {, which just means “define a new macro called vec”.

Then we have the expression line that looks like this: ($($x:expr),* => ({, which just tells us that we have 0 or more metavariables called x that are separated by a comma. In this case x has to be an expression, which lets us write things like 2 + 3, 4, 2.pow(3) and so on.

On the next line let mut vec = Vec::new();, we define a new vector called vec, and then $(vec.push($x);)* just says “for every x, create a line vec.push($x);, where you replace $x with the corresponding expression.

Then lastly we have vec which simply tells us to return the vector out of the block.

It’s super simple, and the syntax is actually a bit similar to regular expressions: * for "0 or more”, and + for “1 or more”. I believe Rust also has ? for “0 or 1”.

So why is this useful? Because it lets you extend the syntax of the language to suit your needs! If you have any kind of long chain of something that you want to reduce down to just a few expressions, you can probably do it with a macro.

Rust’s error handling syntax, the ? is just a macro behind the scenes, and it lets you write

  let foo = f()?;
  let bar = g(foo)?;
  let baz = h(bar)?;

instead of

  let foo = match f() {
    Ok(x) => x,
    Err(e) => return Err(e)
  };

  let bar = match g(foo) {
    Ok(x) => x,
    Err(e) => return Err(e)
  };

  let baz = match h(bar) {
    Ok(x) => x,
    Err(e) => return Err(e)
  };

The possibilities are virtually endless, and the joys are great! If your favourite language of choice has a macro system, I suggest giving it a go, because it’s a great way of reducing otherwise painful boilerplate.

if-some

;; 条件式が nil ではない場合(false も含む)は then を評価する


boot.user> (if-some [foo false]
            (println “then”)
            (println “else”))
then
nil
boot.user> (if-some [foo nil]
            (println “then”)
            (println “else”))
else
nil
boot.user> (if-some [foo true]
            (println “then”)
            (println “else”))
then
nil
boot.user> (if-some [foo ()]
            (println “then”)
            (println “else”))
then
nil
boot.user> (if-some [foo 0]
            (println “then”)
            (println “else”))
then
nil
boot.user> (if-some [foo “”]
            (println “then”)
            (println “else”))
then
nil
boot.user> (if-some [foo true bar false]
            (println “then”)
            (println “else”))
java.lang.IllegalArgumentException: if-some requires exactly 2 forms in binding vector in boot.user:8

Primes again and ‘Apropos Clojure’

I watched & listened to a very cool new Clojure podcast called ‘Apropos Clojure’ (episode #6). I could not watch the last 15 minutes because was very busy but I continued to listen to it. Of course I was later curious what the final solution was but obviously first had to arrive at it myself with help of what I heard while I was busy.

So my solution is here:

(defn sieve1 [acc [fst & rst]]
  (lazy-seq
    (if (some #(divisible? % fst) acc)
      (sieve acc rst)
      (cons fst (sieve (conj acc fst) rst)))))

The final solution shown during the show is roughly this:

(defn sieve2 [acc [fst & rst]]
  (if (some #(divisible? % fst) acc)
    (recur acc rst)
    (lazy-seq
      (cons fst (sieve (conj acc fst) rst)))))

I skipped unimportant differences.

What was surprising to me is that one can use lazy-seq in one of the paths of the function and not all of them. I was just so used seeing it like in my solution. But really why not? It makes sense. Obviously, both solutions gave the same answer and performance-wise seem to be the same on my machine. I was hoping that sieve2 will be faster because it makes fewer calls to lazy-seq but wasn’t in my quick testing with time. Still, good to know!

Anyway, I highly recommend this new 'Apropos Clojure’ show!