We provide a page that lists all the issue messages from the SARL compiler.
Additionally, several run-time errors from the Janus framework are explained here.
No.
When a decimal point is written in the literal, the fractional part and the mantissa part must be specify also, even if these parts are equal to zero. Consequently:
123.0
is correct;0.123
is correct;123.
is incorrect;.123
is incorrect.It is not allowed to put a SARL keyword, such as
agent
, in the name of a package.
But, if you prefix with the ^
character the string
that corresponds to a keyword, then it is possible
to obtain a package name with one of its components
equals to a SARL keyword:
In SARL, the creation of anonymous classes (interface implementation…) must be done with a closure.
Consider the definition of the following interface:
interface MyInterface {
def myfunction(parameter : Object) : void
}
The on-the-fly definition and instantiation of an instance of this interface, a.k.a. anonymous class definition in the Java community, could be written is SARL with the following closure:
var instance : MyInterface
instance = [ parameter | /* The code of myfunction() */ ]
In SARL, it is recommended tp create anonymous classes (interface implementation…) must be done with a closure (see previous question).
The Java-based syntax for defining an anonymous class’s instance is allowed, but not recommended in the SARL language. It means that the following code is valid:
var instance = new MyInterface() {
def myfunction(parameter : Object) {
/* The code of myfunction() */
}
}
Yes and No.
Indeed, the val
keyword defines a name that it could be initialized only once time.
It is similar to the final
modifier of the Java language.
Consider the example below: two values are defined, a
and b
.
The a
variable is a real constant because it has a raw type and it is initialized.
The b
variable is not a real constant because it is a reference to an object.
The reference is constant, but the referred object is not. Consequently, it is still
possible to call the setters of b
.
val a : int = 4
val b : Object = new Object
This is a design choice given that our entities are agents and as such they should not “share” data unless done explicitly in an agent-oriented manner, for example via resources or communication channels. Having static fields in agents or skills would break the “independency” of agents, also known as their autonomy.
It is most probable that such static data can be seen as a resource outside the skill or agent, and as such it should be managed outside it (for example by using the artifact meta-model).
In SARL, the array type may be written with the classic array syntax, such as
int[]
, or the object-oriented syntax, such as List<Integer>
.
SARL considers that the each array is a list of something.
Consequently, retrieving the values of the array must be done with get(int)
.
var a : Integer[] = #[1, 2, 3]
var b : List<Integer> = newArrayList(1, 2, 3)
a.get(0) == b.get(0)
In SARL, the empty generic parameter list, written <>
is
not supported: a generic type expression must be written between them.
For solving this problem, two choices: i) add a type expression between
<
and >
; ii) remove the generic parameter list.
var firstSolution : List<Integer> = new ArrayList<Integer>
var secondSolution : List<Integer> = new ArrayList
==
, ===
, !=
, !==
) in SARL and checking for null: same as Java?The mapping of the operator from SARL to Java are:
a === b
becomes a == b
a !== b
becomes a != b
a == b
becomes a == null ? (b == null) : a.equals(b)
a != b
becomes !Objects.equals(a,b)
. This is null-safe (part of Google API)
and the code of the function is a == b || (a != null && a.equals(b))
.It is always better to test valid against null
with the ===
or !==
operators.
Because the SARL ==
operator is mapped to the Java equals()
function, and the
===
and !==
operators to the Java ==
and !=
operators, it is better/safer,
and a best practice, to use ===
and !==
when one of the operands is of primitive
type, e.g. null
, number constants, primitive type variables. These operators are
not replaced neither operator_equals
nor operator_notEquals
within the Java code.
Usually, the SARL compiler generates a warning to push you to use ===
in place of ==
.
But with null == value
, an ambiguous call error occurs before the warning is generated.
In fact, the SARL compiler tries to find an overloading function for the ==
operator.
Since null
has not a specific type, the SARL compiler find multiple overloading functions.
Check the documentation for details on the overloading mechanism of SARL.
When the calling a capacity function, the SARL compiler complains with an “ambiguous call” error.
In the code below, the function myfunction
is defined in the capacities C1
and C2
.
The call to myfunction
in the agent definition is the place where the error occurs.
capacity C1 {
def myfunction
def myfunction2
}
capacity C2 {
def myfunction
def myfunction3
}
agent MyAgent {
uses C1, C2
on Initialize {
myfunction
myfunction2
myfunction3
}
}
This error is standard because the functions of the capacities C1
and C2
are implicitly accessible
in the scope of the agent definition, see uses
keyword definition. The SARL compiler is then unable
to determine that is the function to call.
For solving this issue, the developer must explicitly call the correct version of myfunction
by
getting the capacity. The following code is the correct call to the function if the function in the
capacity C1
should be called:
getSkill(C1).myfunction
SARL comes with a Pair<A,B>
class to build an object for storing two values, nicknamed “key” and “value”. It comes useful when a method has
to return two values instead of just one. For example, the following function returns the next floor and direction that an elevator has to serve:
def kb_getNextJob() : Pair<Integer, Double> {
//...
}
As of Java 8, and as part of JavaFX, Java provides this Pair<A,B>
class; check here and
here. Note Pairs are different from Map
, which can be seen as a collection
of Pairs and with a proper key/value semantics.
There exist more advanced implementations of Pair
, for example from Apache. See here,
here and here.
SARL itself have compact syntax do deal with Pair
, by using a -> b
to create a Pair
object (a,b)
. There are also compact ways of manipulating Collection and Maps.
Check SARL documentation on that here.
Consider this code:
on CarArrivedPercept {
cars.get(occurrence.car).floor = occurrence.floor
}
We know that occurrence
is static, so cannot be changed. However, in the above code,
occurrence.car
, is not being changed/assigned, but just used to refer to another entity
where assignment is performed.
However, SARL compiler will think that occurrence.car
may be changed due to a border effect
of the get
, and complain with warning.
Consider this code:
on CarArrivedPercept {
occurrence.floor = 1
}
The line occurrence.floor = 1
generates an error because in this case the SARL compiler
is sure that the occurrence
instance is changed.
In order to avoid the warning above, you could write the code as:
on CarArrivedPercept {
var c = occurrence.car
cars.get(c).floor = occurrence.floor
}
The enforcement of no-side-effect in guards was introduced in version 0.9: guard expression must not have side effect.
SARL compiler tries to figure out if the functions used in the behavior guard have side-effect. It does some clever analysis of the name of the method (e.g., getters) and also tries to check if the body has any method that is not pure (i.e., that may have side-effects).
If this analysis does not work, the programmer can mark a method as pure using @Pure
annotation, e.g.,:
@Pure
def MT_getEntityState(param : E_MoveRandomly) : int {
// Do something complex
return 0
}
Details on the documentation page for function definition.
The functions for emitting an event are named emit
(for emitting a specific context) and
wake
(for emitting into the internal context only).
These functions are provided by the agent capacities DefaultContextInteractions
,
ExternalContextAccess
or Behaviors
These two functions have an optional last argument that is the scoping expression:
def emit(e : Event, scope : (Address) => boolean = null)
def wake(e : Event, scope : (Address) => boolean = null)
This scoping expression is a lambda expression that takes the agent’s address of a candidate for receiving the event,
and returns true
if the agent with the given address should receive the event.
Let a local variable named [:selectedagentidfield] of type UUID
that contains the identifier of an agent
that is expected to receive an event of type MyEvent
.
The following code provides the call to the emit
for sending the event only to this selected agent.
emit(new MyEvent) [
it.ID == selectedAgentID
]
The first argument of the emit
is the occurrence of the event to send to the other agents.
The second argument is the lambda expression for scoping the receivers. This argument is written
according to the externalized form of the lambda expression (between brackets).
The lambda expression expression has an argument, named it
by default, of type Address
.
This address is the one of a agent candidate for receiving the event.
Then, the expression in the lanmda expression tests if the identifier of the candidate is equal
to the identifier of the selected agent, namely selectedAgentID
By adding the scoping lambda expression, only the selected agent will receive the agent.
Use setLogLevel()
of the Logging
capacity, as explained here in the
API documentation.
You could also control the general configuration of the log level from the options of your SARL Run-time Environment, such as Janus.
Yes. Since the SARL compiler generates valid Java code including the documentation, you could generate the documentation of your SARL program with the standard javadoc tool applied on the generated Java files.
Additionally, you could use a specific Javadoc doclet in order to generate a documentation that follows the SARL syntax, instead of the Java syntax.
You could find details on the page dedicated to the Maven documentation plugin.
Copyright © 2014-2024 SARL.io, the Original Authors and Main Authors.
Documentation text and medias are licensed under the Creative Common CC-BY-SA-4.0; you may not use this file except in compliance with CC-BY-SA-4.0. You may obtain a copy of CC-BY-4.0.
Examples of SARL code are licensed under the Apache License, Version 2.0; you may not use this file except in compliance with the Apache License. You may obtain a copy of the Apache License.
You are free to reproduce the content of this page on copyleft websites such as Wikipedia.
Generated with the translator docs.generator 0.14.0.