Access HASH_TABLE element eiffel - hashtable

I have this simple code, I'd like to access an element in an ARRAYED_SET what is in a HASH_TABLE, but I get an error:
Error: target of the Object_call might be void.
What to do: ensure target of the call is attached.
here's my code:
class
APPLICATION
inherit
ARGUMENTS
create
make
feature {NONE}
make
local
elem: ARRAYED_SET[INTEGER]
table: HASH_TABLE[ARRAYED_SET[INTEGER], INTEGER]
do
create elem.make (3)
create table.make (1)
elem.put (4)
table.put (elem, 1)
table.at (1).go_i_th (1)
end
end

When you access an item in a HASH_TABLE it's possible that the item is not present. Therefore the signature of this feature is
item (k: K): detachable G
and it returns Void (or a default value for an expanded type) if the item is not found. So, when you try to use an item from HASH_TABLE, it should be checked whether it is attached or not. This can be achieved by replacing:
table.at (1).go_i_th (1)
with:
if attached table.at (1) as la_element then
la_element.go_i_th (1)
end

Related

Java 8 Map merge VS compute, essential difference?

It seems Both merge and compute Map methods are created to reduce if("~key exists here~") when put.
My problem is: add to map a [key, value] pair when I know nothing: neither key existing in map nor it exist but has value nor value == null nor key == null.
words.forEach(word ->
map.compute(word, (w, prev) -> prev != null ? prev + 1 : 1)
);
words.forEach(word ->
map.merge(word, 1, (prev, one) -> prev + one)
);
Is the only difference 1 is moved from Bifunction to parameter?
What is better to use? Does any of merge, compute suggests key/val are existing?
And what is essential difference in use case of them?
The documentation of Map#compute(K, BiFunction) says:
Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). For example, to either create or append a String msg to a value mapping:
map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))
(Method merge() is often simpler to use for such purposes.)
If the remapping function returns null, the mapping is removed (or remains absent if initially absent). If the remapping function itself throws an (unchecked) exception, the exception is rethrown, and the current mapping is left unchanged.
The remapping function should not modify this map during computation.
And the documentation of Map#merge(K, V, BiFunction) says:
If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value. Otherwise, replaces the associated value with the results of the given remapping function, or removes if the result is null. This method may be of use when combining multiple mapped values for a key. For example, to either create or append a String msg to a value mapping:
map.merge(key, msg, String::concat)
If the remapping function returns null, the mapping is removed. If the remapping function itself throws an (unchecked) exception, the exception is rethrown, and the current mapping is left unchanged.
The remapping function should not modify this map during computation.
The important differences are:
For compute(K, BiFunction<? super K, ? super V, ? extends V>):
The BiFunction is always invoked.
The BiFunction accepts the given key and the current value, if any, as arguments and returns a new value.
Meant for taking the key and current value (if any), performing an arbitrary computation, and returning the result. The computation may be a reduction operation (i.e. merge) but it doesn't have to be.
For merge(K, V, BiFunction<? super V, ? super V, ? extends V>):
The BiFunction is invoked only if the given key is already associated with a non-null value.
The BiFunction accepts the current value and the given value as arguments and returns a new value. Unlike with compute, the BiFunction is not given the key.
Meant for taking two values and reducing them into a single value.
If the mapping function, as in your case, only depends on the current mapped value, then you can use both. But I would prefer:
compute if you can guarantee that a value for the given key exists. In this case the extra value parameter taken by the merge method is not needed.
merge if it is possible that no value for the given key exists. In this case merge has the advantage that null does NOT have to be handled by the mapping function.

Inside type definition is reserved: Defining an array of structures inside another structure

Julia throws an error when i try to have an array of structures inside another structure.
ERROR: LoadError: syntax: "grid = Cell[]" inside type definition is reserved
here is the test code i am trying to run.
struct Cell
color::Int64
location::Int64
Cell(color::Int64,location::Int64) = new(color,location)
Cell()=new(0,0)
end
struct Grid
dimensions::Int64
timestep::Int64
grid=Cell[]
courseGrain=Cell[]
Grid(dimensions::Int64,timestep::Int64,grid_cell::Cell,courseGrain_cell::Cell) =
new(dimensions,timestep,push!(grid,grid_cell),push!(courseGrain,courseGrain_cell))
end
Defining default field values within field declarations is currently not allowed. See https://github.com/JuliaLang/julia/issues/10146
To achieve what you want, define your grid and courseGrain as a 1D array of type Cell, i.e. Array{Cell, 1} or equivalently Vector{Cell}, and handle the default case in your constructors.
struct Grid
dimensions::Int64
timestep::Int64
grid::Vector{Cell}
courseGrain::Vector{Cell}
Grid(dimensions::Int64,timestep::Int64,grid_cell::Cell,courseGrain_cell::Cell) =
new(dimensions,timestep,[grid],[courseGrain_cell])
end
If you want one of your constructors to create an empty grid or courseGrain, you may write Cell[] or Vector{Cell}(undef, 0) in your call to new.

