יום חמישי, 7 ביולי 2016

Logging in Kotlin

The post was moved to: https://medium.com/@OhadShai/logging-in-kotlin-95a4e76388f2#.oiwog6cyw

TL;DR - for logging in kotlin use https://github.com/MicroUtils/kotlin-logging

In this blog post I am going to discuss logging frameworks for Kotlin language and JVM environment. Actually, logging seems like a solved problem in the JVM world. The de-facto standard is slf4j and there are plenty of examples in the internet like that:

private static final Logger logger = LoggerFactory.getLogger(ThisClass.class);
...
logger.info("Hi, {}", name);

That works perfectly in Kotlin with the relevant syntax adjustment

val logger = LoggerFactory.getLogger(ThisClass::class)
...
logger.info("Hi, {}", name)

So why not use it as is???


Yes, that is a valid option. However, Kotlin tries to improve readability of the code by making it more concise and fluent. I addition removing boilerplates (ie: copy-paste code) also makes the code cleaner and less error prone.

Is it a real problem or did I just made it up for that blog post?


There are evidences it is a real problem, or at least people are talking about it:

In addition, other JVM languages also tackled that problem.
In Scala we have the StrictLogging trait that exposes a logger member, thus helps avoiding defining the logger name.
In addition, lazy evaluation of the message in Scala assists in avoiding the notorious isDebugEnabled() call before each debug logging to avoid expensive string concatenation and values evaluation.

Is there something similar in Kotlin?


Yes there is. I have created kotlin-logging.
To use it add maven dependency:
<dependency>
  <groupId>io.github.microutils</groupId>
  <artifactId>kotlin-logging</artifactId>
  <version>1.3.2</version>
</dependency>
Then it is possible to get all the benefits like in Scala, but in kotlin using a companion object (unlike Scala where you can define properties in an interface).
The usage is to have the Companion object extends KLogging() and using the logger member in the class like that:
companion object: KLogging()
Then using the logger:
logger.info("hello world")
For sequences that are expected to be frequently used prefer lazy evaluated messages:
logger.debug{"lazy evaluated $message"}
In the above example String is inside a method and gets evaluated only if debug log level is enabled at runtime.

So, what are the benefits over the slf4j original implementation:

  • Getting the logger without the class name itself (excellent for copy paste)
  • Much cleaner messages with String templates and lazy evaluation
  • That's it - it is a small lib!

Are there any other alternatives? Yes there are quite a few:
  • Using plain slf4j
  • Many libraries, with not much traction at the moment
  • Implement it yourself

Hope you enjoy and spread the word of kotlin.logging.
Getting involved and support:



יום שלישי, 26 באפריל 2016

computeIfAbsent() is your new friend for Map in Java

I had a case today I had to populate a map with that signature:

Map<Long, Map<Integer, Integer>> myMap = Maps.newHashMap();

The way I populate it is like that:


resultSet -> {
  resultSet.beforeFirst();
  while (resultSet.next()) {
    Integer count = ...;
    Integer reason = ...;
    Long id = ...;
    //now I have to add the values to myMap
  }
})

prior to Java 8 this is one way to do it:

Map<Integer, Integer> internalMap = myMap.get(id);
if (internalMap == null) {
  internalMap = Maps.newHashMap();
  myMap.put(id, internalMap);
}
internalMap.put(reason, count);


It is a boilerplate oriented code, did it many times in the past. Now with Java 8 it is possible to do something simpler:
How about that? (Hint: Not working)

myMap.getOrDefault(id, Maps.newHashMap()).put(reason, count);

Any guess what's the mistake here?
getOrDefault just returns another value, do not put it on the map, so myMap remains empty.

Another try:

myMap.putIfAbsent(id, Maps.newHashMap()).put(reason, count);

And here I got NullPointerException. Apparently the Java api implementor decided to keep it similar to Map.put and return the previous value. Not a good decision if you ask me since this method should help you prevent working with nulls.

Finally the solution:

