From: Alex Mizrahi
Subject: lisp repl vs unix shell
Date: 
Message-ID: <4572b107$0$49195$14726298@news.sunsite.dk>
there's a post about sbcl 1.0 on reddit

http://programming.reddit.com/info/t1cf/comments

and some guy in comments mentioned that he dislikes SBCL for not as usable 
with Unix shell as CLISP is.

i've told them that:

AM>unix sucks lisp rules. who ever wants unix shell if he has lisp prompt?

and was being downmodded for that. ang guy replying:

Someone who doesn't want to use stuff like (with-output-to-file ("foo.txt" 
:direction :output :if-exists :supersede) ...)" when it's possible to use 
"... >foo.txt".

got upmodded, having such a stupid post.
(i've replied) ain't you able to make a macro for that:
(>> ... "foo.txt")
the Lisp repl is more productive than Unix shell!
if it's not yet for you, go learn Lisp!

i suspect that there are more unix guys trying CL at reddit than real 
Lispers, but who knows; what do real Lispniks think about Unix shell, ain't 
it some ugly parody on REPL? :) 

From: Ari Johnson
Subject: Re: lisp repl vs unix shell
Date: 
Message-ID: <m21wnhw5p1.fsf@hermes.theari.com>
"Alex Mizrahi" <········@users.sourceforge.net> writes:
> i suspect that there are more unix guys trying CL at reddit than real 
> Lispers, but who knows; what do real Lispniks think about Unix shell, ain't 
> it some ugly parody on REPL? :) 

It solves a different problem than a CL REPL does.  Arguably, it
solves that problem better as a result.  I don't do development from
the shell and I don't manage my system from CL just like I don't grill
steaks in a toaster oven and don't cook toast over charcoal.
From: Kjetil S. Matheussen
Subject: Re: lisp repl vs unix shell
Date: 
Message-ID: <Pine.LNX.4.64.0612031233050.6512@ttleush>
On Sun, 3 Dec 2006, Alex Mizrahi wrote:

> there's a post about sbcl 1.0 on reddit
>
> http://programming.reddit.com/info/t1cf/comments
>
> and some guy in comments mentioned that he dislikes SBCL for not as usable
> with Unix shell as CLISP is.
>
> i've told them that:
>
> AM>unix sucks lisp rules. who ever wants unix shell if he has lisp prompt?
>

Although you might be right in your claims, you won't convert anyone by 
using such wording. To non-lispers, your words can sound just as stupid 
as "nitrogen and oxygen sucks, nyrnotack rules" in a discussion about good 
air, even if "nyrnotack" makes you fly and live forever happy.

You need to write why you prefer lisp, and give examples. If not, your 
postings may in worst case generate hostility towards lisp, in best case
nothing.
From: Luke J Crook
Subject: Re: lisp repl vs unix shell
Date: 
Message-ID: <YPqdnbxutemP3-7YnZ2dnUVZ_o2dnZ2d@giganews.com>
Alex Mizrahi wrote:
> i've told them that:
> 
> AM>unix sucks lisp rules. who ever wants unix shell if he has lisp prompt?
> 

Are you a past Amiga owner?
From: Troels Henriksen
Subject: Re: lisp repl vs unix shell
Date: 
Message-ID: <87d571rmlo.fsf@sigkill.dk>
"Alex Mizrahi" <········@users.sourceforge.net> writes:

> i suspect that there are more unix guys trying CL at reddit than
> real Lispers, but who knows; what do real Lispniks think about Unix
> shell, ain't it some ugly parody on REPL? :)

I disagree, I find the Unix shell very useful for file handling,
searching, some administration and other general computer management
tasks. It has a very concise syntax, which is important for something
used interactively, while Lisp has a much fuller and elaborate (and
readable!) syntax, which is important for the creation of true
programs.

When working at the Unix command prompt I probably have a
significantly higher command-per-second rate than when I work at a
REPL, but each command is much simpler, so it's important that I don't
need to press too many keys to get it to do what I want. On the other
hand, designing a computer language with the primary motivation of
reducing the number of keystrokes is probably not a very good idea.

Two different things, two widely different problem domains.

It may be possible to merge them and get something cool, though.

-- 
\  Troels "Athas"
/\ Henriksen
From: Kirk  Sluder
Subject: Re: lisp repl vs unix shell
Date: 
Message-ID: <kirk-48BE49.11415403122006@newsclstr02.news.prodigy.com>
In article <··············@sigkill.dk>,
 Troels Henriksen <·····@sigkill.dk> wrote:
> I disagree, I find the Unix shell very useful for file handling,
> searching, some administration and other general computer management
> tasks. It has a very concise syntax, which is important for something
> used interactively, while Lisp has a much fuller and elaborate (and
> readable!) syntax, which is important for the creation of true
> programs.

