Before starting

For the Compleat Fan
Locked
kib2
Posts: 9
Joined: Fri Nov 07, 2008 3:33 pm
Location: France
Contact:

Before starting

Post by kib2 »

Hi,

I'm new to newLisp, but before I really start playing with it, I need your lights on several points :

- can we make an executable file from a lsp one ? I know that asking such a question on a Lisp forum would result in "you don't have to, just run your script from the REPL". But I really do care about this: users are not programmers, and they need to be able to launch an app without having to spend their time fighting with EMacs/Slime or whatever.

- the only book I've got on Functionnal programming is Peter Seibel's "Practical Common Lisp". The first time he handles a macro, he shows something like this :

Code: Select all

(defmacro backwards (expr) (reverse expr))

CL-USER> (backwards ("hello, world" t format))
hello, world
NIL
I've tried doing the same 'reverse' macro with newLisp, but I don't know where I'm going wrong :

Code: Select all

> (define-macro (backwards expr) (reverse expr))
(lambda-macro (expr) (reverse expr))
> (backwards ("something" println))
(println "something")
The result is not interpreted and I must miss something, but what ?

Thanks for your answsers,

Kib².

unixtechie
Posts: 65
Joined: Sat Sep 06, 2008 6:30 am

Post by unixtechie »

please, read the "Cookbook" ("Code Patterns") and/or "introduction" from the newlisp documentation.
It's chock full of practical examples.
You can reimplement shell scripts, perl scripts and so on to practically useful little programs -- completely avoiding (or rather postponing) the more academic books on the subject, which are mostly interested in "factorial" and then reimplementing very low-level stuff as an exercise in pedantry.

That is the unfortunate tradition in teaching Lisp.
You can avoid it by starting immediately to use high-level perl-like functionality of newlisp if you start from its own documentation.

Experimenting with building unobvious abstractions will be the next step after you've remembered and used the main operators of newlisp (which is like a nice cross between a scheme and common lisp) and got the hang of it.

See "Documentation" here:
http://www.newlisp.org/index.cgi?page=Features


TO ANSWER YOUR FIRST QUESTION, yes one can make a pseudo-standalone executable from a newlisp script: please READ THROUGH THE MANUAL at least once.
Basically, the idea is that you include some command file and run one command, and it will bundle your script with the newlisp executable together.
For the user it'll look like a standalone exec of 230k+(size of your script), very roughly.
For the machine it's a self-extracting script that will be then interpreted in a usual way by the small and fast newlisp language binary.

kib2
Posts: 9
Joined: Fri Nov 07, 2008 3:33 pm
Location: France
Contact:

Post by kib2 »

Hi unixtechie,

You're right I've not read the entire docs (but if you want to test a new language, you often read between the lines...and the manual is just 329 pages long!).

I've no interest in building shell scripts-like, I'm using Python, Perl or Ruby for such everyday tasks. Nor do I want to write another factorial :)

But in following your suggestion, I just realized that I missed the nice vids from Michael Michaes : they are very well done.

Thanks for answering my first answer, I'll try to read the manual carefully.
What about the second one ?

I like playing with text and regexps, so I've tried to download the wiki engine, but the link seems dead.

Another question : when does the v10.0.0 comes out ?

Thanks.

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

Hi Kib2!

I'm not a Lisp expert, and so I'm puzzled by your CL example, but I would assume you want this in newLISP:

Code: Select all

(define-macro (backwards expr) (eval (reverse expr)))
where the eval will actually evaluate the (reverse expr) expression, rather than just reverse it and return...

kib2
Posts: 9
Joined: Fri Nov 07, 2008 3:33 pm
Location: France
Contact:

Post by kib2 »

Hi cormullion,

I've taken the sample from chapter 3 of PCL : http://gigamonkeys.com/book/practical-a ... abase.html (about 3/4 of the page, or search for the word 'macro', it's quicker). PCL is not like other academic books, it has been a pleasure to read.

Yes, once I saw the result in my newLisp code, I though I had to 'eval' the result, and sure it works. Now my question is rather "why should I eval the result ?" and "why is it different from Common Lisp internals ?".

See you.

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

It's an interesting challenge - learning one language from a book written about another. You're almost learning two languages at once... And why not! :)

There are sufficient differences between CL and newLISP that would make that approach a bit frustrating for some people, though. Lutz' advice in the FAQ is to not refer to a Common Lisp or Scheme tutorial:
Don't read books about LISP to learn newLISP. Most books deal with Common LISP or Scheme, two different, older standards of LISP. These books teach you concepts that you don't need to know to learn newLISP. newLISP does things much differently from the older standards, in ways that are more applicable to today's programming tasks.

