nm

11353 Reputation

20 Badges

13 years, 20 days

MaplePrimes Activity


These are questions asked by nm

There is a whole chapter in programming guide on OO in Maple.

How much is OO actually used by Maple programmers? Is OO used much internally at Maplesoft itself in implementing internal code? I do not see questions about OO in Maple in the forum. May be it has not taken off? 

Any one knows of packages in Maple written in OO style, using the Object module? I think OO was added in Maple 16, which is 2012?

p.s. I myself like OO programming. Done alot of it in Java. I think it can be useful for large applications.

 

 

 

This proc is valid, yet Maple mint thinks there is syntax error

foo:= proc(x)
local z := "";
    if not x in ["A","B"] then
        return;
    fi;

    z:=cat("A
            B");    
end proc;

mint t.mpl gives

on line     7:     z:=cat("A
                          ^ Syntax error
A "then" was found without a previous matching "if".
An "end" may be needed to close the "in" construct from line 3.

But these two below procs below it gives no syntax error

foo:= proc(x)
local z := "";
    if not x in ["A","B"] then
        return;
    fi;  
end proc;

And

foo:= proc(x)
local z := "";
    z:=cat("A
            B");    
end proc;

No syntax error on either one. the syntax error only shows up when combining them. 

What does if not x in ["A","B"] then  have to do with the cat  below it? And why when they are combined, the syntax error shows?

I know of workaround, such as changing the cat to  z:=cat("A\nB");     or keep the strings on two lines, but do it like this

    z:=cat("A\n
           B");

Or write it like this

   z:=cat("A "
           "B"); 

But none of these changes were needed before adding the not x in ["A","B"]  before.

Is this a bug in mint? Is there a work around so the first example above still works using 

    z:=cat("A
            B");   

?

When making a function and using the return type, I found Maple is not catching the case when the function returns wrong type.

Actually there are two issues in this example I like to ask about. First, here is the example

restart;
kernelopts(assertlevel):=2;
TypeTools:-AddType(type_A, record(x::integer)):

foo:=proc( A::type_A ) ::type_A;  #this is what return type should be
     print( type(A,'type_A')); #this prints TRUE
     A:-x :=1.5; #opps, wrong type, changes type of record now!
     print( type(A,'type_A')); #This now prints FALSE
     return A;
end proc:

A:=Record('x' = 1);
B:=foo(A):
eval(B)

The call to foo() goes through as expected since type is correct.

First issue: Inside the function doing A:-x :=1.5;  changed the type of record now, since is supposed to be integer and now become real. Is there a way to have Maple detect this at run time?

Second issue: The function was defined to return type_A  but due to this overwriting the field of the record by wrong value, it is no longer type_A  (the print now says false). But why Maple did not detect this? Since the function is defined to only return type_A ?

Is it possible to change the code above to catch these type mistakes I made?

given A := [[1, 0,9], [5, 0, 6], [4, 0, 0]]; and to remove 0 from each entry, I used map2(remove,has,A,0) which gives 

                   [[1, 9], [5, 6], [4]]

Is it possible to do the same thing using ~ notation for mapping?  (Element-wise Operator). Where now each element is each entry in A? I can't figure what the syntax would be if possible.  remove(has,??,0)~A

For exmaple in Mathematica one would use what is called slot number #. So the above mapping would look like in Maple as doing remove(has,#,0)~A  where now acts as place holder to be filled by each entry taken one at a time from list A as the mapping runs.  But do not know if this is possible in Maple.   

map2 does the job, but can be tricky to use when the function to map takes number of different arguments.

One work around is to make seperate function, and use that for mapping, as follows

f:= x->remove(has,x,0);
f~(A)

which gives  [[1, 9], [5, 6], [4]] correctly. 

So I find the above easier to understand and more clear than map2, and I am not unhappy with it, and so I see no reason to use map2 vs. ~ in this case.

But wanted to see if it was possible to use ~ without making separate function, but do it in-line if you well (using what is called pure function, or unamed function in functional programming).

 

I am trying to decide which is better to use, a table or Record, to pass lots of information back and forth between functions inside say a personal Maple package.

So instead of passing each argument on its own, as normally one does when calling a function, instead all the input is put into one table, or into one record, and this is passed instead. So the function always takes as input one argument.

When the function returns result, it also does the same. It updates any fields it needs in the table or in the record, o rmay be add new field, which the caller would have to know about, (since same person has programmed both) and returns that.

I find this easier to handle, than passing each argument on its own.  And on return, rather than return many results in list or sequence and making sure they are in correct order, the function simply update the fields in the table or the record. No problems with wrong order here as caller will read these fields by name later on.

So I made same toy example, one using table and one using record. 2 numbers are passed to a function. The function returns the result of multiplication by adding new field into the table/record.  Here is version using table.

restart;
foo:=proc(input::table)
   local x,y,result,updated;

   x      := input["x"];
   y      := input["y"];
   result := x*y;

   #finished computation. Return result. Copy all content
   #of passed table first, then add new field to write result to

   updated := eval(input);
   updated["result"] := result;
   return updated;      

end proc:

Called using

input:=table(["x"=4,"y"=6]);
r:=eval(foo(input)):
print(r["result"]);

prints 24

 

Here is version using Record

foo2:=proc(input::record)
   local x,y,result,updated;

   x      := input:-x;
   y      := input:-y;
   result := x*y;

   #finished computation. Return result
   #could not update input Record in place, even after deep copy
   #since "result" is not an existing field. So have to make a new Record
   #this is a problem, since this function need to know all fields now in Record

   updated := Record("x"=x,"y"=y,"result"=result);
   return updated;      

end proc:

called as

input:=Record( "x" = 4, "y"=6);
r:=eval(foo2(input)):
print(r:-result);

prints 24

 

Some observations: I found the table more flexible. Because the function called can add a new field to the table, even if this field do not exist. If called function wants to add a new result back to the caller, it can do this.  With Record, all fields have to be decided on when the record is created. So the function has to create new record from all the old fields and add the new field to do this.

This might not be a big problem actually, as one can decide at top of package what all the possible fields that needs to be in the Record, and creates such Record, giving default values for al field. So now Record will have all possible fields in it.  Using this the above can now be written as

restart;
foo3:=proc(input::record)
   local x,y,result;

   x      := input:-x;
   y      := input:-y;
   result := x*y;

   #finished computation. Return result  
   input:-result := result; 
   return input;      

end proc:

And called as

input:=Record( 'x' = 4, 'y'=6, 'result'=NULL);
r:=eval(foo3(input)):
print(r:-result);

24

But it seems both methods suffer from the fact that type checking on the types of the arguments now inside is lost. (But I seem to remember one can do type checking on fields for a Record somehow). So if this is possible, this will be one advantage of Record over table.  But again, it is possible in both methods to check type of field by using whattype() or type() manually if needed.

But other than these two issues, and assuming one wants to pick between table and record, the question is, why choose Record over table?  If the main purpose is to just to pass information back and forth? Is there some hidden advatage to using Record I am overlooking that tables do not provide (again, for the purpose of passing arguments and results between functions and no more).

For me, I see table doing what I want from a record, but a little bit easier to work with as well (field names can be strings for example).  So with table one does  A["x"]=.....  While with Record one does A:-x=...

For me, I see a Maple table just like Python dictionary, so easy to underatand and work with.

Any thoughts from the experts on this subject? 

First 126 127 128 129 130 131 132 Last Page 128 of 199