Sorin Miklós Zsejki | 16 Jul 19:46
Picon

Is "typecase self of" a syntax error?

If I have:

component Main
export Executable

trait T
    m() = typecase self of
        T => "T"
        else => "else"
    end
end

run(args) = ()

end

I get "/path.../Main.fss:5:24: Syntax Error". Is it an error? If I
have "typecase s = self of" instead, I don't get the error message.

Unrelated to this, I've seen I pass "-Dfortress.static.analysis=1"
when I call fortress. Probably this was documented sometime somewhere.
Does this still have an effect? If so, does it have the same effect as
running typecheck before?

Michael Lesniak | 5 Jul 10:12
Picon
Favicon

Implementation of Red-Black Trees

Hello,

First, sorry, if it is the wrong mailing list, I wasn't sure which to
choose, since my question is neither language nor implementation
specific and there's no library mailing list.

My name is Michael Lesniak and I'm working at the parallel programming
research group of the university of Kassel. I'm interested in writing
an implementation of Red-Black Trees (and maybe other collections) in
Fortress and evaluating my observations. But there are still some
questions:

- Is there any prior work?
- (more general) do I have to consider anything special?
- Is it advisable to get full repository access, i.e. sign the Sun
Contributor Agreement? (This won't be a problem)

Fortress seems to grow into a really exciting language and I'd like to
help it grow :)

Best regards,
Michael

Jan-Willem Maessen | 2 Jul 17:47
Picon
Favicon

Mixing # and : in strided ranges

Folks who have been tinkering with Fortress may have noticed that  
strided ranges of the form lower:upper:stride haven't yet been  
implemented.  I'm in the process of thinking about how this might best  
be done.

The big question in my mind is how the # and : notations interact with  
a stride.  My ideal semantics look something like the following:

l:u:s  yields l, l+s, l+2s, ...  <= u (so u is a rigid upper bound on  
the enumeration).
l#n:s  yields l, l+s, l+2s, ... l+(n-1)s
    (so that n exactly dictates the number of items enumerated).

I raise this issue in part to get people's opinions, but also because  
I'll be implementing this by simply overloading the : operator, so  
that it should be possible to write something like:
   myArray.indices():2
And stride through the indices of myArray by 2.  But this will require  
some major revisions to the internals of the types involved; at  
present we do not distinguish l#s from l:(l+s-1) and we would need to  
make that distinction in order for this code to work as we might expect.

-Jan-Willem Maessen

Danielle Fong | 29 Jun 14:58
Picon
Gravatar

Hello ProjectFortress! Questions and discussion on scripting, pattern matching, goal-directed programming, and other nondeterministic idioms.

Hello Project Fortress!

I've been lurking around the project for a while now. As someone who's done a lot of scientific programming, I was routinely dismayed by the linguistic support for what I wanted to do, and set to work learning language design, sometime around last summer. I made a list of things I wanted to try, things I thought I'd really want when I got back to scientific programming. Happily, once I discovered Fortress, I found it had most of them, and many more times good ideas that I hadn't expected -- especially in parallelism. And so I am very excited.

I'm especially glad that you're using mathematical notation. There just weren't enough operators in other languages for everyone to do what they wanted. But the improvements in readability are enormous. And, we can't forget Kernighan's law:

"Debugging is twice as hard as writing the program, so if you write the program as cleverly as you can, by definition, you won't be clever enough to debug it."

That's a big problem people encounter in scientific code. It's not impossible to write, in current languages, but it's really, really hard to read, because all of the management of the mathematical objects (say, vectors and matrices and big numbers), all of the parallelism and numerical checks, needs to be handled inside the main code. And it mucks everything up. So improving notation, and parallelism, and language extensibility, and providing all sorts of powerful primitives and the ability to carry around properties, all this excites me.

I've been kicking a bunch of questions for a while now. And I wanted to put in some more study before I asked them. But I read the exhortation on the Fortress Bootcamp today, to not "hold back your impressions!" So I'll bite my lip and make a fool of myself: here are some of mine:

There are what seem like competing goals you're working under. HPC seems to demand things like unboxed variables, and static type checking, and rock solid exception handling, and a great security model.