Beyond just the syntax, shells like bash, tcsh, and zsh have a lot 
of features such as process control, history, and tab-completion 
that are very useful for interactive work with files and processes. 
Sometimes these features are included in REPLs, and sometimes you 
have to rely on environments like SLIME.

Certainly these features can be implemented as macros, but it's 
generally not worth my time.
From: Kaz Kylheku
Subject: Re: lisp repl vs unix shell
Date: 
Message-ID: <1165195773.778134.312340@j72g2000cwa.googlegroups.com>
Alex Mizrahi wrote:
> there's a post about sbcl 1.0 on reddit
>
> http://programming.reddit.com/info/t1cf/comments
>
> and some guy in comments mentioned that he dislikes SBCL for not as usable
> with Unix shell as CLISP is.
>
> i've told them that:
>
> AM>unix sucks lisp rules. who ever wants unix shell if he has lisp prompt?
>
> and was being downmodded for that. ang guy replying:
>
> Someone who doesn't want to use stuff like (with-output-to-file ("foo.txt"
> :direction :output :if-exists :supersede) ...)" when it's possible to use
> "... >foo.txt".
>
> got upmodded, having such a stupid post.

Not really. It's your post that is stupid. It would take quite a bit of
programming to make a useful Unix shell from Lisp. The basic listener
isn't it.

For one thing, a modern shell has to be able to coordinate process
pipelines, and subject them to POSIX job control. It has to allocate
process groups, and suport ways to switch these groups into and out of
the foreground.

When you run some process pipeline, your Lisp shell has to put itself
into the background. When the user issues Ctrl-Z to suspend it, the
Lisp shell has to put itself into the foreground and that pipeline into
the background. To do that, it has to respond to the change in status
of the child process.

That involves using API's which are probably not wrapped up, in an
out-of-the-box distribution of any Common Lisp, plus tricky signal
handling, so you're looking at a bit of FFI work.

