Reading file to list

comp.lang.lisp,comp.lang.scheme,comp.lang.functional,comp.lang.python,comp.lang.ruby

Here's a interesting toy problem posted by Drew Krause to
comp.lang.lisp:

···

------------------------
On Jan 16, 2:29 pm, Drew Krause wrote [paraphrased a bit]:

OK, I want to create a nested list in Lisp (always of only integers)
from a text file, such that each line in the text file would be
represented as a sublist in the 'imported' list.

example of a file's content

3 10 2
4 1
11 18

example of programing behavior
(make-list-from-text "blob.txt") => ((3 10 2) (4 1) (11 18))

-----------------
Here's a emacs lisp version:

(defun read-lines (file)
  "Return a list of lines in FILE."
  (with-temp-buffer
    (insert-file-contents file)
    (split-string
     (buffer-substring-no-properties 1 (point-max)) "\n" t)
    )
  )

(defvar mylist '() "result list" )
(setq mylist '()) ; init in case eval'd again

(mapc
(lambda (x) (setq mylist
                   (cons (split-string x " ") mylist )) )
(read-lines "xxblob.txt")
)

The above coding style is a typical maintainable elisp.

In a show-off context, it can be reduced to by about 50%, but still
far verbose than ruby or say perl (which is 1 or 2 lines. (python
would be 3 or 5)).

Note that the result element is string, not numbers. There's no easy
way to convert them on the fly. 3 or so more lines will be needed to
do that.

The “read-lines” function really should be a built-in part of elisp.
It is not so mostly because emacs people have drawn themselves into a
elitist corner, closing off to the outside world. (i am sending a
suggestion to the official emacs dev list on adding read-line now.)

-----------------

w_a_x_...@yahoo.com gave a ruby solution:

  IO.readlines("blob.txt").map{|line| line.split }

augumented by Jilliam James for result to be numbers:

  IO.readlines("blob.txt").map{|line| line.split.map{|s| s.to_i }}

Very beautiful.

-------------------

That's really the beauty of Ruby.

This problem and ruby code illustrates 2 fundamental problems of lisp,
namely, the cons problem, and the nested syntax pain. Both of which
are practically unfixable.

The lisp's cons fundamentally makes nested list a pain to work with.
Lisp's nested syntax makes functional sequencing cumbersome.

In the ruby code, its post-fix sequential notation (as a side effect
of its OOP notation) brings out the beauty of functional sequencing
paradigm (sometimes known as functional chain, sequencing, filtering,
unix piping).

its list, like all modern high level langs such as perl, php, python,
javascript, don't have the lisp's cons problem. The cons destroys the
usability of lists up-front, untill you have some at least 2 full-time
years of coding lisp to utilize cons properly. (and even after that,
it is still a pain to work with, and all you gain is a bit of speed
optimization in rare cases that requires largish data, most of which
has better solutions such as a database.)

Both of these problems i've published articles on.

For more detail on the cons problem, see
the section “The Cons Business” at

• Fundamental Problems of Lisp
  http://xahlee.org/UnixResource_dir/writ/lisp_problems.html

For more detail on the nested syntax problem for function chaining,
see
the section “How Purely Nested Notation Limits The Language's Utility”
at:

• The Concepts and Confusions of Prefix, Infix, Postfix and Fully
Nested Notations
  http://xahlee.org/UnixResource_dir/writ/notations.html

  Xah
http://xahlee.org/

:comet:

The code in my previous elisp code got a bump. It should be:

(defun read-lines (file)
  "Return a list of lines in FILE."
  (with-temp-buffer
    (insert-file-contents file)
    (split-string
     (buffer-substring-no-properties 1 (point-max)) "\n" t)
    )
  )

(mapcar
(lambda (x) (split-string x " ") )
(read-lines "xxblob.txt")
)

The article is now archived at:

• A Ruby Illustration of Lisp Problems
  File Not Found

  Xah
http://xahlee.org/

:comet:

···

On Jan 17, 9:16 am, Xah Lee <xah...@gmail.com> wrote:

Here's a interesting toy problem posted by Drew Krause to
comp.lang.lisp:
...

Sorry again. More correction:

(defun read-lines (file)
  "Return a list of lines in FILE."
  (with-temp-buffer
    (insert-file-contents file)
    (split-string
     (buffer-substring-no-properties 1 (point-max)) "\n" t)
    )
  )

(mapcar
(lambda (x)
   (mapcar
    (lambda (y) (string-to-number y) )
    (split-string x " ")
    )
   )
(read-lines "xxblob.txt")
)

this is last post of correction.

  Xah
http://xahlee.org/

:comet:

···

On Jan 17, 9:34 am, Xah Lee <xah...@gmail.com> wrote:

The code in my previous elisp code got a bump. It should be:
...
• A Ruby Illustration of Lisp Problems
File Not Found

Xah Lee schrieb:

comp.lang.lisp,comp.lang.scheme,comp.lang.functional,comp.lang.python,comp.lang.ruby

Here's a interesting toy problem posted by Drew Krause to
comp.lang.lisp:

------------------------
On Jan 16, 2:29 pm, Drew Krause wrote [paraphrased a bit]:

OK, I want to create a nested list in Lisp (always of only integers)
from a text file, such that each line in the text file would be
represented as a sublist in the 'imported' list.

example of a file's content

3 10 2
4 1
11 18

example of programing behavior
(make-list-from-text "blob.txt") => ((3 10 2) (4 1) (11 18))

w_a_x_...@yahoo.com gave a ruby solution:

  IO.readlines("blob.txt").map{|line| line.split }

augumented by Jilliam James for result to be numbers:

  IO.readlines("blob.txt").map{|line| line.split.map{|s| s.to_i }}

Very beautiful.

-------------------

That's really the beauty of Ruby.

This problem and ruby code illustrates 2 fundamental problems of lisp,
namely, the cons problem, and the nested syntax pain. Both of which
are practically unfixable.

*Of course* Xah is wrong, as always.
Who would expect anything else?
In the Lisp style Clojure for example one does exactly the same as
Jillian James (JJ) did in Ruby:
(map #(map (fn [s] (Integer/parseInt s)) (.split % "\\s")) (line-seq (reader "blob.txt")))

This is slightly longer, simply because the functions have longer names.
Integer/parseInt vs to_i

Also the function split takes a regexp, so I have to add the "\\s" here.
I don’t know though if Jillians version also handles any kind of
whitespac per line.
And the last thing is, that the function reader returns a BufferedReader.
So in general this is more valuable in real programs as opposed to one-
line scripts. If we combine line-seq and reader into readline and apply
the two other changes we would say:
(map #(map (fn [s] (to_i s)) (.split %)) (readlines "blob.txt"))
vs
IO.readlines("blob.txt").map{|line| line.split.map{|s| s.to_i }}

So, obviously Xah is far away from any reality.
It took him hours of his life to write up all his ideas about Lisp.
Sad to see that all that time was wasted. All of it was wrong.
Poor Xah :frowning:

And btw, Drew Krause is just a Lisp newbie. No Lisper would ever store
data for his programs in the format
3 10 2
4 1
11 18

but instead as
(3 10 2)
(4 1)
(11 18)

And then read it back into the program with:
(map read-string (line-seq (reader "blob.txt")))

André

···

--

Xah Lee wrote:

• A Ruby Illustration of Lisp Problems
File Not Found

In the Lisp style Clojure for example one does exactly the same as
Jillian James (JJ) did in Ruby:

(map #(map (fn [s] (Integer/parseInt s)) (.split % "\\s")) (line-seq
(reader "blob.txt")))

Note that you have nested map. This is a problem of function chaning
as i detailed.

The other problem of cons, is commonly seen. Just about every week, we
see some perhaps beginning lisper asking how to do various trivial
list
manipulation problem, which you don't see such question or frequency
in any of modern high level lang forms.

The frequently asked list manipulation question we see include how to
append, prepend, or anything involving nested list such as
partitioning, reordering sublists, getting leaves, interpretation of
leaves, etc. This is caused by the cons.

associated lisp problem compound the issue. Namely, the not exactly
regular syntax, and the eval model of sometimes symbol sometimes
uneval'd symbol, e.g. “'(...)”, “`(...,@ ...)” things.

The clojure example you gave above, apparently inherited the irregular
syntax problem. (you see the #, , % things, which is breaks the
lisp's sexp idea) Also, all modern lisp basically all get fucked up by
inheriting the cons (e.g. clojure, NewLisp, Arc lisp, Liskell). Often,
they change the semantic a bit apparently as a mesaure towards solving
the cons problem. (and Qi Lisp creates a huge bag of ad hoc, extremely
ugly, syntax soup)

Advice: if you are creating a lispy lang, two things:

• stick to a _pure_ nested syntax, no exception whatsoever. (e.g. no
more ` ' # % shits) If you want, add a transparent layer on top to
support arbitrary algeraic notation. (e.g. look at Mathematica, CGOL)

• get rid of the cons. (you can still implement the so-called linked
list, but no where it should be shown to the programer)

Further readings:

• Fundamental Problems of Lisp
  File Not Found

  Xah
http://xahlee.org/

:comet:

···

On Jan 17, 12:30 pm, André Thieme <address.good.until. 2009.may...@justmail.de> wrote:

Nice (python code).

Few comments:

• the above code is borderline of atypical. e.g. it is not a average
python code would produce or one'd seen in corporate python code.

• voodoo like the above makes me dislike python. To me, the one
advantage of python is its clarity enforced by its syntax.
Specifically, the forced indendation and quite simple semantics.
However, the way i've seen Guido's propensities and how python 3 is
moving to, it is becoming more mumbo jumbo of computer sciency OOP
jargons with syntax soup. (with iterators, enumerators, list
comprehension... shits forced upon the users)

The above line illustrate well the ad hoc syntax soup nature python is
moving into.

Further readings:

• Perl-Python Tutorial: List Comprehension
  File Not Found

• Lambda in Python 3000
  File Not Found

  Xah
http://xahlee.org/

:comet:

···

On Jan 17, 10:25 am, Tino Wildenhain <t...@wildenhain.de> wrote:

> [[int(x) for x in line.split()] for line in open("blob.txt")]

André Thieme wrote:

Xah Lee schrieb:
> comp.lang.lisp,comp.lang.scheme,comp.lang.functional,comp.lang.pytho
> n,comp.lang.ruby
>
> Here's a interesting toy problem posted by Drew Krause to
> comp.lang.lisp:
>
> ------------------------
> On Jan 16, 2:29 pm, Drew Krause wrote [paraphrased a bit]:
>
> OK, I want to create a nested list in Lisp (always of only integers)
> from a text file, such that each line in the text file would be
> represented as a sublist in the 'imported' list.
>
> example of a file's content
>
> 3 10 2
> 4 1
> 11 18
>
> example of programing behavior
>(make-list-from-text "blob.txt") => ((3 10 2) (4 1) (11 18))
>
> w_a_x_...@yahoo.com gave a ruby solution:
>
> IO.readlines("blob.txt").map{|line| line.split }
>
> augumented by Jilliam James for result to be numbers:
>
> IO.readlines("blob.txt").map{|line| line.split.map{|s| s.to_i }}
>
> Very beautiful.
>
> -------------------
>
> That's really the beauty of Ruby.
>
> This problem and ruby code illustrates 2 fundamental problems of
> lisp, namely, the cons problem, and the nested syntax pain. Both of
> which are practically unfixable.

*Of course* Xah is wrong, as always.
Who would expect anything else?
In the Lisp style Clojure for example one does exactly the same as
Jillian James (JJ) did in Ruby:
(map #(map (fn [s] (Integer/parseInt s)) (.split % "\\s")) (line-seq
(reader "blob.txt")))

That fails when numbers are separated by more than one space.
And what about leading or trailing space?

This is slightly longer, simply because the functions have longer
names. Integer/parseInt vs to_i

Also the function split takes a regexp, so I have to add the "\\s"
here. I don’t know though if Jillians version also handles any
kind of whitespac per line.

irb(main):003:0> puts " foo \t bar "
  foo bar
=> nil
irb(main):004:0> " foo \t bar ".split
=> ["foo", "bar"]
irb(main):005:0> "foo...bar?-!hoo".split /\W+/
=> ["foo", "bar", "hoo"]

And the last thing is, that the function reader returns a
BufferedReader. So in general this is more valuable in real programs
as opposed to one- line scripts. If we combine line-seq and reader
into readline and apply the two other changes we would say:
(map #(map (fn [s] (to_i s)) (.split %)) (readlines "blob.txt"))

That is not a complete program.

vs
IO.readlines("blob.txt").map{|line| line.split.map{|s| s.to_i }}

That is the complete program.

So, obviously Xah is far away from any reality.
It took him hours of his life to write up all his ideas about Lisp.
Sad to see that all that time was wasted. All of it was wrong.
Poor Xah :frowning:

And btw, Drew Krause is just a Lisp newbie. No Lisper would ever store
data for his programs in the format
3 10 2
4 1
11 18

but instead as
(3 10 2)
(4 1)
(11 18)

Perhaps the data was stored by someone else. Understand?

And then read it back into the program with:
(map read-string (line-seq (reader "blob.txt")))

You make a very strong case that Lisp is very feeble at
processing data. I'm almost convinced.

Ruby isn't feeble, so data like this is fine:

shall we begin?
or lotus135? 1984 times!
The 3 stooges: COBOL,LISP,FORTRAN.
3.14, si11y L00KING

Extracting the unsigned integers:

IO.readlines('data').map{|s| s.scan(/\d+/).map{|s| s.to_i}}
    ==>[, [135, 1984], [3], [3, 14, 11, 0]]

André Thieme wrote:

(map #(map (fn [s] (Integer/parseInt s)) (.split % "\\s")) (line-seq
(reader "blob.txt")))

An error results:

java.lang.Exception: Unable to resolve symbol: reader in this context

This works:

(map #(map (fn [s] (Integer/parseInt s)) (.split % "\\s"))
  (.split (slurp "junk") "\r?\n"))

comp.lang.lisp,comp.lang.scheme,comp.lang.functional,comp.lang.python,comp.­lang.ruby

Here's a interesting toy problem posted by Drew Krause to
comp.lang.lisp:

------------------------
On Jan 16, 2:29 pm, Drew Krause wrote [paraphrased a bit]:

OK, I want to create a nested list in Lisp (always of only integers)
from a text file, such that each line in the text file would be
represented as a sublist in the 'imported' list.

example of a file's content

3 10 2
4 1
11 18

example of programing behavior
(make-list-from-text "blob.txt") => ((3 10 2) (4 1) (11 18))

-----------------
Here's a emacs lisp version:

(defun read-lines (file)
  "Return a list of lines in FILE."
  (with-temp-buffer
    (insert-file-contents file)
    (split-string
     (buffer-substring-no-properties 1 (point-max)) "\n" t)
    )
  )

(defvar mylist '() "result list" )
(setq mylist '()) ; init in case eval'd again

(mapc
(lambda (x) (setq mylist
                   (cons (split-string x " ") mylist )) )
(read-lines "xxblob.txt")
)

The above coding style is a typical maintainable elisp.

In a show-off context, it can be reduced to by about 50%, but still
far verbose than ruby or say perl (which is 1 or 2 lines. (python
would be 3 or 5)).

Note that the result element is string, not numbers. There's no easy
way to convert them on the fly. 3 or so more lines will be needed to
do that.

The “read-lines” function really should be a built-in part of elisp.
It is not so mostly because emacs people have drawn themselves into a
elitist corner, closing off to the outside world. (i am sending a
suggestion to the official emacs dev list on adding read-line now.)

scheme:

(define (read-line port)
    (define (rec-read-line port line)
        (define next-char (peek-char port))
        (define number #f)
        (cond ((eof-object? next-char) '())
              ((char=? next-char #\newline) (read-char port) line)
              ((char-numeric? next-char)
                   (set! number (read port))
                   (cons number (rec-read-line port line)))
              ((char=? next-char #\space)
                   (read-char port)
                   (rec-read-line port line))
              (else (error (string-append "bad character \""
                              (string next-char) "\"")))
    ))

    (rec-read-line port '())
)

(define (make-int-list port)
    (define line (read-line port))
    (if (null? line)
        '()
        (cons line (make-int-list port))))

(define (make-list-from-text file)
    (make-int-list (open-input-file file)))

···

On 17 Jan, 17:16, Xah Lee <xah...@gmail.com> wrote:

-----------------

w_a_x_...@yahoo.com gave a ruby solution:

  IO.readlines("blob.txt").map{|line| line.split }

augumented by Jilliam James for result to be numbers:

  IO.readlines("blob.txt").map{|line| line.split.map{|s| s.to_i }}

Very beautiful.

-------------------

That's really the beauty of Ruby.

This problem and ruby code illustrates 2 fundamental problems of lisp,
namely, the cons problem, and the nested syntax pain. Both of which
are practically unfixable.

The lisp's cons fundamentally makes nested list a pain to work with.
Lisp's nested syntax makes functional sequencing cumbersome.

In the ruby code, its post-fix sequential notation (as a side effect
of its OOP notation) brings out the beauty of functional sequencing
paradigm (sometimes known as functional chain, sequencing, filtering,
unix piping).

its list, like all modern high level langs such as perl, php, python,
javascript, don't have the lisp's cons problem. The cons destroys the
usability of lists up-front, untill you have some at least 2 full-time
years of coding lisp to utilize cons properly. (and even after that,
it is still a pain to work with, and all you gain is a bit of speed
optimization in rare cases that requires largish data, most of which
has better solutions such as a database.)

Both of these problems i've published articles on.

For more detail on the cons problem, see
the section “The Cons Business” at

• Fundamental Problems of Lisp
File Not Found

For more detail on the nested syntax problem for function chaining,
see
the section “How Purely Nested Notation Limits The Language's Utility”
at:

• The Concepts and Confusions of Prefix, Infix, Postfix and Fully
Nested Notations
File Not Found

> Here's a interesting toy problem posted by Drew Krause to
> comp.lang.lisp:

> ------------------------
> On Jan 16, 2:29 pm, Drew Krause wrote [paraphrased a bit]:

> OK, I want to create a nested list in Lisp (always of only integers)
> from a text file, such that each line in the text file would be
> represented as a sublist in the 'imported' list.

> example of a file's content

> 3 10 2
> 4 1
> 11 18

> example of programing behavior
> (make-list-from-text "blob.txt") => ((3 10 2) (4 1) (11 18))

<snip>

scheme:

(define (read-line port)
(define (rec-read-line port line)
(define next-char (peek-char port))
(define number #f)
(cond ((eof-object? next-char) '())
((char=? next-char #\newline) (read-char port) line)
((char-numeric? next-char)
(set! number (read port))
(cons number (rec-read-line port line)))
((char=? next-char #\space)
(read-char port)
(rec-read-line port line))
(else (error (string-append "bad character \""
(string next-char) "\"")))
))

\(rec\-read\-line port &#39;\(\)\)

)

(define (make-int-list port)
(define line (read-line port))
(if (null? line)
'()
(cons line (make-int-list port))))

(define (make-list-from-text file)
(make-int-list (open-input-file file)))

an assignment-free version

(define (read-line port)
    (define (rec-read-line port line)
        (let ((next-char (peek-char port)))
            (cond ((eof-object? next-char) '())
                  ((char=? next-char #\newline) (read-char port) line)
                  ((char-numeric? next-char)
                       (let ((number (read port)))
                           (cons number (rec-read-line port line))))
                  ((char=? next-char #\space)
                       (read-char port)
                       (rec-read-line port line))
                  (else (error (string-append "bad character \""
                                   (string next-char) "\""))))))

    (rec-read-line port '()))

(define (make-int-list port)
    (let ((line (read-line port)))
        (if (null? line)
            '()
            (cons line (make-int-list port)))))

(define (make-list-from-text file)
    (make-int-list (open-input-file file)))

(define (mk) (make-list-from-text "blob.txt"))

<snip>

number was originally define'd but I discovered there were
limits to where you could define things

···

On 24 Feb, 15:00, nick_keighley_nos...@hotmail.com wrote:

On 17 Jan, 17:16, Xah Lee <xah...@gmail.com> wrote:

comp.lang.lisp,comp.lang.scheme,comp.lang.functional,comp.lang.python,comp.­lang.ruby

<snip>

The lisp's cons fundamentally makes nested list a pain to work with.
Lisp's nested syntax makes functional sequencing cumbersome.

so hide it

(define (make-list stream eos?)
    (let ((atom (stream)))
        (if (eos? atom)
            '()
            (cons atom (make-list stream eos?)))))

(define (make-int-list port)
    (make-list (lambda () (read-line port)) null?))

the nasty cons then only appears in a single function which
you can hide in a library

In the ruby code, its post-fix sequential notation (as a side effect
of its OOP notation) brings out the beauty of functional sequencing
paradigm (sometimes known as functional chain, sequencing, filtering,
unix piping).

its list, like all modern high level langs such as perl, php, python,
javascript, don't have the lisp's cons problem. The cons destroys the
usability of lists up-front, untill you have some at least 2 full-time
years of coding lisp to utilize cons properly. (and even after that,
it is still a pain to work with, and all you gain is a bit of speed
optimization in rare cases that requires largish data, most of which
has better solutions such as a database.)

is my code to build a list that bad?

Both of these problems i've published articles on.

For more detail on the cons problem, see
the section “The Cons Business” at

• Fundamental Problems of Lisp
File Not Found

I read it. Your point seems to be "cons becomes difficult
with deeply nested structures". Could you give an example?

···

On 17 Jan, 17:16, Xah Lee <xah...@gmail.com> wrote:

the nasty cons then only appears in a single function which
you can hide in a library

I think the following answers that.

Q: If you don't like cons, lisp has arrays and hashmaps, too.

fons. Fons are just like cons except it has 3 cells with 3 accessors:
car, cbr, cdr. Now, gisp is a old lang, the fons are deeply rooted in
the lang. Every some 100 lines of code you'll see a use of fons with
its extra accessor cbr, or any one of the cbaar, cdabr, cbbar, cbbbar,
etc. You got annoyed by this. You as a critic, complains that fons is
bad. But then some gisp fanatics retorts: “If you don't like fons,
gisp has cons, too!”.

You see, by “having something too”, does not solve the problem of
pollution. Sure, you can use just cons in gisp, but every lib or
other's code you encounter, there's a invasion of fons with its cbar,
cbbar, cbbbar. The problem created by fons does not go away by “having
cons too”.

above is from

• Fundamental Problems of Lisp
  File Not Found

···

On Feb 25, 3:34 am, nick_keighley_nos...@hotmail.com wrote:
A: Suppose there's a lang called gisp. In gisp, there's cons but also

---------

I read it. Your point seems to be "cons becomes difficult
with deeply nested structures". Could you give an example?

There are few examples in these articles:

• The Concepts and Confusions of Prefix, Infix, Postfix and Fully
Nested Notations
  File Not Found

the above, 3rd section, gives detail about the problems of fully
nested syntax. In particular, it shows a source code snippet of
language with fully nested syntax, but is not lisp, so that lispers
can get a fresh impression.

• A Ruby Illustration of Lisp Problems
  File Not Found

the above, is a concrete example of showing how full nesting is
cumbersome, by constrasting a simple program in Ruby and lisp.

• Why Lisp Do Not Have A Generic Copy-List Function
  File Not Found

the above, shows the cons problem, by looking Kent Pitman's article
with a different perspective.

A short Plain Text Excerpt of the ruby article cited above follows.
------------------------------

More specifically, 2 fundamental problems of lisp i feel this ruby
example illustrates well:

• the cons impedes many aspects of lists. e.g. difficult to learn,
confusing, hard to use, prevent development of coherent list
manipulation functions.

• nested syntax impedes the functional programing paradigm of function
chaining, esp when each function has 2 or more arguments (e.g. map).

here's a short summary of the nesting problem:

(map f x) ; 1 level of chaining
(map g (map f x)) ; 2 levels
(map h (map g (map f x))) ; 3 levels

compare:

x | f | g | h ----> unix pipe
x // f // g // h ----> Mathematica
h @ g @ f @ x ----> Mathematica
x.f.g.h -------> various OOP langs, esp Ruby, javascript
h g f x -------> some functional langs, Haskell, Ocaml

The way the above works is that each of f, g, h is a lambda themselves
that maps. (that is, something like “(lambda (y) (map f y))”)

Note, that any of the f, g, h may be complex pure functions (aka
lambda). Because in lisp, each lambda itself will in general have
quite a lot nested parens (which cannot be avoided), so this makes any
chaining of functions of 2 args, for more than 2 or 3 levels of
nesting, unusable for practical coding. One must define the functions
separately and just call their names, or use function composition with
lambda (which gets complex quickly). One major aspect of this problem
is that the scope of vars becomes hard to understand in the deep
nested source code. This is worse in elisp, because emacs is
dynamically scoped, so you have to avoid using var of same name.

Xah
http://xahlee.org/

:comet:

Here's a actual lisp code. I don't consider it readable, due to the
profusion of parens.

(defun lisp-complete-symbol (&optional predicate)
  "Perform completion on Lisp symbol preceding point.
Compare that symbol against the known Lisp symbols.
If no characters can be completed, display a list of possible
completions.
Repeating the command at that point scrolls the list.

When called from a program, optional arg PREDICATE is a predicate
determining which symbols are considered, e.g. `commandp'.
If PREDICATE is nil, the context determines which symbols are
considered. If the symbol starts just after an open-parenthesis, only
symbols with function definitions are considered. Otherwise, all
symbols with function definitions, values or properties are
considered."
  (interactive)
  (let ((window (get-buffer-window "*Completions*" 0)))
    (if (and (eq last-command this-command)
       window (window-live-p window) (window-buffer window)
       (buffer-name (window-buffer window)))
  ;; If this command was repeated, and
  ;; there's a fresh completion window with a live buffer,
  ;; and this command is repeated, scroll that window.
  (with-current-buffer (window-buffer window)
    (if (pos-visible-in-window-p (point-max) window)
        (set-window-start window (point-min))
      (save-selected-window
        (select-window window)
        (scroll-up))))

      ;; Do completion.
      (let* ((end (point))
       (beg (with-syntax-table emacs-lisp-mode-syntax-table
        (save-excursion
          (backward-sexp 1)
          (while (= (char-syntax (following-char)) ?\')
      (forward-char 1))
          (point))))
       (pattern (buffer-substring-no-properties beg end))
       (predicate
        (or predicate
      (save-excursion
        (goto-char beg)
        (if (not (eq (char-before) ?\())
      (lambda (sym) ;why not just nil ? -sm
        (or (boundp sym) (fboundp sym)
            (symbol-plist sym)))
          ;; Looks like a funcall position. Let's double check.
          (if (condition-case nil
            (progn (up-list -2) (forward-char 1)
             (eq (char-after) ?\())
          (error nil))
        ;; If the first element of the parent list is an open
        ;; parenthesis we are probably not in a funcall position.
        ;; Maybe a `let' varlist or something.
        nil
      ;; Else, we assume that a function name is expected.
      'fboundp)))))
       (completion (try-completion pattern obarray predicate)))
  (cond ((eq completion t))
        ((null completion)
         (message "Can't find completion for \"%s\"" pattern)
         (ding))
        ((not (string= pattern completion))
         (delete-region beg end)
         (insert completion)
         ;; Don't leave around a completions buffer that's out of date.
         (let ((win (get-buffer-window "*Completions*" 0)))
     (if win (with-selected-window win (bury-buffer)))))
        (t
         (let ((minibuf-is-in-use
          (eq (minibuffer-window) (selected-window))))
     (unless minibuf-is-in-use
       (message "Making completion list..."))
     (let ((list (all-completions pattern obarray predicate)))
       (setq list (sort list 'string<))
       (or (eq predicate 'fboundp)
           (let (new)
       (while list
         (setq new (cons (if (fboundp (intern (car list)))
                 (list (car list) " <f>")
               (car list))
             new))
         (setq list (cdr list)))
       (setq list (nreverse new))))
       (if (> (length list) 1)
           (with-output-to-temp-buffer "*Completions*"
       (display-completion-list list pattern))
         ;; Don't leave around a completions buffer that's
         ;; out of date.
         (let ((win (get-buffer-window "*Completions*" 0)))
           (if win (with-selected-window win (bury-buffer))))))
     (unless minibuf-is-in-use
       (message "Making completion list...%s" "done")))))))))

  Xah
http://xahlee.org/

:comet:

···

On Feb 25, 10:18 am, Xah Lee <xah...@gmail.com> wrote:

On Feb 25, 3:34 am, nick_keighley_nos...@hotmail.com wrote:

> the nasty cons then only appears in a single function which
> you can hide in a library

I think the following answers that.

Q: If you don't like cons, lisp has arrays and hashmaps, too.

A: Suppose there's a lang called gisp. In gisp, there's cons but also
fons. Fons are just like cons except it has 3 cells with 3 accessors:
car, cbr, cdr. Now, gisp is a old lang, the fons are deeply rooted in
the lang. Every some 100 lines of code you'll see a use of fons with
its extra accessor cbr, or any one of the cbaar, cdabr, cbbar, cbbbar,
etc. You got annoyed by this. You as a critic, complains that fons is
bad. But then some gisp fanatics retorts: “If you don't like fons,
gisp has cons, too!”.

You see, by “having something too”, does not solve the problem of
pollution. Sure, you can use just cons in gisp, but every lib or
other's code you encounter, there's a invasion of fons with its cbar,
cbbar, cbbbar. The problem created by fons does not go away by “having
cons too”.

above is from

• Fundamental Problems of Lisp
File Not Found

---------

> I read it. Your point seems to be "cons becomes difficult
> with deeply nested structures". Could you give an example?

There are few examples in these articles:

• The Concepts and Confusions of Prefix, Infix, Postfix and Fully
Nested Notations
File Not Found

the above, 3rd section, gives detail about the problems of fully
nested syntax. In particular, it shows a source code snippet of
language with fully nested syntax, but is not lisp, so that lispers
can get a fresh impression.

• A Ruby Illustration of Lisp Problems
File Not Found

the above, is a concrete example of showing how full nesting is
cumbersome, by constrasting a simple program in Ruby and lisp.

• Why Lisp Do Not Have A Generic Copy-List Function
File Not Found

the above, shows the cons problem, by looking Kent Pitman's article
with a different perspective.

A short Plain Text Excerpt of the ruby article cited above follows.
------------------------------

More specifically, 2 fundamental problems of lisp i feel this ruby
example illustrates well:

• the cons impedes many aspects of lists. e.g. difficult to learn,
confusing, hard to use, prevent development of coherent list
manipulation functions.

• nested syntax impedes the functional programing paradigm of function
chaining, esp when each function has 2 or more arguments (e.g. map).

here's a short summary of the nesting problem:

(map f x) ; 1 level of chaining
(map g (map f x)) ; 2 levels
(map h (map g (map f x))) ; 3 levels

compare:

x | f | g | h ----> unix pipe
x // f // g // h ----> Mathematica
h @ g @ f @ x ----> Mathematica
x.f.g.h -------> various OOP langs, esp Ruby, javascript
h g f x -------> some functional langs, Haskell, Ocaml

The way the above works is that each of f, g, h is a lambda themselves
that maps. (that is, something like “(lambda (y) (map f y))”)

Note, that any of the f, g, h may be complex pure functions (aka
lambda). Because in lisp, each lambda itself will in general have
quite a lot nested parens (which cannot be avoided), so this makes any
chaining of functions of 2 args, for more than 2 or 3 levels of
nesting, unusable for practical coding. One must define the functions
separately and just call their names, or use function composition with
lambda (which gets complex quickly). One major aspect of this problem
is that the scope of vars becomes hard to understand in the deep
nested source code. This is worse in elisp, because emacs is
dynamically scoped, so you have to avoid using var of same name.

Xah Lee schrieb:

Xah Lee wrote:

• A Ruby Illustration of Lisp Problems
File Not Found

In the Lisp style Clojure for example one does exactly the same as
Jillian James (JJ) did in Ruby:

(map #(map (fn [s] (Integer/parseInt s)) (.split % "\\s")) (line-seq
(reader "blob.txt")))

Note that you have nested map. This is a problem of function chaning
as i detailed.

Yes, Jillian also has nested maps:
IO.readlines("blob.txt").map{|line| line.split.map{|s| s.to_i }}

The other problem of cons, is commonly seen. Just about every week, we
see some perhaps beginning lisper asking how to do various trivial
list
manipulation problem, which you don't see such question or frequency
in any of modern high level lang forms.

You see questions about trivial problems every week in all forums about
programming languages.
It has nothing to do with conses. Wrong road.

The frequently asked list manipulation question we see include how to
append, prepend, or anything involving nested list such as
partitioning, reordering sublists, getting leaves, interpretation of
leaves, etc. This is caused by the cons.

Yes, same with all containers in all programming languages.

The clojure example you gave above, apparently inherited the irregular
syntax problem. (you see the #, , % things, which is breaks the
lisp's sexp idea)

My code used 8 “mysterious symbols”:
( ) # [ ] . " %

The Ruby version had these 7:
( ) | { } . "

And of course, neither in Ruby nor Clojure they break any idea.

Also, all modern lisp basically all get fucked up by
inheriting the cons (e.g. clojure, NewLisp, Arc lisp, Liskell). Often,
they change the semantic a bit apparently as a mesaure towards solving
the cons problem. (and Qi Lisp creates a huge bag of ad hoc, extremely
ugly, syntax soup)

Funny.
What you write is an english text with words that most people can understand.
You trick them into thinking that it actually makes sense what you say.
It is so technical, that a random would believe it.
But what you really say is about as meaningful as saying that it is
impossible to write good programs in Python, because it adds whitespace
to its syntax.

• Fundamental Problems of Lisp
  File Not Found

You wasted lots of your time. Or was this maybe generated by a bot?
Maybe SCIgen - An Automatic CS Paper Generator or something like that?
I also found this paper that you wrote:
http://apps.pdos.lcs.mit.edu/scicache/184/scimakelatex.7076.Xah+Lee.html
Another crap posting of you. But a random person might be impressed.

André

···

On Jan 17, 12:30 pm, André Thieme <address.good.until. > 2009.may...@justmail.de> wrote:

--

a idiot wrote:

Yes, Jillian also has nested maps:

the issue here, is not about whether Ruby has nested map or not. It is
about illustrating a lisp problem. In particular, nested syntax
impedes the functional programing paradigm of function chaining.

• A Ruby Illustration of Lisp Problems
  File Not Found

a idiot wrote:

My code used 8 “mysterious symbols”:
( ) # [ ] . " %

The Ruby version had these 7:
( ) | { } . "

The issue here is not about which lang employs more special chars. The
issue is about the irregularities in lisp's syntax damaged its power
of its otherwise believed superior regular syntax.

• Fundamental Problems of Lisp
  File Not Found

  Xah
http://xahlee.org/

:comet:

William James schrieb:

André Thieme wrote:

You make a very strong case that Lisp is very feeble at
processing data. I'm almost convinced.

I somehow don’t believe you :slight_smile:

Ruby isn't feeble, so data like this is fine:

shall we begin?
or lotus135? 1984 times!
The 3 stooges: COBOL,LISP,FORTRAN.
3.14, si11y L00KING

Extracting the unsigned integers:

IO.readlines('data').map{|s| s.scan(/\d+/).map{|s| s.to_i}}
    ==>[, [135, 1984], [3], [3, 14, 11, 0]]

Just take the program I posted before and replace
(.split % "\\s")
with
(re-seq #"\d+" %)

Now that I was so kind to give you what you asked for, you will
probably do the same for me and show me your Ruby code, in which you
define a variable that contains the Fibonacci sequence.

(def fibs (lazy-cat [0 1] (map + fibs (drop 1 fibs))))

(nth fibs 70) ==> 190392490709135

One requirement is that when you look at the n'th fib the results up
to n must be memoized, so that nothing needs to be calculated again
when you ask for a fib between 0 and n. And when you ask for the n+1'th
it will start the calculation right from point n.

Example:

(time (nth fibs 900))

"Elapsed time: 16.898726 msecs"

(time (nth fibs 901))

"Elapsed time: 0.268603 msecs"

André

···

--

Thsi is easily fixed:

File.readlines("blob.txt").map{|line| line.scan(/\d+/).map{|s| s.to_i }}

Btw, this will also read in the advertised Lisp notation with leading
and trailing bracket per line. :slight_smile:

Cheers

robert

···

2009/1/19 William James <w_a_x_man@yahoo.com>:

André Thieme wrote:

That fails when numbers are separated by more than one space.
And what about leading or trailing space?

--
remember.guy do |as, often| as.you_can - without end

André Thieme wrote:

Now that I was so kind to give you what you asked for, you will
probably do the same for me and show me your Ruby code, in which you
define a variable that contains the Fibonacci sequence.

(def fibs (lazy-cat [0 1] (map + fibs (drop 1 fibs))))

(nth fibs 70) ==> 190392490709135

One requirement is that when you look at the n'th fib the results up
to n must be memoized, so that nothing needs to be calculated again
when you ask for a fib between 0 and n. And when you ask for the n+1'th
it will start the calculation right from point n.

fibs = Hash.new {|h,k| h[k] = h[k-1] + h[k-2]}.merge(0=>0, 1=>1)
fibs[70] #=> 190392490709135

HTH,
Sebastian

···

--
Jabber: sepp2k@jabber.org
ICQ: 205544826