If you study other LISPs before trying to understand newLISP, you won't learn to solve problems the newLISP way. But if you want a deeper understanding of newLISP, read the Users Manual section of the newLISP manual, with less theory and more examples. There is also Code Patterns with more tips and code pieces.

Part of the specific answer to your question is that technically (and I'm not confident that I know what I'm talking about here) newLISP doesn't have macros, but fexprs. These are frowned upon in the CL world for (possibly) perfectly valid reasons, but these reasons may not be significant for your application or purpose.

As for version 10, only Lutz knows, but if I were to guess a release date, I'd say early December... :)

Kazimir Majorinc
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia
Contact:

Post by Kazimir Majorinc »

Why CL needs macros, on the first place?

Because there are some things that cannot be done with functions. For example, you cannot write function ifnt that behaves like inverse if ((ifnt a b c) = (if a c b)) in Common Lisp .

Code: Select all

(ifnt (> i 1) (setf i 10) (setf i 100))
because both (setf i 10) and (setf i 100) are evaluated before ifnt is called. And ifnt, just like if wants that only one of these two is evaluated. One might think that expressions can be quoted

Code: Select all

(ifnt '(> i 1) '(setf i 10) '(setf i 100))
But neither it works in Common Lisp - because function ifnt doesn't understand what is the value of i (except if i is global variable). Common Lisp need something much different than function.

In Newlisp this second works - because Newlisp has dynamic scoping and unrestricted eval. CL has static scoping and restricted eval. Newlisp functions see that i from caller environment, you do not need to pass it as a separate argument. So, Newlisp essentially doesn't need macros at all - functions can do all that. And macros are functions with tiny bit of syntactic sugar - one doesn't need to use quotes like in '(> i 1) in caller environment.

CL macros are more complicated. They are evaluated during compile time, and they generate expression that is evaluated during runtime. Newlisp macros are just like functions. That's why texts on CL macros are not very useful for Newlisp macros.

This really isn't simple issue.

m i c h a e l
Posts: 394
Joined: Wed Apr 26, 2006 3:37 am
Location: Oregon, USA
Contact:

Post by m i c h a e l »

kib2 wrote:… I just realized that I missed the nice vids from Michael Michaes : they are very well done.
Thank you for your kind words, kib2. Actually, I've just finished the first episode of a new video series (although work on the second episode is presently holding up completion of the first ;-) This latest offering will be released with a companion slideshow, too!

m i c h a e l

kib2
Posts: 9
Joined: Fri Nov 07, 2008 3:33 pm
Location: France
Contact:

Post by kib2 »

-->cormullion : "You're almost learning two languages at once...
And why not! :)"

You're right, maybe that's not the good approach. Thanks for telling me about
the CL fexprs : I wasn't aware of them.

-->Kazimir :

Thanks for your nice sample. Maybe I'm wrong, but the simple 'if' cannot be a function too : right ?

-->michael :

Cool : the slideshow is a good idea too.

newBert
Posts: 156
Joined: Fri Oct 28, 2005 5:33 pm
Location: France

Post by newBert »

cormullion wrote:It's an interesting challenge - learning one language from a book written about another. You're almost learning two languages at once... And why not! :)
I learnt NewLISP (and Scheme, that I left on one side now to concentrate on newLISP) using a french Python tutorial, that I annotated with newLISP codes.

It's interesting to learn two or more languages at once ...so long as they are not too nearby like newLISP and Common Lisp or newLISP and Scheme for instance. Because, in a way one interfere too much with the other, in any case as for me. I prefer to use different languages, which enrich each other instead...

I quite like using, almost at the same time, newLISP, Rebol, FBSL and ELICA ...

... moreover Practical Common Lisp is an excellent and easy tutorial which gave me help too

:-)
BertrandnewLISP v.10.7.6 64-bit on Linux (Linux Mint 20.1)

Kazimir Majorinc
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia
Contact:

Post by Kazimir Majorinc »

kib2 wrote:
simple 'if' cannot be a function too : right ?
True, if cannot be the function in CL, with or without extra quotes. However, if can be function in Newlisp with extra quotes.

Code: Select all