Understanding Elm's Type Signature return types

I am trying to understand elm's type signatures. What does this function return exactly? It appears to be a function that accepts no arguments and returns ...
route : Parser (Page -> a) a
As a learning exercise for myself I'm going to try to answer this. Others will chip in if I get something wrong.
I'm sure you are used to something like
type Person = Adult String | Child String Age
Child is a type that takes two parameters. Parser is the same. But it's definition is pretty formidable
type Parser a b =
Parser (State a -> List (State b))
type alias State value =
{ visited : List String
, unvisited : List String
, params : Dict String String
, value : value
}
That said, you see how Parser is ultimately a wrapper around a function from a State to a list of States. Ultimately it is going to be passed a List of 'unvisited' strings or params; it will progressively 'visit' each one and the result will be combined into the final 'value'.
Next, note that while Parser takes two type parameters - a, b - parseHash is defined
parseHash : Parser (a -> a) a -> Location -> Maybe a
So, your original
route : Parser (Page -> a) a
is going to have to be
route : Parser (Page -> Page) Page
to type check.
To return to your original question, therefore, route is a Parser (which is a very general object) that encapsulates instructions on how to go from one Page to another, and can be used - via parseHash - to tell you what Page to go to next, and that is of course what you would expect from a router.
Hope this gets you started

Ordering using a declared variable's property

