Supergood!

I spotted encourage-mode for Emacs on twitter the other day, so naturally I had to try it!

(use-package encourage-mode)
(encourage--toggle-encouragements)

For some reason, I had to toggle the encouragements to get it started (it seems like that shouldn’t have been necessary. Update: It’s not…see the comments!). Then I added some more encouragements to the list (most of these are from the Venture Bros.)

(setq encourage-encouragements
  (nconc encourage-encouragements
    '("Excellent!"
      "Hot sandwich!"
      "Mein lieber Schwan!"
      "Nice!"
      "Outstanding!"
      "Ossum!"
      "Quit it!"
      "Scwhanky!"
      "Spanakopita!"
      "SPHINX!"
      "Supergood!"
      "Sweet!"
      "That is so Batman!"
      "Well done, you!"
      "Whoa!")))

Fun!

Supergood!

GADSWAD

Recently, on the Python-Dev mailing list, Guido van Rossum said the transition to Python 4 won’t be like the transition to Python 3 (“we’ve learned our lesson”).

Yukihiro Matsumoto has said similar things (without the cheap shot at Perl, naturally) recently at RubyConf 2015 and at Full Stack Fest 2015 when he talked about Ruby 3.0. In both of those talks, he gave a pretty thorough outline of the similar transitions that Perl, Python, and Ruby have gone through over the last 10 or 15 years. He talks about how Perl started over from scratch, Python made a set of backwards-compatiblity breaking changes all at once, and Ruby made backwards-compatiblity breaking changes gradually over several minor versions.

Python 3 was released nearly seven years ago, yet a majority of Python users are still on Python 2. It looks as though some might never switch. Ruby users, on the other hand, gradually transitioned from 1.9.1 to 1.9.2 to 1.9.3. They find themselves at Ruby 2 without really noticing.

Both GvR and Matz are looking at it like this

Perl 5   -> Perl 6
Python 2 -> Python 3
Ruby 1.8 -> Ruby 2

and feeling pretty good about themselves. Perl 6 isn’t even out yet, so they both did okay, right? And now they’re looking ahead at things like concurrency and performance that will be necessary for the future.

Perl 5   -> Perl 6
Python 2 -> Python 3  -> Python 4
Ruby 1.8 -> Ruby 2    -> Ruby 3

But despite its decline in popularity, I think Perl 5 has maintained feature parity with Python and Ruby. Since Perl 5.10 opened the floodgates, the updates to Perl are collectively known as Modern Perl. I use Modern Perl every day at my job and it’s fine. While Python 3 and Ruby 2 have kept up with it, more or less, they are not a quantum leap ahead by any stretch of the imagination. So I think the situation today looks more like this:

Perl 5   -> Modern Perl
Python 2 -> Python 3
Ruby 1.8 -> Ruby 2

Perl 6 is threatening to finally come out later this month and it is already prepared for the future. That is, I believe we should be comparing Perl 6 to Python 4 and Ruby 3.

Perl 5   -> Modern Perl -> Perl 6
Python 2 -> Python 3    -> Python 4
Ruby 1.8 -> Ruby 2      -> Ruby 3

Of course, there’s still the whole issue of adoption. If Perl 6 is adopted as slowly as Python 3 (or even more slowly!), then it may never matter how futuristic it is.

I think concurrency is going to matter a great deal in the near future, so my recreational programming time lately has been dedicated to things like Clojure, Elixir, Go, and Rust. I’m betting my professional programming time will go that way soon too. Sequential programming is doomed. We’re going to have to figure out concurrency or find another profession.

GADSWAD

Hello, Swift!

The Swift programming language (not to be confused with an earlier Swift programming language) is now open source! This is a language developed at Apple as an alternative to Objective-C, the proprietary language used to develop most OS X and iOS products. Those are popular platforms, but Objective-C was not well-regarded by most developers. Apple needed something better and rather than try to improve Objective-C, they decided to start over. Swift is the result.

My desktop machine is currently running the latest Xubuntu

$ lsb_release -ds
Ubuntu 15.10

which is one of the platforms they claim to support, so why not give it a go? First, the prerequisites (I already have some of these installed, but APT will just skip over them if that’s the case so I’m just going to paste the whole line)

sudo apt-get install git cmake ninja-build clang uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config

Now, download all the source

git clone https://github.com/apple/swift.git swift
git clone https://github.com/apple/swift-llvm.git llvm
git clone https://github.com/apple/swift-clang.git clang
git clone https://github.com/apple/swift-lldb.git lldb
git clone https://github.com/apple/swift-cmark.git cmark
git clone https://github.com/apple/swift-llbuild.git llbuild
git clone https://github.com/apple/swift-package-manager.git swiftpm
git clone https://github.com/apple/swift-corelibs-xctest.git
git clone https://github.com/apple/swift-corelibs-foundation.git

