Functions Using PicoLisp .
Drakopoulos
Anastasios
Summary.
This article describes the use of functions in PicoLisp.
Introduction.
Functions
are indispensable to programming. Little can be done without the use
of functions. The language can be enriched and become more powerful
using functions. PicoLisp supports the use of functions in a simple
though productive way. Considering the fact that everything is a list
and that data and programs coincide, functions become a great tool
for programming. The simplicity employed by PicoLisp is applied to
functions too. The general pattern of the list that defines a
function is the following:
(de
argumens-list program-list)
After
the symbol “de” follows the list of arguments and after that list
the program follows. But when should you use a function? Functions
prevent the useless repetition of code. When you want to execute some
procedures many times, you can and should define a function. Defining
a function means that we define a part of code with parameters. These
parameters make the function flexible enough to be applied in many
different cases and contexts. In this way we prevent repetition of
code saving time and labor. Additionally , creating a function is the
first step for the creation of libraries. When you define a function
it could be useful for many programs in the future. Thus you could
include it into a library. Then you can load this library and use all
the functions included into it to many programs. It is very useful
and this fact could increase your productivity as a programmer
dramatically. A function is defined once but it is used infinitely
many times. Thus when you define a function you should create it in
order to complete a concrete task. In this way you should be able to
use it many times under different contexts.
Function Definition I.
You
should follow the pattern:
(de
arguments-list program-list)
The
argument are used for communication with the function caller while
the program-lists are used to complete a concrete task. Into the
program-list you can use any PicoLisp function you like. Consider the
following trivial example.
(de
my-plus(x y) (+ x y))
The
function “my-plus” accepts two numbers as arguments and returns
their sum. In the same way we could define the following functions
for the arithmetic operations:
(de
my-sub(x y) (- x y))
(de
my-mult(x y) (* x y))
(de
my-div(x y) (/ x y))
You
could call the previous functions as follows:
:
(my-plus 2 3) -> 5
:
(my-sub 5 2) -> 3
:
(my-mult 2 3) -> 6
:
(my-div 6 2) -> 3
One
could ask: if we want to add/subtract/multiply/divide infinitely many
integers? How we have to define the corresponding functions? The
solution is simple:
(de
my-plus-m @ (pass +))
(de
my-sub-m @ (pass -))
(de
my-mult-m @ (pass *))
(de
my-div-m @ (pass /))
That
simple!
Examples
of these functions calls follow:
:
(my-plus-m 1 2 3 4) -> 10
:
(my-plus-m 12 6)
-> 18
:
(my-sub-m 10 2 3 4) -> 1
:
(my-sub-m 10 2 3) -> 5
:
(my-mult-m 2 3 4) -> 24
:
(my-mult-m 1 2 3 5)
-> 30
:
(my-div-m 100 2 5 2) -> 5
The
symbol “@” means that our function can accept infinitely many
arguments. This fact means that we have defined a function that can
be called by a different number of arguments each time. The function
“pass” means that all the arguments given will be passed as
arguments to the primitive functions +,-,*,/ of PicoLisp and the
results will be returned. Be careful ! PicoLisp's simplicity may be
addictive!
Function Definition II.
You
can define a function using the simple “setq” function instead of
“de”, as follows:
: (setq
a-fun '((x)(println x)))
And
you can use it as follows:
:
(a-fun "hello")
-> "hello"
When
you key in a function name with the right arguments into parentheses,
then the expression is evaluated and the results are returned as in
the following example:
:
(a-fun "hello")
-> "hello"
But if
you key in the name of the function only, then its definition is
returned as in the following example:
: a-fun
-> ((x) (println x))
And
here the magic of PicoLisp begins! A list is returned and we can use
the “car” and “cdr” functions to take some parts of it:
: (car
a-fun)
-> (x)
: (cdr
a-fun)
-> ((println x))
Its
almost amazing! The first part [extracted with car] of the list is
its list of arguments while the rest of the list [extracted with cdr]
is the program-list. Alternatively you could use “rest” function
instead of “cdr”. Additionally you could take all the arguments
of a function while inside the function's body using “rest”
function as in the following example:
: (de
b-fun @ (rest))
If you
call the previous
function the list of its arguments is returned as follows:
:
(b-fun 1 2 3 4)
-> (1 2 3 4)
:
(b-fun "hello" 11 22 "my friend" 33 44)
->
("hello" 11 22 "my friend" 33 44)
In
case you want to access a specific argument of a function you can use
the “arg” function as in the following example:
: (de
c-fun @ (println "arg1 = " (arg 1) ) (println "arg2 =
" (arg 2)) (println "arg3 = " (arg 3)))
Calling
the previous function after its definition we get the following
results:
: (c-fun
"hello" 222 "my friend")
"arg1
= " "hello"
"arg2
= " 222
"arg3
= " "my friend"
-> "my
friend"
In
case we want to suppress the last echo “my friend” we have to add
a NIL symbol at the end of function's body as follows:
: (de
c-fun @ (println "arg1 = " (arg 1) ) (println "arg2 =
" (arg 2)) (println "arg3 = " (arg 3)) NIL )
In
this case, calling this function we get the following results:
:
(c-fun "hello" 222 "my friend")
"arg1
= " "hello"
"arg2
= " 222
"arg3
= " "my friend"
->
NIL
Simlpe Examples Of Functions In PicoLisp.
#function that does nothing(de nothing())
#function that returns a "hello"
(de hello-0() "hello")
#function that returns msg
(de msg-0(msg) msg)
#function that prints msg
(de print-msg(msg) (print msg))
#function that returns a salutation
(de salute(user salutation) (pack user " " salutation))
#function that prints a salutation
(de print-salute(user salutation)
(print (pack user " " salutation)) )
(de hello(user)(println (pack "Hello " user)))
(de mul @ (let prd 1 (while (args) (setq prd (* prd (next))))))
(de suma @ (let mysum 0 (while (args) (setq mysum (+ mysum (next))))))
Running the functions into the Picolisp environment we get the following results:
: (nothing)
-> NIL
: (hello-0)
-> "hello"
: (msg-0)
-> NIL
: (msg-0 "hello all my friends")
-> "hello all my friends"
: (print-msg "hello my friends")
"hello my friends"-> "hello my friends"
: (salute "Tom" "Good morning")
-> "Tom Good morning"
: (print-salute "Tom" "Good morning")
"Tom Good morning"-> "Tom Good morning"
#picolisp #function #tutorial #examples :https://t.co/jrsDSH2GOm
— Anas Drak (@anasdrak) September 7, 2019