Wednesday, February 24, 2010

Final classes and platform-specific vocabularies

Final classes

I added final classes, in the Java sense. Attempting to inherit from a final class raises an error. To declare a class as final, suffix the definition with "final", in the same manner that words can be declared "inline" or "foldable":

TUPLE: point x y z ; final

The motivation for final classes was not obvious. There are three main reasons I added this feature.

Unboxed tuple arrays used to have the caveat that if you store an instance of a subclass into a tuple array of a superclass, then the slots of the subclass would be "sliced off":

TUPLE: point-2d x y ;

TUPLE-ARRAY: point-2d

TUPLE: point-3d < point-2d z ;

SYMBOL: my-array

1 my-array set

1 2 3 point-3d boa my-array get set-first

my-array get first .
=> T{ point-2d { x 1 } { y 2 } }

This warranted a paragraph in the documentation, and vigilance on the part of the programmer. Now, tuple arrays simply enforce that the element class is final, and if it is not, an error is raised. This removes a potential source of confusion; it is always nice when written warnings in the documentation can be replaced by language features.

Joe Groff's typed library has a similar problem. This library has a feature where input and output parameters which are read-only tuples are passed by value to improve performance. This could cause the same "slicing problem" as above. Now, typed only passes final read-only tuples by value.

Finally, there was a previous mechanism for prohibiting subclassing, but it wasn't exposed as part of the syntax. It was used by the implementation of struct classes to prevent subclassing of structs. The struct class implementation now simply declares struct classes as final.

Typed words can now be declared foldable and flushable

Factor has a pretty unique feature; the user can declare words foldable (which makes them eligible for constant folding at compile time if the inputs are all literal) or flushable (which makes them eligible for dead code elimination if the output results are not used). These declarations now work with typed words.

Platform-specific vocabularies

I added a facility to declare what operating systems a vocabulary runs on. Loading a vocabulary on an unsupported platform raises an error, with a restart if you know what you're doing. The load-all word skips vocabularies which are not supported by the current platform.

If a platforms.txt file exists in the vocabulary's directory, this file is interpreted as a newline-separated list of operating system names from the system vocabulary. This complements the existing vocabulary metadata for authors, tags, and summary.

This feature helps the build farm avoid loading code for the wrong platform. It used to be that vocabularies with the "unportable" tag set would be skipped by load-all, however this was too coarse-grained. For example, both the curses and DirectX bindings were tagged as unportable, and so the build farm was not loading or testing them on any platform. However, curses is available on Unix systems, and DirectX is available on Windows systems. With the new approach, there is a extra/curses/platforms.txt file listing unix as a supported platform, and the various DirectX vocabulary directories have platforms.txt files listing windows.

Tuesday, February 16, 2010

Factor 0.92 now available

I'm proud to announce the release of Factor 0.92. This release comes two years after the last release, 0.91. Proceed to the Factor website or directly to downloads directory to obtain a copy.

More than 30 developers have contributed code to this release. I would like to thank all of the users and contributors for their efforts; Factor would not be at the stage it is today without your help.

Since there have been so many changes since the last release, the below changelog is only an incomplete summary. In particular, there have been many incompatible syntax and core library changes since the last release.

The next release cycle will not last as long as this one; from this point on, I'm planning on having monthly releases or so. There will be fewer incompatible language changes in the upcoming months; the core language has almost been finalized at this point.

Language improvements

Notable new libraries

  • db: Relational database access library with SQLite and PostgreSQL backends (Doug Coleman)
  • furnace: web framework that runs (Slava Pestov)
  • io.encodings: Extensive support for I/O encodings. All operations that transform strings to bytes and vice versa now take an encoding parameter (Daniel Ehrenberg)
  • unicode: Unicode-aware case conversion, character classes, collation, breaking, and normalization (Daniel Ehrenberg)
  • regexp: DFA-based regular expression matching. Supports Unicode and compiles to machine code (Daniel Ehrenberg)
  • secure sockets with OpenSSL (Slava Pestov)
  •, io.monitors: File system metadata and change monitoring (Doug Coleman, Slava Pestov)
  • images: loading and displaying BMP, TIFF, PNG, JPEG and GIF images (Doug Coleman, Marc Fauconneau)
  • gpu, game: Frameworks for GPU rendering and game development using OpenGL (Joe Groff)
  • math.floats.env: advanced IEEE floating point features (Joe Groff)
  • math.blas, alien.fortran: bindings to BLAS linear algebra library, built on top of a new Fortran FFI
  • math.vectors.simd: high-performance SIMD arithmetic with support for SSE versions up to 4.2 (Joe Groff)
  • specialized-arrays, specialized-vectors, classes.struct: high-performance support for unboxed value types (Slava Pestov, Joe Groff)

Implementation improvements

Editor integration

  • fuel: Factor's Ultimate Emacs Library, a powerful emacs mode for editing Factor code. See misc/fuel/README in the Factor download for details (Jose A Ortega)