myMap.computeIfAbsent(id, key -> Maps.newHashMap()).put(reason, count);

Unlike putIfAbsent, here the api returns the existing value or the new value, allowing you to continue working on it more fluently.

יום רביעי, 30 במרץ 2016

חוק הרמזור הקצר\המתחלף


והפעם קצת מתמטיקה שימושית.

המון פעמים קורה לי שאני עומד ברמזור קצר וצריך לחכות כמה סבבים של ירוק עד שאוכל לעבור.
שמתי לב לעובדה המעניינת הבאה: אם כל המכוניות שלפניי בטור מתחילות לנסוע באור הירוק הנוכחי לפני שהרמזור מתחלף לאדום, ואז הרמזור מתחלף לאדום אני אוכל להגיד בוודאות שאני אעבור את הצומת בפעם הבאה שהרמזור יהפוך לירוק.

לא חשבתי על זה הרבה זמן או באופן רציף, רק כשהייתי נתקע ברמזור קצר או עמוס, אבל תמיד סיקרן אותי אם יש לזה הסבר מתימטי ואם זה באמת ״חוק טבע״.
היום נראה לי שמצאתי הסבר מניח את הדעת למה זה קורה, לפחות מבחינה תיאורטית.

כאשר המכוניות במצב עמידה ונניח שכל המכוניות הן פרטיות באורך עד 5 מטר והן שומרות ביניהן על מרחק מינימלי נניח מטר אחד.
במצב של נסיעה איטית המרחק בין המכוניות גדל ומוכפל כך שאם במצב עמידה המרחק בין החלק הקדמי של מכונית לחלק הקדמי של המכונית אחריה הוא 6 מטר, בנסיעה איטית המרחק ביניהן הוא לפחות 12 מטר.
זאת אומרת שאורך טור המכוניות שלפני הוכפל.
מכיוון שאורך הטור שלפני הוכפל והמרחק לרמזור נשאר קבוע זה אומר שחצי מהמכוניות שלפני עברו את הרמזור, כך שאם כל הנתונים יישארו זהים ברמזור הירקו הבא אוכל לעבור את הצומת. אחחח......

כמובן שבעולם האמיתי יש משאיות, אוטובוסים, אנשים שנרדמו או מתעסקים עם הווטסאפ. אבל למה לבלבל עם העובדות.

תארו לכם עולם שבו כאשר הרמזור היה מתחלף לירוק כל המכוניות היו מתחילות לנסוע מיידית בתיאום - מאיצות בדיוק באותו קצב ושומרות על המרחק שהיה בינהן במנוחה. בעולם כזה פי שתיים מכוניות היו מצליחות לעבור בכל רמזור ירוק... זה היה פותר הרבה עומסי תנועה! עכשיו רק צריך להמציא מכשיר שייאפשר את זה או להכניס את זה לאלגוריתם של הרכב של גוגל. אני זוכר במעורפל שפעם ראיתי תוכנית (נראה לי זה היה תצפית עם יעל דן) שבה תכננו שמכוניות ייסעו אוטונומית בטורים ארוכים אחרי משאיות. לא שראיתי את זה קורה אבל בטח אפשר להתבסס על אותה טכנולוגיה.

יום רביעי, 16 בדצמבר 2015

a talk with Scala REPL

THIS IS A TRUE STORY...
At the request of the survivors,
the names have been changed.
Out of respect for the dead,
the rest has been told exactly
as it occurred


me> 1 to
scala> error: ambiguous reference to overloaded definition,
both method to in class RichInt of type (end: Int, step: Int)scala.collection.immutable.Range.Inclusive
and  method to in class RichInt of type (end: Int)scala.collection.immutable.Range.Inclusive
match expected type ?
       1 to
         ^
me>ah... 1 to 10

...

me> (1 to 10) map _ * 2
scala> error: missing parameter type for expanded function ((x$1) => 1.to(10).map(x$1.$times(2)))
       (1 to 10) map _ * 2
                     ^
