merits of Lisp vs Python

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Robert Uhl

    Re: merits of Lisp vs Python

    "JShrager@gmail .com" <JShrager@gmail .comwrites:
    >
    I have the code here (probably not the latest bcs I left the company
    when it was acquired), let's do a little experiment, for what it's
    worth: 89727 lines of Lisp code in 131 modules (lisp code files), 3306
    "(defun" (by grep|wc), and 261 "(defmacro" . [We did NOT use macros as
    functions!] [Note that lines of code doesn't really matter in Lisp.]
    Wow--my emacs install has 1,152,598 lines of code in 1,570 files, 29,244
    defuns and 1,393 defmacros. This really doesn't prove anything
    whatsoever (as I imagine that your stuff was a _lot_ more complex),
    except maybe how great the FSF is for giving away this sort of thing for
    free.

    --
    Robert Uhl <http://public.xdi.org/=ruhl>
    `We're ten parsecs from Regina, we've got a full tank of LH-two, a half
    pack of cigarettes, I've dimmed the lights, and we're wearing sunglasses.'
    `Let's jump.' --Leslie Bates

    Comment

    • Markus Triska

      Re: merits of Lisp vs Python

      Ken Tilton <kentilton@gmai l.comwrites:
      I think all-rules-all-the-time Prolog is the poster boy for paradigm
      slavery. (I did try for a famous two months to use Prolog as a
      general-purpose programming language.)
      Don't expect to learn Prolog properly in so little time. To your
      previous question whether the ~180 lines of Lisp code in some online
      book constitute an "industrial strength" Prolog: only if the following
      ~180 lines of Prolog code implement an "industrial strength" Lisp.


      ws --[W], { W =< 0' }, ws.
      ws --[].

      open_paren --ws, "(", ws.
      close_paren --ws, ")", ws.

      parse(String, Expr) :- phrase(expressi ons(Expr), String).

      list(Es) --open_paren, expressions(Es) , close_paren.

      expressions([E|Es]) -->
      expression(E), ws,
      !, % single solution: longest input match
      expressions(Es) .
      expressions([]) --[].

      expression(symb ol(A)) --symbol(A0), { name(A, A0) }.
      expression(numb er(N)) --number(N0), { name(N, N0) }.
      expression(List ) --list(List).
      expression([symbol(quote),Q]) --"'", expression(Q).

      number([D|Ds]) --digit(D), number(Ds).
      number([D]) --digit(D).

      digit(D) --[D], {0'0 =< D, D =< 0'9 }.

      symbol([A|As]) -->
      [A],
      { memberchk(A, "+/-*><=abcdefghijk lmnopqrstuvwxyz ") },
      symbolr(As).

      symbolr([A|As]) -->
      [A],
      { memberchk(A, "+/-*><=abcdefghijk lmnopqrstuvwxyz 0123456789") },
      symbolr(As).
      symbolr([]) --[].

      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Interpretation
      --------------
      Declaratively, execution of a Lisp form establishes a relation
      between the (function and variable) binding environment before its
      execution and the environment after its execution. A Lisp program
      is a sequence of Lisp forms, and its result is the sequence of
      their results. Initially, the environment is empty.
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

      run(Program, Values) :-
      parse(Program, Forms0),
      empty_assoc(E),
      compile_all(For ms0, Forms),
      eval_all(Forms, E, _, E, _, Values).

      fold([], _, V, V).
      fold([F|Fs], Op, V0, V) :- E =.. [Op,V0,F], V1 is E, fold(Fs, Op, V1, V).

      compile_all(Fs0 , Fs) :- maplist(compile , Fs0, Fs).

      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      compile/2 marks (with "user/1") calls of user-defined functions.
      This eliminates an otherwise defaulty representation of function
      calls and thus allows for first argument indexing in eval/7.
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

      compile(F0, F) :-
      ( F0 = number(_) -F = F0
      ; F0 = symbol(t) -F = t
      ; F0 = symbol(nil) -F = nil
      ; F0 = symbol(_) -F = F0
      ; F0 = [] -F = []
      ; F0 = [symbol(quote)|A rgs] -F = [quote|Args]
      ; F0 = [symbol(setq),sy mbol(Var),Val0] ->
      compile(Val0, Val),
      F = [setq,Var,Val]
      ; F0 = [symbol(Op)|Args 0],
      memberchk(Op, [+,-,*,equal,if,>,< ,=,progn,eval,l ist,car,cons,
      cdr,while,not]) ->
      compile_all(Arg s0, Args),
      F = [Op|Args]
      ; F0 = [symbol(defun),s ymbol(Name),Arg s0|Body0] ->
      compile_all(Bod y0, Body),
      maplist(un_symb ol, Args0, Args),
      F = [defun,Name,Args |Body]
      ; F0 = [symbol(Op)|Args 0] ->
      compile_all(Arg s0, Args),
      F = [user(Op)|Args]
      ).

      un_symbol(symbo l(S), S).

      eval_all([], Fs, Fs, Vs, Vs, []).
      eval_all([A|As], Fs0, Fs, Vs0, Vs, [B|Bs]) :-
      eval(A, Fs0, Fs1, Vs0, Vs1, B),
      eval_all(As, Fs1, Fs, Vs1, Vs, Bs).

      eval(number(N), Fs, Fs, Vs, Vs, N).
      eval(t, Fs, Fs, Vs, Vs, t).
      eval(nil, Fs, Fs, Vs, Vs, nil).
      eval(symbol(A), Fs, Fs, Vs, Vs, V) :- get_assoc(A, Vs, V). % variable lookup
      eval([L|Ls], Fs0, Fs, Vs0, Vs, Value) :- eval(L, Ls, Fs0, Fs, Vs0, Vs, Value).

      eval(+, Args0, Fs0, Fs, Vs0, Vs, Value) :-
      eval_all(Args0, Fs0, Fs, Vs0, Vs, Args),
      fold(Args, (+), 0, Value).
      eval(-, [V0|Rest], Fs0, Fs, Vs0, Vs, Value) :-
      eval(V0, Fs0, Fs1, Vs0, Vs1, V1),
      eval_all(Rest, Fs1, Fs, Vs1, Vs, Vals),
      fold(Vals, (-), V1, Value).
      eval(*, Args0, Fs0, Fs, Vs0, Vs, Value) :-
      eval_all(Args0, Fs0, Fs, Vs0, Vs, Args),
      fold(Args, (*), 1, Value).
      eval(equal, [A0,B0], Fs0, Fs, Vs0, Vs, Value) :-
      eval(A0, Fs0, Fs1, Vs0, Vs1, A),
      eval(B0, Fs1, Fs, Vs1, Vs, B),
      ( A == B -Value = t ; Value = nil ).
      eval(if, [Cond,Then|Else], Fs0, Fs, Vs0, Vs, Value) :-
      eval(Cond, Fs0, Fs1, Vs0, Vs1, V),
      ( V = nil ->
      eval_all(Else, Fs1, Fs, Vs1, Vs, Values),
      last(Values, Value)
      ; eval(Then, Fs1, Fs, Vs1, Vs, Value)
      ).
      eval(not, [Arg], Fs0, Fs, Vs0, Vs, Value) :-
      eval(Arg, Fs0, Fs, Vs0, Vs, V),
      ( V == nil -Value = t ; Value = nil ).
      eval(>, [Arg1,Arg2], Fs0, Fs, Vs0, Vs, Value) :-
      eval(Arg1, Fs0, Fs1, Vs0, Vs1, V1),
      eval(Arg2, Fs1, Fs, Vs1, Vs, V2),
      ( V1 V2 -Value = t ; Value = nil ).
      eval(<, [Arg1,Arg2], Fs0, Fs, Vs0, Vs, Value) :-
      eval(Arg1, Fs0, Fs1, Vs0, Vs1, V1),
      eval(Arg2, Fs1, Fs, Vs1, Vs, V2),
      ( V1 < V2 -Value = t ; Value = nil ).
      eval(=, [Arg1,Arg2], Fs0, Fs, Vs0, Vs, Value) :-
      eval(Arg1, Fs0, Fs1, Vs0, Vs1, V1),
      eval(Arg2, Fs1, Fs, Vs1, Vs, V2),
      ( V1 =:= V2 -Value = t ; Value = nil ).
      eval(progn, Ps, Fs0, Fs, Vs0, Vs, Value) :-
      eval_all(Ps, Fs0, Fs, Vs0, Vs, Values),
      last(Values, Value).
      eval(eval, [Form0], Fs0, Fs, Vs0, Vs, V) :-
      eval(Form0, Fs0, Fs1, Vs0, Vs1, Form1),
      compile(Form1, Form2),
      eval(Form2, Fs1, Fs, Vs1, Vs, V).
      eval(quote, [Q], Fs, Fs, Vs, Vs, Q).
      eval(setq, [Var,V0], Fs0, Fs, Vs0, Vs, V) :-
      eval(V0, Fs0, Fs, Vs0, Vs1, V),
      put_assoc(Var, Vs1, V, Vs).
      eval(defun, [Func,Args|Body], Fs0, Fs, Vs, Vs, Func) :-
      put_assoc(Func, Fs0, Args-Body, Fs).
      eval(list, Ls0, Fs0, Fs, Vs0, Vs, Ls) :-
      eval_all(Ls0, Fs0, Fs, Vs0, Vs, Ls).
      eval(cons, [Car0,Cdr0], Fs0, Fs, Vs0, Vs, [Car|Cdr]) :-
      eval(Car0, Fs0, Fs1, Vs0, Vs1, Car),
      eval(Cdr0, Fs1, Fs, Vs1, Vs, Cdr).
      eval(car, [Ls0], Fs0, Fs, Vs0, Vs, Car) :-
      eval(Ls0, Fs0, Fs, Vs0, Vs, [Car|_]).
      eval(cdr, [Ls0], Fs0, Fs, Vs0, Vs, Cdr) :-
      eval(Ls0, Fs0, Fs, Vs0, Vs, [_|Cdr]).
      eval(while, [Cond|Body], Fs0, Fs, Vs0, Vs, Value) :-
      eval(Cond, Fs0, Fs1, Vs0, Vs1, V),
      ( V == nil -Value = nil, Fs = Fs0, Vs = Vs0
      ; eval_all(Body, Fs1, Fs2, Vs1, Vs2, _),
      eval(while, [Cond|Body], Fs2, Fs, Vs2, Vs, Value)
      ).
      eval(user(F), Args0, Fs0, Fs, Vs0, Vs, Value) :-
      eval_all(Args0, Fs0, Fs, Vs0, Vs, Args),
      get_assoc(F, Fs, As-Body),
      empty_assoc(E),
      bind_arguments( As, Args, E, Bindings),
      eval_all(Body, Fs, _, Bindings, _, Results),
      last(Results, Value).

      bind_arguments([], [], Bs, Bs).
      bind_arguments([A|As], [V|Vs], Bs0, Bs) :-
      put_assoc(A, Bs0, V, Bs1),
      bind_arguments( As, Vs, Bs1, Bs).


      They give you a simple Lisp and, in contrast to some online books
      claiming to give you "Prolog" (an ISO-standardised language) and then
      failing to even parse a single proper Prolog term, also let you write
      it in its natural form. Example queries tested with SWI Prolog:

      "append":

      ?- run("(defun append (x y) (if (equal x '()) y (cons (car x) (append (cdr x) y)))) (append '(1 2 3) '(4 5))", V).

      ==V = [append, [number(1), number(2), number(3), number(4), number(5)]] ;


      Fibonacci, naive version:

      ?- time(run("(defu n fib (n) (if (= 0 n) 0 (if (= 1 n) 1 (+ (fib (- n 1)) (fib (- n 2)))))) (fib 24)", V)).

      ==V = [fib, 46368] ;
      9,567,271 inferences, 3.42 CPU in 3.50 seconds (98% CPU, 2797448 Lips)

      Different version:

      ?- time(run("(defu n fib (n) (if (= 0 n) 0 (fib1 0 1 1 n))) (defun fib1 (f1 f2 i to) (if (= i to) f2 (fib1 f2 (+ f1 f2) (+ i 1) to))) (fib 100)", V)).

      ==16,275 inferences, 0.01 CPU in 0.01 seconds (163% CPU, 1627500 Lips)
      V = [fib, fib1, 354224848179261 915075] ;


      Using a while loop:

      ?- time((run("(def un fib (n) (setq f (cons 0 1)) (setq i 0) (while (< i n) (setq f (cons (cdr f) (+ (car f) (cdr f)))) (setq i (+ i 1))) (car f)) (fib 200)", V))).

      ==20,509 inferences, 0.02 CPU in 0.01 seconds (239% CPU, 1025450 Lips)
      V = [fib, 280571172992510 140037611932413 038677189525] ;


      Showing "eval" and "map":


      ?- run("(defun map (f xs) (if (equal xs '()) '() (cons (eval (list f (car xs))) (map f (cdr xs))))) (defun plus1 (x) (+ 1 x)) (map 'plus1 '(1 2 3))", Vs).

      ==Vs = [map, plus1, [2, 3, 4]] ;


      Prolog's analogon to Lisp's macros is term_expansion/2 by the way.


      All the best!
      Markus Triska

      Comment

      • Robert Uhl

        Re: merits of Lisp vs Python

        "Stephen Eilert" <spedrosa@gmail .comwrites:
        >
        So, let's suppose I now want to learn LISP (I did try, on several
        occasions). What I would like to do would be to replace Python and
        code GUI applications. Yes, those boring business-like applications
        that have to access databases and consume those new-fangled
        web-services and whatnot. Heck, maybe even code games using DirectX.
        GUIs are a weak point, or were last I looked. There are at least three
        GTK+ interfaces.

        Database access is handled very nicely with CLSQL, which does OR mapping
        right.

        I've not written code to 'consume web-services,' but I daresay that
        NET.HTML.CLIENT (believe that's the name) would do the trick.

        --
        Robert Uhl <http://public.xdi.org/=ruhl>
        If anybody can show me in the Bible the command, 'Thou shalt not smoke,'
        I am ready to keep it; but I haven't found it yet. I find ten
        commandments, and it's as much as I can do to keep them; and I've no
        desire to make them into eleven or twelve. --C. H. Spurgeon

        Comment

        • greg

          Re: merits of Lisp vs Python

          Juan R. wrote:
          I see no dinamism on your example, just static overloading.
          There's nothing static about it:

          q = raw_input()
          if q == "A":
          a = 1
          b = 2
          else:
          a = "x"
          b = "y"
          c = a + b

          There is no way that the compiler can statically
          determine what the + operator needs to do here.

          --
          Greg

          Comment

          • greg

            Re: merits of Lisp vs Python

            Espen Vestre wrote:
            Paul Rubin <http://phr.cx@NOSPAM.i nvalidwrites:
            there is a huge amount of
            state scattered all through a running Python program, that the
            application can modify at random
            >
            That's what I call /kludgy/, not /dynamic/ ;-)
            I think "kludgy" is a bit unfair, since this is a
            result of doing things in a very simple and uniform
            way -- rather a Lispy concept, I would have thought. :-)

            --
            Greg

            Comment

            • greg

              Re: merits of Lisp vs Python

              Paul Rubin wrote:
              I think the Lispies see "more dynamism" as a good thing and are
              therefore defending their language from suggestions that Python is
              even more dynamic than Lisp. I mean "dynamic" in a less good way--
              Indeed, Python has sometimes been described
              as "pathologic ally dynamic". All that dynamism
              is handy sometimes, but it does get in the
              way of improving efficiency.

              Often discussions take place on python-dev
              about ways to selectively limit the dynamism
              to make some optimisation possible.

              --
              Greg

              Comment

              • greg

                Re: merits of Lisp vs Python

                Jon Harrop wrote:
                Outside Lisp, macros are for syntax. Evaluation semantics (e.g. lazy
                evaluation) then have nothing to do with macros.
                I don't think that's entirely true. With currying
                and lazy evaluation, there's a sense in which
                Haskell function definitions already *are* macros.

                There are limits to the degree of syntactical
                transformation you can reasonably achieve -- it
                wouldn't be easy to make Haskell code look exactly
                like Cobol, for example. But usually that's not
                what you're after -- rather you just want to
                devise some way to express your intent with a
                minimum of boilerplate.

                I once implemented a parser in HUGS. Using nothing
                but built-in language features, I was able to
                construct a system whereby I could more or less
                just write down the BNF grammar rules and feed them
                straight into the HUGS compiler. Achieving a
                similar trick in Lisp would probably have required
                using macros.

                --
                Greg

                Comment

                • greg

                  Re: merits of Lisp vs Python

                  Robert Uhl wrote:
                  o Symbols
                  >
                  In Lisp, a symbol is essentially a hashed string;
                  Are you aware that strings can be interned in Python?
                  Furthermore, any string literal in the source that
                  is a syntactically valid identifier is automatically
                  interned, and you can intern any string explicitly
                  if you need. This gives you exactly the same
                  capabilities as symbols in Lisp.

                  For example, due to the automatic interning, the
                  string comparison in the following is just a pointer
                  comparison:

                  fred = 'hello'
                  if fred == 'hello':
                  print 'Greetings'

                  --
                  Greg

                  Comment

                  • greg

                    Re: merits of Lisp vs Python

                    George Sakkis wrote:
                    I'm sure there should be more convincing examples for macros, but
                    neither this nor the 'unless' syntax sugar cuts it.
                    Also, the new 'with' statement and associated
                    protocol covers much of the ground that was left
                    out by the existing constructs.

                    --
                    Greg

                    Comment

                    • Ken Tilton

                      Re: merits of Lisp vs Python



                      Markus Triska wrote:
                      Ken Tilton <kentilton@gmai l.comwrites:
                      >
                      >
                      >>I think all-rules-all-the-time Prolog is the poster boy for paradigm
                      >>slavery. (I did try for a famous two months to use Prolog as a
                      >>general-purpose programming language.)
                      >
                      >
                      Don't expect to learn Prolog properly in so little time.
                      Lawdy, no, but I had all those Art of Prolog and Craft of Prolog and a
                      couple other books and I was staring at pages of intense code just
                      trying to do basic stuff. I had not learned prolog, but I could see the
                      masters writing hairy code to basic stuff so I concluded...run away! run
                      away! :)

                      I think the other thing that got me was cuts, which I translated as "did
                      we say unification all the time? sorry..." :)

                      To your
                      previous question whether the ~180 lines of Lisp code in some online
                      book constitute an "industrial strength" Prolog: only if the following
                      ~180 lines of Prolog code implement an "industrial strength" Lisp.
                      <snip lisp-in-Prolog>

                      Way cool.

                      ken


                      --
                      Algebra: http://www.tilton-technology.com/LispNycAlgebra1.htm

                      "Well, I've wrestled with reality for thirty-five
                      years, Doctor, and I'm happy to state I finally
                      won out over it." -- Elwood P. Dowd

                      "I'll say I'm losing my grip, and it feels terrific."
                      -- Smiling husband to scowling wife, New Yorker cartoon

                      Comment

                      • Ken Tilton

                        Re: merits of Lisp vs Python



                        Robert Uhl wrote:
                        "Stephen Eilert" <spedrosa@gmail .comwrites:
                        >
                        >>So, let's suppose I now want to learn LISP (I did try, on several
                        >>occasions). What I would like to do would be to replace Python and
                        >>code GUI applications. Yes, those boring business-like applications
                        >>that have to access databases and consume those new-fangled
                        >>web-services and whatnot. Heck, maybe even code games using DirectX.
                        >
                        >
                        GUIs are a weak point, or were last I looked.
                        LW comes with CAPI, portable across the big 3. ACL has Common Graphics
                        on win32, and I think they have Gtk bindings elsewhere (just guessing,
                        really). Everyone has Ltk, Cells-Gtk, and Celtk. (Two Tks, one Gtk if
                        that is not clear).

                        ken

                        --
                        Algebra: http://www.tilton-technology.com/LispNycAlgebra1.htm

                        "Well, I've wrestled with reality for thirty-five
                        years, Doctor, and I'm happy to state I finally
                        won out over it." -- Elwood P. Dowd

                        "I'll say I'm losing my grip, and it feels terrific."
                        -- Smiling husband to scowling wife, New Yorker cartoon

                        Comment

                        • Neil Cerutti

                          Re: merits of Lisp vs Python

                          On 2006-12-13, hit_the_lights <langstefan@gmx .atwrote:
                          Neil Cerutti schrieb:
                          >
                          > a[i] = b[n]
                          >>
                          >with
                          >>
                          > (setf (aref a i) (aref b n))
                          >>
                          >and the attractions of Python may make more sense.
                          >
                          Here Python and Lisp are equal, 7 tokens vs 7 tokens, but in
                          Python one has to write less since "[]" are 2 chars while
                          "aref" are 4, plus the setf. But from counting the brain
                          units which I regard as an important factor they are both
                          equal.
                          >>
                          >A comparison of brain units of the above snippets is
                          >irrelevant, since the snippets are not equivalent.
                          >>
                          >The Python snippet will work for any object a that provides
                          >__setitem__ and any object b that provides __getitem__.
                          >>
                          >I don't know what an equivalent Lisp snippet would be (or even
                          >exactly how close the above snippet comes to matching the
                          >Python code), but whatever it is would be a better foundation
                          >for comparing brain units with the above Python.
                          >
                          It would be exactly like the example given, just "aref"
                          replaced with something else. An example implementation:
                          >
                          >============== =============== =============
                          (defgeneric $ (container key))
                          (defgeneric (setf $) (value container key))
                          >
                          ;;; Implementation for arrays
                          >
                          (defmethod $ ((container array) (key integer))
                          (aref container key))
                          >
                          (defmethod (setf $) (value (container array) (key integer))
                          (setf (aref container key) value))
                          >============== =============== =============
                          >
                          And usage:
                          >
                          >============== =============== =============
                          CL-USER(3): (defparameter a (vector 1 2 3 4 5))
                          A
                          CL-USER(4): ($ a 0)
                          1
                          CL-USER(5): (setf ($ a 0) 9)
                          9
                          CL-USER(6): a
                          #(9 2 3 4 5)
                          >============== =============== =============
                          >
                          The nice thing is, that you *can* dispatch on the container,
                          the key and the value.
                          That's cool. Thanks for posting the code.

                          Is the above 'duck-typing' idiom considered very useful to a
                          Lisper? It seems logical to me that duck-typing works best in an
                          environment where it is ubiquitous. If users have to implement
                          accessors specifically to use your library, it is not as good as
                          if they had already implemented one as a matter of routine.

                          --
                          Neil Cerutti

                          Comment

                          • josephoswaldgg@hotmail.com

                            Re: merits of Lisp vs Python


                            Bjoern Schliessmann wrote:
                            Robert Uhl wrote:
                            >
                            Because it's the language for which indentation is automatically
                            determinable. That is, one can copy/paste a chunk of code, hit a
                            key and suddenly everything is nicely indented.
                            >
                            Cool, so in other languages I need to set block marks like () and {}
                            and also indent the code for readability, and in Python I indent
                            only. From my POV that's less work.
                            Try reading again. In Lisp, you use () and *your editor* automatically
                            indents according to the universal standard, or you leave it sloppy
                            until other folks reading your code convince you to get a proper
                            programming editor. Indentation does not get out of sync with semantics
                            because the editor virtually never misses parentheses that the Lisp
                            compiler sees. Expressions keep the same meaning even if you have to
                            start breaking them across lines, etc.

                            In Python, you group in your mind, and press indentation keys to make
                            it happen in your editor. The editor cannot help that much, because it
                            cannot read your mind. White space screwups in copy-paste cannot be
                            fixed by the editor automatically, because it cannot read the original
                            programmer's mind, and you have to fix it manually, and risk screwing
                            it up.

                            Comment

                            • JShrager@gmail.com

                              Re: merits of Lisp vs Python

                              Robert Uhl wrote:
                              "JShrager@gmail .com" <JShrager@gmail .comwrites:
                              I have the code here (probably not the latest bcs I left the company
                              when it was acquired), let's do a little experiment, for what it's
                              worth: 89727 lines of Lisp code in 131 modules (lisp code files), 3306
                              "(defun" (by grep|wc), and 261 "(defmacro" . [We did NOT use macros as
                              functions!] [Note that lines of code doesn't really matter in Lisp.]
                              >
                              Wow--my emacs install has 1,152,598 lines of code in 1,570 files, 29,244
                              defuns and 1,393 defmacros. This really doesn't prove anything
                              whatsoever (as I imagine that your stuff was a _lot_ more complex),
                              except maybe how great the FSF is for giving away this sort of thing for
                              free.
                              Let us note that it's not FSF that gives this stuff away for free -- or
                              if it is them proximally, it is not them ultimately -- ultimately it's
                              the engineers who did all that work that gave it away for free.

                              Comment

                              • Neil Cerutti

                                Re: merits of Lisp vs Python

                                On 2006-12-13, josephoswaldgg@ hotmail.com
                                <josephoswald@g mail.comwrote:
                                Try reading again. In Lisp, you use () and *your editor*
                                automatically indents according to the universal standard, or
                                you leave it sloppy until other folks reading your code
                                convince you to get a proper programming editor. Indentation
                                does not get out of sync with semantics because the editor
                                virtually never misses parentheses that the Lisp compiler sees.
                                Expressions keep the same meaning even if you have to start
                                breaking them across lines, etc.
                                Yes, it's the same way in Python. Of course, not everything is an
                                expression in Python, so it's not saying quite as much.
                                In Python, you group in your mind, and press indentation keys
                                to make it happen in your editor. The editor cannot help that
                                much, because it cannot read your mind. White space screwups in
                                copy-paste cannot be fixed by the editor automatically, because
                                it cannot read the original programmer's mind, and you have to
                                fix it manually, and risk screwing it up.
                                It is very easy a manual process, possibly as simple as selecting
                                the correct s-expr and pasting it into the right place in your
                                code.

                                --
                                Neil Cerutti

                                Comment

                                Working...