> (i've replied) ain't you able to make a macro for that:
> (>> ... "foo.txt")

That macro has to rebind the standard output file descriptor so that
the output now goes into "foo.txt". This has to be done at the Lisp
level and at the file descriptor level.

I've recently hacked on CLISP code where I had to do do redirection. I
needed the output to be redirected to a pipe inside CLISP itself /and/
inside any child process that is run by CLISP. Turns out that that this
is tricky, because the file descriptors underlying *STANDARD-OUTPUT*
and *STANDARD-INPUT* aren't necessarily 1 and 0.  If you fork off a
child process in CLISP which takes input from a pipe, you discover that
its *STANDARD-INPUT* reads are actually pulling data from some
whacked-out file descriptor number like 4 or 5, and so the data you are
writing to fd 1 on the parent side, and which is appearing in file
descriptor 0 on the child side, is being ignored.

CLISP has dup2 wrapped as EXT:DUPLICATE-HANDLE, so I used that to put
the ends of the pipe into the appropriate descriptors (having called
pipe using a FFI call out). I then used EXT:MAKE-STREAM to open up
streams over the file descriptors, using those streams to replace
*STANDARD-INPUT* and *STANDARD-OUTPUT*. MAKE-STREAM internally
duplicates the file descriptor that it is given, so these streams are
not talking to 1 and 0.

So the CLISP equivalent of "command | shell-function" actually takes a
bit of work to implement. (No, you can't use
EXT:MAKE-PIPE-OUTPUT-STREAM, because that only launches external
commands: it wraps fork /and/ exec).

Here is my CLISP ``process pipe'' code, not including the FFI
definitions in the "UNIX-FUNCS" package that it needs:

(defstruct process-pipe
  (stream)
  (child-pid)
  (direction)
  (fd))

(defun create-process-pipe (func direction)
  (multiple-value-bind (result fd) (unix-funcs:pipe)
    (when (< 0 result)
      (error "failed to create pipe: ~A"
             (unix-funcs:strerror unix-funcs:errno)))
    (let ((child (unix-funcs:fork)))
      (cond
        ((< child 0)
         (map nil #'unix-funcs:close fd)
         (error "fork failed: ~A."
                (unix-funcs:strerror unix-funcs:errno)))
        ((zerop child)
          (case direction
            (:output
              (ext:duplicate-handle (aref fd 0) 0)
              (setf *standard-input* (ext:make-stream
                                       (aref fd 0)
                                       :direction :input
                                       :element-type 'character)))
            (:input
              (ext:duplicate-handle (aref fd 1) 1)
              (setf *standard-output* (ext:make-stream
                                        (aref fd 1)
                                        :direction :output
                                        :element-type 'character))))
          (map nil #'unix-funcs:close fd)
          (funcall func)
          (force-output *standard-output*)
          (unix-funcs:_exit 1))
        (t
          (unwind-protect
            (case direction
              (:output
                (make-process-pipe
                  :stream (ext:make-stream (aref fd 1)
                                           :direction direction
                                           :element-type 'character)
                  :direction direction
                  :fd (ext:duplicate-handle (aref fd 1))
                  :child-pid child))
              (:input
                (make-process-pipe
                  :stream (ext:make-stream (aref fd 0)
                                           :direction direction
                                           :element-type 'character)
                  :direction direction
                  :fd (ext:duplicate-handle (aref fd 0))
                  :child-pid child)))
            (map nil #'unix-funcs:close fd)))))))

(defun close-process-pipe (pipe)
  (unix-funcs:default-sigchld)
  (close (slot-value pipe 'stream))
  (unix-funcs:close (slot-value pipe 'fd))
  (setf (slot-value pipe 'stream) nil)
  (setf (slot-value pipe 'fd) nil)
  (loop for result = (unix-funcs:waitpid (slot-value pipe 'child-pid)
0)
        do (when (and (< result 0) (/= unix-funcs:errno
unix-funcs:eintr))
             (error "waitpid failed: ~A"
                    (unix-funcs:strerror unix-funcs:errno)))
        until (>= result 0))
  (setf (slot-value pipe 'child-pid) nil)
  (values))

The DEFAULT-SIGCHLD thing is needed because CLISP does a very stupid
thing: it sets SIGCHLD to SIG_IGN, which breaks code that tries to reap
child processes.

All of the above basically gives you the equivalent of the shell's

  command | function

In other words, fork off a process to run the function, and pipe into
it. Actually, no it doesn't quite give you the above. Only the child
side of it! In the parent, you have a stream which has not yet been
patched into standard input or output. For that, you need more code
such as this. Here it is assumed you have a variable called PIPE in
scope which holds a process pipe object. A redirection of standard
input or output is preformed based on the pipe's direction:

(let ((saved-handle)
      (saved-handle-which)
      (*standard-output* *standard-output*)
      (*standard-input* *standard-input*))
  (unwind-protect
    (progn
      (case (slot-value pipe 'direction)
        (:output
          (setf *standard-output* (slot-value pipe 'stream))
          (setf saved-handle (ext:duplicate-handle 1))
          (setf saved-handle-which 1)
          (ext:duplicate-handle (slot-value pipe 'fd) 1))
        (:input
          (setf *standard-input* (slot-value pipe 'stream))
          (setf saved-handle (ext:duplicate-handle 0))
          (setf saved-handle-which 0)
          (ext:duplicate-handle (slot-value pipe 'fd) 0)))

      ;; code goes here

    (ext:duplicate-handle saved-handle saved-handle-which)
    (close-process-pipe pipe)))
From: Alex Mizrahi
Subject: Re: lisp repl vs unix shell
Date: 
Message-ID: <4573f3cf$0$49198$14726298@news.sunsite.dk>
(message (Hello 'Kaz)
(you :wrote  :on '(3 Dec 2006 17:29:33 -0800))
(

 KK> Not really. It's your post that is stupid. It would take quite a bit of
 KK> programming to make a useful Unix shell from Lisp. The basic listener
 KK> isn't it.

why to make unix shell from lisp?
is there a thing that you can do in a shell but can't do in a repl?

there was a Lisp OS. did it have unix shell?

 KK> That macro has to rebind the standard output file descriptor so that
 KK> the output now goes into "foo.txt". This has to be done at the Lisp
 KK> level and at the file descriptor level.

that's needed if if want to generate data from external program.
but why do i need that if i can generate data with lisp itself?

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"People who lust for the Feel of keys on their fingertips (c) Inity") 
From: Kirk  Sluder
Subject: Re: lisp repl vs unix shell
Date: 
Message-ID: <kirk-8720E7.10223104122006@newsclstr02.news.prodigy.com>
In article <·························@news.sunsite.dk>,
 "Alex Mizrahi" <········@users.sourceforge.net> wrote:

> why to make unix shell from lisp?
> is there a thing that you can do in a shell but can't do in a repl?

Probably nothing, given enough time and frustration....
 
> there was a Lisp OS. did it have unix shell?
.....
> that's needed if if want to generate data from external program.
> but why do i need that if i can generate data with lisp itself?

I find it interesting how this same discussion pops up once a year 
in regards to lots of different languages. I've seen the exact same 
argument made for perl and python.  I imagine that someone out there 
has made the same arguments for ruby and tcl as well.

Here is my generic answer to this. While I can import Unix system 
data into perl/python/lisp/ruby and manipulate that data as 
perl/python/lisp/ruby objects, in most cases Unix shells and 
associated utilities offer "good enough" results for minimal time 
and investment.  If someone else wants to bootstrap their way in a 
pure perl/python/lisp/ruby environment, the more power too them. 

Shells are excellent "glue" languages for getting unrelated programs 
to work together. Common Lisp strikes me as a very bad choice for a 
"glue" language because of the lack of a common interface for basic 
POSIX functions. I can't assume that scripts developed for OpenMCL 
will work with CMUCL or CLISP. 

> 
> )
> (With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
> "People who lust for the Feel of keys on their fingertips (c) Inity")
From: Pascal Bourguignon
Subject: Re: lisp repl vs unix shell
Date: 
Message-ID: <87k617zm2k.fsf@thalassa.informatimago.com>
Kirk  Sluder <····@nospam.jobsluder.net> writes:
> Shells are excellent "glue" languages for getting unrelated programs 
> to work together. Common Lisp strikes me as a very bad choice for a 
> "glue" language because of the lack of a common interface for basic 
> POSIX functions. I can't assume that scripts developed for OpenMCL 
> will work with CMUCL or CLISP. 

Well that was true last year, but not anymore. Nowadays we have CFFI
(and Fetter), so one could generate the POSIX FFI automatically and
get a portable API on which to develop the needed scripting layer.


And lisp as shell as a nice proof of concept with scsh.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

COMPONENT EQUIVALENCY NOTICE: The subatomic particles (electrons,
protons, etc.) comprising this product are exactly the same in every
measurable respect as those used in the products of other
manufacturers, and no claim to the contrary may legitimately be
expressed or implied.
From: Kirk  Sluder
Subject: Re: lisp repl vs unix shell
Date: 
Message-ID: <kirk-B5CDE9.11561904122006@newsclstr02.news.prodigy.com>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <···@informatimago.com> wrote:

> Kirk  Sluder <····@nospam.jobsluder.net> writes:
> > Shells are excellent "glue" languages for getting unrelated programs 
> > to work together. Common Lisp strikes me as a very bad choice for a 
> > "glue" language because of the lack of a common interface for basic 
> > POSIX functions. I can't assume that scripts developed for OpenMCL 
> > will work with CMUCL or CLISP. 
> 
> Well that was true last year, but not anymore. Nowadays we have CFFI
> (and Fetter), so one could generate the POSIX FFI automatically and
> get a portable API on which to develop the needed scripting layer.

That's cool. Thanks for the information.  Still though, how much 
work would you have to go through bootstrapping your way up to 
having the equivalent of the shell + associated utilities?
 
> And lisp as shell as a nice proof of concept with scsh.

I spent about 4 hours in scsh working on a script before jumping 
back to bash or zsh. I think the basic problem I ran into was with 
globbing or regex editing of filenames.  It is probable that with 
enough willingness to scale the learning curve I could have figured 
it out, but I already knew how to perform the task with a 
combination of bash and sed. So I was unwilling to invest much more 
time into learning it. 

Which is where I keep finding myself defending shells and UNIX 
utilities in relationship to other languages.  I could learn to do 
it all in perl/python/lisp/ruby, but I've not been given a 
convincing reason why I should. 

The authors of the scsh faq don't recommend bare-bones scsh as an 
interactive shell due to a lack of command-line editing and history.  
I'd also add tab-completion as a must-have tool for any shell for 
me.
From: Alexander Schreiber
Subject: Re: lisp repl vs unix shell
Date: 
Message-ID: <slrnen92l3.poc.als@mordor.angband.thangorodrim.de>
Alex Mizrahi <········@users.sourceforge.net> wrote:
> there's a post about sbcl 1.0 on reddit
>
> http://programming.reddit.com/info/t1cf/comments
>
> and some guy in comments mentioned that he dislikes SBCL for not as usable 
> with Unix shell as CLISP is.
>
> i've told them that:
>
> AM>unix sucks lisp rules. who ever wants unix shell if he has lisp prompt?
>
> and was being downmodded for that

And rightly so. At worst, this kind of comment cements the image of Lisp
users as arrogant pricks and creats hostility against Lisp. At best, it
achieves nothing.

> the Lisp repl is more productive than Unix shell!
> if it's not yet for you, go learn Lisp!
>
> i suspect that there are more unix guys trying CL at reddit than real 
> Lispers, but who knows; what do real Lispniks think about Unix shell, ain't 
> it some ugly parody on REPL? :) 

No. Both solve different problems. And the Unix shell works really well
as a universal plumbing bench for connecting all those Unix utilities
into machines of any size needed.

Replace it with a Lisp shell on Unix and you'll either have to
reimplement at least half of the Unix userland in Lisp or write
industrial-strength layers of glue around them. That's not exactly
elegant.

If, however, you use the Lisp shell as the commandline environment on a
Lisp OS, where all the features, bells, whistles and other stuff are
_part_ of the Lisp environment, then your Lisp shell would most likely
be very powerful indeed.

So grab the latest Movitz Code and get coding ;-)


HTH,
    Alex.
-- 
"Opportunity is missed by most people because it is dressed in overalls and
 looks like work."                                      -- Thomas A. Edison