Macros need explanation
-
- Posts: 15
- Joined: Sun May 10, 2009 3:11 am
Macros need explanation
I hail from Common Lisp, where the entire idea of macros is completely different, it seems, from that of newLisp.
Could someone please explain to me exactly what a newLisp macro does? Does it evaluate its body and not evaluate its inputs? Or does it evaluate its inputs but not its body? How can I use these macros to turn newLisp into a programmable programming language - the Lisp I know and love?
And slightly off topic, but the (clean ...) function seems to have a bug that produces a segmentation fault.
Could someone please explain to me exactly what a newLisp macro does? Does it evaluate its body and not evaluate its inputs? Or does it evaluate its inputs but not its body? How can I use these macros to turn newLisp into a programmable programming language - the Lisp I know and love?
And slightly off topic, but the (clean ...) function seems to have a bug that produces a segmentation fault.
-
- Posts: 388
- Joined: Thu May 08, 2008 1:24 am
- Location: Croatia
- Contact:
Welcome!
Newlisp macro is like function that gets unevaluated arguments. Newlisp macros existed in pre CL Lisps under the name of fexprs, and it is usually considered fexprs are more expressive, but harder to compile efficiently than CL macros, and it was the main reason fexprs are dropped from CL. Because Newlisp is interpreter it doesn't matter much.
Obviously, they are very similar to functions:
(set 'f (lambda(x y) some-code ))
(set 'm (lambda-macro(x y) some-code ))
(m a b) has exactly the same result as (f 'a 'b).
One difference between Newlisp and CL macro is that result of Newlisp macro is not evaluated once again in the body of the caller, like it is the case in Common Lisp macros. If you want that Newlisp macros work on similar way as CL macros, you have to add one eval.
(defmacro m(arguments) some-code)
is roughly equivalent to Newlisp
(define-macro (m arguments)(eval some-code))
Usually Newlisp macros have that extra eval, but it might be pushed deeper into macro body.
I have one blog post about that here:
http://kazimirmajorinc.blogspot.com/200 ... spers.html
Many other posts in my blog demonstrate some uses of macros.
Newlisp macro is like function that gets unevaluated arguments. Newlisp macros existed in pre CL Lisps under the name of fexprs, and it is usually considered fexprs are more expressive, but harder to compile efficiently than CL macros, and it was the main reason fexprs are dropped from CL. Because Newlisp is interpreter it doesn't matter much.
Obviously, they are very similar to functions:
(set 'f (lambda(x y) some-code ))
(set 'm (lambda-macro(x y) some-code ))
(m a b) has exactly the same result as (f 'a 'b).
One difference between Newlisp and CL macro is that result of Newlisp macro is not evaluated once again in the body of the caller, like it is the case in Common Lisp macros. If you want that Newlisp macros work on similar way as CL macros, you have to add one eval.
(defmacro m(arguments) some-code)
is roughly equivalent to Newlisp
(define-macro (m arguments)(eval some-code))
Usually Newlisp macros have that extra eval, but it might be pushed deeper into macro body.
I have one blog post about that here:
http://kazimirmajorinc.blogspot.com/200 ... spers.html
Many other posts in my blog demonstrate some uses of macros.
Some things to consider while kicking the newLISP "tires" during a "test drive"...
LISP is a gear shift high performance Formula One race car*...
Scheme is a gear shift midget race car on a cross-country Formula One course in Europe...
newLISP is an automatic shift hybrid automobile on a modern American super highway...
While LISP and Scheme "cars" are certainly high performance modes of transportation, and fun to drive once you are trained and race qualified... newLISP aims to be a more practical and economical mode of programming "transportation"... All three share the same kind of technology "under the hood", but there are tradeoffs made for total cost of ownership versus performance... That is, I can compile my custom designed code in LISP and Scheme for speed, but newLISP can still get the job done even if it is a bit slower... And by using newLISP's built in convenience functions, I save huge time costs in developement...
While most people may prefer driving clunky Java/C++/PHP SUV's, a green newLISP hybrid is the future... (And with newLISP, I don't wrap it around a light pole every time I go to the supermarket for milk ;o)
-- xytroxon
*on a snowy and muddy road in Siberia ;o)
LISP is a gear shift high performance Formula One race car*...
Scheme is a gear shift midget race car on a cross-country Formula One course in Europe...
newLISP is an automatic shift hybrid automobile on a modern American super highway...
While LISP and Scheme "cars" are certainly high performance modes of transportation, and fun to drive once you are trained and race qualified... newLISP aims to be a more practical and economical mode of programming "transportation"... All three share the same kind of technology "under the hood", but there are tradeoffs made for total cost of ownership versus performance... That is, I can compile my custom designed code in LISP and Scheme for speed, but newLISP can still get the job done even if it is a bit slower... And by using newLISP's built in convenience functions, I save huge time costs in developement...
While most people may prefer driving clunky Java/C++/PHP SUV's, a green newLISP hybrid is the future... (And with newLISP, I don't wrap it around a light pole every time I go to the supermarket for milk ;o)
-- xytroxon
*on a snowy and muddy road in Siberia ;o)
"Many computers can print only capital letters, so we shall not use lowercase letters."
-- Let's Talk Lisp (c) 1976
-- Let's Talk Lisp (c) 1976
-
- Posts: 15
- Joined: Sun May 10, 2009 3:11 am
I don't understand this misconception that Common Lisp/Scheme are faster just because they are compiled. In most benchmarks they perform worse than Perl (which we'll call a "fast" interpreted language) even when speed 3 safety 0 is on.
When I saw the mergesort benchmark, I was pretty impressed; newLisp seems to perform on par with Perl, so I have no trouble with speed in NL at all (if I did, I have old faithful C, and the fact that newLisp has a FFI that makes sense to turn to).
That aside, these concepts of macros seem to be a bit troublesome. In CL, you used macros to redefine the language and selectively expand/replace expressions, choosing which parts of the expression you wanted to eval now and which parts you wanted to eval later.
I suppose I would be a little more comfortable if NL had support for that `( , ,) syntax that I'm used to.
EDIT.
Cool, it clicked. So a macro in newlisp is just a function that doesn't evaluate its arguments when passing them, unlike in CL where its a replacement sort of thing.
When I saw the mergesort benchmark, I was pretty impressed; newLisp seems to perform on par with Perl, so I have no trouble with speed in NL at all (if I did, I have old faithful C, and the fact that newLisp has a FFI that makes sense to turn to).
That aside, these concepts of macros seem to be a bit troublesome. In CL, you used macros to redefine the language and selectively expand/replace expressions, choosing which parts of the expression you wanted to eval now and which parts you wanted to eval later.
I suppose I would be a little more comfortable if NL had support for that `( , ,) syntax that I'm used to.
EDIT.
Cool, it clicked. So a macro in newlisp is just a function that doesn't evaluate its arguments when passing them, unlike in CL where its a replacement sort of thing.
-
- Posts: 388
- Joined: Thu May 08, 2008 1:24 am
- Location: Croatia
- Contact:
Newlisp doesn't have ` , - but it has letex and expand serving similar purpose.
is directly translated to
After some practice one can write his own unquote and quasiquote.
Code: Select all
(defmacro my-dotimes(head body)`(dotimes ,head (progn ,body (print "hi"))))
Code: Select all
(define-macro (my-dotimes head body)
(eval (expand
'(dotimes head (begin body (print "hi"))) 'head 'body)))
Yes. And vice versa - Newlisp functions can do everything Newlisp macros can - except for that apostrophes. So, unlike in other Lisp dialects, one can define IF as a function.Cool, it clicked. So a macro in newlisp is just a function that doesn't evaluate its arguments when passing them, unlike in CL where its a replacement sort of thing.
Code: Select all
(set 'IF (lambda()
(eval
((args)
(find (true? (eval (first (args))))
'(* true nil))))))
-
- Posts: 15
- Joined: Sun May 10, 2009 3:11 am
-
- Posts: 2038
- Joined: Tue Nov 29, 2005 8:28 pm
- Location: latiitude 50N longitude 3W
- Contact:
The more metaphors (mixed or otherwise), the merrier! ;p)cormullion wrote:Me, I think of newLISP as a bicycle... :) Small, light, portable, and quick off the mark...
To expand and expound on this "ailing equine"... (i.e. this topic maybe becoming the proverbial "dead horse")
The superhighway is of course the internet, which newLISP excels at traveling... Without the internet, newLISP is not going anywhere very interesting... But, if the internet disappears tomorrow, LISP and Scheme will just as happily stay on their own closed racetracks...
And the different fuel sources, that power the "super" hybrid newLISP "car"?
Windows - gasoline / petrol (cheap at first, very costly later)
Mac - electric battery (continually reincarnating /recharging "dead" techology)
Linux - ethanol (everyone can have their own distillery/distro)
Unix - solar (high tech fabrication required)
-- xytroxon
"Many computers can print only capital letters, so we shall not use lowercase letters."
-- Let's Talk Lisp (c) 1976
-- Let's Talk Lisp (c) 1976
-
- Posts: 608
- Joined: Mon Feb 05, 2007 1:04 am
- Location: Abbotsford, BC
- Contact:
-
- Posts: 388
- Joined: Thu May 08, 2008 1:24 am
- Location: Croatia
- Contact:
-
- Posts: 2038
- Joined: Tue Nov 29, 2005 8:28 pm
- Location: latiitude 50N longitude 3W
- Contact:
:)
To return to the original post: I'm interested in the question:
I'm currently trying to learn Objective-C, while leaving newLISP on the back burner for a while (still transitioning to v10). For now I'm trying to avoid any comparisons or translations. I want to learn the "objective-c-ness" of Objective-C as it is, rather than trying to find or force any "newLISPness". There might be some natural overlap between the two, although at the moment my biggest problem is that I keep starting each line of code with a "("...
To return to the original post: I'm interested in the question:
I think there's plenty of scope for exploring code-data interaction in newLISP, but I'm also kind of intrigued as to why the OP is looking for a 'fling' with newLISP after professing love for CL. :) Perhaps after such affairs the return to the familiar is a welcome home-coming...?! Or is there some magic missing from the relationship...?How can I use these macros to turn newLisp into a programmable programming language - the Lisp I know and love?
I'm currently trying to learn Objective-C, while leaving newLISP on the back burner for a while (still transitioning to v10). For now I'm trying to avoid any comparisons or translations. I want to learn the "objective-c-ness" of Objective-C as it is, rather than trying to find or force any "newLISPness". There might be some natural overlap between the two, although at the moment my biggest problem is that I keep starting each line of code with a "("...
-
- Posts: 394
- Joined: Wed Apr 26, 2006 3:37 am
- Location: Oregon, USA
- Contact:
The quote continues:John Foderaro wrote:"Lisp is a programmable programming language."
— CACM, September 1991
This makes me think of one’s ability to modify an already defined user-function in newLISP:“Not only can you program in Lisp (that makes it a programming language) but you can program the language itself. This is possible, in part, because Lisp programs are represented as Lisp data objects, and partly because there are places during the scanning, compiling and execution of Lisp programs where user-written programs are given control.”
Code: Select all
(s)hell> newlisp
newLISP v.10.0.4 on OSX IPv4 UTF-8, execute 'newlisp -h' for more info.
> (define (cubed n) (* n n n))
(lambda (n) (* n n n))
> (cubed 3)
27
> (cubed 3.5)
27
> (nth 1 cubed)
(* n n n)
> (setf (nth 1 cubed) '(mul n n n)) ; notice the quote
(mul n n n)
> (cubed 3.5)
42.875
> _
This was my experience when one language or another proved too difficult or simply just felt wrong to me. I would go back to my previous language and immediately feel right at home. The downside is this can also make it difficult to readily see the true merits of a new language. And speaking of other languages . . .cormullion wrote:Perhaps after such affairs the return to the familiar is a welcome home-coming...?!
I don’t envy you your current affair, cormullion. Especially if you are simultaneously trying to get your mind around the whole of Cocoa’s API. I’ve tried twice and failed both times. If you already know Smalltalk, you will be way ahead (Objective-C’s message calling is similar to Smalltalk’s). Just think of the square brackets as newLISP parens ;-)
m i c h a e l
P.S. Great visualizations of the three languages, Kazimir :-)