reading file to list
Xah Lee
xahlee at gmail.com
Wed Feb 25 19:46:52 EST 2009
On Feb 25, 10:18 am, Xah Lee <xah... at gmail.com> wrote:
> On Feb 25, 3:34 am, nick_keighley_nos... at 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
> http://xahlee.org/UnixResource_dir/writ/lisp_problems.html
>
> ---------
>
> > 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
> http://xahlee.org/UnixResource_dir/writ/notations.html
>
> 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
> http://xahlee.org/UnixResource_dir/writ/lisp_problems_by_ruby.html
>
> 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
> http://xahlee.org/UnixResource_dir/writ/lisp_equal_copy_list.html
>
> 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.
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/
☄
More information about the Python-list
mailing list