(set 'iff (lambda(a b c)(if (eval a) (eval b) (eval c)))

(iff '(= (+ 2 2) 4)'(println "yes")'(println "no"))
The function iff uses macro-like primitive if, but it can be avoided.

Code: Select all

(set 'ifily (lambda(a b c)
             (eval (nth (find (eval a) '(true nil))
                        (list b c)))))

(ifily '(= (+ 2 2) 5) '(println "yap!") '(println "nope!"))
Note that CL has not fexprs=Newlisp macros. Older, pre-CL Lisps had fexprs. It would be hard to implement fexprs in CL; on the other hand, it is easy to implement CL macros in Newlisp.
Last edited by Kazimir Majorinc on Mon Nov 10, 2008 12:36 pm, edited 1 time in total.

kib2
Posts: 9
Joined: Fri Nov 07, 2008 3:33 pm
Location: France
Contact:

Post by kib2 »

Note that CL has not fexprs=Newlisp macros. Older, pre-CL Lisps had fexprs. It would be hard to implement fexprs in CL; on the other hand, it is easy to implement CL macros in Newlisp.
ok, that suggest me some more questions :

- if fexprs were so good, why do they disappear from CL ?

- P.Seibel said :
And, in a compiled Lisp program, that new language is just as efficient as normal Lisp because all the macro code--the code that generates the new expression--runs at compile time. In other words, the compiler will generate exactly the same code whether you write
. Is this statement true for newLisp too ?

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

newLISP doesn't compile, so you just write elegant and efficient code to begin with. :)

As for the fexpr stuff, that wikipedia article told me more than I wanted to know... :) They pose problems for compilers, was my understanding... (" the compiler cannot tell whether a subexpression can be safely optimized, since the subexpression might be treated as unevaluated data at run-time".

Kazimir Majorinc
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia
Contact:

Post by Kazimir Majorinc »

kib2 wrote:if fexprs were so good, why do they disappear from CL ?
In my opinion it is bad design. It is justified by fact that fexprs are hard to understand by programmers, and trouble for compiler writers. For example, one of the arguments is that if you have fexprs, compiler cannot optimize (f (+ 1 1)) because it doesn't know whether f is fexpr of function. Function doesn't care, but fexpr does. Kent Pitman wrote historically important article Special forms in Lisp about that. It took me long time to understand it, but I think it is all more-less wrong.
- P.Seibel said :
And, in a compiled Lisp program, that new language is just as efficient as normal Lisp because all the macro code--the code that generates the new expression--runs at compile time. In other words, the compiler will generate exactly the same code whether you write
. Is this statement true for newLisp too ?
If Newlisp has optimizing compiler, it could be the truth. With "ordinary" compiler, compiled code would be bit slower. Only a bit, however. But, as Cormullion said, there is no compiler for Newlisp at all, it is interpreter, so every function and macro you write is necessarily slower than primitives.

However, that macroexpansion phase that Siebel described enthusiastically is not really good thing in every situation. Look at following CLisp code:

Code: Select all

[1]> (defun pump-l(n x)(setf L ())(dotimes(i n)(push x L)))
[2]> (defun eval-whole-L()(dolist (f L)(eval f)))

[3]> (pump-l 100000 '(progn (setq A ())(push 0 A)))
[4]> (time (eval-whole-l))

Real time: 3.046875 sec.
Run time: 3.046875 sec.
Space: 91965272 Bytes
GC: 144, GC time: 0.375 sec.
This is relatively slow - because it contains macro push. Now, look what happens if I avoid macro (push 0 A), replacing it with its expansion (setq A (cons 0 A)) manually:

Code: Select all

[5]> (pump-l 100000 '(progn (setq A ())(setq A (cons 0 A))))
[6]> (time (eval-whole-l))

Real time: 0.1875 sec.
Run time: 0.1875 sec.
Space: 800008 Bytes
GC: 1, GC time: 0.015625 sec. 
You see, 15 times faster code and 100 times less memory use. Why? In this example, code is generated - and then evaluated during runtime. Hence, because code contained push macro, macroexpansion happened during runtime - there was no choice. And that macroexpansion took some 95% of total processing time. So, CL macros are not really suitable for code generated and evaluated during runtime.

newdep
Posts: 2038
Joined: Mon Feb 23, 2004 7:40 pm
Location: Netherlands

Post by newdep »

I love how intresting topics popup here...
...and with even nicer explanations ;-)


PS: Kazimir, you got some psychedelic webpage there ;-)
-- (define? (Cornflakes))

Kazimir Majorinc
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia
Contact:

Post by Kazimir Majorinc »

newdep wrote:PS: Kazimir, you got some psychedelic webpage there ;-)
Yes, I have one socrealist version also, but I decided to go with psychedelic one.

kib2
Posts: 9
Joined: Fri Nov 07, 2008 3:33 pm
Location: France
Contact:

Post by kib2 »

Kazimir :

thanks for all these references and snippets, you're handling CL or newLisp with great ease: congrats ! Your psychedelic webpages reminds me the times when I was coding on a Commodore 64 computer.

I also just saw you came from Croatia, I've been there 2 years ago and I must say it has been one of the best trip I've ever made : very nice country !

cormullion : sure, newLisp is not compiled, my fault !

newdep :
I love how intresting topics popup here...
...and it's just a start :

- Is there any IRC chanel for newLisp ?
- Why do you choose newLisp over CL, Scheme, Clojure, Scala, Haskell, or whatever functionnal langage ?

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

For Irc, try:

http://www.alh.net/newlisp/phpbb/viewto ... rc+newlisp

or if you want to see me struggle through making an irc client badly, see:

http://unbalanced-parentheses.nfshost.com/idlechatter

Sadly, noone here uses #newlisp at Irc, so the room is usually empty. And often I'm not at my computer when someone drops in.

For why, there's:

http://www.alh.net/newlisp/phpbb/viewtopic.php?t=1930

which has a few thoughts.

xytroxon
Posts: 296
Joined: Tue Nov 06, 2007 3:59 pm
Contact:

Post by xytroxon »

IRC is difficult to schedule... We all live in very different time zones and like to sleep (when possible) ;)

For short tasks, newLISP gets the job done in less time than it takes my Python or PHP interpreters to finsh loading, let alone start executing my Python or PHP code...

I use newLISP to "data mine" the internet... Download a webpage with get-url and using regex functions find, replace etc. to retrieve info and create reports etc... In my opinion, that reason alone is enough to learn and use newLISP!!!

------

Other ramblings...

LISP is the world's second oldest programming language (Fortran was first)... And LISP (Scheme, et al), is the longest running advanced grad-student programming research project in history... IMHO, gone crazy. ;)

newLISP is new... Many times the newLISP version I use is only days or hours or even minutes old... ;)