Whew! Now try building

$ cd swift
$ utils/build-script -h
Traceback (most recent call last):
  File "utils/build-script", line 24, in <module>
    from SwiftBuildSupport import *
  File "/home/tim/swift/swift/utils/SwiftBuildSupport.py", line 15, in <module>
    import ConfigParser
ImportError: No module named 'ConfigParser'

Oops! Apparently, the build script is written in Python 2 and my environment has Python 3 as the default (it being nigh 2016 and all). I guess I’ll switch back for this

$ pyenv global system
$ utils/build-script -h
...
To build everything with optimization without debug information:

  [~/src/s]$ ./swift/utils/build-script -R

To run tests, add '-t':

  [~/src/s]$ ./swift/utils/build-script -R -t

To run normal tests and validation tests, add '-T':

  [~/src/s]$ ./swift/utils/build-script -R -T
...

Alrighty then, let’s give it a try!

$ cd ..
$ ./swift/utils/build-script -R -T
...

[Time elapses.] Okay, where are the results?

$ find . -name swift
./swift
./swift/test/PrintAsObjC/Inputs/clang-headers/swift
./swift/include/swift
./lldb/tools/repl/swift
./lldb/swift
./lldb/packages/Python/lldbsuite/test/lang/swift
./lldb/packages/Python/lldbsuite/test/lang/swift/variables/swift
./llbuild/bindings/swift
./build/Ninja-ReleaseAssert/swift-linux-x86_64/include/swift
./build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift
./build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swift
./build/Ninja-ReleaseAssert/swift-linux-x86_64/test-linux-x86_64/Driver/Output/options-repl.swift.tmp/usr/bin/swift
./build/Ninja-ReleaseAssert/swift-linux-x86_64/test-linux-x86_64/Driver/Output/options-repl-darwin.swift.tmp/Toolchains/Test.xctoolchain/usr/bin/swift

I guess ./build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swift is probably my compiler. Now, how to write a Swift program. A little googling gets me this.

println("Hello, World!")

That looks easy. Let’s try it.

$ ./build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swift hello.swift
hello.swift:2:1: error: 'println' has been renamed to 'print'
println("Hello, World!")
^~~~~~~
print
Swift.println:2:13: note: 'println' has been explicitly marked unavailable here
public func println<T>(value: T)
            ^

Hrm. I guess that tutorial is out of date. No worries, that error message tells us exactly what to do— a very good sign!

print("Hello, World!")

Now we get

$ ./build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swift hello.swift
Hello, World!

Oh, it didn’t just compile it, it compiled and ran it!

$ ls -l ./build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/
total 401048
-rwxr-xr-x 1 tim tim 64661808 Dec  4 09:28 lldb-moduleimport-test
-rwxr-xr-x 1 tim tim 68172720 Dec  4 09:28 sil-extract
-rwxr-xr-x 1 tim tim 68801512 Dec  4 09:26 sil-opt
-rwxr-xr-x 3 tim tim 73638760 Dec  4 09:26 swift
lrwxrwxrwx 1 tim tim        5 Dec  4 09:27 swift-autolink-extract -> swift
lrwxrwxrwx 1 tim tim        5 Dec  4 09:27 swiftc -> swift
-rwxr-xr-x 1 tim tim   862680 Dec  4 09:27 swift-demangle
-rwxr-xr-x 1 tim tim 66063096 Dec  4 09:27 swift-ide-test
-rwxr-xr-x 1 tim tim 68444448 Dec  4 09:28 swift-llvm-opt

Okay, maybe swiftc is the “swift compiler”.

$ ./build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swiftc hello.swift
$ ./hello
Hello, World!

Success!

$ ./build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swiftc -version
Swift version 2.2-dev (LLVM 46be9ff861, Clang 4deb154edc, Swift e0e52576c4)
Target: x86_64-unknown-linux-gnu

I guess I should make a link to swiftc in my bin directory or something.

Now let’s try the arguments greeter seen elsewhere.

if Process.arguments.count <= 1 {
    print("Hello, World!")
} else {
    var n = Process.arguments.count - 1

    for s in Process.arguments[1...n] {
        print("Hello, \(s)!")
    }
}

That took longer than you might expect and it’s still pretty clumsy (there must be a better way to iterate through the arguments than that), but it works.

$ ./build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swiftc hello.swift

$ ./hello
Hello, World!

$ ./hello Hank Dean Brock
Hello, Hank!
Hello, Dean!
Hello, Brock!

I don’t know if the world needs yet another class-based object-oriented programming language right now, but this one doesn’t seem half bad…and better open than closed!

Hello, Swift!

Ruby’s Lonely Operator

