john skaller | 30 Mar 13:01 2015
Picon
Picon

Re: [felix] fix patterns


On 30/03/2015, at 7:18 PM, Martin DeMello wrote:
>> 
>> This won't work as you might expect because in that pattern NIL is a variable.
>> Easy to miss. You have to write
>> 
>>        | A (_, #NIL) => ..
>> 
>> to tell the parser the NIL is a type constructor.
> 
> Would it be hard to make this an actual warning, viz
> 
> warning: variable NIL has same name as constructor. did you mean #NIL?

I don't know, it could be quite hard. It would mean at least doing a lookup
on EVERY variable name used. The problem is that the "desugaring"
of pattern matching is done long before it is possible to do any lookup.
So by the time the compiler comes to bind the code, it has no idea
it's dealing with a pattern match variable.

Pattern matches are basically macros. You can, in fact, invent your own.
It basically goes:

	if  (!_match_ctor_CTOR (arg)) goto next_case;
	var arg1, arg2 = _ctor_arg_CTOR (arg);

	// do handler

	goto endmatch;
next_case:
(Continue reading)

john skaller | 30 Mar 04:14 2015
Picon
Picon

fix patterns

Using a nice tool, flx_batch_replace:

/usr/local/lib/felix/felix-latest/host/bin/flx_batch_replace -v src '.*\.(flx|fdoc)'
'fixup/src/${0}' '\?([A-Za-z][A-Za-z0-9_]*)' '\1'
cp -r fixup/src/* src

Be interested how to do that with standard unix tools.

I do note the inconsistent replacement notation ${group} for files,
but \group for strings. Internally these search and replace operations
are in fact similar. I put the ${group} in because its so hard to type \1
inside a string and get the quoting right. OTOH in bash ${1} is the first
command line argument so that needs to be quoted right too.

--
john skaller
skaller@...
http://felix-lang.org

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
john skaller | 29 Mar 20:42 2015
Picon
Picon

review of brackets

Apart from in structs, unions, and function/procedure definitions,
here is a possibly incomplete catalogue:

	{ expr } --> function returning expr
	{ stmt; stmt; expr } -> function returning expr
	{ stmt; stmt; return expr; } -> function returning expr
	{ stmt; stmt; } --> procedure
	{ pattern : type | expr } --> set form

	( expr ) --> expr
	( expr, expr ) --> tuple
	(x=expr, y=expr) -> record
	struct {x = expr; y=expr; } -> record (deprecated)
        ( stmt; stmt; expr ) --> expr // means #{ stmt; stmt; expr }
	() --> unit tuple
	( var expr ) --> expr (eagerly evaluated, same as (let x = expr in x))

I am looking at some more short forms, such as

	if(x)stmt;
	while(x)stmt;

like C. It's not clear these will work, since they're ambiguous.
An alternative (from COBOL):

	if x perform stmt;
	while x perform stmt;

Note these are already allowed:

(Continue reading)

john skaller | 28 Mar 14:20 2015
Picon
Picon

Re: [felix] Set form

Sometimes it's hard to believe Felix is SOO dang good!
This works now:

var squares = \{ (?x,?y) : int * int | y == x * x \} ;
println$ (3,9) \in squares;

The general form is

	\{ pattern : type | predicate \}

A predicate is any expression evaluating to bool, which may use
the variables in the pattern match. We have to specify the type
of the pattern, and our patterns have ugly ? in them sometimes,
but otherwise this is similar to a mathematical set.

A set_form is a real object. Any object with a method

	has_elt: T -> bool

acts like a set courtesy of these definition in std/algebra/set.flx:

interface set_form[T] { has_elt: T -> bool; }
fun \in[T] (elt:T, s:set_form[T]) => s.has_elt elt;

If your object has other methods you can "cast" them away
with a coercion to meet the specification.

It's easy to define the union now:

	fun \cup[T] (A:set_form[T], B:set_form[T]) => \{ ?x : T | x \in A or x \in B \};
(Continue reading)

john skaller | 25 Mar 22:40 2015
Picon
Picon

Re: [felix] Design issue


On 26/03/2015, at 5:30 AM, Martin DeMello wrote:

>>> I believe this is where you went wrong - a set isn't a container with
>>> a membership operator, it's a container with a membership operator and
>>> the property that all elements are distinct.
>> 
>> How would you specify that property?
> 
> You can't without dependent types, certainly. (I'm not even sure you
> can *with* dependent types; I know very little about them). In actual
> code you could always maintain the invariant by simply removing
> duplicates on all set-modifying operations.

I think you're missing the point.

	class Set[C,T] { virtual fun \in : T * C -> bool; }

defines a Set as a data type with a member operator.

Now, an array, even with duplicate values stored,
can satisfy the axiom, because there's no requirement
about duplication of elements in an array. 

Note there's also no requirement for an equality operator,
and no size. This is not your usual mathematical set.
I actually defined a Container as a Set with a length operator.

Consider a regexp: RE2 "(a|b)*abb". That's a set, using the obvious
rule that a string that matches the regexp is in the set.
(Continue reading)

john skaller | 25 Mar 11:46 2015
Picon
Picon

Re: [felix] Design issue


On 25/03/2015, at 1:26 PM, Martin DeMello wrote:

>> 
>>        Set -- membership operator
>>        Container -- as set with a size operator (i.e. a finite set)
>> 
> 
> I believe this is where you went wrong - a set isn't a container with
> a membership operator, it's a container with a membership operator and
> the property that all elements are distinct.

How would you specify that property?

--
john skaller
skaller@...
http://felix-lang.org

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
john skaller | 25 Mar 03:19 2015
Picon
Picon

Design issue

I have just run into an interesting problem. 

I like pretty math operators so I've been making the TeX symbols
for set comparisons work. Stuff like \subseteq for example.

Now, at the moment you can write:

	x \in (1,2,3,4)

and it works. This is because "an array is a Set". FYI we have these
basic concepts:

	Set -- membership operator
	Container -- as set with a size operator (i.e. a finite set)

as well as Eq (equivalence relation, equality), Pord (partial order),
and Tord (total order).

I decided to do SubSet, with the nice curvy comparisons for sets from
maths: its just a Set with \subseq and \subseteq defined, the other
operators are derived. I did this:

class SubSet[c] {
   inherit Eq[c];
   virtual fun \subseteq: c * c -> bool;
   virtual fun \subset (x:c, y:c) => x \subseteq y and not x == y;
   fun \subseteqq (x:c,y:c) => x \subseteq y;

and then I realised WHOA! Hold on there!!

(Continue reading)

john skaller | 21 Mar 13:08 2015
Picon
Picon

pointers

Hi, I am still grappling with this problem:

Felix has a rule for concrete data types, in particular products.
We have quite a few product type: tuples, records, structs, arrays.

Products are characterised by projection functions.
Each product type has a different way of naming them.
We like for a record type:

	typedef r_t = (p1:int, p2:int);
	val r : r_t = (p1=1, p2=2);

to express projections like:

	r.p1

in the OO tradition. Felix says p1 is an ordinary function thingo,
and 

	x . f

means exactly the same as

	f x

so we can also write:

	p1 r

Consequently you can write this too:
(Continue reading)

john skaller | 19 Mar 15:00 2015
Picon
Picon

graph algos

I have done Felix version of Skiena's representation of a graph,
and a breadth first search.

As usual i'm less interested in the representation as such than the typing,
abstraction, etc. However, Skiena's representation makes me feel uneasy.

  typedef digraph_t = (vertices: darray[vertex_t], nedges: int);

  // x index implicit, the edge source
  // y index is the edge destination
  typedef edge_t = (elabel:E, y:int, weight:int); 
  typedef vertex_t = (vlabel:V, outedges: list[edge_t]);

1. Skiena uses a flag to tell the difference between an undirected and
directed graph. I have only a digraph here. It's not clear to me the
two things shouldn't be completely distinct, even though an undirected
graph can be represented by a digraph with edge pairs (x,y) and (y,x).

2. The rep is compact, but the edge type doesn't tell the source of the
edge, it's implicit from the position in the array. I don't like that,
the *actual* edge required a pair int * edge_t.

3. Using integers to represent vertices leaves open the problem
of how to properly build the graph. I solved that by adding default
vertices to fill up the list up to the currently specified maximum integer.

My graph has both edge and vertex labels, but these can't be assumed
unique. But identifying by integer is a plain wrong. It may be OK for a static
graph, but even after construction of a graph, one might like to perform
mutations.
(Continue reading)

john skaller | 17 Mar 19:08 2015
Picon
Picon

assignment fun

I wrote this:

  proc push_front (dl:&dlist_t, v:T) { 
    var oldfirst = dl*.first;
    var node = new (data=v, next=oldfirst, prev=nullptr[dnode_t]); 
    dl.first <- Ptr node;
    match oldfirst with
    | nullptr => dl.last <- Ptr node;
    | Ptr p => p.prev <- Ptr node;
    endmatch; 
  }

This is for a doubly linked list. Now I will show you the beauty of the pointer projection semantics:

   match oldfirst with | nullptr => dl.last | Ptr p => p.prev endmatch <- Ptr node;

In fact we can do better if we like convoluted expressions:

	proc asgn2[T] (p: &T, q:&T) (var v:T) { p <- v; q <-v; }

to save writing "Ptr node" more than once :)

--
john skaller
skaller@...
http://felix-lang.org

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
(Continue reading)

john skaller | 14 Mar 00:03 2015
Picon
Picon

interesting problem

I recently changed the parser to ensure:

  x[sfactor_pri] := x[sfactor_pri] "*." sthe_name =># "`(ast_dot ,_sr ((ast_deref ,_sr ,_1) ,_3))";
  x[sfactor_pri] := x[sfactor_pri] "&." sthe_name =># "`(ast_apply ,_sr (,_3 (ast_ref ,_sr ,_1)))";

The first one should actually read like the second. In Felix notation

	p*b == (*p).b
	a&.b == (&a).b

If b is a projection of a product (tuple, struct, record, array) then

	(*p).b == *(p.b)

Ok, so here's the problem. With any ArrayObject such as varray i have overloaded &. to mean

    fun unsafe_get_ref: varray[v] * size -> &v = "$1+$2";

which is invoked by

  fun n"&." [I in ints] (x:t, i:I) : &v = {
    assert i.size < x.len; 
    return unsafe_get_ref (x,i.size); 
  }

but this overload no longer works.

So here's my problem: Classes cannot say 

	"for all products. p&.b means &p.b"
(Continue reading)


Gmane