2015-11-27
A thought on the apparent popularity of new static typing languages
It all started with Elben Shira's The End of Dynamic Languages, which sparked Have Static Languages Won? (via) from Maxime Chevalier-Boisvert. In that I read the following:
Like [Elben Shira], I've noticed that despite the fact that there have been an enormous number of new programming languages coming out recently, the overwhelming majority of them are statically typed. [...]
I'm an outsider bystander on all of this, but it strikes me that one possible contributing reason for lots of people creating new statically typed languages is that there is a significant body of academic research that has not yet made it into a popular, mainline programming language. Here I'm thinking primarily of sophisticated type systems and type inference. As long as this situation exists, people tempted to create languages have a clear void that their new modern statically typed language might possibly fill (at least in theory).
(And then they can mingle in some degree of immutability and this and that from other academic research. There's a lot of academic work on statically typed languages that hasn't gotten into popular languages yet. There's also a bunch of people who are grumpy about this lack of popularity, which is another crucial ingredient for creating new languages; see, for example, all of the people who are unhappy at Go for having such a simple and 'primitive' type system in the face of much more powerful ones being out there.)
While I'm not fully in touch with the dynamic language world either, my impression is that there is no similar reserve of well-established academic research on them that has yet to be reflected in popular dynamic languages. Without that, if you're going to create a new dynamic language today it's not clear how you're going to make it significantly different from the existing popular dynamic languages. And if you can't make it very different from the existing good options, what's the point? Certainly you're not likely to get much traction with a slightly different version of Python, JavaScript, or the like.
(Arguably you're not very likely to get significant traction for an advanced statically typed language if so many other ones before you have not been hits, but that's somewhat different in that hope springs eternal. It's the same impulse that keeps people writing new Lisp like languages that they want to be popular.)
PS: I could be totally wrong on this in that maybe there's a pile of good academic research on dynamic languages that's begging to be implemented and made popular. I'd actually like that; it'd mean we have the prospect of significantly better and nicer dynamic languages.
2015-11-21
What I think I want out of autocompletion in GNU Emacs (for Go coding)
I mentioned a while back that I had set up autocompletion in GNU Emacs for Go, using gocode and the auto-complete Emacs package. I also mentioned that I wasn't sure if I liked autocompletion and was going to stick with it. Well, the verdict is in for now; I found it too annoying and I wound up turning it off. However, I still kind of miss it. Thinking about what I miss and what made me hate it enough to turn it off has led me to what I think I want out of autocompletion.
Why I turned autocompletion off is that it kept stealing my keystrokes (in order to do the wrong autocompletion); cursor keys, the return key, and I think even sometimes the space bar. I type fast and I type ahead, so I absolutely, utterly hate having the sequence of what I'm typing be derailed because autocompletion decided to grab a cursor motion or a return or whatever. Unless I go out of my way, I want what I type at the keyboard to actually be what shows up in the file I'm editing. At the same time, the prompting and information that autocompletion gave me was genuinely useful; it was a great way to not have to remember the full names of things in Go packages and so on.
Given that I liked the information display, I don't want all of (auto)completion to be deferred until I use a special key sequence like C-M-i. If I spent a lot of time in GNU Emacs I might be able to train myself to hit that by reflex, but with my more casual use it'd just insure that I mostly never used completion at all. But I don't want any actual completing of things to happen until I hit a key to start it (and once I hit the key, it's fine if autocompletion steals my cursor keys and return key and so on).
So in short what I want from autocompletion is immediate information on possible completions coupled with deferred actual completion until I take some active step to start the completion process. This is fairly similar to the completion model I'm happy with in Unix shells, where nothing starts getting filled in until you hit TAB.
(Defering only actual completion doesn't appear to be possible in auto-complete. I can't entirely blame the package, because what I'm calling an information display is what it thinks of as a completion menu and completion prompt.)
Part of my irritation with autocompletion is specific to the Go
autocompletion mode provided by gocode. For instance, in Go I
don't want to have completion happen when I'm typing in language
keywords like package and func; I find it both distracting and
not useful. Completion is for things that I might have to look up;
if I'm typing a keyword, that is not the case.
(This completion of keywords is especially irritating because it's
blind to context. If I start typing 'pa' on a new line in a function
body, I'll still get offered 'package' as a possible completion
despite that clearly not being correct or even valid. Gocode is context
aware in general, in that it does things like offer local variables as
completions.)
PS: That part of my issues are with gocode itself suggests that even switching to vim wouldn't entirely help.
2015-11-15
I should remember that I can cast things in Go
I think of Go as a strongly typed language.
My broad and somewhat reflexive view of strongly typed languages is
that they mostly don't allow you to cast things around because most
casts will require expensive data conversion and the language wants
you to do that explicitly, with your own code. Go even sticks to this
view; you can cast numbers around (because it's too useful) and you
can go between string and []byte (because it's a core operation),
and that's mostly it.
(Then there's interfaces, which expose some tricks. Interface casting involves a bunch of potentially expensive magic, but it's a core feature of Go so it's an exception to the 'no expensive operations via casts' rule of thumb.)
However, there is an important practical exception to this, which
comes about because of another thing that Go encourages: lots of
named types that you derive from fundamental types. Rather than using,
say, int, for all sorts of different things in your code, everyone
knows that you should instead create various specific types:
type Phase int type Action int type OneMap map[string]string type TwoMap map[string]string
This way you can never accidentally use a Phase when the actual
function, field, or whatever is supposed to be an Action, or pass
a OneMap function a TwoMap, and so on. Go's strong typing will
force them to be separate (even if this is sometimes irritating,
for example if you're dealing with cgo).
These derived types can be cast to each other and to their underlying type. This is not just if they're numbers; any derived type can be cast around like this, provided that the underlying 'real' types are the same (per the Conversions section of the language spec).
(At a mechanical level it's easy to see why this is okay; since the two derived types have exactly the same memory layout, you don't have to do expensive conversion to generate a type-safe result.)
Now, ordinarily you still don't want to cast a OneMap to a TwoMap
(or to a map[string]string). But there is one special case that
matters to me, and that's if I want to do the same operation on
both sorts of maps. Since I actually can cast them around, I don't
need to write two duplicated blocks of (type-specific) code to do
the same operation. Instead I can write one, perhaps one that's
generic to the map[string]string type, and simply call it for
both cases through casts. This is not the only way to create common
code for a generic operation but it's probably the easiest one to
add on the fly without a bunch of code refactoring.
So this is why I need to remember that casting types, even complex types, is something that I can do in Go. It's been kind of a reflexive blind spot in my Go code in the past, but hopefully writing this will avoid it in the future.