Well, I understand pointers themselves. I understand that the name of an array, when passed to a function, is really just a pointer to the head of a contigous block of memory. Function pointers just get screwy because of the syntax needed:
long* (*fn_pointer)( int*, int*)
Whereas in lisp you can simply store a function in any symbol...
(setf my-symbol #'make-hash-table)
Setf sets the value of the symbol "my-symbol" to the function "make-hash-table" (every symbol can have a variable value and a functional value. To get at the functional value you use the #' syntax...so in this example my-symbol is set to the function stored under the symbol "make-hash-table".)
To call this function, just like any other function call in Lisp, all you have to do is put that symbol as the first element of a lisp form...
so
(my-symbol :size 200)
now creates a hash-table of 200 elements. It's equivalent to the call
(make-hash-table :size 200)
Both calls will, in fact, will produce the exact same machine code.
Another simple thing I love about lisp...keyword parameters. Keyword parameters are named parameters (like :size in the function call above) that may be omitted from the function call, or they can be placed *in any order*.
In most languages, you can have optional parameters, but they won't let you omit any of the parameters out of order. I.e: You could decide to provide only the 1st and 2nd param, but if you wanted to provide only the 5th you'd have to include the 4 before it. Not so with Lisp.
You can also call make-hash-table with a :rehash-size parameter, a :test parameter (which is a function which is used to compare the provided key to the stored key), etc. Any and or all parameters may be included or omitted.
But truly the most powerful part of lisp is the fact that you can use the full power of the language as a "pre-compiler" using Lisps macro system. And, given Lisps regularity of syntax, it is easy to treat code as data and manipulate it prior to compiling it. You could for instance write a Macro that allowed you to write C++ code that would then get translated to lisp. Granted, that'd be a lot of work, but it is possible. One example of a cool macro is Lisps built in LOOP macro, which defines it's own mini language and allows you to type something like this:
(defparameter *random* (loop repeat 100 collect (random 10000)))
(loop for i in *random*
counting (evenp i) into evens
counting (oddp i) into odds
summing i into total
maximizing i into max
minimizing i into min
finally (return (list min max total evens odds)))
*random* here is a variable with a list of 100 random values, 0-9999. The loop itself should be quite clear as to what it is doing. It creates local variables with the "into" keyword. Counting, summing, maximizing and minimizing are all keywords in this little mini-language, and direct the loop to do just as their name implies. Finally, the loop returns a list of the values accumulated during the loop.
The loop macro is completely non-lispy, but gets turned into lisp code before being compiled. This is because the above code gets passed to the loop macro, which then processes the code (it's basically a mini-compiler for this domain specific language) and turns it into lisp code that actually gets compiled.
This of course means that you can write your own scripting language with any syntax you desire and suffer no speed loss because it actually gets translated to lisp prior to compilation.
long* (*fn_pointer)( int*, int*)
Whereas in lisp you can simply store a function in any symbol...
(setf my-symbol #'make-hash-table)
Setf sets the value of the symbol "my-symbol" to the function "make-hash-table" (every symbol can have a variable value and a functional value. To get at the functional value you use the #' syntax...so in this example my-symbol is set to the function stored under the symbol "make-hash-table".)
To call this function, just like any other function call in Lisp, all you have to do is put that symbol as the first element of a lisp form...
so
(my-symbol :size 200)
now creates a hash-table of 200 elements. It's equivalent to the call
(make-hash-table :size 200)
Both calls will, in fact, will produce the exact same machine code.
Another simple thing I love about lisp...keyword parameters. Keyword parameters are named parameters (like :size in the function call above) that may be omitted from the function call, or they can be placed *in any order*.
In most languages, you can have optional parameters, but they won't let you omit any of the parameters out of order. I.e: You could decide to provide only the 1st and 2nd param, but if you wanted to provide only the 5th you'd have to include the 4 before it. Not so with Lisp.
You can also call make-hash-table with a :rehash-size parameter, a :test parameter (which is a function which is used to compare the provided key to the stored key), etc. Any and or all parameters may be included or omitted.
But truly the most powerful part of lisp is the fact that you can use the full power of the language as a "pre-compiler" using Lisps macro system. And, given Lisps regularity of syntax, it is easy to treat code as data and manipulate it prior to compiling it. You could for instance write a Macro that allowed you to write C++ code that would then get translated to lisp. Granted, that'd be a lot of work, but it is possible. One example of a cool macro is Lisps built in LOOP macro, which defines it's own mini language and allows you to type something like this:
(defparameter *random* (loop repeat 100 collect (random 10000)))
(loop for i in *random*
counting (evenp i) into evens
counting (oddp i) into odds
summing i into total
maximizing i into max
minimizing i into min
finally (return (list min max total evens odds)))
*random* here is a variable with a list of 100 random values, 0-9999. The loop itself should be quite clear as to what it is doing. It creates local variables with the "into" keyword. Counting, summing, maximizing and minimizing are all keywords in this little mini-language, and direct the loop to do just as their name implies. Finally, the loop returns a list of the values accumulated during the loop.
The loop macro is completely non-lispy, but gets turned into lisp code before being compiled. This is because the above code gets passed to the loop macro, which then processes the code (it's basically a mini-compiler for this domain specific language) and turns it into lisp code that actually gets compiled.
This of course means that you can write your own scripting language with any syntax you desire and suffer no speed loss because it actually gets translated to lisp prior to compilation.