My hobbyist coding updates and releases as the mysterious "Mr. Tines"

Tuesday 26 May 2009

The Jython/Scala stack revisited

After last year's experiments, another refinement in the process of getting the two languages to talk, this time from inside NetBeans.

Last year, doing everything from the command line, I got across the language bridge by adding the scala jar to the classpath. Inside NetBeans, you get a little way along the road by adding the scala-library jar and the jars from the scala layer of the stack to the project Python Path. This will let you import types, and see that traits have the expected members. Classes, however, appear as None valued.

For development purposes, you can, instead of adding the jars to the classpath, add them to sys.path instead, like:

sys.path.append(r'C:\Users\Tines\.netbeans\6.5\scala\scala-2.7.3.final\lib\scala-library.jar')
sys.path.append(r'C:\Users\Tines\Documents\FTPStack\FTPlib\dist\FTPLib.jar')

For a real app, rather than hard-coding, these file paths could be supplied as arguments.

Scala companion objects, with names ending in $ don't show up at all in the namespaces when imported into Jython, so anything static-like will have to be accessed through a throwaway class instance.

Monday 11 May 2009

Scala is not C#

Took a while to debug what was going wrong here

        val tmp = toUnsigned(leftSide.digits(i)) * toUnsigned(rightSide.digits(j)))
           +  toUnsigned(da(k)) + carry

because it compiles, silently discarding the fact that this is two statements, the second with no immediately apparent side-effects.

It should be more like

        val tmp = (
          (toUnsigned(leftSide.digits(i)) * toUnsigned(rightSide.digits(j))) +
          toUnsigned(da(k)) + carry)

where the parentheses and the trailing operators give a belt-and-braces approach to delineating the statement boundaries.

Saturday 9 May 2009

Integrating Scala with Erlang -- Initial steps

So, I've started a parallel implementation of jinterface 1.5 in Scala, the idea being

  1. To teach myself Scala by doing
  2. To experiment with the actor-based concurrency as a counterparty to the Erlang model
  3. 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.