The Element_Type of the Vector is not limited, while the Queue is. How to organize a Queue Vector?
with Ada.Containers.Unbounded_Synchronized_Queues;
with Ada.Containers.Synchronized_Queue_Interfaces;
with Ada.Containers.Vectors;
package Queue_Vector is
package Integer_Queue_Interfaces is new
Ada.Containers.Synchronized_Queue_Interfaces
(Element_Type => Integer);
package Integer_Queues is new
Ada.Containers.Unbounded_Synchronized_Queues
(Queue_Interfaces => Integer_Queue_Interfaces);
package Queue_Vectors is new
Ada.Containers.Vectors
(Index_Type => Positive,
Element_Type => Integer_Queues.Queue);
end Queue_Vector;
This is uncomfortable, but compiles:
type Integer_Queue_P is access Integer_Queues.Queue;
package Queue_Vectors is new
Ada.Containers.Vectors
(Index_Type => Positive,
Element_Type => Integer_Queue_P);
You might want to make a smart pointer out of the Integer_Queue_P (as here), so as to make sure the actual Queue gets freed on overwrite or deletion of a Vector.
I did not take into account that access to protected queues in an unprotected vector is meaningless, vector must also be protected. So I made a secure object containing a Hashed_Map of Vectors to solve my problem.
Related
I am trying to create a dictionary of functions with symbols as keys but I am getting an error. I have tried the following:
functions = Dict{
:gauss => (v::Float64)->gauss(v, 0.0, 1.0),
:sin => (v::Float64)-> sin(v),
:nsin => (v::Float64)->(-sin(v)),
:cos => (v::Float64)-> cos(v),
:ncos => (v::Float64)->(-cos(v)),
:tanh => (v::Float64)->tanh(v),
:sigm => (v::Float64)->sigmoid(v),
:id => (v::Float64)->id(v)
}
The error I am getting :
ERROR: LoadError: TypeError: in Type, in parameter, expected Type, got Pair{Symbol,getfield(Main, Symbol("##105#113"))}
Please let me know what I am doing wrong. Thanks for the help in advance.
I figured the{} need to replaced by ().
As you found out your yourself, the {} brackets indicate type parameters whereas the paranthesis indicate a constructor call.
Note, that the ::Float64 type annotations aren't necessary for your functions to be performant. Think of them more as a user interface restriction; that is users won't be able to call your methods with non-Float64s. However, if you want to specify types explicitly, you could also specify the type of your dictionary explicitly as such Dict{Symbol, Function}(...). However, since you don't initialize the Dict empty, Julia will figure out the best type based on your input (symbol function pairs).
Is there a way to achieve some kind of recursively-typed functions in Ceylon? For example, I can define combinatory logic in Ceylon in a type-safe way like so:
class Fi(shared Fi(Fi) o) { }
Fi veritas =
Fi((Fi t) =>
Fi((Fi f) =>
t));
Fi perfidas =
Fi((Fi t) =>
Fi((Fi f) =>
f));
Fi si =
Fi((Fi l) =>
Fi((Fi m) =>
Fi((Fi n) =>
l.o(m).o(n))));
print(si.o(veritas).o(veritas).o(perfidas) == veritas);
print(si.o(perfidas).o(veritas).o(perfidas) == perfidas);
print(si.o(veritas).o(perfidas).o(veritas) == perfidas);
print(si.o(perfidas).o(perfidas).o(veritas) == veritas);
This code works as intended. However, for clarity, brevity, and applicability to other problems, I would like to be able to do implement this behavior using only functions. Take something like the following (non-working) example:
alias Fi => Fi(Fi);
Fi veritas(Fi t)(Fi f) => t;
Fi perfidas(Fi t)(Fi f) => f;
Fi si(Fi l)(Fi m)(Fi n) => l(m)(n);
print(si(veritas)(veritas)(perfidas) == veritas);
print(si(perfidas)(veritas)(perfidas) == perfidas);
print(si(veritas)(perfidas)(veritas) == perfidas);
print(si(perfidas)(perfidas)(veritas) == veritas);
In the function alias version, the Fi type represents functions whose operands and return values can be composed indefinitely. Note that due to their recursive nature, the types Fi, Fi(Fi), and Fi(Fi)(Fi) could be considered functionally equivalent; all that the consumer of any of them knows is that if they have a function that, if called on a Fi, will given them another Fi.
Here is my understanding of what Ceylon currently supports:
Recursive aliases are not supported due to being erased during compilation.
I am unaware of any current Ceylon feature that could be used to specialize the Callable type recursively or otherwise get the needed kind of infinite chaining.
A possibly related question got a negative response. However, that was two and a half years ago, before some potentially related features like type functions were implemented in Ceylon 1.2 and a pair of blogs written by Gavin King on new type function support.
There is a github issue on higher order generics.
There is another github issue on allowing custom implementations of Callable.
Can the desired behavior be implemented in the current version of Ceylon? Or would it definitely require one or both of the aforementioned backlog features?
I've been using Ada.Containers.Indefinite_Hased_Maps to create my own custom hashed maps, and it worked quite well until I tried to use a vector as the element type. Here is an example of the problematic code:
package String_Vectors is new Ada.Containers.Vectors(Element_Type => Unbounded_String, Index_Type => Natural);
subtype String_Vector is String_Vectors.Vector;
package Positive2StringVector_HashMaps is new Ada.Containers.Indefinite_Hashed_Maps --Compiler fails here
(Element_Type => String_Vector,
Key_Type => Positive,
Hash => Positive_Hash,
Equivalent_Keys => Positive_Equal);
Basically, I cannot Positive2StringVector_HashMaps package, because the compiler comes up with:
no visible subprogram matches the specification for "="
From what I understand, it isn't finding the equality operator for the String_Vector , am I correct? If I am, what is the proper way of implementing it? And if I'm not, what am I doing wrong??
You don’t need to implement
function “=“ (L, R : String_Vectors.Vector) return Boolean
yourself, because there already is one in String_Vectors; see ALRM A.18.2(12). So you write
package Positive2StringVector_HashMaps is new Ada.Containers.Indefinite_Hashed_Maps
(Element_Type => String_Vector,
Key_Type => Positive,
Hash => Positive_Hash,
Equivalent_Keys => Positive_Equal,
“=“ => String_Vectors.”=");
By the way, is there some reason you used Ada.Containers.Vectors on Unbounded_String rather than Indefinite_Vectors on String? (wanting to change the length of a contained string would count as a Good Reason!)
Can I have a vector filled with both, type A and B? I will fill it only with one type, so I am always sure, what I will get out of it. But it would make many things very easy for me, if I can define the vector once.
type T is tagged null record;
type A is new T with
record
x : Integer;
end record;
type B is new T with
record
y : Integer;
end record;
package Some_Vector is new Ada.Containers.Indefinite_Vectors (
Index_Type => Positive,
Element_Type => T <- ???
);
You can say:
package Some_Vector is new Ada.Containers.Indefinite_Vectors (
Index_Type => Positive,
Element_Type => T'Class
);
Some_Vector is now able to hold elements of type T or any type derived from it, including A or B. There's no requirement that all the elements have to be of the same type, as long as they're all derived from T; so if you don't really care whether this property is enforced, the above should work. If you really want the compiler to enforce that all elements are the same type, then you should simply declare two packages, A_Vector and B_Vector, for vectors of the two types; but then there's no way to write a "class-wide" type name that could refer to either an A_Vector or a B_Vector.
If you really want to combine both--have a vector type that could refer either to a vector of A or a vector of B, but still enforce that all elements of the vector have the same type, then I think this could be done if you define your own vector type and perform the needed check at run time, but it could get complicated. This compiles, but I haven't tested it:
generic
type Elem is new T with private;
package Sub_Vectors is
type Sub_Vector is new Some_Vector.Vector with null record;
overriding
procedure Insert (Container : in out Sub_Vector;
Before : in Some_Vector.Extended_Index;
New_Item : in T'Class;
Count : in Ada.Containers.Count_Type := 1)
with Pre => New_Item in Elem;
end Sub_Vectors;
package body Sub_Vectors is
procedure Insert (Container : in out Sub_Vector;
Before : in Some_Vector.Extended_Index;
New_Item : in T'Class;
Count : in Ada.Containers.Count_Type := 1) is
begin
Some_Vector.Insert
(Some_Vector.Vector(Container), Before, New_Item, Count);
end Insert;
end Sub_Vectors;
Unfortunately, you'd have to override every Insert and Replace_Element operation that could put an element into the vector. After you do all this, though, you can instantiate Sub_Vectors with Elem => A and with Elem => B, and the class Some_Vector.Vector'Class would be a class-wide type that would include both Sub_Vector types in the instance packages.
If you really want the compiler to enforce that all elements are the
same type, then you should simply declare two packages, A_Vector and
B_Vector, for vectors of the two types; but then there's no way to
write a "class-wide" type name that could refer to either an A_Vector
or a B_Vector.
You can, however, have a vector that points only to the A or B subtrees of the hierarchy:
type T is tagged null record;
type A is new T with null record;
type B is new T with null record;
type C is new T with null record;
type TAB is access all T'Class
with Dynamic_Predicate =>
TAB = null or else
(TAB.all in A'Class or TAB.all in B'Class);
Above yields the TAB Type which must be a [pointer to] an A'Class or B'Class, which you should be able to use in your vector. -- The only problem I've run into is you have to use GNAT's 'Unchecked_Access to get the access values of objects (due, I think, to my quick and dirty testing).
I'm building a job chain in Oracle (11R2) DBMS Scheduler. The chain has two steps. Each step runs the same program, but with different arguments. I can see how how to define the chain, the steps, the rules, etc - but I cannot figure how to set the argument values for the steps.
When I build jobs that are single calls to programs, I set the arguments like this:
dbms_scheduler.set_job_argument_value(
job_name => 'MY_JOB',
argument_position => 1,
argument_value => 'foo');
My question is: Which dbms_scheduler func/proc would I call to set the arguments for a job step? Using the examples below, how would set an argument for 'STEP_1' in 'MY_CHAIN'?
Thanks,
John
DBMS_SCHEDULER.CREATE_CHAIN (
chain_name => 'MY_CHAIN',
rule_set_name => NULL,
evaluation_interval => NULL,
comments => 'Chain calls 2 steps. Same program but with different arg values.');
DBMS_SCHEDULER.DEFINE_CHAIN_STEP (
chain_name => 'MY_CHAIN',
step_name => 'STEP_1',
program_name => 'MY_PROGRAM');
DBMS_SCHEDULER.DEFINE_CHAIN_STEP (
chain_name => 'MY_CHAIN',
step_name => 'STEP_2',
program_name => 'MY_PROGRAM');
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'MY_CHAIN_JOB',
job_type => 'CHAIN',
job_action => 'MY_CHAIN',
repeat_interval => 'freq=daily;byhour=12;byminute=0;bysecond=0',
enabled => TRUE);
I believe that you'd have to define two different programs for this, although they can of course reference the same stored procedure or executable.
In the case o the former unless I'm going to be modifying the argument values I tend to use anonymous block program types to specify the arguments to stored procedures -- it's complex enough without adding in all that program argument stuff.