I enjoyed Matz’s closing keynote address at RubyConf 2015! In particular, I adored his description of the lonely operator:

Lonely_operator.png

“Look at this figure…and then…you can see…someone sitting on the floor looking at a dot. On the floor. By themself. Now you don’t forget. Yeah.” – @yukihiro_matz

He’s right, I think I will never forget this. It’s ossum! I intend to download Ruby 2.3 the minute it is available and write something that uses this operator. Just because.

Ruby’s Lonely Operator

Regexes > regular expressions

I absolutely loved Hsing-Hui Hsu’s talk about parsers at RubyConf 2015 last week. It’s a terrific talk and it’s well worth your time to watch it.

But I did have one little nit to pick. What we call regexes in Ruby (and many other programming languages) are much more powerful than the original definition. In addition to regular languages, Ruby regexes can express context-free languages, and even some context-sensitive languages.

ab_language.png

For example, Ruby has no trouble with the “ab” language in the presentation:

#!/usr/bin/env ruby

%w(ab aabb aaaaabbbbb aaaaaa abb aab ababab).each do |s|
    printf "%10s - %-8s\n", s,
         /^(?<ab>a(\g<ab>)?b)$/.match(s) ? 'valid' : 'invalid'
end

Running the above gives:

$ ./ab.rb 
        ab - valid   
      aabb - valid   
aaaaabbbbb - valid   
    aaaaaa - invalid 
       abb - invalid 
       aab - invalid 
    ababab - invalid

Easy peazy! We can even use the x modifier to make a more readable regex.

#!/usr/bin/env ruby

pat = /^
       (?<ab>         # start a capture named ab
         a            # look for a literal 'a'
           (\g<ab>)?  # optionally re-execute ab recursively
         b            # followed by a literal 'b'
       )              # end of capture; this is ab
       $/x

%w(ab aabb aaaaabbbbb aaaaaa abb aab ababab).each do |s|
    printf "%10s - %-8s\n", s, pat.match(s) ? 'valid' : 'invalid'
end

This is clear as can be: we look for ‘a’ followed by ‘b’, or ‘ab’ preceded by ‘a’ and followed by ‘b’ (‘aabb’), or that preceded by ‘a’ and followed by ‘b’ (‘aaabbb’), and so on.

Regular expressions regularly (har, har) get slagged for being line noise, but it’s sometimes unfair. If you try to re-write a gnarly regex in Ruby (or your favorite language) without using regexes, you often find it’s even worse! Regexes are very powerful. And they’re pretty cool. Don’t dismiss them!

ab_language_terrible.png

Regular expressions are one of my favorite programming languages, but they’re not the best tool for everything. Like @SoManyHs says, parsers are awesome. And for many tasks, they’re more appropriate than regexes. We should use them.

Just keep in mind, regexes are more than (historical) regular expressions.

Regexes > regular expressions

Hello, Elixir!

A while ago, I talked about trying Elixir and finished with this example of Hello World

#!/usr/bin/env elixir

greet = fn s -> IO.puts "Hello, #{s}!" end

if length(System.argv) == 0 do
  greet.("World")
else 
  Enum.each(System.argv, greet)
end

This looks pretty much the same as it would in an imperative language. First, we define a greet function that prints “Hello, string!” for whatever string we give it. If we’re given no arguments, we call this with “World”. Otherwise, we call it for each of the arguments (okay, that part is already looking a tiny bit functional, since a for loop is missing).

But we don’t often use if-then-else in Elixir. I ended that post saying I would look for a more elixiry way to do it. I did so, but I didn’t post about it.

My second pass at hello world in Elixir looked like this

#!/usr/bin/env elixir

greet = fn s -> IO.puts "Hello, #{s}!" end

hello = fn
  [] -> greet.("World")
  list -> Enum.each(list, greet)
end

hello.(System.argv)

This is the same greet function, but rather than an if-then-else, we define a new function, hello, that has one behavior when handed an empty list and a different behavior when handed a non-empty list. Then we simply call this function with the argument list of the program.

For a third pass, I threw in Elixir’s amazing pipe operator.

#!/usr/bin/env elixir

greet = fn s -> IO.puts "Hello, #{s}!" end

hello = fn
  [] -> greet.("World")
  list -> list |> Enum.each(greet)
end

hello.(System.argv)

This doesn’t really show it off much, but the pipe operator seems to be an important part of Elixir’s readability in real code.

Finally, I learned that we usually name standalone scripts like this with a .exs rather than .ex in Elixir, so the new hello.exs works the same as before

$ ./hello.exs
Hello, World!
$ ./hello.exs Hank Dean Brock
Hello, Hank!
Hello, Dean!
Hello, Brock!

Keen!

Hello, Elixir!