Archive for the ‘Languages’ Category.

OOPSLA Day 2: Explicit Use-Case Representation in Programming Languages

One of the emerging themes at this conference is the need to move “examples” (and their older siblings, scenarios and use-cases) “into the code,” so that examples/stories/scenarios/use-cases, which are tremendously meaningful to the subject-matter experts, are actually traceable directly into the code, which is tremendously meaningful to, you know, the machine.

I very much enjoyed a talk on “Use-case Representation in Programming Languages,” which described a system called UseCasePy that added a @usecase annotation to Python methods. So you would have:
[/sourcecode]
@usecase(DrawARectangle,DrawALine)
def drawLine(ptA, ptB) … etc …

Now, even if you go no further, you’re doing better than something in a documentation comment, since you can easily write a tool that iterates over all source-code, queries the metadata and builds a database of what classes and methods participate in every use-case: very useful.

Even better, if you have a runtime with a decent interception hook, you can run the program in a particular use-case (perhaps from your BDD test suite, perhaps from an interactive tool, acquire the set of methods involved, and determine, by exercising a large suite of use-cases, metrics that relate the codes “popularity” to user-meaningful use-cases, which could be very helpful in, for instance, prioritizing bug-fixes.

Oh, by the way, apparently we no longer call them “users” or even “domain experts,” they are now “Subject Matter Experts” or even SMEs (“Smees”).

OOPSLA Day 2: More on Dart

I think when people saw that Dart was from Gilad Bracha and Lars Bak there was an expectation that Dart was going to be a grand synthesis: a blazingly-fast NewSpeak-with-curly-brackets. It’s very much not such a language. It doesn’t seem, academically, vastly innovative because it doesn’t add much. But, in truth, optional types are a radical design decision in that they take away runtime aspects that a lot of mainstream programmers expect. (Of course, this raises the question of how to define the “mainstream”…)

Pros and Cons of Mandatory Typing In Descending Order of Importance (per Gilad Bracha):

Pros:

  • machine-checkable documentation
  • types provide conceptual framework
  • early error detection
  • performance advantages

Cons:

  • expressiveness curtailed
  • imposes workflow
  • brittleness

Having said that, I attended a lecture in which someone, perhaps from Adobe, measured the performance impact of optional typing. Their conclusion, although admittedly done on the troublesome-ly small and artificial SunSpider benchmarks, was that the performance penalty of implicit types amounts to 40% (with a very large standard of deviation). That “feels” about right to me — definitely significant but not the overwhelming performance benefit you might get from either parallelization or an algorithmic change.

OOPSLA Day 2: Gilad Bracha on Dart

Gilad Bracha started the day’s Dynamic Languages Symposium with an invited talk on Dart, a new Web programming language (read: JavaScript replacement) in which “Sophisticated Web Applications need not be a tour de force.”

OOPSLA is attended by academics, who are typically less interested in the surface appearance of a program (they’ve seen just about variation) and more interested in semantic questions whose impact in the real-world might not be felt for many years. So Bracha begins his talk by disavowing the “interesting-ness” of Dart: it’s a language whose constraints are entirely mundane:

  • Instantly familiar to mainstream prorgammer
  • Efficiently compile to JavaScript

(Personally, I take it as a damnation of the audience that “Of interest to 90% of the programming world” is not of importance, but the gracious interpretation is that these are the trail-blazers who are already deep in hostile territory.)

The gist of Bracha’s talk was on Dart’s “optional types” semantics. The great takeaway from this, I think, is that:
“Dart’s optional types are best thought of as a type assertion mechanism, not a static type system”
which allows for code that can make your blood run cold; what certainly looks like a statement of programmer intention (“this variable is of type Foo”) can be blithely trod over at runtime (“in fact, this variable is of type Bar”) without so much as a by-your-leave.

The type expression is only evaluated at compilation time and, if the developer puts the compiler in “development” mode, you get warnings and errors. But once out of development mode, there are no runtime semantics of the type expressions. They have no behavior, but on the other hand, they have no cost. And, argues Bracha, this seemingly extreme position is important to support a language that remains truly dynamic and does not “put you in a box” wherein the type system becomes a restriction on expressiveness.

One of the seemingly-obscure corners of language design are the semantics of generics (the building blocks of collection classes). Generics in Dart are reified and covariant, which to an academic means “the type system is unsound.” Bracha acknowledges this and says that he’s “given up” on fighting this battle.

Another interesting design element of Dart is its recognition that the “classic” object-oriented constructor is a failed abstraction that only allows for “I want to allocate a new instance…” instead of common scenarios such as “I want to get an object from cache,” “I want an object from a pool of a specific size (often 1),” etc. So you can declare something that looks an awfully lot like a classical constructor, but in fact is “allowed” to return whatever the heck it wants. (I put “allowed” in quotes because, remember, all this type stuff is just epiphenomenal <– mandatory big word every paragraph!)

The lack of mandatory types preclude the creation of type classes or C#-style extension methods. Those are grating, but really of concern to me is that their lack also precludes type-based initialization. This leads to the disturbing design that variables will have the value null until they are assigned to; a “disturbing design” that is standard in the mainstream but hated by all.

…off to lunch, more later…

OOPSLA Day 0

I am in Portland for OOPSLA / SPLASH, a conference that is my sentimental favorite. I think my first OOPSLA was in New Orleans circa 1990 and OOPSLA Vancouver 92 is filled with memories (mostly because Tina came and we dove Orcas Island in wetsuits).

OOPSLA is traditionally the big academic conference for programming language theory and implementation. When I was a magazine editor and track chair for the Software Development Conferences, OOPSLA is where I trolled for new fish — concepts and writers that were ready for trade exposure. That’s no longer my business, and I wonder if I’ll get the same thrill from attending that I used to.

The program looks promising and I’ve just spent a few hours going over the papers in the proceedings DVD (no more phonebook-sized proceedings to bow the bookshelves, but I’m sure I can still steal some article ideas…).

I’m happy by the late addition of talks by Gilad Bracha and Lars Bak on Dart, the new programming language from Google. I’m unabashedly a fan of Bracha’s NewSpeak and the one time I heard Bak talk, I said he was “dynamite….Concrete, informed, impressive….” so I’m favorably disposed to like their language, even if it does have null (and not just have it, but

In Dart, all uninitialized variables have the value null, regardless of type. Numeric variables in particular are therefore best explicitly initialized; such variables will not be initialized to 0 by default.

Which strikes me as flat-out crazy, reiterating Tony Hoare’s “Billion-Dollar Mistake.”
Early reaction to Dart has been pretty harsh, it will be interesting to discuss it in-person (where the tone will be 1000x more reasonable and respectful than on the Internet).

Getting To Know Scala: Project Euler Primes

Prime numbers are not my thing, but generating them is a common task in the early Project Euler problems. The one algorithm I know for generating primes is the Sieve of Eratosthenes, which I defined in Scala as:

def successor(n : Double) : Stream[Double] = Stream.cons(n, successor(n + 1))

def sieve(nums : Stream[Double]) : Stream[Double] = Stream.cons(nums.head, sieve ((nums tail) filter (x => x % nums.head != 0)) )

val prime_stream = sieve(successor(2))

The first function is the only function that I’ve ever written that I’m sure is properly “functional.” It’s stuck in my head from circa 1982 LISP. It uses Scala’s Stream class, which is like a List but is “lazily evaluated,” in other words, it only calculates the next value in the List when it’s needed (the Stream pattern is to create a List whose head is the next value and whose tail is a recursive call that, when executed will produce the next value).

The 2nd function sieve is my take on the Sieve of Eratosthenes. It too returns a Stream of primes. (By the way, the reason I use Double rather than an Int or Long is that one of the early Project Euler problems involves a prime larger than LONG_MAX.)

In case you’re not familiar with the algorithm, the Sieve is conceptually simple. Begin with a list containing all positive integers starting at 2 (the first prime) [2, 3, 4, ...] . Remove from the list every multiple of your current prime. The first number remaining is the next prime. For instance, after removing [2, 4, 6, ... ], the first number remaining is 3. Prime! So remove [3, 6 (already removed), 9, ... ]. Since 4 was removed as a multiple of 2, the next available is 5. Prime! Remove [5, 10 (already removed), 15 (already removed), ...] …

The 7th Project Euler problem is “What is the 10001st prime number?” Unfortunately,

scala> prime_stream take 10001 print
2.0, 3.0, 5.0, 7.0, ...SNIP ... 29059.0, 29063.0, java.lang.OutOfMemoryError: Java heap space
 at scala.Stream$cons$.apply(Stream.scala:62)
 at scala.Stream.filter(Stream.scala:381)
 at scala.Stream$$anonfun$filter$1.apply(Stream.scala:381)
 at scala.Stream$$anonfun$filter$1.apply(Stream.scala:381)
 at scala.Stream$cons$$anon$2.tail(Stream.scala:69)
 at scala.Stream$$anonfun$filter$1.apply(Stream.scala:381)
 at scala.Stream$$anonfun$...

That will never do. Obviously, I could run Scala with more heap space, but that would only be a bandage. Since a quick Google search shows that the 1000th prime number is 104,729 and I’m running out of heap space near 30K, it seems that “messing around with primes near the 10Kth mark” requires some memory optimization.

Converting the Sieve

If I really wanted to work with very large sequences of primes, I should certainly move away from the Sieve of Eratosthenes. But I’m not really interested in prime number algorithms, I’m interested in the characteristics of the Scala programming language, so I’m going to intentionally ignore better algorithms.

My first thought was “OK, I’ll allocate a chunk of memory and every time I find a prime, I’ll set every justFoundPrime-th bit to 1.” But that would depend upon my allocated memory being sufficient to hold the nth prime. With my Google-powered knowledge that the 10001st prime is only 100K or so, that would be easy enough, but (a) it seemed like cheating and (b) it would require a magic number in my code.

My next thought was “OK, when I run out of space, I’ll dynamically allocate double the space– no, wait, I only need justFoundPrime-(2 * justFoundPrime) space, since I’ve already checked the numbers up to justFoundPrime.”
My next thought was “And really I only need half that space, since I know 2 is a prime and I can just count by 2…And, y’know, I know 3 is prime too, so I can check–” At which point, I engaged in a mental battle over what was appropriate algorithmic behavior.

On the one hand, I didn’t want to change algorithms: if I moved from the Sieve to a slightly better algorithm, then wasn’t it Shameful not to move to at least a Quite Good algorithm? On the other hand, the instant I opened the door to allocating new memory, I committed to keeping around the list of already-discovered primes, since I would have to apply that list to my newly-allocated memory. But if you have a list of numbers, checking if your candidate number is a multiple of any of them can be done without consuming any additional memory. But is it the same algorithm? Isn’t the Sieve fundamentally about marking spots in a big array?

Finally, I decided that checking a candidate number against the list of already-discovered primes was the Sieve algorithm, just with a smallest possible amount of memory allocation — one number. (By the way, did you read the article in which scientists say that rational thought is just a tool for winning arguments to which you’re already emotionally committed?)

Here then, is what I wrote:

def multiple_of = (base : Long, target : Long) => target % base == 0;

val twoFilter = multiple_of(2, _ : Long)
val threeFilter = multiple_of(3, _ : Long)

println(twoFilter(4))
println(twoFilter(5))
println(twoFilter(6))
println(threeFilter(4))
println(threeFilter(5))
println(threeFilter(6))

The first function multiple_of is a function literal (?) that returns true if the target is a multiple of the base. The next two lines, where I define twoFilter and threeFilter are  an example of the functional idiom of partial function application (I think — “currying” is the use of partial function application to accomplish a goal, right?).

This is an undeniably cool feature of functional languages. Without any fuss, these lines create new functions that require one less argument to have their needed context. Once you have a twoFilter, you don’t need to keep the value “2″ around to pass in. Which might not seem like a big win, since a function named twoFilter or threeFilter is no more compact than calling multiple_of(2, x) or multiple_of(3,x). But…

def filter = (x : Long) => multiple_of(x, _ : Long);

val fs = List(filter(2), filter(3))
for(f <- fs){
   println("Eight is a multiple of this filter: " + f(8))
}

OK, now that’s nice and compact! Now we have a new tk function literal? tk called filter and rather than have a bunch of variables called twoFilter and threeFilter and fiveFilter, we just have a List of filters. With such a list in hand, it’s easy to figure out which numbers in a list are relatively prime:

def relatively_prime(fs : List[(Long)=>Boolean], target : Long) : Boolean = {
 for(f <- fs){
    if(f(target)){
      return false;
    }
 }
 return true;
}

println("4 is prime? " + relatively_prime(fs, 4))
println("5 is prime? " + relatively_prime(fs, 5))

val list = List[Long](2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
println(list.map(relatively_prime(fs, _)))

Which leads to a simple recursive function to find the next prime:

def next_prime(fs : List[(Long)=>Boolean], x : Long) : Long = {
 if (relatively_prime(fs, x)) {
    return x
 }
 return next_prime(fs, x + 1)
}

println(next_prime(fs, 4))
println(next_prime(fs, 8))

Which leads to our solution:

def primes(fs : List[(Long)=>Boolean], ps: List[Long], x : Long, nth : Long) : List[Long] = {
   if(ps.size == nth){
      return ps;
   }

   val np = next_prime(fs, x)
   val sieve = fs ::: List(filter(np));
   primes(sieve, ps ::: List(np), np + 1, nth);
}

println("Missing 3 because its in fs" + primes(fs, List[Long](2L), 2, 8))
println((primes(List(filter(2)), List(2L), 2, 8) reverse) head)

def nth_prime(nth : Long) : Long = {
   (
      primes(
         List(filter(2)),
         List(2L),
         2,
         nth
     ) reverse
   ) head
}

println(nth_prime(8))
println("The 10001st prime is " + nth_prime(10001))

Knowing Scala (Intermission)

I’m getting to the point in my Scala understanding where I’m making small commits to our Very Important Project at work. I ended up wasting four hours of work the other day because I put stuff in the wrong place and then spent a lot of time reorganizing things. In the context of FP, which puts such an emphasis on composition, “reorganizing” seems to this learner more tedious than reorganizing an OOP program.

Where to put your stuff” is a big deal for a programming paradigm, and it seems to me that OOP is significantly better than FP in guiding you towards structure. The FP proponents are always talking about keeping things small, but a real system is going to be large and it seems to me that OOP class structures provide a lot of guidance.

Since my organization has chosen Scala as our language, I can use OOP. But when you’re learning the FP mindset, there’s so much emphasis on compressing functions and minimizing your working set that it’s very natural to make a mistake, and write a series of functions that combine to do the operation at hand only to realize (as I did) that if only you had located the function over here, in this class, you could write fewer functions, with simpler combinations, to accomplish the same goal.

Hmm…

I always try to remember my experience learning OOP. I was a C programmer and had just been hired as the Product Review Editor at Computer Language Magazine. OOP was the hot new thing and I installed a brand new copy of Smalltalk/V 286 and diligently worked through the tutorial (which involved turtle graphics, as I recall). Everytime I had a few minutes I’d sit and try to understand “where the main() is.” And I just didn’t get it. I could type in code and it would work but I just had no idea how it was supposed to help my programming.

After about six weeks I was panicked, thinking “OMG, I don’t understand this subject that’s the topic of more and more of our articles.” I decided to break the shrink-wrap on Zortech C++ (the first C++ compiler for DOS) and simply use C and laugh knowingly every time someone mentioned OOP. And from almost the first minute of firing up the C++ compiler, I got objects. What had been obscure in a pure environment was crystal clear in a hybrid environment where what had seemed like obscure topics could be applied to the everyday challenges of writing C code.

And even more interesting, after working in C++ for awhile, when I fired up my Smalltalk environment again (perhaps for the Smalltalk/v 386 release), I absolutely loved it. It took C++ for me to understand the programming value of OOP and, once that was internalized, the environmental benefits of Smalltalk were many and obvious.

I try to keep this in mind with Scala. Right now, I’ll admit to not feeling enthusiastic about Scala. I’ve yet to feel “Oh, I couldn’t have done that in Ruby” while it seems like I bump into type-system limits and syntactical weirdness quite often (the type-erasure of generics in the JVM seems to mean that “finger typing” is not uncommon and I’ve yet to internalize Scala’s logic about parentheses, braces, and new-lines). But, if history is a guide, perhaps I’ll return to Ruby in a few months and suddenly say “OMG, in Scala I could just…”

We’ll see.

Knowing Scala: Exercise 1

Taking my own 15 Exercises to Know A Programming Language as a starting point for my exploration of Scala…

The first set of exercises are right up the alley of a language with pattern-matching and list-processing:

Write a program that takes as its first argument one of the words ‘sum,’ ‘product,’ ‘mean,’ or ‘sqrt’ and for further arguments a series of numbers. The program applies the appropriate function to the series.

The first thing I did was write the functions:

val args = List(1, 2, 3, 4, 5)
args.foldLeft(0)(_+_) //Sum
args.foldLeft(1)(_*_) //Product
args.sort(_ < _)(if(args.length % 2 == 0) args.length / 2 - 1 else args.length / 2) //Median
args.map(Math.sqrt(_)) //Sqrt

Here the list-processing functions (highlighted in red) shine. The foldLeft() family of functions, also known as reduce, inject, or aggregate, applies a predicate to the elements of a data structure, accumulating a value. It’s hard to imagine cleaner code than what we have for the ‘sum’ and ‘product’ challenges. Similarly, the map() function is similarly clean-as-a-whistle for the ‘sqrt’ challenge. The ‘median’ challenge I’m less thrilled about: Passing in a custom comparator predicate to sort() is lovely, but my fingers typed in the C-language ternary operator :? and I was sorry to find that Scala doesn’t have it.

A big win for Scala is that I typed these in the Read-Evaluate-Print-Loop aka interactive console rather than having to deal with the overhead of a ‘real’ program and a edit-compile-test loop.

Moving on, the complete program follows:

object Main
{
	def main(args : Array[String])
	{
		val argList = List.fromArray(args)
		val op = opMatch(argList.head)
		val numList = argList.tail.map(java.lang.Double.parseDouble(_))
		val result = op(numList)
		print(result)
	}

	def sum(args : List[Double]) : Double = { args.foldLeft(0.0)(_+_) }

	def product(args : List[Double]) : Double = { args.foldLeft(1.0)(_*_) }

	def median(args : List[Double]) : Double =
	{
			args.sort(_ < _)(if(args.length % 2 == 0) args.length / 2 - 1 else args.length / 2)
	}

	def sqrt(args : List[Double]) : List[Double] = { args.map(Math.sqrt(_)) }

	def opMatch(arg : String) : (List[Double]) => Any =
	{
		arg match
		{
			case "sum" => return sum
			case "product" => return product
			case "median" => return median
			case "sqrt" => return sqrt
			_ => throw new java.lang.IllegalArgumentException("Unrecognized operator " + arg)
		}
	}
}

Let’s see… The translation of the REPL code into functions was very straightforward, although I have to admit to being somewhat disappointed that I could not use a type more abstract than Double. I don’t know if I could define a trait and then apply it retroactively to types in the java.lang package.

opMatch() shows some functional goodness — it’s declared as a function that takes a String and return a function that takes a List of Doubles and returns Any kind of object.

I’m not sure if I could do something more precise for my needs, like “returns a Double or List[Double]“. The pattern-matching in opMatch() is nice but not advanced.

If you have any observations to share, please comment below…

FunLoft: Reactive Concurrent Programming Language

It sounds like someone designed a programming language with the express intention of intriguing me:

FunLoft is an experimental language for concurrent programming, designed with the following objectives:

  • make concurrent programming simpler by providing a framework with a clear and sound semantics.
  • provide a safe language, in which, for example, data-races are impossible.
  • control the use of resources (CPU and memory); for example, memory leaks cannot occur in FunLoft programs, which always react in finite time.
  • have an efficient implementation which can deal with large numbers of concurrent components.
  • benefit from the real parallelism offered by multicore machines.

… FunLoft is based on a programming model which is a variant of reactive programming

Hau’oli Mahahiki Hou!

2009 was definitely a mixed bag for us, as was, I suppose, the “aughts.”In other words, life.

Out with the old:

img_0191

in with the new!

img_1219

“You Put In Other Details”

Young Denis grew up to be every client you’ll ever develop software for:

3936544529_02f007a1fe_o