
NewLisp - jsnathan
http://www.newlisp.org/index.cgi?Home
======
gecko
Has anyone ever used NewLisp for something interesting? Would you mind talking
about your experience? NewLisp, despite the name, is actually quite old at
this point, and its release cycle has slowed down a bit over the years. I'm
assuming it landed so high on the front page because people are interested, so
some real-life stories would be helpful.

(I have a real-life story that concludes with "so I got fed up and rewrote the
thing in Python", but I'm not all convinced that the problem wasn't with me.)

~~~
jwr
I remember looking at it 12 years ago or so, for embedded applications. For
some reason I decided to go with ISLISP instead, though I no longer remember
why.

~~~
TheSmoke
oh, so newlisp is not that much new then.

~~~
dragonwriter
> oh, so newlisp is not that much new then.

Well, its new compared to Lisp in general.

~~~
namekuseijin
its features are comparable to old Lisps from the 70's, prior to Scheme and
Common Lisp. Nothing really new here at all and lots of old bugs passing for
features.

------
munificent
Dynamic scope.

Pass everything by value.

No closures.

No GC.

Implement almost the whole thing in one giant 7k line file[1].

I can't tell if this is a work of genius or madness.

[1]:
[https://github.com/kosh04/newlisp/blob/develop/newlisp.c](https://github.com/kosh04/newlisp/blob/develop/newlisp.c)

------
riscy
I'm just going to list all of my criticisms after reading what's on the
website:

1\. Treating functions as lists effectively makes this a weakly typed language
like C, whereas both Scheme and Common Lisp are both strong.

2\. What advantage does having implicit function arguments (using nil if not
provided, not default arguments) have at all unless if you just hate type
safety and would prefer unreliable software? There are lots of other ways to
maintain type safety while eliding runtime type checks in hot loops.

3\. Changing the binding time for free variables within a closure would also
imply that a binding by that name must be in scope at the time the function is
called, no? This sounds like dynamic scoping... which is known to be difficult
to use and error prone. Do you just assume 'nil' when no binding exists?

~~~
kazinator
NewLisp was designed by a psychologist, who took meticulous care to endow it
with design elements such that it would be instantly hated and denounced by
anyone who has had anything to do with real Lisp, causing them to spew babble
that is incomprehensible to NewLisp n00bies, save for the lingering perception
that something gratuitously negative has been spoken. This, in turn, has the
calculated effect of making them dig deeper into their trenches.

It is best to remain silent upon the subject of the NewLisp design. Let people
make their bed and lie in it.

By the way, if you want to see a really crazy NewLisp zealot, search for
Kazimir Majorinc. Wow ...

Maybe he's quit since (and even reformed?); it's been a few years.

> _Changing the binding time for free variables within a closure_

What closure? NewLisp has done away with those, and offers "name space
contexts"

[http://www.newlisp.org/index.cgi?page=Closures](http://www.newlisp.org/index.cgi?page=Closures)

These are basically something like modules with static variables.

~~~
JeremyReimer
I'm not sure it's fair to tar all newLISP advocates with the same brush. I
understand the design choices that Lutz Mueller made, and I can understand how
they might be considered unsatisfactory by other Lisp users. That's fine-- I
don't expect newLISP to be everything to everybody, and I don't consider it to
be the be-all and end-all of languages.

I do find it to be very lightweight and flexible, with excellent documentation
and a good built-in library. This makes it useful as a scripting language and
for rapid prototyping. I wouldn't recommend it for very large-scale tasks or
for projects developed by large teams.

~~~
kazinator
> _I don 't expect newLISP to be everything to everybody, and I don't consider
> it to be the be-all and end-all of languages._

Lutz Mueller does. For instance, quote: _LISP is an old language born, grown,
and standardized in times very different from today, times when programming
was for highly educated people who engineered programs. newLISP is LISP reborn
as a scripting language: pragmatic and casual, simple to learn without
requiring you to know advanced computer science concepts._

Sure, no advanced computer science concepts: just five different hacks to
choose from to do some aspect of what a lexical closure does. (Just pick the
one whose assumptions are least likely to break in your use case: but no
engineering knowledge required to do that, nope!)

NewLisp requires the users to absorb advanced concepts that have fallen by the
wayside of the computer science mainstream. A fexpr or self-modifying code are
still computer science concepts.

Basically what Lutz is the real problem in NewLisp; other than that, the thing
is what it is, take it or leave it. More than needing a compiler, garbage
collection or lexical closures, it just needs a dose of humility, really.

On that note, it's somewhat good to see that a lot of the anti-Lisp ranting
has been toned down compared to just several years ago. I don't get the sense
that Lutz is yet eating any real crow. At best, he's pouring crow-flavored
syrup over his ice cream. But at least that's a start!

------
pjlegato
People interested in NewLisp may also like Pixie, a small Clojure-like
scripting language.

[https://github.com/pixie-lang/pixie](https://github.com/pixie-lang/pixie)

~~~
jopython
But, newpLisp's tiny C codebase can be compiled and made to run on even
obscure UNIXes like AIX, Solaris, HPUX etc without installing any dependencies
which Pixie needs.

~~~
pjlegato
Of course, Pixie is not the most appropriate tool for every possible
application. How fortunate that we have so many great open source tools to
choose from!

------
jacobush
[http://picolisp.com/](http://picolisp.com/)

------
bjourne
The memory management scheme is very novel:
[http://www.newlisp.org/MemoryManagement.html](http://www.newlisp.org/MemoryManagement.html)
I don't get how it can work since it would require most objects to be passed
by value and not reference.

~~~
kazinator
It isn't novel. Basically, it assumes that objects are stack allocated and
blows them away when expressions finish evaluating. Anything which escapes out
of an expression is copied, so there is no reference graph.

Copying objects to avoid lifetime computations is far, far from novel. It is
ancient. Think about all the C program modules that use strdup on strings that
are passed around, over the place, so that they can then `free` their copy
with confidence that nobody else has a pointer to it. In C++, there are smart
pointers for one-reference only, like std::unique_ptr. (Long before that
became standard, C++ coders did similar things from scratch.)

Stack allocation of temporaries which go away when a stack frame is blown away
is certainly not new. The implementor of NewLisp just had to look to the
implementation language C to get this idea.

Mature Lisp implementations have this as a built-in optimization in their
compilers. That is to say, recognizing non-escaping temporary objects and
optimizing their reclamation, and even allocating them on the stack. ANSI
Common Lisp also has the (declare (dynamic-extent ...)) declaration to
manually request, or suggest that this may be done with an object. (The
programmer promises not to let that object escape, and in return, the
implementation can stack-allocate it.)

NewLisp's claim is that the memory managent is novel in _interpreters_
(because the author knows that Lisp _compilers_ can identify temporary objects
that don't need to be retained past the evaluation of their containing
expression). Is it really novel? It might be true of the limited number of
interpreters that the author knows about. If we were to exhaustively research
the history of computing, we'd probably find other interpreted languages with
copying memory management. Oh, here is one: GNU Bash. Look for uses of the
function copy_word_list in the Bash sources. GNU Bash seems to be implementing
"ORO" memory management for lists of strings passed around as arguments and
other structures.

------
thegeomaster
On a tangentially related note, there's a project that aims to redesign some
of Common Lisp's semantics to be more modern [0]. Its name is CL21, as it's
meant to be "Common Lisp for the 21st century", and it's written entirely in
Common Lisp, relying on the kick-ass features of _reader macros_ to introduce
new syntax to the language. In my humble experience, integrating it with
Shelly [1] and the large swath of Quicklisp [2] libraries can turn it into a
terse and reasonably efficient scripting language. (Sadly, you still need a CL
implementation and runtime, and they are mostly quite slow.) Definitely worth
a look if you like NewLisp's syntax and libraries, as I can see some
similarities in the philosophies.

[0]: [http://cl21.org/](http://cl21.org/)

[1]: [http://shlyfile.org/](http://shlyfile.org/)

[2]: [https://www.quicklisp.org/beta/](https://www.quicklisp.org/beta/)

~~~
zeveb
> Sadly, you still need a CL implementation and runtime, and they are mostly
> quite slow.

Say what now? SBCL is normally within a factor of 2 of C, and sometimes faster
than C, and the commercial Lisps are even better.

~~~
thegeomaster
I was referring more to their startup time. The runtime introduces delay when
you type in the script command on a CLI.

Regardless of that, the factor-of-two-or-sometimes-faster argument sounds a
little far-fetched for me, care to provide some sources on the benchmarks? Not
saying it's not true, I'm just not accustomed to seeing highly extensible and
dynamically-typed languages such as Common Lisp perform so fast.

~~~
dmm
Check out the benchmark game for some decent benchmarks of various languages.
Here's sbcl vs gcc c:

[https://benchmarksgame.alioth.debian.org/u64q/benchmark.php?...](https://benchmarksgame.alioth.debian.org/u64q/benchmark.php?test=all&lang=sbcl&lang2=gcc&data=u64q)

On several benchmarks sbcl is less than three times slower than c.

And I never noticed a startup delay with sbcl. Let's do a simple test.

    
    
        $ echo 'print("hello")' > test.py
        $ echo '(format t "hello")' > test.lisp
        $ time python test.py
        hello
        
        real    0m0.033s # 33ms 
        user    0m0.027s
        sys     0m0.003s
        
        $ time sbcl --script test.lisp
        hello
        real    0m0.006s # 6ms
        user    0m0.000s
        sys     0m0.003s
    
        # I couldn't figure out how to run newlisp w/o starting
        # the interactive interp so I'll give it a string
        $ time newlisp -e '(print "hello")'
        hello"hello"
        
        real    0m0.002s # 2ms
        user    0m0.000s
        sys     0m0.000s
    

So sbcl starts up about 5 times faster than python, which lots of people use
for scripting. newlisp seems to startup about 4ms faster than sbcl. I really
don't see a scenario where the startup time of sbcl is a problem. Just for fun
let's look at java.

    
    
        $ java -version
        openjdk version "1.8.0_60"
        OpenJDK Runtime Environment (build 1.8.0_60-b24)
        OpenJDK 64-Bit Server VM (build 25.60-b23, mixed mode)
        $ time javac hello.java
        
        real    0m0.386s # ouch
        user    0m0.910s
        sys     0m0.040s
    
        $ time java hello
        hello
        
        real    0m0.066s # 66ms, once compiled
        user    0m0.067s
        sys     0m0.007s

------
fao_
I discovered this a while back, because Nearly Free Speech has it as a CGI
scripting language. The details of it's GC was rather interesting -- I've been
meaning to implement it in one of my lisp projects.

EDIT: I just checked, apparently nfsn doesn't support that? Weird, now I have
to work out what website I found it through...

~~~
cag_ii
It is listed as a LISP on the NFS CGI versions page:

[http://ultraviolet-cgi.nfshost.com/](http://ultraviolet-cgi.nfshost.com/)

~~~
fao_
Ah, that's where it got to! I was searching somewhere entirely different for
some reason. Thanks.

------
ninjakeyboard
I saw this
[https://news.ycombinator.com/item?id=2909881](https://news.ycombinator.com/item?id=2909881)

------
amirouche
This is an honest question: why create a lisp instead of a scheme? What is the
fundamental feature that makes NewLisp a LISP more that a scheme language?

~~~
lispit
newLISP is not a derivative of Common Lisp or Scheme or any other Lisp. It's a
different language in a similar style.

I wish the Common Lisp camp wasn't so insistent on equating "Lisp" to "Common
Lisp." It's annoying having to tiptoe around them by saying "Lisp-like
language."

~~~
junke
When people developped Rust or Go, did they say "this is a C", or "This is
newC"? They said: "this is new language with a C-like syntax with such and
such features". Why not be precise?

~~~
lispit
When Stroustrup created C++ or Hejlsberg created C#, did C progammers spend
decades whining about their choice of names and alienating newcomers?

~~~
muuh-gnu
They didnt have to, neither Stroustrup nor Hejlsberg called their languages "a
C".

