Tuesday, July 31, 2018

Factor 0.98 now available

“Even though you're growing up, you should never stop having fun.” - Nina Dobrev

I'm very pleased to announce the release of Factor 0.98!

OS/CPUWindowsMac OS XLinux

Source code: 0.98

This release is brought to you with almost 4,300 commits by the following individuals:

Alexander Ilin, Arkady Rost, Benjamin Pollack, Björn Lindqvist, Cat Stevens, Chris Double, Dimage Sapelkin, Doug Coleman, Friedrich von Never, John Benediktsson, Jon Harper, Mark Green, Mark Sweeney, Nicolas Pénet, Philip Dexter, Robert Vollmert, Samuel Tardieu, Sankaranarayanan Viswanathan, Shane Pelletier, @catb0t, @hyphz, @thron7, @xzenf

Besides several years of bug fixes and library improvements, I want to highlight the following changes:

  • Improved user interface with light and dark themes and new icons
  • Fix GTK library issue affecting some Linux installations
  • Support Cocoa TouchBar on MacOS
  • Factor REPL version banner includes build information.
  • Bindings for ForestDB
  • New graphical demos including Minesweeper, Game of Life, Bubble Chamber, etc.
  • Better handling of "out of memory" errors
  • Improved VM and compiler documentation, test fixtures, and bug fixes
  • Much faster Heaps and Heapsort
  • Support for Adobe Brackets, CotEditor, and Microsoft Visual Studio Code editors
  • On Mac OS X, allow use of symlinks to factor binary
  • Lots of improvements to FUEL (Factor's emacs mode)

Some possible backwards compatibility issues:

  • Flattened unicode namespace (either USE: ascii or USE: unicode).
  • Unified CONSTRUCTOR: syntax to include generated word name
  • Returning a struct by value with two register-sized values on 64bit now works correctly
  • Since shutdown hooks run first, calling exit will now unconditionally exit even if there is an error
  • On Windows, don't call cd to change directory when launching processes; there is another mechanism for that
  • In libc, renamed (io-error) to throw-errno
  • In match, renamed ?1-tail to ?rest
  • In sequences, renamed iota to <iota>
  • In sequences, renamed start/start* to subseq-start/subseq-start-from
  • In syntax, renamed GENERIC# to GENERIC#:
  • Improve command-line argument parsing of "executable"
  • Make buffered-port not have a length, because of problem with Linux virtual files and TCP sockets
  • Fix broken optimization that made floats work for integer keys in case statements
  • Growable sequences expand by factor of 2 (instead of 3) when growing
  • Removed support for "triple-quote" strings

What is Factor

Factor is a concatenative, stack-based programming language with high-level features including dynamic types, extensible syntax, macros, and garbage collection. On a practical side, Factor has a full-featured library, supports many different platforms, and has been extensively documented.

The implementation is fully compiled for performance, while still supporting interactive development. Factor applications are portable between all common platforms. Factor can deploy stand-alone applications on all platforms. Full source code for the Factor project is available under a BSD license.

New Libraries:

Improved Libraries:


Unknown said...

Hi factor team,

Thanks very much for the new release,
What are the plans for release 0.99 or even 1.0?


George Cherevichenko said...
This comment has been removed by the author.
George Cherevichenko said...

Could you tell me, where is matrix multiplication?


mrjbq7 said...


Look at m* and related math words.

George Cherevichenko said...

John, tell me please. I want to use map-reduce to get 2*3 + 2*3
I write
: fff ( -- n m )
2 { 3 3 } [ [ dup ] dip * ] [ + ] map-reduce ;
and get 24. Why?

George Cherevichenko said...

Stack effect of map-reduce
..a map-quot: ( ..a elt -- ..b intermediate ) reduce-quot: (..b prev intermediate -- ..a next ) -- ..a result
Can we apply reduce-quot only after two applying of map-quot? How can we apply map-quot to the second element?

George Cherevichenko said...

Sorry, stack effect is
..a seq map-quot
and so on. But all problems are the same.

mrjbq7 said...

The map-reduce will "map" over the first two values, before reducing them, you can see that by putting a breakpoint in:

2 { 3 3 } [ B dupd * ] [ B + ] map-reduce

When you are trying to use values under the stack, there are various ways, one is to curry them into the quotation:

2 { 3 3 } swap '[ _ * ] [ + ] map-reduce

Or pass them as a named value:

:: fff ( x -- y )
{ 3 3 } [ x * ] [ + ] map-reduce ;

Feel free to send me an email if you want to start a discussion, join Gitter.im, Discord, Slack, the mailing list, or file a bug on GitHub and we can chat there -- I don't always notice comments on this blog promptly.

George Cherevichenko said...

John, optimizing compiler does not check stack effect properly. Can I discuss it with Pestov?


mrjbq7 said...

Feel free to email the mailing list or open a GitHub issue. Or describe the issue here. I’d love to address whatever the deficiency is. Slava isn’t as actively involved these days, but could be contacted if we had a sufficient test case that isn’t easy to resolve.

George Cherevichenko said...

Stack effect of map-reduce
..a seq map-quot: ( ..a elt -- ..b intermediate ) reduce-quot: (..b prev intermediate -- ..a next ) -- ..a result
Try to compute 2*3+2*3
2 { 3 3 } [ dupd * ] [ + ] map-reduce
Why we obtain 24? Because the first [ dupd * ] put the result 2*3=6 to stack
2 6 { 3 3 }
The second [ dupd * ] get 6*3=18
The proper stack effect of map-reduce is
seq map-quot: ( elt -- intermediate ) reduce-quot: ( prev intermediate -- next ) -- result
but compiler does not give an error. I am trying to find the error in the vocab stack-checker and want to discuss it with Pestov (in Russian)

mrjbq7 said...

It looks like the map quotation is applied twice, and the arguments are preserved on the stack for the second call, that's not quite what the stack effect implies, so that is a bug of sorts. I will look at this.

mrjbq7 said...

This is a possible fix:


George Cherevichenko said...

Hi, John. I think the "right" definition of map-reduce is following
: (map-reduce) ( acc seq map-quot reduce-quot -- acc )
[ dup length 0 swap ] 2dip '[ [ swap n-th @ @ ] 2keep 1 + ] times 2drop ;
but it doesn't work:) I have a strategic plan: replace all recursive definitions with "times" (mathematicians calls it "primitive recursion") and rewrite "stack-cheker" vocab to do correct stack-checking.