me> ah, ok, just a missing curly brackets: (1 to 10) map {_ * 2}

..

me> val a: (Int, Int) = 5,5
scala>:1: error: ';' expected but ',' found.
val a: (Int, Int) = 5,5
                     ^
me> ah, ok, just a missing brackets: val a: (Int, Int) = (5,5)

...

To be continued...

יום שלישי, 10 בנובמבר 2015

Java is not perfect


Java is one of the most popular languages out there for back-end programming. It has many advantages that made it so popular. I am not going to discuss that here.
But Java is old, and keeps compatibility between versions. Some things could have been implemented in a different way, in retrospective.
In this post I want to focus on some syntactic constructs that should be avoided or reconsidered.

  • null - I did not invented it of course, but although it is there it should be avoided. 
Even the inventor said that. What can we use instead? in many cases we are using null when we don't have a value or "answer" to give the client back. Such examples are: return from method, or default behavior in switch statements. 
In many cases it is better to just throw a RuntimeException or IllegalArgumentException to indicate such state. Another way to workaround that is to use Guava's Optional. When returning that from a method, it indicates very clearly that the user of that method should be aware an empty value is possible.
  • Checked exception - First a short reminder: Checked exceptions are exception that when thrown must be declared in the method signature and handled explicitly by the client. 
In Java all exceptions are checked except RuntimeException and Error (and its predecessors). In that case, it is really a matter of taste but here is what I think about using checked exceptions. 
In first glimpse checked exception sounds like a novel idea, similar to the optional above. Implementer can declare in the method signature about errors to allow the client handle them. But it has few major drawbacks that leave them unusable:
    • Checked exceptions are like implementation details that are thrown into the method signature, so for example if your method used files to retrieve a value it will throw IOException. then later the implementer decided to use database, he will throw a JdbcException so the user of the method has to modify the usage because of a change in internal details.
    • Many time - the best place to handle the exception is not directly at the usage of a method but in another, more general place when you can get a valid state to recover from that error. that cause all the methods on the way to get polluted with the exception signature as well. just another details that will make refactor harder.
    • Anyway, a user of a method has to handle runtime exceptions.
    • I saw many cases that it ended up with just throwing the general not-saying-anything Exception. This is like saying that an error might occurred. Ha!
    • Well, no other language used it after Java AFAIK. That is a sign, isn't it?!

  • Language feature such as generics and lambda - In this case I just suggest to be cautious. I have seen far too many cases that a new feature comes to Java, and developers (like myself) just start using it all over the code, make the code unreadable. So when using a new feature, like driving a car, start with a low gear.
  • Un-popular or un-maintained frameworks - Java SDK comes with a lot of goodies, But they do mistakes there also.
Java logging for example, was introduced when log4j was already popular. However, java logging gave a poor api compare to log4j or slf4j. The main advantage of it is you don't have to depend on a third-party library, but you pay for that in convinience. 
A different example is the apache-commons. It was a good library with many features, but it is so ancient and unmaintained that it even doesn't support Java 5 generics well. In most cases I prefer other alternatives such as Google's guava.
That's all for now. LMK what you think.






יום שני, 28 בספטמבר 2015

פחדים וחרדות של ילדים, תפקיד ההורים

