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