So, I've started a parallel implementation of jinterface 1.5 in Scala, the idea being
- To teach myself Scala by doing
- To experiment with the actor-based concurrency as a counterparty to the Erlang model
- To experiment with Scala as a dual VM technology
So far, just the term-representation classes, and the start of the Input/Decode and Output/Encode part; and some unit tests, only for Atom so far.
I am impressed at how much I've been able to do without bringing in platform types that I will need to abstract out. What was memory-based I/O in Java or C# becomes Seq[Byte] or Queue[Byte] as appropriate and basing all exceptions off the shared name Exception root class gets rid of any dependence on concrete subclasses. It's only BigInt that is a known problem so far, where I'll need to factor out a platform abstraction later. Of course abstracting ZLib support is a task lurking in the near future, as well.
The first noticeable difference from trying to tidy the C#2 port of an older Java version is that the functional style and rich library support make a lot of previously long-winded support methods significantly more expressive. Contrast the Erlang list (of integer values) to String
public System.String StringValue { get { char[] body = new char[Arity]; ReadOnlyCollection<IObject> e = Elements; for (int i = 0; i < Arity; ++i) { Integer v = e[i] as Integer; if (null == v) body[i] = '?'; else { System.Diagnostics.Debug.Assert(v != null && v.Value != null); char? c = v.Value.ToChar(); if (null == c) c = '?'; body[i] = (char)c; } } return new string(body); } } // and elsewhere public char? ToChar() { try { return (char)System.UInt16.Parse(this.ToString(), System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture); } catch (OverflowException) { return null; } }
with
def AsString = { (Elements map List.AsChar).mkString } // and elsewhere def AsChar(obj : IObject) = obj match { case c : Integer if c.Value < (Integer.Zero + Char.MinValue.toInt) => '?' case c : Integer if c.Value >= (Integer.Zero + Char.MaxValue.toInt) => '?' case c : Integer => c.Value.intValue.toChar case _ => '?' }
Yes, using C#3's functional extensions, that too could be simplified; this is really the Java equivalent of doing that.
Code drop on the MediaFire page.
No comments:
Post a Comment