פוסט אורח של ד”ר יונתן קושניר
כמה מכם ההורים מכירים את אחד או יותר מהמשפטים הבאים:
“הוא לא נותן לי לישון בלילה”, “אני חייב לשים מזרון בחדר שלה כדי שתישן”, “אני חייב לענות לו על שאלות כל היום אחרת הוא יפחד”, ” מאז שהיא נולדה אנחנו לא יוצאים, לא היינו בחופשה לבד – מרוב חשש היא לא נותנת לנו לצאת”, “היא מחייבת אותי לרחוץ ידיים לפני שאני משחק איתה אחרת היא דואגת שתהיה חולה”, “אנחנו כבר לא בקשר עם יוסי וזהר כי יעל מפחדת ולא מוכנה ללכת לבית שיש בו כלב”, “היא לא נותנת לנו אף זמן פרטי בלילה”, “אנחנו חייבים לענות בשבילו כששואלים אותו שאלה ואם לא יענה הוא ידאג ולא יפסיק לשאול”, ” הילדה שלנו לא מצביעה בכיתה אבל היא כל כך חכמה, היא בטח חושבת שתגיד שטות”, “במסעדה הוא מאוד מתבייש ולא מסוגל לדבר עם המלצר אני חייב להזמין בשבילו ואם הוא מזמין אז זה בקול מאוד חלש, “הילד לא מוכן ללכת לאף הצגה, הוא מפחד מהשחקנים, לכן אף ילד שלנו לא הולך להצגה”.
בנקודה זו עולות כל מיני שאלות לגבי מצבים אלה, למשל:
א.      מה הבעיה/בעיות במצבים אלו?
ב.      האם יש משהו לעשות?
ג.       מי נפגע מזה?
ד.      האם זה לא יעבור מעצמו?
ה.      למה זה ממשיך?
ו.        איפה הבעיה? הבעיה היא בילד? בנו ההורים?
בהמשך המאמר אנסה לענות על שאלות אלו.

יום שני, 17 באוגוסט 2015

What I miss in eclipse when using intellij's idea

After ten years or so working with eclipse I moved to intellij's idea as my primary IDE. The reason for that is that my new team is working with intellij (on Mac!). 
I'v decided to take the long way and use it "as god created it" -- not with eclipse keymap so it will be easy to collaborate with other guys and learn from their experience. In addition, I guess there is some kind of logic for the keymap of shortcuts. Still trying to figure that out.

Definitely the main difference is the keyboard shortcuts. To help me get thru that I created shorty, a small utility that on focus,click the shortcut from eclipse, and the intellij equivalent is displayed.

Another big difference is the (lack of) save button. I am so used to that in eclipse so ctrl+shift+s is like a second nature for me. But that was relatively easy to get used to because I am using webstorm for a while. 
Still, sometime it is annoying. For example when using 'gulp watch', you have to step out of intellij and return in order for the modified files to get noticed for changes. same for save actions and infintest.

I added a list for the rest of the things, please let me know if you find any mistake or I am not using it correctly, so I can learn from it:
  • ctrl + j (find as you type) - I think there is a plugin for that, but didn't try that.
  • duplicating lines and moving them around is much more convenient with eclipse's ctrl + alt + arrow up/down, then leaving the alt to continue the move. intellij has ctrl + d, and I dont like the fact that it is not duplicating full lines on selection.
  • problems view (compilation errors): I am used to see it on the fly so it feels like with intellij I don't see the big picture, rather bump into errors in the build. Speaking of that, intellij is not working so good with compilation errors when trying to run. I tried to configure that but the errors still disturb execution even if its not related to the executed code. I am trying to run unit tests of a class and intellij is shouting about something in completely different area of the code.
  • show the console on new output - why do they don't have that feature?
  • debug java code seems better in eclipse:
    • drop to frame is missing so much.
    • the smart step into is not as convenient as the ctrl+alt+mouse left click shortcut.
    • compiler hot swap is not in the level of eclipse.
  • svn support:
    • I cant make the history view sync with editor file.
    • synchronize view was very convenient.
    • on the other hand I like intellij annotate, change-sets, and shelve support.
  • organize imports - it's just better in eclipse.
Last but not least is the Look&Feel. Eclipse looks so much better in Mac, and on any other platform. Its amazing that a paid product is using swing ui these days. It doesn't looks good and have some weird things that do not feel native to the os.

But there are still a couple of things I like about intellij's idea, maybe the biggest one is the plugins and language support. It is much more mature. You can actually expect a plugin to work. One such an example is subversion support that is "out of the box" unlike subclipse... but there are more. big plus!

And final words about performance & quality. In that case I suffered with both ide's. with large projects they have bottlenecks and doesn't work smooth. I wish it wasn't like that.