On the other hand, I see great potential in Fortress, or a Fortress derived language, as a *scripting* language for scientists and mathematicians. I can imagine something like it replacing Mathematica as the default first language people learn, and the default language people work and think in. This is partly because the parser and character set are so powerful, and the language is so extensible, that the natural expression of many statements will, with the right libraries, take little effort to translate into Fortress. Also, with parallelism and easily parallelized constructs built so deeply into the language, I can imagine the computations that slow maple and mathematica down just blazing on Fortress, and that would be really great.

But for it to be a nice scripting language, the syntax seems a little heavy. At least at first, that's my impression. I look at the conjugate gradient example and think 'my, that's beautiful, it's like the canonical encoding of what that algorithm *means*'. But then I look at even Hello World and I'm a little daunted, because it still looks like there's an awful lot of code around that isn't core to the meaning. What's all this 'export' and 'executable' and run =, and component stuff? The canonical representation of hello world is 'print "hello world"'!

One of the core philosophies of the scripting world is that you can get up and running in an extremely short time. And then it's a really, really simple matter to move next to simple calculations, and variable assignment, and loops, and so on. Access to a powerful and helpful interactive interpreter/debugger, like Python, or Mathematica, is really helpful too (if you go one step further, and typeset code and equations, it will be even better).

These features make a smooth gradient for absolute beginners to climb. Eventually, they'll get all the way up to being able to build library code. I think that smoothing that gradient out could really be crucial for Fortress. A goal should be that it's a language people will want to teach students *first*. It is so different from previous languages that I see only a few of the old guard, those really in the know, switching -- the rest will have to pick it up early on. But that's okay, you have long term goals.

So one of my impressions, which I'll just put out here, is that having a 'script mode' might be a very handy thing: for code outside of a 'component' score, by default, assume that the component has its name being its filename, which by default exports (or even just plain runs) an executable. This simplifies things for beginners and everyone else -- you can just name components by the filename, you don't need to write the name twice, which was one of the things that annoyed me about Java, even before I started scripting. There's a name for this philosophy used in the Python world: don't repeat yourself.

For example, code blocks are delimited with 'end'. Are they needed? Python does without them, and I think that pays major dividends in readability. And it takes less work to type. Programmers by default seem to follow the path of least typing. Is there anything in the parser, or in the semantics, that need it? And I imagine that the default method for coding fortress would eventually include a realtime typesetting ide, so in fact readability would be even easier than in Python -- you could control the block spacing to guide the eye.

Finally, I would like to make the case for some exploration of declarative, nondeterministic programming. Fortress indulges in both, in some sense, due to implicit parallelism. I don't really have anything settled in my mind yet, but there are directions that are interesting to me. I have been playing with the pattern matching mechanisms of Erlang and Haskell (of which multiple assignment, like python and ruby have, is a subset). It's not a fully declarative language like Prolog -- they used only the stuff they could make fast. But what I've found is that it's extremely useful as a 'do everything' control flow abstraction. I'm afraid it's too late tonight for me to give examples, but if you ask me I can write some later. For now, you should know that Erlang uses pattern matching for variable assignment. Erlang uses it for sanity checks. Erlang uses it for string manipulation. Erlang uses it to simplify calling and writing anonymous functions. Erlang uses to it implement typing. Erlang uses it to implement array/list/data structure slicing. Erlang uses it to implement object orientation. Erlang uses it to streamline exception handling. Erlang actually has an if statement, but nobody uses it because case statements, with the limited pattern matching that Erlang gives, are so incredibly useful.

In principle pattern matching is the sort of thing I could add on later. But some of the biggest wins come from applying it in these nooks and crannies, and they're really everywhere. It could be a very valuable thing to have right at the core of the language. So I'd like to see,at this early stage, if it's a feasible thing to look into. Erlang's pattern matching is one of the most powerful, time-saving abstractions I've come across, and they're not even taking it as far as they could.

The other thing is that the pattern matching is an abstraction that mathematicians are really used to. People have an innate sense of the 'shape' or 'pattern' of some expression, and can easily see you taking one thing, and splitting it up, and putting it in some other thing. It's very easy to grasp, conceptually. That's almost what mathematical calculation is: everytime you see a derivation with an = or an arrow what you're really seeing is some pattern matching and symbol manipulation, of which variable assignment is a tiny subcase. Even consider the way people write case statements, or multi valued functions: here, for example. http://mathworld.wolfram.com/HeavisideStepFunction.html

