An Ioke spelling corrector


A while back Peter Norvig (of AI, Lisp and Google fame) published a small entry on how spelling correctors work. He included some code in Python to illustrate the concept, and this code have ended up being a very often used example of a programming language.

It would be ridiculous to suggest that I generally like to follow tradition, but in this case I think I will. This post will take a look at the version implemented in Ioke, and use that to highlight some of the interesting aspects of Ioke. The code itself is quite simple, and doesn’t use any of the object oriented features of Ioke. Neither does it use macros, although some of the features used is based on macros, so I will get to explain a bit of that.

For those that haven’t seen my Ioke posts before, you can find out more at http://ioke.org. The features used in this example is not yet released, so to follow along you’ll have to download and build yourself. Ioke S should be out in about 1-2 weeks though, and at that point this blog post will describe released software.

First, for reference, here is Norvig’s original corrector. You can also find his corpora there: http://norvig.com/spell-correct.html. Go read it! It’s a very good article.

This code is available in the Ioke repository in examples/spelling/spelling.ik. I’m adding a few line breaks here to make it fit the blog width – expect for that everything is the same.

Lets begin with the method “words”:

words = method(text,
  #/[a-z]+/ allMatches(text lower))

This method takes a text argument, then calls the method “lower” on it. This method will return a new text that is the original text converted to lower case. A regular expression that matches one or more alphabetical characters are used, and the method allMatches called on it. This method will return a list of texts of all the places matches in the text.

The next method is called “train”:

train = method(features,
  features fold({} withDefault(1), model, f,
    model[f] ++
    model))

The argument “features” should be a list of texts. It then calls fold on this list (you might know fold as reduce or inject. those would have been fine too.) The first argument to fold is the start value. This should be a dict, with a default value of 1. The second argument is the name that will be used to refer to the sum, and the third argument is the name to use for the feature. Finally, the last argument is the actual code to execute. This code just uses the feature (which is a text), indexes into the dict and increments the number there. It then returns the dict, since that will be the model argument the next iteration.

The next piece of code uses the former methods:

NWORDS = train(words(FileSystem readFully("small.txt")))

alphabet = "abcdefghijklmnopqrstuvwxyz" chars

As you can see we define a variable called NWORDS, that contains the result of first reading a text file, then extracting all the words from that text, and finally using that to train on. The next assignment gets a list of all the characters (as text) by calling “chars” on a text. I could have just written [“a”, “b”, “c”, …] etc, but I’m a bit lazy.

OK, now we come to the meat of the code. For an explanation of why this code does what it does, refer to Norvig’s article:

edits1 = method(word,
  s = for(i <- 0..(word length + 1),
    [word[0...i], word[i..-1]])

  set(
    *for(ab <- s,
      ab[0] + ab[1][1..-1]), ;deletes
    *for(ab <- s[0..-2],
      ab[0] + ab[1][1..1] + ab[1][0..0] + ab[1][2..-1]), ;transposes
    *for(ab <- s, c <- alphabet,
      ab[0] + c + ab[1][1..-1]), ;replaces
    *for(ab <- s, c <- alphabet,
      ab[0] + c + ab[1]))) ;inserts

The mechanics of it is this. We create a method assigned to the name edits1. This method takes one argument called “word”. We then create a local variable called “s”. This contains the result of executing a for comprehension. There are several things going on here. The first part of the comprehension gives a generator (that’s the part with the <-). The thing on the right is what to iterate over, and the thing on the left is the name to give it on each iteration. Basically, this comprehensions goes from 0 to the length of the word plus 1. (The dots denote an inclusive Range). The second argument to “for” is what to actually return. In this case we create a new array with two elements. The three dots creates an exclusive Range. Ending a Range in -1 means that it will extract the text to the end of it.

The rest of the code in this method is four different comprehensions. The result of these comprehensions are splatted, or spread out as arguments to the “set” method. The * is symbol to splat things. Basically, it means that instead of four lists, set will get all the elements of all the lists as separate arguments. Finally, set will create a set from these arguments and return that.

Whew. That was a mouthful. The next method is easy in comparison. More of the same, really:

knownEdits2 = method(word,
  for:set(e1 <- edits1(word),
    e2 <- edits1(e1),
    NWORDS key?(e2),
    e2))

Here we use another variation of a comprehension, namely a set comprehension. A regular comprehension returns a list. A set comprehension returns a set instead. This comprehension will only return words that are available as keys in NWORDS.

known = method(words,
  for:set(w <- words,
    NWORDS key?(w), w))

This method uses a set comprehension to find all words in “words” that are keys in NWORDS. As this point you might wonder what a comprehension actually is. And it’s quite easy. Basically, a comprehension is a piece of nice syntax around a combination of calls to “filter”, “map” and “flatMap”. In the case of a set comprehension, the calls go to “filter”, “map:set” and “flatMap:set” instead. The whole implementation of comprehensions are available in Ioke, in the file called src/builtin/F10_comprehensions.ik. Beware though, it uses some fairly advanced macro magic.

OK, back to spelling. Let’s look at the last method:

correct = method(word,
  candidates = known([word]) ifEmpty(
    known(edits1(word)) ifEmpty(
      knownEdits2(word) ifEmpty(
        [word])))
  candidates max(x, NWORDS[x]))

The correct method takes a word to correct and returns the best possible match. It first tries to see if the word is already known. If the result of that is empty, it tries to see if any edits of the word is known, and if that doesn’t work, if any edits of edits are known. Finally it just returns the original word. If more than one candidate spelling is known, the max method is used to determine which one was featured the most on the corpus.

The ifEmpty macro is a bit interesting. What it does is pretty simple, and you could have written it yourself. But it just happens to be part of the core library. The implementation looks like this:

List ifEmpty = dmacro(
  "if this list is empty, returns the result of evaluating the argument, otherwise returns the list",

  [then]
  if(empty?,
    call argAt(0),
    self))

This is a dmacro, which basically just means that the handling of arguments are taken care of. The argument for a destructured macro can be seen in the square brackets. Using a dmacro instead of just a raw macro means that we will get a good error message if the wrong number of arguments are provided. The implementation checks if its list is empty. If it is it returns the value of the first argument, otherwise it doesn’t evaluate anything and returns itself.

So, you have now seen a 16 line spelling corrector in Ioke (it’s 16 without the extra line breaks I added for the blog).



An Ioke update


I haven’t written here in a while – the reason being that I’ve been seriously heads down with Ioke, having a blast implementing new things and planning the future. I’m happy to have received several contributions from other people. Github makes this so easy it’s silly.

Since December 23rd – when Ioke 0 was released – I have made quite a lot of changes to Ioke. The highlights are these:

  • fixed all outstanding bugs reported
  • several examples, contributed by Carlos Villela
  • Range#each
  • ensure (like Ruby ensure, Java finally)
  • lexical macros
  • become!
  • full implementation of Regexp and Regexp Match
  • freeze!, thaw!
  • case expression
  • list comprehensions, set comprehensions and dict comprehensions
  • support for TextMate
  • alternative syntax for text and regexps
  • interpolation inside of regexps
  • support for syntactic macros
  • support for quoting and metaquoting
  • cond expression
  • destructuring macros
  • added support for inverted ranges
  • added methods to remove cells
  • added methods to find the owner of cells

So as you can see, I’ve been kinda busy. Ioke has garnered some real attention too, which is great fun. The github repository has over a 100 watchers. The guide has been viewed over 3500 times. The distribution packages have been downloaded about 400 times.

But right now I’m looking to the future. There are still many, many small holes in the core libraries, but with regards to the big stuff there is basically three pieces missing. These are Java integration, aspects and concurrency. I haven’t started on any of these because I haven’t decided exactly how they should look like. Especially the concurrency issue is definitely problematic. So I’m punting on it right now. But I promise to have an answer within a few weeks to these three major issues.

So what’s the plan? Ioke S will be released within 2 weeks. The guide need to be updated quite substantially, since all the features I listed above need to be described, and some of them are really complicated. They are very nice of course. I will also create at least a few more examples to show some actual code. I might write about it here to show some features.



Ioke 0 released


I am very happy to announce the first release of Ioke!

Ioke is a dynamic language targeted at the Java Virtual Machine. It’s been designed from scratch to be a highly flexible general purpose language. It is a prototype-based programming language that is inspired by Io, Smalltalk, Lisp and Ruby.

Homepage: http://ioke.org
Download: http://ioke.org/download.html
Programming guide: http://ioke.org/guide.html

Ioke 0 is the first release of Ioke, and as such is not production ready. I would appreciate if people tried it out and reported bugs, thoughts and ideas.

Features:
– Strong, dynamic typing
– Prototype based object orientation
– Homoiconic language
– Simple syntax
– Powerful macro facilities
– Condition system
– Developed using TDD
– Documentation system that combines documentation with specs
– Wedded to the JVM

Go ahead! Try it out!



Expressive power vs performance


We all know that all programming languages in use today are Turing complete. But what this comes down to in reality is Greenspun’s Tenth Rule, which isn’t that useful for common discourse. So I will ignore Turing completeness in this post, and argue as if some languages are absolutely more powerful than others in terms of expressiveness. How to measure that power is a different discussion, and something Paul Graham and many others have written about. So I’ll make it really simple here – I’m going to use my own subjective view of the power of different programming languages, where succinctness (ability to compress without losing readability, a hard thing indeed), high classes of abstractions and support for different paradigms are supported. Not surprisingly, this put languages like Lisp, Smalltalk and Haskell in the absolute top, while languages like Java, C#, Basic and many other end up further down the scale to different degrees. Assembler is somewhere near the absolute bottom.

My contention is that expressive power is the absolutely most important property to focus on right now. We have progressively gotten better and better at this, but it still feels as if many decisions in programming languages are still based on whether they can be implemented efficiently or not. That is definitely important in some circumstances, but maybe not as often as we think. As we know, programmers are prone to premature optimization, and I think this is true for programming language design too.

One of the core guiding principles for Ioke is to forcefully remove all concerns about performance when thinking about new abstraction capabilities. I think there are new abstractions, new ways of programming – or even just incrementally better ways of doing things – that aren’t being explored enough. Take something like Ruby’s variables and instance variables, which spring into use the first time they are assigned to. This is highly useful, and lead to very neat code, but it’s hell to implement efficiently. And the situation can be even worse, like what I do in Ioke, where it’s not possible to statically/lexically see if a variable assignment is the first or not, and where it belongs. This means that there is no way to create efficient closure structures, no way to create efficient storage mechanisms for local scope, and so on. Some guesses can be made, but in the general cases it’s hard to make it perform well.

So why do it? Well, we’ve been pretty good at creating medium expressive languages that perform well, and we’re really good at designing languages that aren’t expressive at all while performing very well. But I’m lacking the other end of the scale. The most expressive languages I mentioned above still make concessions to performance in many places. Just take something like let-bindings in Lisp, which actually turns out to be really easy to compile well. Lexical closures is also not too bad from an efficiency stand point. Actually, lexical closures are way more efficient than the dynamic scope most Lisps used to have once upon a time. Was the decision to move away from dynamic scope driven by performance? No, not entirely. There were other good reasons to abandon it – but note that Common Lisp and Emacs Lisp still contain it.

So. I hope there are new things to be found in terms of expressiveness. I hope I can find some of them with Ioke. One simple thing is the control over scoping that I’ve mentioned before. Another is implementing local variables as cells on objects, just like all other properties in Ioke. A third is allowing both macros and syntax. Another is the ‘it’ variable in if statement. Another is removing any kind of immediate objects (so numbers and symbols are simple objects just like everything else in Ioke. You can override a method on one specific symbol instance of you want, which isn’t really possible in Ruby.) Another is removing all floats from the language. That data type just doesn’t have a good purpose in Ioke.

But this is just beginning. I hope to see new ways of doing stuff later on. But keep in mind, whenever I talk about some feature of Ioke, I will try to disregard the performance cost of it. Really.



Naming of anonymous, first class code segments


One of the things I’m starting to notice when working on Ioke is that current programming languages doesn’t seem to have enough names for first class code segments. There are of course the usual suspects, that most languages have in some or another form. Depending on the evaluation strategy these things can mean slightly different things, but they’re still very few concepts. The different types I can see at the moment are this

Lambdas: these are anonymous functions that generally tend to be closures. In some languages lambdas doesn’t have to be lexical closures, but can instead have free variables that are dynamically bound. These distinctions doesn’t seem to have different names. In some languages there are only lambdas, such as Scheme. In Ruby lambdas are generally called blocks because they are distinct from the other function primitive – named methods. Ruby blocks are of course not really first class, but they can be reified.

Uhm. Well. That was it. For unnamed, first class code, lambdas seem to be it. Of course there are functions and methods with different semantic meaning in different languages. Methods are generally not closures in the conventional sense – instead they are bound and executed in a dynamic scope depending on the receiver of the method call, so that free variables in the method will be resolved as coming from the receiver of that method call. The difference between functions and method seem to be that a function doesn’t have an explicit receiver, while a method has.

This also explains why anonymous methods aren’t that common. Their main power lies in resolving names dynamically on the receiver, which means it would be quite hard to create a method at runtime that is a lexical closure. How does the implementation know which variables are supposed to be lexically scoped and which should be scoped to the receiver? The only default rule would be to check for current lexical variables at parse time, and assign all other names to the dynamic scope. And that feels kinda cumbersome, and also like it would be hard to intuitively grasp the rules.

In Ioke I have fn/fnx and method. The result of fn and fnx is a LexicalBlock, and the result of a call to method is a DefaultMethod. In Ioke, a method can be anonymous. This means that for those methods you have to explicitly send in the receiver.

So what’s the problem? Well, the problem is that there are several other kinds of code that you might come across in Ioke, and it would be nice to have some kind of naming strategy for them. Take the simple example of doubling numbers in a list. This can be done in two different ways with map: “[1,2,3] map(n, n*2)” and “[1,2,3] map(*2)”. The second example notice that no argument name is given, so assume that the given argument is a message chain that should be applied to each element from the list. The first example works like most lexical code blocks. It will create a new lexical scope that exists with a surrounding pointer to the place where the call to map happens, and then set n in that scope, and finally call the code. So that code could be more or less equivalent to sending in a lexical block that takes one argument. It’s more or less the same thing. The second example is not like that, though. In fact it doesn’t establish any new scope at all. It executes exactly like if you would have executed that code in the calling context. So what should that kind of code be called?

There are other examples, where you send in a code segment like that, and that code will be applied in a totally different context. And there are other variations in if there is a lookup strategy for doing dynamic lookup on the receiver or not, if the lexical scope AND the receiver scope should be mixed together, and so on. All if it is exposed in the language, but I know that as soon as I will start writing a tutorial about this, I will run into the naming issue for real. And I’m not sure about it. Maybe I can just go on and make up names that make sense, but on the other hand I’m not sure if there isn’t already a treasure trove of names already created for different kinds of anonymous code fragments. Ioke can’t be the first language with these kind of features, right?



QCon San Francisco recap


So, I literally just got back from San Francisco, having attended QCon there. As always, it turned out to be a great event, with fantastic people and a very interesting presentations on the schedule. As it turns out, me and Nick’s tutorial was on the afternoon of the Monday, so after that everything could just get better. … In fact, the tutorial ended up working very well. I was happy to have Nick there, so I didn’t have to do all the talking myself. And Nick is much better at Rails than me anyway. So it was definitely a success.

The morning before out tutorial I spent in the Erlang tutorial, which was fun. Francesco is a very good teacher, and we got through lots of material.

Having finished my stuff the first day, I spent the rest of the week cruising around, relaxing and hanging out with nice people. The Tuesday I ended up in Martin’s, Neal’s and Rebecca’s tutorial on DSLs. I’ve been in this tutorial several times, but it just keeps getting better. Especially Rebecca’s pieces on parsing turned out to be very well polished this time. And of course, they are all great presenters.

The Wednesday keynote with Martin and Rebecca was about architecture, and how agile can help architecture groups with their problems as well as help bridge the gap between developers and architects, that often exist in larger organizations. Very well done.

The rest of the Wednesday I sat in the “Ruby in the Enterprise” track. I found out that Merb 1.0 runs very well on JRuby. Jason Seifer pronounced JRuby the winner among all the existing Ruby implementations, which was nice.

And then I had to run away and do an impromptu JRuby presentation at the nearby Girls In Tech Developer Forum.

At the end of the day, I saw Dean Wampler mix up all the free floating ideas about polyglot programming, and talk about it in something that approached a cohesive whole (which I’ve never been able to do). A well done presentation.

I can’t say I got too much out of Kent’s evening keynote, though. I ended up going out for a quiet dinner instead.

The Thursday began Tim Bray talking about the future of storage mediums. This presentation was too far away from my interests to produce anything stronger than a “meh…”.

After that I have a large gap in the schedule – I was supposed to see some presentations, but ended up hacking on a new language grammar with Kresten instead. Great fun of course.

After lunch I sat in on Brian’s talk on concurrency with the fork-join framework. This one I think I’d already seen, so I ended up working on Ioke during it.

Dennis Byrne gave a very cool talk on DSLs in Erlang. There is some stuff you can do that’s totally unbelievable. Best talk of the day. Possibly of the week.

After Dennis talk I’m not sure what I did actually. No memory. Oh, that’s right, I looked at the JUG panel and then went to the speakers dinner. The JUG panel was among others Rod Johnson, Bob Lee and one of the Seam guys. There were some mention of Rails in a way that meant the persons mentioning it hadn’t actually used it. There was also some static typing bias (especially from Bob who said that static typing was objectively better than dynamic typing).

During the Friday I spent some time in the functional language track (and saw a very nice talk about using Haskell to work with music), and I also saw Eric Evans give a very good talk about Strategic Design.

And that was QCon San Francisco. A very good conference, as usual.



Interviewed by Akita


At QCon SF last week, I had the pleasure of being interviewed by Fabio Akita. It turned out to become an almost 2 hour long interview that touched on many geek subjects, and ended up with some fairly detailed content about Ioke. If you’re interested, and have the energy to hear my opinions about loads of programming languages, you can get it here: http://www.akitaonrails.com/2008/11/22/rails-podcast-brasil-qcon-special-ola-bini-jruby-ioke.



The magic it variable in if, or solving regular expressions in Ioke


I’ve spent some time trying to figure out how to handle regular expression matching in Ioke. I really like how Ruby allows you to use literal regexps and an infix operator for matching. That’s really nice and I think it reads well. The problem with it is that as soon as you want to get access to the actual match result, not just a yes or no, you have two choices – either you use the ‘match’ method, instead of ‘=~’. The other solution is to use the semi-globals, like $1, or $&, etc. I’ve never liked the globals, so I try to avoid them – and I happen to think it’s good style to avoid them.

The problem is that then you can’t do the matching as well, and the code doesn’t read as well. I’ve tried to figure out how to solve this problem in Ioke, and I think I know what to do.

The solution is to introduce a magic variable – but it’s distinctly different from the Ruby globals. For one, it’s not a global variable. It’s only available inside the lexical context if an ‘if’ or ‘unless’ method. It’s also a lexical variable, meaning it can be captured by a closure. And finally, it’s a general solution to more things than the regular expression problem. The Lisp community has known about this for a long time. In Lisp the macro is generally called aif. But I decided to just integrate it with the if and unless methods.

What does it look like? Well, for matching something and extracting two values from it, you can do this:

str = "foo bar"
if(#/(.*?) (.*?)/ =~ str,
  "first  element: #{it[1]}" println
  "second element: #{it[2]}" println)

The interpolation syntax is the same as in Ruby.

The solution is simple. An if-method, or unless-method will always create a new lexical scope including a value for the variable ‘it’, that is the result of the condition. That means that you can do a really complex operation in the condition part of an if, and then use the result inside of that. In the case of regular expressions, the =~ invocation will return a MatchData-like object if the match succeeds. If it fails, it will return nil. The MatchData object is something that can be indexed with the [] method to get the groups.

The end result is that the it variable will be available where you want it, but not otherwise. Of course, this will incur a cost on every if/unless invocation. But following my hard line of doing things without regard for optimization, and only with regard for expressability, this seems like the right way to do it.

It’s still not totally good, because it’s magic. But it’s magic which solves a specific problem and makes some things much more natural to express. I’m not a 100% comfortable with it, but I’m pretty close. Your thoughts?



Reverse Cambridge Polish notation for Lisp?


One of the things that still seem unnatural sometimes with Lisp, is the fact that in many cases the actual evaluation need to start quite for into the structure – especially if you’re programming in a heavily functional style. The problem with this is that the way you read code doesn’t go left-to-right. Instead you need to read inside out. To make this less abstract, take a look at this example Lisp code:

(defun foo (x)
  (flux
   (bar
    (conc "foo"
          (get-bar
           (something "afsdfsd")
           (if (= x "foo")
               (conc "foo" "bar")
               (conc "bar" "foo")))))))

As you can see, this is totally bogus code. The nesting makes it possible to identify the parts that will be evaluated first. Compare that to the order it will actually be evaluated. You can see this order by transforming it to Reverse Cambridge Polish notation. This is equivalent – although I know no Lisp that actually does it. As you can see the way you read it, is actually the order it will be evaluated:

(foo (x)
  ((("foo"
     (("afsdfsd" something)
      ((x "foo" =)
       ("foo" "bar" conc)
       ("bar" "foo" conc)
       if)
      get-bar)
     conc)
    bar)
   flux)
  defun)

Well. It’s different, I grant you that. And of course, you need to keep the stack in your head, while reading it. But it’s an interesting experiment.



Ioke /.FAQ


One of the more obvious points from the slashdot posting is that people have a tendency to easily misunderstand what I’m doing here. I’ll paraphrase some of the more common questions/comments from the /. thread and write a little bit about Ioke. This should maybe make some things clearer.

The name?

I didn’t know that the name would cause so many comments, but apparently it did. I personally am quite fond of the name because it can contain lots of different interpretations. The main derivations that go into the name was part including Io in the name, since Io is the main influence on the language. And partly, I liked the symmetry with the Nordic (not only Norse) trickster god Loke (which is generally written Loki in English). Some commenters thought the name was pronounced like ‘joke’. That’s not true. The pronunciation I use is three syllables: ii-oo-kee. Some felt it is a stupid name. I can only disagree – it’s a name that has multiple meanings in multiple languages. I like language trickery, both at the level of programming languages, and at the level of human languages, and I enjoy that this is reflected in the name of the programming language. And the fact that it generates some discussion is actually a testament that the name was well chosen

The JVM?

This is probably the most common misunderstanding, and it’s not at all specific to Ioke – in fact, it’s one of the most common questions about JRuby too, although I think finally this is starting to abate. There are several questions involved in this. The first – why not use Java on the JVM – there isn’t any big difference anyway, right? Well, wrong. I believe that languages are fundamentally different. (Yeah, Turing equivalence, blah blah, greenspuns tenth law, blah blah, I know all those arguments.) My point is, programming languages matter; it’s obvious that they do.

So the second question about the JVM hinges on a misunderstanding what the JVM actually gives you. Or rather, the misunderstanding is that you don’t get much from running on the JVM, except that your language will be much slower than something you coded in C – which obviously is the only manly language you can use. I call this a misunderstanding, and it comes from two camps. The first one is the camp of people who never implemented a modern language from scratch. These people doesn’t know what’s actually necessary to create a language implementation, and thus doesn’t understand how the JVM can help. Many fall into this fallacy without realizing it themselves.

The second camp is language implementors who doesn’t know what a good piece of engineering the JVM actually is, how fast Hotspot can be and how good the GC really is.

Just to give you a quick summary if you are in any of these two camps: The JVM provides – among other things – 4 (soon to be 5) kick ass garbage collectors, that are generally considered among the best in the world. It provides a thread implementation that’s been tuned for 15 years, including giving access to very capable implementations of concurrency and threading primitives. It provides a collection of libraries that is unmatched in size (including JDBC adapters for up to a few hundred different databases) – much of it open source. It provides application servers that give you all the services you would ever need. It provides interoperability with the low level native features when you need it, but you generally doesn’t need it. Of course, the JVM runs on a very wide range of platforms, and in most cases nothing need to be done to port your language to a new operating system.

And it provides an optimizing just-in-time compiler that will profile your code and dynamically optimize and deoptimize the parts of your code to get the best performance.

All of this, you get for free, when choosing to build something for the Java platform. And there’s lots more. Anyway. So why am I not interested in building my own garbage collector? Or my own thread scheduler?

I said something in the InfoQ Ioke interview, that I probably should have phrased a bit differently. Specifically, this part:

…and I don’t understand why people who create languages want to write their own GC…

What I really mean is that too me, when I think about creating a language, I first want to get everything working, including the GC, as quick as possible. When designing a language, the GC is something that should just be there, doing it’s job. Writing a GC is definitely a noble endeavor, but it’s not the main point for most languages – so if you don’t have to do it, it makes it easier to focus on the language design and the core of the implementation.

This all means that the JVM is a fantastic place for Ioke, in my opinion.

Why not Lisp/Smalltalk?

This question was mostly in the form of – paraphrased here – “If you’d like a language with the features you describe, why don’t you just use Lisp or Smalltalk?”. I think the one reason for this is the idea that Lisp and/or Smalltalk are the best versions of these kinds of languages you can ever create, and anything else will be inferior. That might be true, but it’s probably not true. I don’t think that Lisp or Smalltalk is the ultimate language. They show the way, but it’s not the end. I don’t seriously believe that Ioke will be better than any Lisp or Smalltalk, but it might happen. I like it very much right now.

At the same time, Ioke is very close to falling into the Lisp black hole. It doesn’t have S-expressions, but I could definitely argue for it being a dialect of Lisp. That’s not really interesting to do at this point, though. It doesn’t look like Lisp, but it feels like it. The other arguments for why not Lisp/Smalltak I’ve lumped together under the next heading

Why another language?

This question is basically this – there are so many good languages out there already, why create a new language? Or, there are so many languages, why do you think you can create something better? Or, oh no, not another language with stupid features that I will have to maintain. Or, if you like Lisp/Smalltalk/Ruby/Io so much, why don’t you use it instead?

I think all of these reactions are quite new. People haven’t done that many language projects from scratch, and posted about it like I do. At least I don’t think so. Of course, the Kambrian explosion during the 70’s happened in an environment where sharing was natural, and things were quite public. But there seems to have been a different feeling about new languages at that point.

So, why create a new language? First: why not? I’m creating Ioke for myself. If anyone else likes it, that would great, but it’s not the goal. The goal is to see if I can create a language that I like better than all the alternatives, and while I’m doing that see if I can write and discuss all the decisions I make in the process. I would have loved to see someone else do something like this, but I haven’t seen it. Most language creation seem to happen in a closed environment, at least initially. And it’s those first steps that I find really intriguing. So no, I don’t think I can create something better. But there’s always the possibility. And I learn something in the process.

Of course, the language will not become popular. There’s virtually no chance of it, and that’s fine too. And it means you won’t have to use it, or maintain it.

And to the last question – yeah, I like these languages, but I like different parts of them, and they all have things I don’t like. All languages are tradeoffs on different scales, and I would like to see a language that does the tradeoffs that I feel make sense

Announcing it too early?

This was an interesting point. I didn’t think I announced anything – except that I’ve started this project, and want to see how it turns out. As I said earlier, no one is going to force any one to use Ioke.

Lack of beard

This is really bad, actually. Probably the most real detriment to Ioke, of all these points, is the fact that I don’t have a beard. A language designer without a beard won’t work. Of course, the obvious example of Matz is a counter point to it, so maybe there is hope for me anyway. Because growing a beard is something I will not do. =)

In conclusion: Ioke is a language I’m creating for myself. If anyone else likes it, that’s great! But I’m not really announcing anything, when I’m talking about Ioke in this blog. Rather, I’m sharing my experiences, and if anyone’s not interested it’s actually very simple: don’t read this blog.