I have a ScInfo class that exists in many different classes. This class also has a list of ScDetails which has a Date member variable called nextExecution.
I need to continuously look up eligible objects with their ScDetails object's nextExecution member variable is after or equal to the current server's time (i.e. persistenceManagerInstance.getServerDate()). Meaning that I need to look up objects, with ScInfo having a ScDetails object with nextExecution >= serverDate)
So I use the following method (A portion is shown):
public List<Object[]> getEligbleForExecution(long amount) {
PersistenceManager pm = null;
Transaction t = null;
try {
pm = getPM();
t = pm.currentTransaction();
t.begin();
Query q = pm
.newQuery(
entityClass, //This is generic
"!this.deleted && this.scheduleActive && det.active == true && (det.nextExecution == null || det.nextExecution <= :serverDate) && det.running == false && this.scInfo.scDetails.contains(det)");
q.declareVariables(ScDetail.class.getName() + " det;");
q.setRange(0, amount);
q.setResult("this, det");
q.setOrdering("det.nextExecution"); // This is the statement I need to apply but it's causing the error below
Date serverDate = pm.getServerDate();
List<Object[]> raw = new ArrayList<Object[]>((List<Object[]>) q.execute(serverDate));
Which throws the following error stack trace (DEBUG level, I mentioned what I thought to be essential for solving this problem):
14:54:32 DEBUG (Log4JLogger.java:58)-[main] >> QueryToSQL.processVariable (unbound) variable=det is not yet bound so returning UnboundExpression
14:54:32 DEBUG (Log4JLogger.java:58)-[main] Updating mapping of org.datanucleus.store.rdbms.sql.expression.NullLiteral#727f3b8a to be org.datanucleus.store.mapped.mapping.DateMapping#e72a8082
14:54:32 DEBUG (Log4JLogger.java:58)-[main] Transaction rolling back for ObjectManager org.datanucleus.MultithreadedObjectManager#fba0f36
14:54:32 DEBUG (Log4JLogger.java:58)-[main] Rolling back [DataNucleus Transaction, ID=Xid={A strange uncopyable character is in here !}, enlisted resources=[]]
14:54:32 DEBUG (Log4JLogger.java:58)-[main] Transaction rolled back in 1 ms
14:54:32 ERROR (ScTasksDAOImpl.java:67)-[main] Looking up eligible SC tasks
java.lang.NullPointerException
at org.datanucleus.store.rdbms.query.QueryToSQLMapper.processVariableExpression(QueryToSQLMapper.java:3245)
at org.datanucleus.store.rdbms.query.QueryToSQLMapper.processPrimaryExpression(QueryToSQLMapper.java:2075)
at org.datanucleus.query.evaluator.AbstractExpressionEvaluator.compilePrimaryExpression(AbstractExpressionEvaluator.java:180)
at org.datanucleus.query.evaluator.AbstractExpressionEvaluator.compileUnaryExpression(AbstractExpressionEvaluator.java:169)
at org.datanucleus.query.evaluator.AbstractExpressionEvaluator.compileAdditiveMultiplicativeExpression(AbstractExpressionEvaluator.java:148)
at org.datanucleus.query.evaluator.AbstractExpressionEvaluator.compileRelationalExpression(AbstractExpressionEvaluator.java:123)
at org.datanucleus.query.evaluator.AbstractExpressionEvaluator.compileOrAndExpression(AbstractExpressionEvaluator.java:65)
at org.datanucleus.query.evaluator.AbstractExpressionEvaluator.evaluate(AbstractExpressionEvaluator.java:46)
at org.datanucleus.query.expression.Expression.evaluate(Expression.java:337)
at org.datanucleus.store.rdbms.query.QueryToSQLMapper.compileOrdering(QueryToSQLMapper.java:845)
at org.datanucleus.store.rdbms.query.QueryToSQLMapper.compile(QueryToSQLMapper.java:403)
at org.datanucleus.store.rdbms.query.JDOQLQuery.compileQueryFull(JDOQLQuery.java:883)
at org.datanucleus.store.rdbms.query.JDOQLQuery.compileInternal(JDOQLQuery.java:343)
at org.datanucleus.store.query.Query.executeQuery(Query.java:1747)
at org.datanucleus.store.query.Query.executeWithArray(Query.java:1666)
at org.datanucleus.api.jdo.JDOQuery.execute(JDOQuery.java:243)
at com.sc.ipk.sc.services.ScTasksDAOImpl.getEligbleForExecution(ScTasksDAOImpl.java:41)
at com.sc.ipk.ixl.services.IxlTestDAOImpl.main(IxlTestDAOImpl.java:977)
14:54:32 DEBUG (Log4JLogger.java:58)-[main] Object Manager "org.datanucleus.MultithreadedObjectManager#fba0f36" closed
So is it not possible to use declared variables to query ordering ? I tried using sub-queries but I couldn't get that to work either, may be I can start a new question for that, if ordering using declared variables isn't possible.
EDIT:
Neil generously suggested that ordering based on an element that should exist in a collection doesn't look reasonable to him. I understand that but I cannot for example look-up ScDetails objects first after ordering them of course and then look-up my main objects afterwards because my target main object may differ from time to time and I may look-up ScDetails objects that doesn't belong to the main candidate class.
For example:
A has ScInfo which has a collection of ScDetails
B, C (Same as above)
So if I lookup ScDetails objects first (After ordering an all), I cannot filter my main candidate classes (A, B & C) because I may use a ScDetails that belongs to A while I'm trying to get B or C candidates.
Thank you.
I don't see how you can order by that variable. It represents an element of a collection of the candidate. Consequently if a candidate has say 5 elements then it is indeterminate how it can order by some property on the element (1-N mapping). Obviously if the candidate was the element then ordering by some property of the element makes perfect sense, whether variable or not.

How do you emit to class that has a 'params' constructor?

Here is the definition of my Package class:
type Package ([<ParamArray>] info : Object[]) =
do
info |> Array.iter (Console.WriteLine)
member this.Count = info.Length
and here is the IL, I'm trying:
let ilGen = methodbuild.GetILGenerator()
ilGen.Emit(OpCodes.Ldstr, "This is 1")
ilGen.Emit(OpCodes.Ldstr, "Two")
ilGen.Emit(OpCodes.Ldstr, "Three")
ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<Object[]>|]))
ilGen.Emit(OpCodes.Ret)
but this doesn't seem to work. I tried:
ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<String>; typeof<String>; typeof<String>|]))
a well as:
ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<Object>; typeof<Object>; typeof<Object>|]))
but it just laughs at me. What am I doing wrong?
The [<ParamArray>] attribute indicates to a compiler that a method accepts a variable number of arguments. However, the CLR doesn't really support varargs methods -- it's just syntactic sugar provided by the C#/VB.NET/F# compilers.
Now, if you take away the [<ParamArray>], what are you left with?
(info : Object[])
That is the signature of the constructor you're trying to call.
So, you'll need to use the newarr and stelem opcodes to create an array, store the values into it, then call the constructor using the array as the argument. This should do what you want (though I haven't tested it):
let ilGen = methodbuild.GetILGenerator()
// Create the array
ilGen.Emit(OpCodes.Ldc_I4_3)
ilGen.Emit(OpCodes.Newarr, typeof<obj>)
// Store the first array element
ilGen.Emit(OpCodes.Dup)
ilGen.Emit(OpCodes.Ldc_I4_0)
ilGen.Emit(OpCodes.Ldstr, "This is 1")
ilGen.Emit(OpCodes.Stelem_Ref)
// Store the second array element
ilGen.Emit(OpCodes.Dup)
ilGen.Emit(OpCodes.Ldc_I4_1)
ilGen.Emit(OpCodes.Ldstr, "Two")
ilGen.Emit(OpCodes.Stelem_Ref)
// Store the third array element
ilGen.Emit(OpCodes.Dup)
ilGen.Emit(OpCodes.Ldc_I4_2)
ilGen.Emit(OpCodes.Ldstr, "Three")
ilGen.Emit(OpCodes.Stelem_Ref)
// Call the constructor
ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<Object[]>|]))
ilGen.Emit(OpCodes.Ret)
NOTE: In this code, I used the dup OpCode to avoid creating a local variable to hold the array reference while storing the element values. This is only feasible because this code is fairly straightforward -- I strongly suggest you create a local variable to hold the array reference if you want to build something more complicated.

Resources