Filed under: Best Practices
  Comments: 1

NexJ Scheme is NexJ’s scripting language, which is based on and extends Scheme R(6)RS.

The at sign (“@”) is a special macro in NexJ Scheme, and provides a special way of accessing a value through associations relative to this pointer and much more.

This table summarizes the most common use cases of the @ macro within NexJ Scheme, provided with examples and their explanations. Pay close attention to the “Note” column for macro usage recommendations and performance concerns.

Use Example Effect Note
Retrieve attribute value (@ lastName)

(@ act title)

(@ addrs fullName)

(this'lastName)

((this'act)'title)

((this'addrs)'fullName)

Recommended especially for long association paths, as it simplifies the nested brackets.

Note that (@ addrs fullName) returns an instance associated collection, not a regular collection or list.

Set attribute value (@ lastName : "New Name") (this'lastName "New Name") Avoid using this special syntax as it is difficult to read.
Invoke class event (@ createCopy : entity) (this'createCopy entity) Avoid using this special syntax as it is difficult to read.
Get size of instance associated collection In Act class:

(@ entityParticipations act :size)

Returns total count of all acts associated to all assign to entities on the current act. These also work:

(length (@ entityParticipations act :list)

(collection-length (@ entityParticipations act))

Use in collection-find-item In Entity class:

(collection-find-item (@ addrs) (= (@ city) (“Toronto”)))

Finds the first address for the entity in city Toronto. The @ macro in (@ addrs) refers to the current entity instance.

The @ macro in (@ city) is a special way of referring to the current address instance in the (@ addrs) collection.

Dynamic type checking In Entity class:

(@ addrs (= (@ city) "Toronto") address1)

 

In Address class:

(@ entity (instance? (@) Person) lastName)

Returns a collection of address first lines where the address’s city is “Toronto”.

 

When using instance? within the association path, it will evaluate the last entry in the association path (for example, entity) with the inner association page (for example, (@)), and check its class against the one passed in: if it’s true, it will continue along the association path, otherwise it will return null.

Supports conjunctions. For example: (@ entity (and (instance? (@) Person) <another-condition1> ...) lastName)

 

Note that the filtering (city = “Toronto”) of Address class instances is performed in memory via multiple SQL statements:

select A.id, A.locking from NJAddress A where A.entityId = ?

select A.id, A.address1, … from NJAddress A where A.id = ?

Iterate over association paths with collections In Entity class:

(for-each
(lambda (city) …)
(@ addrs city)
)

Iterates over all the cities in the addresses collection. Can have arbitrary combinations of collections and instances on the association path, and supports filters.
Optimize database filtering on collection associations (Person'read
'(firstName)
'(any (= (@ addrs city)
"Toronto"))
'() '() '() '()
)
Reads all Persons where the address city is Toronto.

 

SQL:

select A.id, A.firstName, A.classCode, A.locking from NJEntity A where A.deletedFlag = 0 and exists(select 1 from NJAddress B where A.id = B.entityId and B.city = 'Toronto') and A.classCode in (N'PSN', N'USR')

Recommended since the database will return only one person record per matching addresses as opposed to returning as many copies of a person record as there are matching addresses when using the equals operator (Person'read ... '(= (@ addrs city) "Toronto") ...)

 

SQL:

select A.id, A.firstName, A.classCode, A.locking from NJEntity A inner join NJAddress B on A.id = B.entityId where A.deletedFlag = 0 and B.city = 'Toronto' and A.classCode in (N'PSN', N'USR')

Interchange this with @ In Scheme Console:

(define this entity)

(@ businessAddress city)

Setting this allows @ to work accordingly. Useful when debugging in Scheme Console.

Also used in macros like (map-this).

Use in aggregate functions (Person'read'(firstName lastName (: _countryCnt (count (@ addrs country))) '() '() '() '() '()) Reads Persons and counts the number of countries tied to addresses. Attribute annotations must be aggregate expressions including: unique, count, sum, average, minimum, maximum.

Do not use on large collections, for system scalability reasons.

 

Advanced: What is the “@@” Syntax?

The “@@” syntax is very different from “@” and can be useful in the following two scenarios:

  • For downcasting attributes
  • To indicate a reverse association with the WHERE clause. Be careful as this syntax has two completely unrelated meanings

Attribute downcast

Use Example Effect Note
(Entity'read '(lastName (@@ Person homePhone)) () () () () ()) Reads from Entity class and retrieves the homePhone attribute for the Person subclass of Entity only. Attribute homePhone is defined on Person class only. Useful for performing polymorphic from a base class and loading subclass-specific attributes.
Where clause reverse association (Address'read '() `(= (@@ User person addrs) ,(user)) '() '() '() '()) Reads Addresses from the person associated to the current user.
Note that this is equivalent to (((user)’person)’addrs).
SQL:
select A.id, A.locking from NJAddress A inner join NJEntity B on A.entityId = B.id inner join NJUserPerson C on B.id = C.id where A.deletedFlag = 0 and A.viewPrincipalId in (…) and C.userId = ‘00000000000010008000BEEF0000000C’
Useful when querying from the end of an association back to the class you are reading, for example, querying on Address of User based on User instance, as opposed to forward association query on User based on User’s Address instance.
NexJ UI clients may use this syntax.
The syntax form is (@@ part3 part2 part1) where part1 (for example, addrs) represents an attribute with a type of the class (for example, Address) being read.

Feedback

  Comments: 1

  1. Vaibhav khopade

    Vaibhav khopade


    Thank you so much for the wonderful article.
    This is very helpful for better understanding of scheme scripting.

Your feedback

You must be logged in to post a comment.