# Language Reference/Terms/Arguments

< Language Reference | Terms

This article contains preliminary documentation for Visual Prolog 9.The relevant features may be absent or different in Visual Prolog 8. |

This section describes named, default, optional parameters and functor originals. Even though these notions are individual they also have a significant impact on each other and therefore they are described together.

In brief:

**Named parameters**: In a call the actual arguments can be supplied by formal parameter name rather than position.**Default parameters**: A default parameter value can be stated toghether with a formal argument in a predicate declaration. This value is used when no actual parameter is supplied.**Optional parameters**: An actual parameter is optional and can therefore be skipped.- '
*Functor original*: Functor term which is used as/bound to the original of another functor term (in a functor term expression).

#### Named parameters

The formal parameter names from a declaration can be used to specify the actual arguments in a call by using the syntax **:<Formal> = <Actual>**.

**addPerson**:

class predicates addPerson : (string Name, integer Height, integer Weight).

You can call **addPerson** using positional arguments like this:

addPerson("Hans", 175, 75)

But you can also use named parameters like this

addPerson(:Name = "Hans", :Height = 175, :Weight = 75)

Where **Name**, **Height** and **Weight** are the names that is used in the declaration.

When using named parameters the order of the parameters are insignificant, so this call has the same meaning:

addPerson(:Weight = 75, :Name = "Hans", :Height = 175)

Poisitional and named parameters can be mixed such that the first arguments are given by position and the last by name. Here the **Name** is given by position and **Weight** and **Height** are given by name

addPerson("Hans", :Weight = 75, :Height = 175)

Notice that all positional arguments must be to the left of the first named argument.

#### Default parameters

A default parameter is defined by adding **= <value>** after a formal parameter in a declaration (**<value>** must be a compiletime constant expression).

**addPerson**has three parameters

**Name**,

**Height**and

**Weight**::

class predicates addPerson : (string Name, integer Height = 175, integer Weight = 75).

**Height** has default value **175** and **Weight** has default value **75**.

#### Optional parameters

If a parameter is **[out]** or if it has a default value then the actual argument is optional and can be skipped provided that it is the last argument in the call. Skipping an **[out]** parameter corresponds to supplying an anonymous variable for that parameter. Skipping a parameter that has a default value corresponds to supplying the default value for the parameter.

class predicates ppp : (integer A = 17, integer B [out]).

We can skip **B** because it is the last parameter and **[out]**, so here we supply **12** for **A** and ignore the **B** output:

ppp(12) % corresponding to ppp(12, _)

In the call above **12** is the last argument, but there is a default value for that parameter so that argument can also be skipped:

ppp() % corresponding to ppp(17, _)

Using named arguments we can exchange the order of the parameters:

ppp(:B = Out, :A = 17)

In that call the last parameter has a default value so it can be skipped:

ppp(:B = Out) % corresponding to ppp(B: = Out, :A = 17) --> ppp(17, Out)

#### Functor originals

A functor original is a syntactic construction that describes an *original* for a functor term expression. Syntactically it takes the following form:

<functor>(<arguments> | <functor original> )

The functor original can either be a a functor value or a free variable. In both cases the construction inticates that the functor may have more arguments than those mentioned explicitly in front of the bar.

If the functor original is a functor value then it will be used as original for constructing a new functor value.

domains person = person(string Name, integer Height, integer Weight). class predicates updateName : (person Person, string NewName) -> person Updated. clauses updateName(Person, NewName) = person(NewName | Person).

Here we use **Person** as original in the functor term expression **person(NewName | Person)**. This expression will create a new **person** value which has **NewName** as the **Name**/first component. All the remaining functor components (i.e. **Height** and **Weight**) are taken from the original, i.e. **Person**.

The use of functor originals can be combined with named parameters:

domains person = person(string Name, integer Height, integer Weight). class predicates updateWeight : (person Person, Integer NewWeight) -> person Updated. clauses updateWeight(Person, NewWeight) = person(:Weight = NewWeight | Person).

Here **NewWeight** is used as **Weight** component. And again the remaining functor components (i.e. **Name** and **Height**) are taken from the original, i.e. **Person**.

The functor original can be any kind of term as long as it evaluates to an appropriate functor term.

clauses mkPerson(Name) = person(Name | getCurrentPerson()).

If a functor domain has more than one alternative, then the functor original must be of same kind as the term that is constructed.

domains transport = aircraft(string Name, integer Seats, integer Range); car(string Name, integer Doors).

The following is legal:

A1 = aircraft("Cruiser 1", 25, 300), A2 = aircraft("Cruiser 2" | A1) % legal A1 is an aricraft

Because **A1** is an **aircraft**, and it is an **aircraft** we are constructing (as **A2**).

This is illegal:

C = car("Taxi 23", 4), A = aircraft(:Seats = 25, :Range = 173 | C) % illegal C is a car

Because **C** is a **car** but we are constructing an **aircraft**, it does * not* matter/help that a

**car**has a

**Name**component, which is what we need for the

**aircraft**we are constructing.

In a functor match the functor original can be an anonymous variable. And in that it simply indicates that the term can have more components which we don't care about.

class predicates getName : (transport Transport) -> string Name clauses getName(aircraft(Name | _)) = Name. getName(car(Name | _)) = Name.

Here we have used an anonymous variable as functor original indicating that the functor term has/may have more arguments (which we are not interested in).

In the **car** case the functor original only represents one additional argument, but using this form the code will be robust to adding aditional components to **car** later. For the same reason, it can make sense to provide a functor original that doesn't represent any addiational arguments (i.e. that represents zero extra arguments).

Here is a predicate that determines whether a **transport** is a **car**:

class predicates isCar : (transport Transport) determ. clauses isCar(car( | _)).

This example also shows that it is not necessary to provide any regular arguments at all besides the functor original.

In a functor match the functor original can be a **named** variable. If the variable is bound then it is used as an original for constructing a functor value and then that functor value is used in the match.

C = car("Taxi 23", 4), car("Taxi 24" | C) = getCurrentCar()

**C**is used as original creating the term

**car("Taxi 24", 4)**. This term is then matched against the result of calling

**getCurrentCar**.

If the functor original is a free variable (in a functor match) then that variable will be bound to the entire functor term:

**Free**is a free variable

car("Taxi 24" | Free) = getCurrentCar(),

This code is equivalent to this code:

Free = getCurrentCar(), car("Taxi 24" | _) = Free,

I.e. **Free** is bound to the result of calling **getCurrentCar** and then it is matched to this functor pattern **car("Taxi 24" | _)**.

Notice that the code will **fail** (and not raise an exception) if **getCurrentCar** returns an **aircraft**.

Also consider this code (where **Name** and **Car** are both free variables):

car(Name | Car) = getCurrentCar(),

it equivalent to this code

Car = getCurrentCar(), car(Name | _) = Car