The perens in lisp dilects is there for a reson... macros

macros are sort of like c macros but more powerful. they are the
manafestation of treating code like data. lisp code is just a textual
representation of a data structure that is the list. this means that
you can manipulate code to emulate structured controll constructs and
elemanate boilerplate code. to show you the power of a macro heer is a
while loop

(defmacro while (test &body body) `(do () ((not ,test)) ,@body)

Another one would be untill

(defmacro untill (test &body body) `(while (not ,test) ,@body))

wich is defined on top of while

another test to wead out programers would be lisp stile macros because
of variable capture
and other perls of the macro world. but higenic macros can not have the
power of true macros

i also hear you talk about introspection. in lisp you use eval list

lets define a sum function to show you

(defun sum (lst) (eval (append '(+) lst)))

another example would be this

(loop (print (eval (read)))) this is an interactive top level in 1 line

another use is for calling of functions

(defvar cmds `('foo ,(lambda () (format t "hello world"))) (funcall (getf cmds (read-from-string (read-line)))) of corse no error checking for comas and other things that could crash the program

The parentheses are not strictly necessary for macros. They’re just the
traditional LIspy way to do it. For instance, this is from UCBLogo’s
help documentation (I copied the first screenful from a terminal
emulator):

.MACRO procname :input1 :input2 … (special
form)
.DEFMACRO procname text

    A macro is a special kind of procedure whose output is evaluated
    as Logo instructions in the context of the macro's caller.
    .MACRO is exactly like TO except that the new procedure becomes
    a macro; .DEFMACRO is exactly like DEFINE with the same 

exception.

    Macros are useful for inventing new control structures 

comparable
to REPEAT, IF, and so on. Such control structures can almost,
but
not quite, be duplicated by ordinary Logo procedures. For
example,
here is an ordinary procedure version of REPEAT:

            to my.repeat :num :instructions
            if :num=0 [stop]
            run :instructions
            my.repeat :num-1 :instructions
            end

    This version works fine for most purposes, e.g.,

            my.repeat 5 [print "hello]

    But it doesn't work if the instructions to be carried out 

include
OUTPUT, STOP, or LOCAL. For example, consider this procedure:

            to example
            print [Guess my secret word.  You get three guesses.]
            repeat 3 [type "|?? | ~
                      if readword = "secret [pr "Right! stop]]
            print [Sorry, the word was "secret"!]
            end

    This procedure works as written, but if MY.REPEAT is used 

instead
of REPEAT, it won’t work because the STOP will stop MY.REPEAT
instead of stopping EXAMPLE as desired.

    The solution is to make MY.REPEAT a macro.  Instead of actually
    carrying out the computation, a macro must return a list 

containing
Logo instructions. The contents of that list are evaluated as
if
they appeared in place of the call to the macro. Here’s a macro
version of REPEAT:

[email protected] writes:

This appears to be the continuation of some conversation / flamewar
somewhere else. Why bring this crud over here? Is there some reason
that we should care?

Fine, lisp macros are great and glorious and the be all and end all of
programming constructs, and all other languages hopelessly inferior.
All hail lisp macros. They’re even so great and wonderful we’ll bow
down before the wisdom of someone who manages to cram three spelling
errors and an awful grammar error into the subject line. You’ve
proven your vast superiority over us with your l33t lisping skillz.

Can you just go away now and let us get back to ruby?

On Sun, 2006-08-06 at 13:34 +0900, Rick DeNatale wrote:

a while, and I’ve been wondering the same thing about the apparently
endless discussion of the merits of C, C++, Ocaml, and Java

That stuff doesn’t bother me, it seems normal for users, enthusiasts,
and people interested in one programming language to talk about other
programming languages. Programmers these days usually have to use
multiple languages in their work anyway, and may have some functionaliy
written in another language that they need to interface with Ruby. It’s
less fun to have a topic-nazi policy.

I’ve also noticed that Rubyists seem have a high tendency (at least
higher than Javaists and others, I think) to be programming-language
geeks, the kind of folks who like to learn about the general concepts of
programming languages, learn lots of different ones, and compare them.
I’d count myself more among those than a Rubyist at this point, as I’ve
yet to work on a real project in Ruby yet (but I’m itching to).

–ch–

On 8/5/06, Daniel M. [email protected] wrote:

[email protected] writes:

This appears to be the continuation of some conversation / flamewar
somewhere else. Why bring this crud over here? Is there some reason
that we should care?

I’ve only recently subscribed to this list, after just sampling it for
a while, and I’ve been wondering the same thing about the apparently
endless discussion of the merits of C, C++, Ocaml, and Java

Rick DeNatale wrote:

a while, and I’ve been wondering the same thing about the apparently
endless discussion of the merits of C, C++, Ocaml, and Java
Whatever you opinions about any programming language are, Ruby is
implemented in C at the moment, so C at least has that going for it!
:slight_smile: :slight_smile:

On Sun, 2006-08-06 at 13:34 +0900, Rick DeNatale wrote:

On 8/5/06, Daniel M. [email protected] wrote:

[email protected] writes:

Oh, and if anyone’s keeping score, the parens in Lisp/Scheme are there
to structure the code and data. Where other languages are full of {},
[], ;, and all sort of other punctuation marks, in Lisp you only
have/need parentheses to serve all the same purposes. It doesn’t have
anything to do with macros per se.

–ch–

Charles Hoffman wrote:

That stuff doesn’t bother me, it seems normal for users, enthusiasts,
and people interested in one programming language to talk about other
programming languages.
Especially the denizens of the main Ruby mailing list, which includes
the founder of the language. We are people who use or want to use Ruby,
and we want it to have what it needs from other languages. Matz did a
pretty good job of that all by himself. :slight_smile:

Programmers these days usually have to use
multiple languages in their work anyway,
Well … my personal opinion is that more than two languages is probably
overload. You need one general purpose language and whatever
domain-specific language fits what you’re doing. More than that and you
start losing time context switching and spending time looking up things
like “how do I parse a date/time string to a date/time object in Ruby
when I know how to do it in R?” :slight_smile:

I’ve also noticed that Rubyists seem have a high tendency (at least
higher than Javaists and others, I think) to be programming-language
geeks, the kind of folks who like to learn about the general concepts of
programming languages, learn lots of different ones, and compare them.

That may be because of Ruby’s youth relative to other general-purpose
languages. I remember the same phenomenon when Java was a young
language. I’m personally a language geek and have been since … well,
let’s just say that the first code I wrote in my life was for a machine
built from vacuum tubes that had only an assembler. :slight_smile:

Charles Hoffman wrote:

Oh, and if anyone’s keeping score, the parens in Lisp/Scheme are there
to structure the code and data. Where other languages are full of {},
[], ;, and all sort of other punctuation marks, in Lisp you only
have/need parentheses to serve all the same purposes. It doesn’t have
anything to do with macros per se.

–ch–

There’s a bit more to it than that. Ironically, Lisp originated as an
implementation of “parenthesis-free (Polish) prefix” notation in
symbolic logic. That is, rather than write “A + (B * C)” one writes "+ A

  • B C". The parentheses came about for a number of reasons:
  1. Unlike my example, Lisp functions even in Lisp 1 did not have a fixed
    arity,
  2. As someone already pointed out, S expressions used them,
  3. It’s more natural when you have multi-character atoms,

etc. So in Lisp you end up with “(PLUS A (TIMES A B))”.

The reverse Polish form “B C * A +” is what the early compilers
generated, and is now known as Forth. :slight_smile:

Incidentally, the original Lisp spec had list elements separated by
commas, for example “(ALPHA,(BETA,GAMMA))”. There was a bug/feature in
the first implementation that allowed spaces, and the rest is history.
:slight_smile:

On Mon, 2006-08-07 at 00:49 +0900, M. Edward (Ed) Borasky wrote:

Whatever you opinions about any programming language are, Ruby is
implemented in C at the moment, so C at least has that going for it! :slight_smile: :slight_smile:

Java’s VM is written in C too, is it not?

MTASC, a rather good open-source ActionScript compiler, is written in
OCaml… as is haXe, I think.

C is kind of an obvious choice for interpreters/compilers because of the
availability of Lex and Yacc (and/or flex and Bison), I suppose.

Hmmm… I had rather thought that functional-style languages were more
common for writing language interpreters/compilers in. Aren’t Lisp guys
always on about using Lisp to write another language more specific to
the problem domain, and working from there?

In the Programming Languages course I took at UNI we developed an
interpreter for a simple language in Scheme… the professor I took that
course with just e-mailed me a Joy interpreter he wrote, also in Scheme,
that I had expressed interest in. In another course I took with another
prof, we used a Mumps compiler he had written in C++; actually it
translated Mumps to C++ and compiled that with gcc.

I think gForth is written in C, but there are faster Forth environments
out there; I wonder what they used. I’m pretty sure a lot of Forth
environments are started in assembler.

Anyway I’m rambling, just because this is a fun topic.

I’d learned that it was common to develop a minimal subset of a new
language in another language, then use that small version of the
language to write the rest. The Lisp environments I’ve used certainly
appear to have been implemented in this way, and Forth is explicitly so.
There definitely seem to be some very low-level functions in Ruby that
seem to be mainly used by more advanced Rubyists, usually for
metaprogramming-like things. Stuff like instance_eval. Am I on-track
in having the impression that Ruby is designed that way? Just curious.

–ch–

On 8/5/06, Daniel M. [email protected] wrote:

This appears to be the continuation of some conversation / flamewar
somewhere else. Why bring this crud over here? Is there some reason
that we should care?

No. It looks more like trolling in an incoherent way, than a discussion
with
meaningful information about lisp.

Rick DeNatale wrote:

I’ve only recently subscribed to this list, after just sampling it for
a while, and I’ve been wondering the same thing about the apparently
endless discussion of the merits of C, C++, Ocaml, and Java

Apparently some people do care. If you don’t, then why reading the
thread?

On Mon, 07 Aug 2006 00:49:20 +0900, M. Edward (Ed) Borasky wrote:

Whatever you opinions about any programming language are, Ruby is
implemented in C at the moment, so C at least has that going for it!
:slight_smile: :slight_smile:

Exactly! It is quite useful to know C, for example to write bindings to
existing libraries, or to rewrite the parts of your program that are
slow
in C.

Regards,
Kristof

On Mon, Aug 07, 2006 at 02:05:03AM +0900, Charles Hoffman wrote:

Hmmm… I had rather thought that functional-style languages were more
common for writing language interpreters/compilers in. Aren’t Lisp guys
always on about using Lisp to write another language more specific to
the problem domain, and working from there?

Err . . . not exactly. It’s more like in Lisp you create a
domain-specific “jargon” that allows you to abstract the problem further
according to the needs of the moment – like using a particularly long
lever to gain the ability to move larger things with less “heavy
lifting” power provided by you, the programmer.

As one uses a higher-level programming language rather than moving bits
around one at a time with a pair of tweezers when one wants to (for
instance) edit some text, so one uses Lisp to create domain-specific
syntaxes for further abstracting things so that not even the extra work
of using that “higher-level” programming language is necessary. At
least, that’s my understanding: it’s not about literally writing a
compiler for a language, then writing programs in that language.

I could be wrong, though.

Kristof B. [email protected] writes:

On 8/5/06, Daniel M. [email protected] wrote:

This appears to be the continuation of some conversation / flamewar
somewhere else. Why bring this crud over here? Is there some reason
that we should care?

No. It looks more like trolling in an incoherent way, than a discussion with
meaningful information about lisp.

Looking up other posts by [email protected] on google groups is
informative. It looks like the poster is continuing some
pre-existing conversation, but he’s not. However, I’m not sure that
this is trolling in the sense of “the poster is consciously trying to
arouse an emotional response”, unless the entire persona of
[email protected] is one long extended troll.

There’s lisp macro activity, which would be annoying on this list to
begin with, then there’s poor lisp macro activity, which attempts to
wax on about how wonderful lisp macros are without providing more than
trivial examples (easily done with higher-level functions), then
there’s incoherent advocacy, which is what we have here. (not merely
incoherent from the bizarre spelling and atrocious grammar, but also
incoherent at a structural level - he can’t decide if he’s defending
lisp as a wonderful language or as a sieve to separate the
uebermenschen from the rest of humanity)

Anyway. This is entirely much more time spent on this poster than I
meant to spend.

Charles Hoffman wrote:

That makes sense to me, except that it doesn’t seem all that different
from what you do with any language by writing functions and classes and
the like. You end up with all these concepts that you’ve defined in
code and given names to, and then work with those. So why do Lispies
make such a big deal over it?

I did something similar a long time ago in macro assembler, which I
learned a long time before I learned Lisp. Interestingly enough, I dug
out my copy of Leo Brodie’s “Thinking Forth” last night. That
programming style, and the term “factoring”, are prominent in that work
(which by the way is available on line now as a PDF). I think it’s
something all programmers of a certain level of maturity do regardless
of language.

I learned Lisp (1.5) in the early 1970s, and this style of programming
seemed to be tied to Lisp at the time, but I actually had used it
earlier. For some reason FORTRAN programmers, including myself when I
was one, don’t usually use this style, perhaps because the original
FORTRAN didn’t have structured concepts and forced the use of GO TO
statements.

Lisp is probably the third oldest programming language in use today,
after FORTRAN and COBOL. Since FORTRAN and COBOL programmers didn’t tend
to program that way and Lisp programmers did, I suspect the Lispniks
make a big deal of it because they “invented” it and have been doing it
longer. :slight_smile:

On Mon, 2006-08-07 at 16:04 +0900, Chad P. wrote:

lever to gain the ability to move larger things with less "heavy
I could be wrong, though.

That makes sense to me, except that it doesn’t seem all that different
from what you do with any language by writing functions and classes and
the like. You end up with all these concepts that you’ve defined in
code and given names to, and then work with those. So why do Lispies
make such a big deal over it?

–ch–

Francis C. wrote:

I’ve always been fascinated by one specific aspect of functional
languages: in theory, it’s possible to use tools to prove programs
correct. What a productivity win that would be. At different times, I
used professional programmers who worked for me as guinea pigs to see
just how they would take to the functional style, and the results were
dismal.
You are bringing back memories and dreams I had in graduate school. :slight_smile:
Nobody where I went to school knew anything about this, but it was all
in the library. I still have most of the books I bought on the subject,
which date back to the mid-1970s for the most part.

I learned the Von Neumann style first – it’s hard not to when your
first programming class is taught on ILLIAC I. :slight_smile: But I learned the
functional style and prefer it.

But one of the more insightful things I’ve heard recently is this:
Turing-completeness works against productivity and makes programs less
tool-able. And this is a direct consequence of its power, which
necessarily gives you Godel-undecidability in the general case.
More memories and dreams. :slight_smile: Maybe that’s why regular expressions are so
popular – because they’re equivalent to the lowest common denominator,
a finite state machine, about which you can pretty much prove and
discover everything.
The Lispish style (conceptualizing programs as artifacts in a
domain-specific language), which Ruby does extremely well in an
imperative-language context, can be said to have the following virtue:
it allows you to work with your problem domain using a language that
is not Turing-complete. (Let that sink in for a moment.) That means
that your programs are easier to reason about, easier to debug, and
eventually, easier to tool. What you lose in expressive power is
trivial because your standard for language power is related to your
problem domain, not to Turing-completeness in general. What you gain
in productivity is potentially immense.
Well … there are two reasons to write a Domain Specific Language:

  1. As a way of organizing your own programming, and
  2. As a tool to be used by others to perform a job.

For 1, I think any way of doing things that organizes your code for
yourself and your team/enterprise that works is in some sense the
“right” way, whether that be functional, object-oriented, or even
spaghetti code. :slight_smile: But for 2, I’m not at all convinced by the DSLs I’ve
seen over the years, including those I’ve written myself. People in
general aren’t programmers, and designing a programming language for
them may not in fact lead to increases in their productivity.

When I look at the main project I’ve been working on for the past ten
years, in my mind, at any rate, it is a domain-specific language. Most
of it is written in fairly small Perl scripts, with some graphics done
in R. In all, it’s probably smaller in lines of code than Rails. I think
I could “prove things about its correctness”. It badly needs a
rewrite/refactoring, given that big chunks of it were developed on a
system that only allowed 14-character file names. :slight_smile: But it is in fact a
small application – we aren’t talking millions of lines of code or
anything like that. What’s large is the data, which is typical of
“scientific” applications.

On 8/8/06, M. Edward (Ed) Borasky [email protected] wrote:

I learned Lisp (1.5) in the early 1970s, and this style of programming
seemed to be tied to Lisp at the time, but I actually had used it
earlier. For some reason FORTRAN programmers, including myself when I
was one, don’t usually use this style, perhaps because the original
FORTRAN didn’t have structured concepts and forced the use of GO TO
statements.

I’ve always been fascinated by one specific aspect of functional
languages: in theory, it’s possible to use tools to prove programs
correct. What a productivity win that would be. At different times, I
used professional programmers who worked for me as guinea pigs to see
just how they would take to the functional style, and the results were
dismal.

Even though the Church and Turing models of computation are unified
(and were unified long before digital computers existed), there still
seems to be something intuitively attractive to many programmers about
stuffing values into little boxes and being able to go get the values
out of the boxes later. I’m not sure if this is fundamental, or a
side-effect of the fact that our practical computing machines are all
Turing machines and most programmers learn something about “memory”
and “secondary storage” early in their training. This explains why
pure functional programming is stylistically so challenging in
practice, whether or not you believe it’s challenging in theory.

But one of the more insightful things I’ve heard recently is this:
Turing-completeness works against productivity and makes programs less
tool-able. And this is a direct consequence of its power, which
necessarily gives you Godel-undecidability in the general case.

The Lispish style (conceptualizing programs as artifacts in a
domain-specific language), which Ruby does extremely well in an
imperative-language context, can be said to have the following virtue:
it allows you to work with your problem domain using a language that
is not Turing-complete. (Let that sink in for a moment.) That means
that your programs are easier to reason about, easier to debug, and
eventually, easier to tool. What you lose in expressive power is
trivial because your standard for language power is related to your
problem domain, not to Turing-completeness in general. What you gain
in productivity is potentially immense.

M. Edward (Ed) Borasky wrote:

Well … there are two reasons to write a Domain Specific Language:

  1. As a way of organizing your own programming, and
  2. As a tool to be used by others to perform a job.

For 1, I think any way of doing things that organizes your code for
yourself and your team/enterprise that works is in some sense the
“right” way, whether that be functional, object-oriented, or even
spaghetti code. :slight_smile: But for 2, I’m not at all convinced by the DSLs I’ve
seen over the years, including those I’ve written myself. People in
general aren’t programmers, and designing a programming language for
them may not in fact lead to increases in their productivity.

I’m glad you enjoyed the trip down memory lane ;-). I gave up on
functional programming over a dozen years ago, for two reasons: first, I
learned the hard way that writing really good compilers for lambda-based
languages requires a huge amount of mathematical knowledge, and mine
doesn’t go beyond partial diffeqs. Second, my experiments with ordinary
professional programmers proved that the proportion of them who are
mentally receptive to the functional style is too small to be
commercially valuable. I was completely taken with FP myself, but one
programmer does not a team make.

To your point about regexes: remember that they are level-0 languages,
whereas most programming languages (including useful DSLs) are level-1
languages (context-free grammars). AFAIK, a language that generates
expressions that can be reduced to NFAs can not be Turing-complete, but
correct me if I’m wrong on that.

A poorly-designed DSL is just as useless as any other tool that doesn’t
reflect an appropriate modeling of the problem domain (not too powerful,
not too trivial, but just right). Still, I think it’s pretty exciting
that Ruby makes DSLs easy and graceful, thus activating for imperative
programmers one of the most useful aspects of Lisp. (I’m sure that
statement will be hotly contested by Lisp partisans, but let them rant.)

With DSLs, I’m thinking about tools for programmers, not for
non-programmers. (Although there is a very interesting class of
highly-successful mini-languages for non-programmers, like MS Office
macros.) My point about “tooling” was in regard to automatic programs
that can reason about other programs. DSLs and other mini-languages are
far easier to write workbenches and IDEs for, which I think is really
interesting and potentially a huge productivity boost. And again, it’s
the reduction from full Turing-completeness that may be the secret
sauce. I wish I could prove that, but I’ve already told you that I’m no
mathematician, so it’s a hunch at best.

On Wed, 9 Aug 2006, Francis C. wrote:

I’m glad you enjoyed the trip down memory lane ;-). I gave up on functional
programming over a dozen years ago, for two reasons: first, I learned the
hard way that writing really good compilers for lambda-based languages
requires a huge amount of mathematical knowledge, and mine doesn’t go beyond
partial diffeqs. Second, my experiments with ordinary professional
programmers proved that the proportion of them who are mentally receptive to
the functional style is too small to be commercially valuable. I was
completely taken with FP myself, but one programmer does not a team make.

can you elaborate? i’m very interested in your personal opinion without
regard to other team members (i work with only one other person and
she’s a
math genius).

regards.

-a

Francis C. wrote:

I’m glad you enjoyed the trip down memory lane ;-). I gave up on
functional programming over a dozen years ago, for two reasons: first, I
learned the hard way that writing really good compilers for lambda-based
languages requires a huge amount of mathematical knowledge, and mine
doesn’t go beyond partial diffeqs.
Ah, but you can buy or download for free really good compilers for
functional languages. See the conference announcement I posted a couple
of days ago. Maybe you’d even like to come visit the City of Roses? :slight_smile:

To your point about regexes: remember that they are level-0 languages,
whereas most programming languages (including useful DSLs) are level-1
languages (context-free grammars). AFAIK, a language that generates
expressions that can be reduced to NFAs can not be Turing-complete, but
correct me if I’m wrong on that.

Right … I don’t know who first made the point about the tradeoff
between a language’s expressive power and the ability to reason about
programs in that language – level 0 languages have the least expressive
power and are easiest to reason about. However, I first saw it elegantly
expressed in James Petersen’s book on Petri nets. I don’t have it here,
but I can dig it up.

With DSLs, I’m thinking about tools for programmers, not for
non-programmers. (Although there is a very interesting class of
highly-successful mini-languages for non-programmers, like MS Office
macros.) My point about “tooling” was in regard to automatic programs
that can reason about other programs.

  1. MS Office itself is a useful doman-specific language for
    non-programmers. I haven’t found VBA usable by non-programmers, however.
  2. Regarding “tooling” – if programmers are willing to restrict
    themselves to constructs that can be tooled, of course. They tend not to
    be willing to use functional languages, they tend not to be willing to
    declare types of variables, and they tend to balk at any restriction
    on their ability to shoot themselves and their customers in the foot. :slight_smile:

But of course, the Rails folks rediscovered all of this – the power
that comes from restricting some freedoms. Maybe the Python motto –
“There’s only one way to do it” is the right thing after all.

DSLs and other mini-languages are
far easier to write workbenches and IDEs for, which I think is really
interesting and potentially a huge productivity boost. And again, it’s
the reduction from full Turing-completeness that may be the secret
sauce. I wish I could prove that, but I’ve already told you that I’m no
mathematician, so it’s a hunch at best.
It’s an obvious conclusion – I’ll dig up the Petersen reference. :slight_smile: