newLISP for VisualNEO Win. Part 1: getting started
newLISP has been compiled into a Windows DLL (dynamic link library): newLISP.dll. Hans Peter Wickern made a free VisualNeo Win plugin that makes it possible to use newLISP within your VisualNeo Win GUI application builder (download hpwNewLISP from https://visualneo.com/product/hpwnewlisp).
Why to use newLISP?
a. shorter and more efficient code, e.g. by combining functions in one command
b. in many cases, faster performance, e.g. in case of nested loops
c. more than 350 built functions
d. functions can be combined in one command
e. great use of regular expressions
f. VisualNeo applications with newLISP run fine and fast under Wine/Linux (in contrast to VBScript, that often crashes).
g. newLISP is very well tested, so bugs will be rare.
And quoting the developer Lutz Mueller:
[newLISP] loads quickly and has a small memory footprint. newLISP is as fast or faster than other popular scripting languages and uses very few resources.
Distribution
Although newLISP is licensed as GPL 3.0, the author of newLISP Lutz Mueller allows you to distribute newLISP.dll along with your VisualNeo Win binary, without having to release your newLISP code under GPL 3.0 (restriction: “as long as your scripts do not use other 3rd party GPL’ed software in the form of imported libraries or loaded modules, your newLISP scripts don’t need to be GPL licensed.” – www.newLISP.org/index.cgi?FAQ)
When using newLISP in your software always mention the www.newlisp.org website in your documentation as a place where source code for newLISP is available.
To make your application work for users, you only have to distribute your VisualNeo binary, together with newLISP.dll and the free hpwNewLISP.nbr (found in the plugin package of Hans-Peter Wickern. Download: https://visualneo.com/product/hpwnewlisp).
Using newLISP code in VisualNeo Win
For testing VisualNeo Win examples you have to download hpwNewLISP from https://visualneo.com/product/hpwnewlisp and install the plugin.
Make a folder, e.g. D:\mcNewLISP, and put my sample ‘mcTestNewLISP.exe‘ -necessary resources inclusive- in it (www.mcdigit.nl/mcTestnewLISP.zip).
Try the instructions and examples below and you will be familiar with using newLISP in ‘mcTestNewLISP.exe‘.
Notice that you’ve sometimes to replace ” (double apostrophe) with { and } (or with [#34]) and sometimes [ by [#91] and ] by [#93]. I make a remark on that when necessary for the newLISP examples here.
1. First steps in newLISP
In this blog you’ll find no or no extended excursions on syntax topics of newLISP. I only provide information on newLISP that is useful for you as a VisualNeo user. We start with function calls, that offers you many possibilities.
Notice that newLISP is case-sensitive and uses e.g. lowercase function names!
1.1. Syntax function calls
Function calls in newLISP have an easy and consistent syntax. Study the next Lisp expression template, consisting of balanced parentheses and one or more items:
(function-name argument-1 argument-2 … argument-n)
An working example using this template is
(add 2 3.5)
This Lisp expression contains a call to the function ‘add’ with two arguments, i.e. 2 and 3.5. The returned value is 5.5
Keep in mind that
– the arguments are optional
– some functions need no argument and other functions >= 1
1.2. All functions in newLISP return a value.
Run the VisualNeo sample application ‘mcTestNewLISP.exe’, enter the expression
(add 2 3.5)
into the first textentry field, press the button ‘Call Lisp’ and the second textentry field shows the result, the value 5.5
In fact, the following VisualNeo Win code will run:
hpwnewLISPCall "(add 2 3.5)" "[DllRetvar]"
The result will be evaluated via
If "[nlcError]" "=" "" SetVar "[LispReturn]" "[DllRetvar]" Else SetVar "[LispReturn]" "Error: [nlcError]" Endif
Enter now the incorrect expression
(add 2 3.5
into the first textentry field (so without balanced parentheses) and press the button ‘Call Lisp’.
The second textentry field shows the result, the message Error:
6 ERR: missing parenthesis : “…(add 2 3.5”
1.2.1 Evaluation of all arguments first
newLISP evaluates the arguments first, before the function is applied to the arguments.
(+ 2 (- 6 3) (* 3 4))
→ 17
Notice that → means ‘returns the value: ‘.
The steps in this example:
(+ 2 (- 6 3) (* 3 4))
(- 6 3)
→ 3
(* 3 4)
→ 12
(+ 2 3 12)
→ 17
So, the expressions (- 6 3) and (* 3 4) are first evaluated before sent to the function.
These math examples are not very useful for you (VisualNeo has simple alternatives) but they were only meant as a demonstration of elementary newLISP syntax. Of course, I’ll present in the section ‘4. Exercises and examples’ some interesting math examples.
2. Functions can be combined
(div 8 3 2 2)
→ 0.6666666666666666
(round (div 8 3 2 2) -2)
→ 0.67
(add (round (div 8 3 2 2) -2) 5)
→ 5.67
3. TRUE or NIL
Some functions evaluate to TRUE or NIL. To test of all numbers are ordered in an ascending way, we could write
(< 2 3 5 7 8)
which returns TRUE.
(< 2 3 5 4 8)
returns NIL, which is the newLISP equivalent to FALSE.
4. Exercises and examples
To be complete, the functions add, sub, mul and div return a floating number if one of the operands is a floating number. The floating number is displayed without decimals if the decimals are all 0.
(add 2 3.25 9.75)
→ 15> (float? (add 2 3.25 9.75))
→ true
For integer arithmetic you can also use +, -, *, / Only for clarity, I present you these function calls, which you can modify as you like.
> (* 4.5 7.5)
→ 28
> (mul 4.5 7.5)
→ 33.75
(format “%2.1f” (* 4.5 7.5))
→ 28.0
The following functions are more useful for you. Please check www.newlisp.org/downloads/manual_frame.html for the precise syntax of the functions.
4.1 Basic arithmetic
(max 2 1.5 3 2.7)
→ 3
(min 2 1.5 3 2.7)
→ 1.5
(log (exp 3))
→ 3
(log 100 10)
→ 2
(pow 100 2)
→ 10000
(pow 100 0.5)
→ 10
(pow 100 0.5 3)
→ 1000
(% 10 3)
→ 1
(% -10 3)
→ -1
(mod 10.5 3.3)
→ 0.6
(mod -10.5 3.3)
→ -0.6
(mod -10.5 1)
→ -0.5
is equivalent to (mod -10.5)
(inc 0.25)
→ 1.25
(dec 9 0.25)
→ 8.75
(NaN? (sqrt -1))
→ true
(NaN? (div 0 0))
→ true
(inf? (div 1 0))
→ true
4.2 Trigonometric functions
Available functions:
acos, acosh, asin, asinh, atan, atanh, atan2, cos, cosh, sin, sinh, tan, tanh
(acos 1)
→ 0
(acosh 2)
→ 1.316957897
(cosh (acosh 2))
→ 2
(NaN? (acosh 0.5))
→ true
4.3 Rounding
(round 123.49 2)
→ 100
(round 123.49 1)
→ 120
(round 123.49 0)
→ 123
(round 123.49)
→ 123
(round 123.49 -1)
→ 123.5
(round 123.49 -2)
→ 123.49
(ceil -1.5)
→ -1
(ceil 3.4)
→ 4
(floor -1.5)
→ -2
(floor 3.4)
→ 3
4.4 Random selections
(rand 3)
could generate 0 or 1 or 2
(rand 3 10)
could generate (2 2 0 2 2 1 0 0 2 1)
(random 0 1 4) could generate
could generate (0.1555528427991577 0.5039216284676656 0.7320169682912686 0.4055909909360027)
(random 10 5)
could generate 11.0971 (a number between 10 and 15)
(random 10 7)
could generate 11.0971 (a number between 10 and 17)
(amb 1 2 3 4 5)
could generate 1 or 2 or 3 or 4 or 5
4.5 Sequences
(sequence 10 5)
→ (10 9 8 7 6 5)
(sequence 0 1 0.2)
→ (0 0.2 0.4 0.6 0.8 1)
(sequence 2 0 0.3)
→ (2 1.7 1.4 1.1 0.8 0.5 0.2)
(series 2 2 5)
→ (2 4 8 16 32)
(series 2 3 3)
→ (2 6 18)
The function ‘ssq’ calculates the sum of squares of a list of numbers:
(ssq (sequence 1 5))
→ 55
4.6 Lists
All Lisp expressions above are in fact a list, a typical newLISP data type. Normally the first element of a list is interpreted by newLISP as a reference to a function, which will then be invoked (recall what was said above in 1.1. Syntax function calls). Sometimes you do not want this and like to pass a list simply as data (and not as a implicit function call). In this case the list has to be quoted, i.e. preceded by an apostrophe. Example:
(ssq (sequence 1 5))
is a call to the function ‘ssq’ and its argument. This argument is a list that will be evaluated to the list (1 2 3 4 5). We can skip the call to the function ‘sequence’ and pass the list (1 2 3 4 5) directly to the function ‘ssq’.
(ssq ‘(1 2 3 4 5))
→ 55
The quoted list ‘(1 2 3 4 5) means: “take this list literally”, i.e. as a list of numbers, as data. (1 2 3 4 5) without preceding ‘ would be interpreted by newLISP as the function 1 and its parameters 2 3 4 5. This command will give of course an error.
4.7 From list to string
Sometimes the result of a newLISP function is a list (see the previous examples in 4.5 Sequences). To use such a list in VisualNEO, we could convert it into a CSV string. Example:
(join (map string (series 2 3 3)) “;”)
→ “2;6;18”
What this command does?
(series 2 3 3)
→ (2 6 18)
The list contains the three numbers 2, 6 and 18.
(map string (series 2 3 3))
→ (“2” “6” “18”)
The list has now three string elements. The function ‘map’ translated the list of numbers into a list of strings.
(join (map string (series 2 3 3)) “;”)
→ “2;6;18”
The function ‘join’ concatenates the list of string elements (“2” “6” “18”) into a string “2;6;18” and inserting the character ; between each string element.
Notice that the shorter equivalent (join ‘(“2” “6” “18”) “;”) has the same result but an apostroph before the list with the three strings is in that case necessary. Such a quoted list means to newLISP “take the list literally”, i.e. do not interprete the first element as a function!
5. You want to learn more about newLISP?
The previous information on newLISP syntax is all you need to know for making a successful start with newLISP in your VisualNeo application. If you can’t wait till the next tutorials are posted and want to learn more about newLISP, I recommend the following:
– https://en.wikibooks.org/wiki/Introduction_to_newLISP is a nice introduction on newLISP.
– http://www.newLISP.org/downloads/manual_frame.html gives you excellent information on newLISP.
Thank you for reading. Till next time!
Reinier Maliepaard
last update: 31-05-2019
Comments