Exception handling is another thing I'm interested in. Unfortunately, I think the standard way of handling exceptions causes an awful lot of clutter.

Here are some examples.

Very, very often, you know that something could cause an exception, but you want that exception to pass silently, because it's either not important to the program, or it's part of a chain of actions for which you know what to do if any of them fail.

For example (in python, taken from http://code.causes.com/blog/drying-out-deep-checks):

We found ourselves very often writing code with conditions that looked like:

if object && object.child && object.child.valid?
do_something(object.child)
end

In this case all we really want to do is verify that object.child.valid? returns true, but writing

if object.child.valid?

left us vulnerable to the dreaded

# NoMethodError: undefined method `child' for nil:NilClass

They then implemented the 'try' method, which just maps and uncaught exception -> nil (false), and on anything else it just yields control.
if try { object.child.valid? }

This is a common idiom. Another one, taken from the wikipedia page on Icon. http://en.wikipedia.org/wiki/Icon_(programming_language)

For instance, we can write a program to copy an entire input file to output in a single line:

while write(read())

When the read() command fails, at the end of file for instance, the failure will be passed up the chain and write() will fail as well. The while, being a control structure, stops on failure, meaning it stops when the file is empty. For comparison, consider a similar example written in Java-based pseudocode:

try {
while ((a = read()) != EOF) {
write(a);
}
} catch (Exception e) {
// do nothing, exit the loop
}

It's a simple notion - things eventually fail, so just tell the program what to do when it does. Here's another example.

Icon includes several generator-builders. The alternator syntax allows a series of items to be generated in sequence until one fails: 1 | "hello" | x < 5 can generate "1", "hello", and "5" if x is less than 5. Alternators can be read as "or" in many cases, for instance:

if y < (x | 5) then write("y=", y)

You can see how this could have a wonderful synergy with Fortress. Goal directed execution allows you to multicast control flow. Often in combinatorial code, for example, you need to find some solution, but you don't really care which one you get. You could write

if test(possible_solution_generator) then return solution

and be done with it.

Also in exception handling. there may be cases where an elaborate exception heirarchy is really valuable, but in my (limited) experience, just keeping things flat and using message passing is more flexible, and easier. One of the problems is that people, in the Java world, use the exception heirarchy as a method to handle control flow -- some things are unexpected errors, but others just prompt a response. The trouble seems to be that this demands that you define, ahead of time, a class heirarchy of exceptions, and then carefully plan how each function will throw or handle different types. It's a big, front loaded design task, and something that people tend to get wrong on a first pass. Usually you can't forsee errors. I don't know if this is like this in Fortress, but in Java, the idiom is to make a new exception class, and then throw it, mentioning on all possible calling functions how this exception is supposed to be handled. This is a major task. And people pollute the heirarchy with exceptions that are simply 'events' that you need to handle. Frankly, I think this is better solved with co-routines.

-----

Wow. This has gotten way longer than I wanted it to be. But it's 6am now, and I better get some rest. Hopefully, it's not so long that nobody responds, but, if so, I guess it's worth of refinement.

In any case, I wish everyone on the project all the best.

Danielle Fong

daniellefong.com


Victor Luchangco | 17 Jun 12:42
Picon
Favicon

Comments and end annotations

In reading some library code recently, I got confused because I  
didn't realize that some code was commented out, and that some other  
code was part of an object declaration.  So I wonder if what others  
think about the following:

1. When code within comments is rendered as ordinary Fortress code,  
it is slightly indented with a continuous vertical line at the left  
margin.  If there are multiple levels of nesting such commented-out  
code, then there should be one such line for each level of nesting.   
(Basically mimicking quoting in many mail handlers.)  This affects  
only the rendering of Fortress comments, not the syntax or semantics  
of Fortress code.

2. After the closing "end" of a multiline trait or object  
declaration, or a component or api declaration, it is permissible  
(but not required) to write the name of the trait/object/api/ 
component being declared.  Such a name must appear on the same line  
as the end, and it is a static error if it does not match the name  
declared.  (The static parameter list is not considered part of the  
name for this, or any other, purpose.)  For example,

object O
end O

trait A[\X\]
end A

(* the following is a static error *)
trait T
end x

- Victor

Russel Winder | 10 Jun 08:53

2008 Concertant Multicore Processor Survey

Although not directly relevant to Fortress per se, I hope I am not out
of order putting this email on this list.

Just over a year ago, I undertook a small survey about multicore
processors (MCPs) and the market.   The answers I got contributed to an
analysis of the market.  A lot of people were very interested in the
results of the analysis, even though it was relatively informal.  This
has led to undertaking a more structured survey, which will probably
become an annual thing so we can get longitudinal data.

The survey covers the whole gamut of those involved with MCPs including,
but by no means limited to, end-users, specifiers, hardware and software
engineers, programmers, applications developers, consultants and those
responsible for strategic programmes. We are as ever interested in both
embedded and general-purpose systems and their application in everything
from control and signal analysis,  to weather forecasting and
sub-nuclear physics via databases, medical imaging, financial modelling
and real-time data-analysis. In other words just about anything you
could envisage using them for. 

This survey is hosted at Survey Monkey.  If you can offer a few minutes
of your time to complete the survey then the URL is:

 https://www.surveymonkey.com/s.aspx?sm=f63fQptffFOoC2wFSAPKUQ_3d_3d

The survey is open till 2008-07-07 23:59:59+01:00.

We will mail respondents a copy of the summary findings when they become
available. Please use the email address at the end of the questionnaire
to confirm that you want to receive a copy.

Judging from the 2006/7 report and recent market developments, we
anticipate some very interesting results.

Thanks.
--

-- 
Russel.
====================================================
Dr Russel Winder                 Partner

Concertant LLP                   t: +44 20 7585 2200, +44 20 7193 9203
41 Buckmaster Road,              f: +44 8700 516 084
London SW11 1EN, UK.             m: +44 7770 465 077
Picon

Thought on typecase

I find it uncomfortable that it is not easy to select a parameterized
type with a typecase. Suppose:
trait X[\T extends Y\] end
then I can't specify a clause that matches any instantiation of X. It
is possible to create an additional nonparametric trait that X
extends, but it isn't practical nor nice to do so just to be able to
use typecase. I could do
trait X[\T extends Y\] extends X[\Y\] end
but leads to a stack overflow if I then use X[\Y\] (just as trait Z
extends Z end does). I can create a ticket for this if it's
appropriate, but the question could be whether it is legal to declare
that a trait extends itself (doesn't it always?).

Picon

Functional method in object expression throws an error

Defining a functional method in an object expression gives a "Missing
value: f in environment:" message.

component Main
export Executable

run(args) = do
    o = object
        f(self) = ()
    end
end

end

Dan Smith | 2 Jun 21:03
Favicon

Java language RFE: Allow overriding to resolve return type conflict

I just submitted this overloading-related RFE to the Java Bug  
Database.  Thought others might find it interesting.  In Fortress, the  
three method declarations are valid due to the Meet Rule (15.6.4) and  
the Subtype Rule (which verifies that the return types are safe)  
(15.6.2).

—Dan

Begin forwarded message:

> From: Sun Microsystems <IncidentUpdateDaemon@...>
> Date: June 2, 2008 2:11:15 AM CDT
> To: dlsmith@...
> Subject: Re: (Incident Review ID: 1259860) Allow overriding to  
> resolve return type conflict
>
> --- Note: you can send us updates about your Incident ---
> --- by replying to this mail.  Place new information  ---
> --- above these lines.  Do not include attachments.   ---
> --- Our system ignores attachments and anything below ---
> --- these lines.                                      ---
>
> Hi Dan Smith,
>
> Thank you for taking the time to suggest this enhancement to the  
> Java Standard Edition.
>
> We have determined that this report is an RFE and has been entered  
> into our
> internal RFE tracking system under Bug Id: 6709429
>
> You can monitor this RFE on the Java Bug Database at:
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6709429
>
> It may take a day or two before the RFE shows up in this external  
> database. As you are a member of the Sun Developer Network (SDN),  
> there are two additional options once the bug is visible.
>
> 1. Voting for the RFE
>   Click http://bugs.sun.com/bugdatabase/addVote.do?bug_id=6709429
>
> 2. Adding the report to your Bug Watch list.
>   You will receive an email notification when this RFE is updated.
>   Click http://bugs.sun.com/bugdatabase/addBugWatch.do?bug_id=6709429
>
> SDN members can obtain fully licensed Java IDEs for web and  
> enterprise development.  More information is at
http://developers.sun.com/prodtech/javatools/free/ 
> .
>
> We greatly appreciate your efforts in identifying areas in the Java  
> Standard Edition where we can improve upon and I would request you  
> to continue doing so.
>
> Regards,
> Nelson
>
> ~ 
> ~ 
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> NOTICE: This message, including any attachments, is for the intended
> recipient(s) only.  If you are not the intended recipient(s), please
> reply to the sender, delete this message, and refrain from disclosing,
> copying, or distributing this message.
> ~ 
> ~ 
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --------------- Previous Messages ----------------
>
>
> --------------------- Report ---------------------
>
>      category : java
>   subcategory : specification
>       release : 6
>          type : rfe
>      synopsis : Allow overriding to resolve return type conflict
> customer name : Dan Smith
> customer mail : dlsmith@...
>        sdn id : dlsmith@...
>      language : en
>       company : Rice University
>      hardware : x86
>            os : windows_vista
>        bug id : 6709429
>  date created : Fri May 30 10:45:39 MST 2008
> date evaluated : Mon Jun 02 00:08:57 MST 2008
>   description :
> A DESCRIPTION OF THE REQUEST :
> I'd like to define a type hierarchy for which a child overrides a  
> method in two parents with different return types.  In general, this  
> looks like:
>
> interface A {}
> interface B {}
> interface C extends A, B {}
>
> interface X { A foo(); }
> interface Y { B foo(); }
> interface Z extends X, Y { C foo(); }
>
> Per JLS 8.4.8.4 (or perhaps an equivalent section describing  
> constraints on interface methods rather than class abstract  
> methods), this is illegal because no interface can extend both X and  
> Y: A is not substitutable for B, nor vice versa.  However, it is  
> impossible for any class that implements Z to violate type safety:  
> foo() will always return an A, as required by X, and will always  
> return a B, as required by Y.
>
>
>
> JUSTIFICATION :
> There are useful type hierarchies that can't be expressed without  
> relaxing this restriction.  For example:
>
> /** A set of pairs. */
> interface Relation<T1, T2> {
>  Relation<T2, T1> inverse();
> }
>
> /** A many-to-one relation. */
> interface FunctionalRelation<T1, T2> extends Relation<T1, T2> {
>  InjectiveRelation<T2, T1> inverse();
> }
>
> /** A one-to-many relation. */
> interface InjectiveRelation<T1, T2> extends Relation<T1, T2> {
>  FunctionalRelation<T2, T1> inverse();
> }
>
> interface OneToOneRelation<T1, T2>
> extends FunctionalRelation<T1, T2>, InjectiveRelation<T1, T2> {
>  OneToOneRelation<T2, T1> inverse();
> }
>
> On the flip side, I'm not aware of technical restrictions that make  
> this difficult to allow.  It's just a matter of relaxing the  
> overriding restriction.
>
>
>
> EXPECTED VERSUS ACTUAL BEHAVIOR :
> EXPECTED -
> The compiler accepts declarations like that for OneToOneRelation  
> without error.
> ACTUAL -
> javac produces an error:
>
> types InjectiveRelation<T1,T2> and FunctionalRelation<T1,T2> are  
> incompatible; both define inverse(), but with unrelated return types
>
>
>
> ---------- BEGIN SOURCE ----------
> public class TestOverriding {
>  interface Relation<T1, T2> {
>    Relation<T2, T1> inverse();
>  }
>  interface FunctionalRelation<T1, T2> extends Relation<T1, T2> {
>    InjectiveRelation<T2, T1> inverse();
>  }
>  interface InjectiveRelation<T1, T2> extends Relation<T1, T2> {
>    FunctionalRelation<T2, T1> inverse();
>  }
>  interface OneToOneRelation<T1, T2>
>      extends FunctionalRelation<T1, T2>, InjectiveRelation<T1, T2> {
>    OneToOneRelation<T2, T1> inverse();
>  }
> }
>
>
> ---------- END SOURCE ----------
>
> CUSTOMER SUBMITTED WORKAROUND :
> The return type of one of the conflicting interfaces must be  
> modified so that it is a supertype of the other, resulting in less  
> precise typing (and probably leading to subsequent downcasting).   
> For example, InjectiveRelation could simply inherit  
> Relation.inverse() with return type Relation<T2, T1>.

Sorin Miklós Zsejki | 30 May 19:27
Picon

How to "overload a function with static parameters"?

Let's say I have:

trait P end
trait R[\T extends P\] end
f[\T extends P\](p: T): R[\T\]

Now I add this:

trait SubP extends P end
trait SubR[\T extends SubP\] extends R[\T\] end

and I want an overloading of f like this:

f[\T extends SubP\](p: T): SubR[\T\]

This is not possible because the static parameters of f must exclude
each other. So my question is how to do this _without giving up the
static parameters_.

I know I could do something like:

trait R1 extends R end
trait R2 extends R excludes R1 end

and declaring f for R1 and R2, but what I want is a general
declaration of f and an overloading for the more specific cases like
SubP. I don't want the general case (the first 3 lines of code) to
make any reference to SubP or SubR.

I think with where clauses I could do something like:

trait OverloadsF extends P end
f[\T extends P\](p: T): SubR[\T\] where {T excludes OverloadsF}

and then SubP would also extend OverloadsF. Is that right?

Another question is why the static parameters must exclude each other?
The types of the parameters of overloaded functions don't, so can't
static parameters work similarly?

Guy.Steele | 30 May 07:30
Picon
Favicon

Proposal to expand set of operator words

Background:

(1) A basic principle of operator words in Fortress, as far as we are
able to support it, has been that if you know the LaTeX name for
an operator symbol, then if you leave off the backslash and write
it using uppercase letters, then that is a name for that symbol in
Fortress and "ASCII conversion" will replace that name with the
character itself.

(2) The AMS has been working with other scientific and mathematical
publishing societies and corporations to produce a comprehensive set
of freely available fonts that will cover all mathematical operatiors in
Unicode version 5.  They also plan to provide LaTeX support for these
fonts, and as part of that process will provide a LaTeX macro to name
each operator symbol for use in "math mode".  See http://www.stixfonts.org .

(3) Our plan for the last two years has been that when the AMS eventually
releases its STIX fonts (later this year, we hope), we will adopt their names
for the Unicode mathematical operators in accordance with principle (1).

(4) At present, operator words in Fortress are words that would otherwise
be regarded as identifiers except that they are distinguished by consisting
entirely of uppercase letters and underscores, and containing two distinct
letters, and neither beginning nor ending with an underscore.

(5) The reason for excluding words ending in underscore from the set of
operator words was that such words are needed as names of SI unit symbols,
for example MW_ for megawatts.  (Note that the trailing underscore indicates
that the identifier MW_ is to be set in a roman typeface (rather than italics),
which is correct style for dimensional units.)  The related prohibition against
beginning an operator word with an underscore was introduced primarily for
symmetry.

Problem:

Some of the names chosen by the STIX fonts effort are identical except
for case distinctions.  For example, \sqcap and \Sqcap are distinct macro
names for distinct symbols.  Likewise, \dashv and \dashV and \Dashv and
\DashV represent four distinct symbols.

The table that defines these names may be seen at http://www.ams.org/STIX ;
the latest version of the table is http://www.ams.org/STIX/bnb/stix-tbl.ascii-2006-10-20 .

Proposal:

Modify principle (4) so that operator words may begin (but not end)
with an underscore.

Modify principle (1) to specify that a LaTeX name is converted to an
operator word by omitting the backslash, changing lowercase letters
to uppercase, and preceding letters that are already uppercase by
an underscore.  Thus we would have the following transformations:

LaTeX    Fortress

\sqcap   SQCAP
\Sqcap   _SQCAP
\dashv   DASHV
\dashV   DASH_V
\Dashv   _DASHV
\DashV   _DASH_V

This would allow us to use (nearly) all the names specified by the STIX  fonts
consortium in a systematic manner.

--Guy


Gmane