LISP contains obsolete machine specific syntax: car, cdr, etc... And weird pseudo extensions like: caar, caaar, cddr, cdddr, cddddr... (What's that ugly mess???)

newLISP uses first, last, n-th... Simplicity is beauty...

LISP tries to be all things, and self contained... A "real" LISP doesn't need (or want) a C/C++ compiler... (until open source movement created current C/C++ versions of LISPs) Also code libraries are an exercise left to the LISP user to figure out...

newLISP is written in C, allowing it to compile on most modern computerss... Code libraries are either "built in" or easy to connect to directly from the newLISP language... The later, is is a major achievement over the insane process needed to compile Python library dlls...

LISP's creator John McCarthy has said that the test of a true LISP dialect is that it must be able to recreate itself (or another LISP version)... That is, to be called "LISP", the interpreter/compiler must be able to create a new interpreter/compiler...

newLISP? We have Lutz to create new versions of newLISP ;0

LISP was used to create almost all of the data structures and techniques that other programming languages have borrowed... But LISP was slow to embrace object oriented programming... (Use a list, stupid.)

newLISP is lean and mean, and uses the best LISP techniques that work to get the job done.. FOOP was added to newLISP easily and seemlessly... (How did we live without it?)

LISP programmers know everything...

newLISP programmers know little, if anything... (Just ask any LISP programmer ;)

LISP programmers are snobs to newbies...

newLISP programmers are helpful... Your newLISP questions help use to learn more and to think in different ways...

LISP is for race car designers...

newLISP is for space ship captains...

newLISP's motto: Simply to do LISP's original mission... Realise the full potential of LISt Processing...

-- xytroxon
"Many computers can print only capital letters, so we shall not use lowercase letters."
-- Let's Talk Lisp (c) 1976

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

:) like it

space ship captains?!

DrDave
Posts: 126
Joined: Wed May 21, 2008 2:47 pm

Post by DrDave »

cormullion wrote::) like it

space ship captains?!
seek out new worlds... go where no man has gone before.
...it is better to first strive for clarity and correctness and to make programs efficient only if really needed.
"Getting Started with Erlang" version 5.6.2

xytroxon
Posts: 296
Joined: Tue Nov 06, 2007 3:59 pm
Contact:

Post by xytroxon »

DrDave wrote:
cormullion wrote::) like it

space ship captains?!
seek out new worlds... go where no man has gone before.
The newLISP mission:
To seek out new programming paradigms and idioms... To boldy go... Where no scripting laanguage has gone... before...
"Many computers can print only capital letters, so we shall not use lowercase letters."
-- Let's Talk Lisp (c) 1976

Locked