Learning Kotlin: Hello World
- The code being referenced.
- This is the 1st post in a multipart series.
If you want to read more, see our series index
So let’s start with line one: package i_introduction._0_Hello_World
In Kotlin package is just the same as a package in Java or Namespaces in .NET. There is no link between package name and the filesystem.
Next up is imports:
import util.TODO
import util.doc0
Imports are the same as import in Java and Using in C#. Kotlin does import a number of packages by default:
- kotlin.*
- kotlin.annotation.*
- kotlin.collections.*
- kotlin.comparisons.* (since 1.1)
- kotlin.io.*
- kotlin.ranges.*
- kotlin.sequences.*
- kotlin.text.*
Next up is our first function defination fun todoTask0(): Nothing = ...
We use the fun keyword to state it is a function, followed by the function name todoTask0 and the parameters… in this case, that is empty.
The function returns Nothing though that isn’t specifically required as the compiler can infer the return type.
This is a single statement function so it ends with an equal sign.
The next function is a little different
fun task0(): String {
return todoTask0()
}
The second function returns a String and is not a single statement function.
So how do we solve this Koan?
fun task0(): String {
return "OK"
}
Learning Kotlin: Introduction
I have recently decided to start to learn Kotlin, and have started with the Koans.
Koans are simple unit tests which help ease you into learning a new language.
The first step was setting this up, in Windows and VSCode… cause for some reason I hate myself that much.
Requirements
- Install Java SDK
- Install the Java Extension Pack for VSCode
- Install the Kotlin Language Extension for VSCode
Using
So I am using VSCode as the editor and then the command line to run the unit tests.
Parts
Since this will be ongoing, I am going to break it into a number of parts, listed below (this list will be updated over time):
- Hello World
- Java To Kotlin Converter
- Named Arguments
- Default Arguments
- Lambdas
- String Templates
- Data Classes
- Nullable Types
- Smart Casting
- Extension Functions and Extensions On Collections
- Object Expressions and SAM Conversions
- Kotlin’s Elvis Operator
- Return when
- The awesome that is the backtick
- Collections
- It is a thing
- Operators
- Operators don’t need to mean one thing
- Destructuring
- For Loop
- Invoke
- Looking at the In Operator & Contains
- The .. operator
- Todo
- By
- The lazy delegate
- The Observable Delegate (with a slight detour on reference functions)
- The map delegate
- The vetoable delegate
- The notnull delegate and lateinit
Quick tip: Column display
When you work with delimited data (CSV, TSV etc…) it can be a pain to just see the data in a nice way, for example, this data:
cat people-example.csv.txt First Name,Last Name,Country,age “Bob”,“Smith”,“United States”,24 “Alice”,“Williams”,“Canada”,23 “Malcolm”,“Jone”,“England”,22 “Felix”,“Brown”,“USA”,23 “Alex”,“Cooper”,“Poland”,23 “Tod”,“Campbell”,“United States”,22 “Derek”,“Ward”,“Switzerland”,25
With Unix like OSs, you can use the column command to format the layout; for example:
column -t -s’,’ people-example.csv.txt First Name Last Name Country age “Bob” “Smith” “United States” 24 “Alice” “Williams” “Canada” 23 “Malcolm” “Jone” “England” 22 “Felix” “Brown” “USA” 23 “Alex” “Cooper” “Poland” 23 “Tod” “Campbell” “United States” 22 “Derek” “Ward” “Switzerland” 25
With Windows, you can use Import-CSV and Format-Table in PowerShell:
Import-Csv .\people-example.csv.txt | Format-Table
First Name Last Name Country age
Bob Smith United States 24 Alice Williams Canada 23 Malcolm Jone England 22 Felix Brown USA 23 Alex Cooper Poland 23 Tod Campbell United States 22 Derek Ward Switzerland 25
SFTPK: Binary Search Tree
This post is one in a series of stuff formally trained programmers know – the rest of the series can be found in the series index.
Binary Search Tree
In the previous post, we covered a Binary Tree, which is about the shape of storing the data. The Binary Search Tree (BST) is a further enhancement to that structure.
The first important change is that the data we are storing needs a key; if we have a basic type like a string or number then the value itself can be the key and if we have a more complex class, then we need to define a key in that structure or we need to build a unique key for each item.
The second change is a way to compare those keys which is crucial for the performance of the data structure. Numbers are easiest since we can easily compare which is larger and smaller.
The third and final change is the way we store the items; the left node’s key will always be smaller than the parent nodes key and the right node’s key will be larger than the parent node.
As an example, here is a BST using just numbers as keys:
{height=300}
Note that all nodes to the left are smaller than their parent and all parents above that.
Why?
So, why should we care about a BST? We should care because searching is really performant in it as each time you move a depth down, you eliminate approximately 50% of the potential nodes.
So, for example, if we wanted to find the item in our example with the key 66, we could start at the root (50) and move right. At that point, we have eliminated 8 possible nodes immediately. The next is to the left from the node with the 70 (total possible nodes removed 12). Next is to the right of the node with the value of 65, and then to 66 to the left of 67. So we found the node with 5 steps.
Going to Big O Notation, this means we achieved a performance of close to O(log n). It is possible to have a worst case of O(n), when the tree is not Optimal or Unbalanced.
Balanced versus Unbalanced
In the above example we have a binary search tree which is Optimal, i.e. it has the lowest depth needed. Below we can see a totally valid BST; Each child node is to the right of the parent because it is bigger than the parent.
{height=300}
This, however, will result in a O(n) search performance which is not ideal. The solution is to rebalance the BST and for our example above we can end up with multiple end states (I’ll show two below). The key takeaway is that we go from a depth of 5 to a depth of 3.
{height=300}
#Implementations .NET has a built-in implementation with SortedDictionary. Unfortunately, nothing exists out of the box for this in JavaScript or Java.
Quick tip: Grep in Git
This quick tip is about two small features of Git I wish I had known about earlier as it makes it way easier to do searching through it.
git-grep
git-grep is a way to search through your tracked files for whatever you provide. For example, if we want all files with the word index in it: git grep index
We can limit to specific files, for example, if we want to filter the above example to just JSON files: git grep index -- '*.json'
We can search for multiple items in a single file, for example, if we want to find all files with index and model in it: git grep --all-match -e index -e model
git-log grep
git-log has a grep function too which is awesome for finding commit messages with a specific word or words in it. For example, if I want to find all commits about Speakers for DevConf I could do: git log --all --grep "Speaker"
Drupal Geshi Cheatsheet
Since redoing this blog, I switched out the syntax highlighting to use the Drupal Geshi Module.
For the love of everything I can’t remember the tricks for using it, so here is a cheatsheet; mostly for myself but maybe you get value too. These are all HTML attributes you add can to your code block.
- language this controls the language for rendering.
-
line_numbering controls if line numbering is off, on or fancy with the values
off
,normal
andfancy
respectively.- With fancy line numbers you can use the attribute interval to control how often to show the line numbers.
- title adds a title to the code block.
- special_lines takes a comma-separated list of numbers and highlights them.
- linenumbers_start controls what the first line number is.
Information worked out from this code.
Quick tip: The handy command line calculator
*[WSL]: Windows Subsystem for Linux
Who needs a GUI to do math when we have options for Unix like (MacOS, Linux etc…), Command Prompt, and PowerShell?
#Unix like OSs {#commandlinecalculatorunix} Unix OSs, including MacOS, WSL & Linux, include an awesome calculator called BC. From the man page:
bc is a language that supports arbitrary precision numbers with interactive execution of statements. There are some similarities in the syntax to the C programming language. A standard math library is available by command line option. If requested, the math library is defined before processing any files. bc starts by processing code from all the files listed on the command line in the order listed. After all the files have been processed, bc reads from the standard input. All code is executed as it is read.
The only cavet to use, is the file input; you can’t just pass in parameters… but you can use echo
to pass in the equation. For example:
echo ‘1 + 2 + 3 + 4’ | bc 10
bc can also work with different number bases, for example:
echo “obase=2; ibase=10; 42” | bc 101010
obase stands for output base & ibase stands for input base. So in the example, we are turning 42 (base 10) to binary.
Floating point division is a weirdness with bc. For example, you would expect the answer to be 0.4 below but it is 0:
echo “2/5” | bc 0
The solution is to use the math library switch -l
:
echo “2/5” | bc -l .40000000000000000000
and if 20 point position, you can use scale
to control it:
echo “scale=3; 2/5” | bc -l .400
Windows Command Prompt {#commandlinecalculatorcmd}
Command prompt has a similar tool with the set
command.
set /a 3+3 6 set /a (3+3)*3 18 set /a “203>>3” 25
PowerShell {#commandlinecalculatorps}
PowerShell natively supports some basic functionality, but if you want to use more advanced functionality you can use the entire System.Math class to do a lot of functionality.
4+5 9 6*7 42 [Math]::Sin(50) -0,262374853703929 [Math]::Max([Math]::Tan(40), [Math]::Cos(40)) -0,666938061652262
Quick tip, the Say command
MacOS has a great tool, called say which just says what you pass it. For example say "Hello"
and next you’ll hear your device say Hello.
Where this is really useful is when you want to do a long running action and get notified when it is done. For example git clone https://github.com/torvalds/linux.git && say "clone complete"
So, what about for Windows? You can do something similar with Powershell. First the setup:
Add-Type -AssemblyName System.speech
$say = New-Object System.Speech.Synthesis.SpeechSynthesizer
Once you have that in place you can use it like this: git clone https://github.com/torvalds/linux.git; $say.Speak("clone complete")
VSCode - Too many open files
If you are getting the too many open files error with MacOS it could be VSCode trying to too many open files (or by default opening more than 10240 files).
You can confirm that with the following:
lsof | awk ‘{ print $2 “ “ $1; }’ | sort -rn | uniq -c | sort -rn | head -20
So, what can you do about it? If the files are not important, say it is your output folder, then you can use VSCode settings to exclude them. In the example below, I configure VSCode to ignore build folders. I would encourage this as a workspace setting, so everyone in the team gets it.
// Configure glob patterns for excluding files and folders.
"files.exclude": {
"**/build": true
},
“files.watcherExclude”: {
“**/build”: true
},
“search.exclude”: {
“**/build”: true
},
MacOS utilities I find useful
After using a MacBook Pro for two years I thought it was time to share what utilities I found really useful to have. These are obviously weighted towards being a software developer, so your mileage might vary.
Brew
It is the missing package manager for MacOS, so as with NPM, Chocolatey, or Composer, where you can install what you need via the command line.
It may seem weird, like what is wrong with just download and install what you need?! The advantage is that you can write this stuff down so that if you need to reinstall it is easier (and also easier to share to help others get up and running).
A second advantage is updating, it takes one command to update all the tools I use.
VSCode
More than an IDE, this is my go-to tool for anything text; Editing config ✅taking notes ✅anything really.
Install with Brew: brew install homebrew/cask/visual-studio-code
An important tweak for VSCode is to make sure it is launching from the Terminal, thankfully it is really easy.
Aerial
The AppleTV has the best screensaver I’ve ever seen, and some smart person ported it to MacOS with the name Aerial.
A word of warning, these videos are massive and will destroy your bandwidth. One tip to solve that is that under the settings is a Cache section - make sure you have the Cache Aerials As They Play checked else this will destroy your bandwidth. If you are on uncapped, then there is also a download now option which is a must to use.
Install with Brew: brew install caskroom/cask/aerial
Fish
Bash is nice, Fish is nicer. It just feels like what you expect in a modern world.
Install with Brew: brew install fish
Fish Node Manager
Part of my job has involved working with multiple projects, and that means multiple versions of Node, and that was a pain. Thankfully there is a Node Manager for Fish that lets you easily change what version of Node you are using.
Unfortunately, this isn’t as easy to setup, as to install it you first need Fisherman, which is like Brew but for Fish; which leads to this 3 step process to install it and configure it.
curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs https://git.io/fisher
fisher fnm
fnm use latest
Amphetamine
Amphetamine is a massively useful tool for MacOS, especially in a DevOps culture where you might get up in the night and just need your machine to behave the exact way you want it. Its core use is to not let your Mac go to sleep and you can control what triggers that, automatically or manually.
Status Clock
Another very useful tool is Status Clock which can show a second time on the menu which is exceptionally useful if you need to work across countries.
Settings Tweaks
Beyond useful tools, there are some useful tweaks to the standard MacOS settings: