From: Gabor Melis
Subject: how to do a lisp intro?
Date: 
Message-ID: <fb0fb805.0405130518.26607bcc@posting.google.com>
I am to present an introduction to CL to a few colleagues. The guys
are volunteers so I expect at least mild interest :-). This need not
necessarily be a one time presentation, it may become a course if
interest persists.

Now I'm wondering how to do it:
? speak at the whiteboard / show off development with a projector and
some narrative / give everyone a machine to work on
? limit the number of people to ~5 in any given lecture to ...
? give assignments
? include some minimal ELisp for the immediate rewards/confusion
? emphasize the practical side
? Emacs+SLIME / demo version of ACL/Lispworks

The guys are suspect to losing interest quickly. Basically, I want to
give them a good bait, knock their socks off or at least hint at cool
things to come. I'd do that mostly in demonstration mode with a
projector for the first lecture. This way, more people could get a
taste of what to expect. Ideally, even if one only attends this first
lecture he could walk away with a limited understanding of what Lisp
is about and basic knowledge that allows to read Lisp code and avoid
heartattack at the sight of parentheses.

With the few brave souls who survive the culture shock I would switch
to a more interactive, in depth style with a limited number of
participants (I'd be glad to repeat lectures due to high interest) and
give out assignments.

What do you think of this approach? Have you done something similar?

Gabor

From: David Steuber
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <87d658nrzm.fsf@david-steuber.com>
····@hotpop.com (Gabor Melis) writes:

> ? Emacs+SLIME / demo version of ACL/Lispworks

What Kenny, Mikel, and Raymond said.  But if you have to go with Emacs
+ SLIME (which is not at all bad but not yet ready for prime time), I
would make sure a few simple things are in your .emacs file:

(show-paren-mode t)
(slime-autodoc-mode)

These two little gems are worth more than their weight in text.  The
former makes the parens far less intimidating.  The latter is just
expected in a modern IDE.  You should probably also have the hyperspec
installed because SLIME is able to look up symbols in it.

Other demos to consider would be anything that falls under XP.  The
fact that you can test without dropping to the shell like with Perl or
doing a compile (what stone age technology is that?) is a big win.  It
really helps me out when I am just working out such simple things as
dotimes so that it returns what I wanted.

One thing I wish I had a better grasp on is the debugger.  I bring
that up so often it seems like such a shame to do an abort each time
instead of taking advantage of its power (except perhaps in the case
of typos).  Oh, that reminds me.  SLIME's autocompletion is something
that is now expected in a modern IDE.

-- 
I wouldn't mind the rat race so much if it wasn't for all the damn cats.
From: Kenny Tilton
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <h6Loc.111282$WA4.14582@twister.nyc.rr.com>
Gabor Melis wrote:

> I am to present an introduction to CL to a few colleagues. The guys
> are volunteers so I expect at least mild interest :-). This need not
> necessarily be a one time presentation, it may become a course if
> interest persists.
> 
> Now I'm wondering how to do it:
> ? speak at the whiteboard / show off development with a projector and
> some narrative / give everyone a machine to work on
> ? limit the number of people to ~5 in any given lecture to ...
> ? give assignments
> ? include some minimal ELisp for the immediate rewards/confusion
> ? emphasize the practical side
> ? Emacs+SLIME / demo version of ACL/Lispworks
> 
> The guys are suspect to losing interest quickly. Basically, I want to
> give them a good bait, knock their socks off or at least hint at cool
> things to come. I'd do that mostly in demonstration mode with a
> projector for the first lecture. This way, more people could get a
> taste of what to expect. Ideally, even if one only attends this first
> lecture he could walk away with a limited understanding of what Lisp
> is about and basic knowledge that allows to read Lisp code and avoid
> heartattack at the sight of parentheses.
> 
> With the few brave souls who survive the culture shock I would switch
> to a more interactive, in depth style with a limited number of
> participants (I'd be glad to repeat lectures due to high interest) and
> give out assignments.
> 
> What do you think of this approach? Have you done something similar?

(a) Good idea. (b) A little.

First of all, I recommend using /your/ strongest IDE. If that includes 
AllegroCL's IDE, go with that. It has a built-in project manager and 
ready access to a GUI-builder (which I never use) -- these things may be 
what your audience expects to see. You can also F1 over to the 
HyperSpec, which is nice.

One thing to demo might be something mathematical like factorial (if 
that lends itself to the following setup):

1. Show them the thing, then run it, get a correct answer.
2. Use TIME to time it.
3. Use disassemble to show the compilation
4. Add some declarations
5. Disassemble to show the reduced expansion
6. Time again to show improved, C-like performance.

That shows off two neat features (TIME and DISASSEMBLE) and that CL can 
be as fast as you want it to be.

Then ask Erann about his de-socks-ing demo. IIRC, you set things up so 
you call a GF on an instance for which no specialization exists. Land in 
a backtrace, add a necessary superclass to the instance's class 
definition (or some extant superclass), recompile the changed class, 
then restart from the backtrace to successful completion.

That shows off dynamism, and the debugger. They may even notice that CL 
not only has OO, it has the best OO model going.

Then of course they'll want to know about Cells...

:)

kenny



-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: mikel
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <xwMoc.66780$mR.58826@newssvr25.news.prodigy.com>
Kenny Tilton wrote:
> 
> 
> Gabor Melis wrote:
> 
>> I am to present an introduction to CL to a few colleagues. The guys
>> are volunteers so I expect at least mild interest :-). This need not
>> necessarily be a one time presentation, it may become a course if
>> interest persists.
>>
>> Now I'm wondering how to do it:
>> ? speak at the whiteboard / show off development with a projector and
>> some narrative / give everyone a machine to work on
>> ? limit the number of people to ~5 in any given lecture to ...
>> ? give assignments
>> ? include some minimal ELisp for the immediate rewards/confusion
>> ? emphasize the practical side
>> ? Emacs+SLIME / demo version of ACL/Lispworks
>>
>> The guys are suspect to losing interest quickly. Basically, I want to
>> give them a good bait, knock their socks off or at least hint at cool
>> things to come. I'd do that mostly in demonstration mode with a
>> projector for the first lecture. This way, more people could get a
>> taste of what to expect. Ideally, even if one only attends this first
>> lecture he could walk away with a limited understanding of what Lisp
>> is about and basic knowledge that allows to read Lisp code and avoid
>> heartattack at the sight of parentheses.
>>
>> With the few brave souls who survive the culture shock I would switch
>> to a more interactive, in depth style with a limited number of
>> participants (I'd be glad to repeat lectures due to high interest) and
>> give out assignments.
>>
>> What do you think of this approach? Have you done something similar?
> 
> 
> (a) Good idea. (b) A little.
> 
> First of all, I recommend using /your/ strongest IDE. If that includes 
> AllegroCL's IDE, go with that. It has a built-in project manager and 
> ready access to a GUI-builder (which I never use) -- these things may be 
> what your audience expects to see. You can also F1 over to the 
> HyperSpec, which is nice.
> 
> One thing to demo might be something mathematical like factorial (if 
> that lends itself to the following setup):
> 
> 1. Show them the thing, then run it, get a correct answer.
> 2. Use TIME to time it.
> 3. Use disassemble to show the compilation
> 4. Add some declarations
> 5. Disassemble to show the reduced expansion
> 6. Time again to show improved, C-like performance.
> 
> That shows off two neat features (TIME and DISASSEMBLE) and that CL can 
> be as fast as you want it to be.
> 
> Then ask Erann about his de-socks-ing demo. IIRC, you set things up so 
> you call a GF on an instance for which no specialization exists. Land in 
> a backtrace, add a necessary superclass to the instance's class 
> definition (or some extant superclass), recompile the changed class, 
> then restart from the backtrace to successful completion.
> 
> That shows off dynamism, and the debugger. They may even notice that CL 
> not only has OO, it has the best OO model going.
> 
> Then of course they'll want to know about Cells...


Kenny's suggestions are good. I suggest also showing multimethods and 
EQL specializers, which help newbies to Lisp who are not newbies to 
programming understand that there is something actually different about 
CLOS--that it isn't just a different syntax. I've done things like using 
EQL specializers instead of case logic--not that doing that is such a 
big deal, it just makes it easy for programmers to see that there is 
some novelty here.

Another source of aha! moments is change-class. Another is to write 
something that processes data, then feed it some broken data, then add 
code to properly handle to broken data and restart the computation from 
the break loop.

Another species of aha! comes from things like Edi Weitz's regex coach, 
mentioned in another thread, which shows how you can extend and reuse 
working code in exciting ways without touching the source of that code.

Working programmers a lot of times like memoization demos. They show how 
easy it is in Lisp to add efficiency hacks and instrumentation to 
working code without breaking it.

Finally, in the same spirit as Kenny's disassembly suggestions, it can 
be really nice to show how some algorithm can be built very easily with 
data structures that are easy to manipulate (e.g. lists), and then show 
how easy it is to substitute a more efficient data structure without 
changing your API at all, once you understand how the algorithm should 
work. Working programmers like that sort of stuff, too.
From: Raymond Wiker
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <86vfj0nxd6.fsf@raw.grenland.fast.no>
mikel <·····@evins.net> writes:

> Kenny's suggestions are good. I suggest also showing multimethods and
> EQL specializers, which help newbies to Lisp who are not newbies to
> programming understand that there is something actually different
> about CLOS--that it isn't just a different syntax. I've done things
> like using EQL specializers instead of case logic--not that doing that
> is such a big deal, it just makes it easy for programmers to see that
> there is some novelty here.
>
> Another source of aha! moments is change-class. Another is to write
> something that processes data, then feed it some broken data, then add
> code to properly handle to broken data and restart the computation
> from the break loop.

        Or even to break into a running (recursive?) function, change
the function and continue. A simple function that could be used to
illustrate this would be

(declaim (notinline testit))

(defun testit ()
        (format t "foo!~%")
        (force-output)
        (sleep 1)
        (testit))

(testit)

then, break and replace the definition of testit with

(defun testit ()
        (format t "bar!~%")
        (force-output)
        (sleep 1)
        (testit))

and continue.

> Working programmers a lot of times like memoization demos. They show
> how easy it is in Lisp to add efficiency hacks and instrumentation to
> working code without breaking it.

        Memoization is really effective with the fibonacci function
mentioned earlier...

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Svein Ove Aas
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <Ry2pc.1461$RL3.32548@news2.e.nsc.no>
Raymond Wiker wrote:

> mikel <·····@evins.net> writes:
> 
>> Kenny's suggestions are good. I suggest also showing multimethods and
>> EQL specializers, which help newbies to Lisp who are not newbies to
>> programming understand that there is something actually different
>> about CLOS--that it isn't just a different syntax. I've done things
>> like using EQL specializers instead of case logic--not that doing that
>> is such a big deal, it just makes it easy for programmers to see that
>> there is some novelty here.
>>
>> Another source of aha! moments is change-class. Another is to write
>> something that processes data, then feed it some broken data, then add
>> code to properly handle to broken data and restart the computation
>> from the break loop.
> 
>         Or even to break into a running (recursive?) function, change
> the function and continue. A simple function that could be used to
> illustrate this would be
> 
> (declaim (notinline testit))

This one makes little sense to me.

It's a recursive function - how can it be inlined?
Does this disable tail-optimization, or something? What happens, exactly?
From: Raymond Wiker
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <86r7tnnq2v.fsf@raw.grenland.fast.no>
Svein Ove Aas <··············@brage.info> writes:

> Raymond Wiker wrote:
>
>>         Or even to break into a running (recursive?) function, change
>> the function and continue. A simple function that could be used to
>> illustrate this would be
>> 
>> (declaim (notinline testit))
>
> This one makes little sense to me.
>
> It's a recursive function - how can it be inlined?
> Does this disable tail-optimization, or something? What happens, exactly?

        It's supposed to disable tail-optimization, meaning that every
call to testit has to go via the function binding for 'testit.

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Svein Ove Aas
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <fi4pc.1461$eH3.38003@news4.e.nsc.no>
Raymond Wiker wrote:

> Svein Ove Aas <··············@brage.info> writes:
> 
>> Raymond Wiker wrote:
>>
>>>         Or even to break into a running (recursive?) function, change
>>> the function and continue. A simple function that could be used to
>>> illustrate this would be
>>> 
>>> (declaim (notinline testit))
>>
>> This one makes little sense to me.
>>
>> It's a recursive function - how can it be inlined?
>> Does this disable tail-optimization, or something? What happens,
>> exactly?
> 
>         It's supposed to disable tail-optimization, meaning that every
> call to testit has to go via the function binding for 'testit.

Well, all right, but that has its own problems - namely, wasting stack
space.

You can *still* drop the current stack frame when optimizing tail calls,
even if you want to check the function binding each call, so how do you
do that?

(declaim (notinline real-recurse))

(defun recurse (n)
        (loop from 1 to n
         with last-result = 1
         do (setf last-result (real-recurse last-result))
         finally last-result))

Er... you see what I mean, I hope, although that _thing_ is fugly. I'd
want to have real-recurse (what an ironic name) decide when to exit the
loop, for one thing.
From: Raymond Wiker
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <86iseznllu.fsf@raw.grenland.fast.no>
Svein Ove Aas <··············@brage.info> writes:

> Raymond Wiker wrote:
>
>> Svein Ove Aas <··············@brage.info> writes:
>> 
>>> Raymond Wiker wrote:
>>>
>>>>         Or even to break into a running (recursive?) function, change
>>>> the function and continue. A simple function that could be used to
>>>> illustrate this would be
>>>> 
>>>> (declaim (notinline testit))
>>>
>>> This one makes little sense to me.
>>>
>>> It's a recursive function - how can it be inlined?
>>> Does this disable tail-optimization, or something? What happens,
>>> exactly?
>> 
>>         It's supposed to disable tail-optimization, meaning that every
>> call to testit has to go via the function binding for 'testit.
>
> Well, all right, but that has its own problems - namely, wasting stack
> space.

        I *know* that. This was just a simple illustration of how it
is possible to modify a function, and keep running. A better example
would be

(declaim (notinline testit-internal))
(defun testit-internal ()
  (format t "foo!~%")
  (force-output))

(defun testit ()
  (loop
    (testit-internal)
    (sleep 1)))


> You can *still* drop the current stack frame when optimizing tail calls,
> even if you want to check the function binding each call, so how do you
> do that?
>
> (declaim (notinline real-recurse))
>
> (defun recurse (n)
>         (loop from 1 to n
>          with last-result = 1
>          do (setf last-result (real-recurse last-result))
>          finally last-result))
>
> Er... you see what I mean, I hope, although that _thing_ is fugly. I'd
> want to have real-recurse (what an ironic name) decide when to exit the
> loop, for one thing.

        By using catch/throw (or something a bit higher-level, perhaps)?

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Svein Ove Aas
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <ED4pc.1484$RL3.33129@news2.e.nsc.no>
Raymond Wiker wrote:

> Svein Ove Aas <··············@brage.info> writes:
> 
>> Raymond Wiker wrote:
>>
>>> Svein Ove Aas <··············@brage.info> writes:
>>> 
>>>> Raymond Wiker wrote:
>>>>
>>>>>         Or even to break into a running (recursive?) function,
>>>>>         change
>>>>> the function and continue. A simple function that could be used to
>>>>> illustrate this would be
>>>>> 
>>>>> (declaim (notinline testit))
>>>>
>>>> This one makes little sense to me.
>>>>
>>>> It's a recursive function - how can it be inlined?
>>>> Does this disable tail-optimization, or something? What happens,
>>>> exactly?
>>> 
>>>         It's supposed to disable tail-optimization, meaning that every
>>> call to testit has to go via the function binding for 'testit.
>>
>> Well, all right, but that has its own problems - namely, wasting stack
>> space.
> 
>         I *know* that. This was just a simple illustration of how it
> is possible to modify a function, and keep running. A better example
> would be

<snip>, as it isn't recursive.

I'd like to know how to do it in recursive functions, while still
eliminating the current stack frame. Is that even possible?


>> (declaim (notinline real-recurse))
>>
>> (defun recurse (n)
>>         (loop from 1 to n
>>          with last-result = 1
>>          do (setf last-result (real-recurse last-result))
>>          finally last-result))
>>
>> Er... you see what I mean, I hope, although that _thing_ is fugly. I'd
>> want to have real-recurse (what an ironic name) decide when to exit the
>> loop, for one thing.
> 
>         By using catch/throw (or something a bit higher-level, perhaps)?
> 

I don't want to try it. The horrors of that code still echo in the darkest
corners of my mind.
From: Raymond Wiker
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <86ekpnnjsc.fsf@raw.grenland.fast.no>
Svein Ove Aas <··············@brage.info> writes:

> Raymond Wiker wrote:
>
>> Svein Ove Aas <··············@brage.info> writes:
>> 
>>> Raymond Wiker wrote:
>>>
>>>> Svein Ove Aas <··············@brage.info> writes:
>>>> 
>>>>> Raymond Wiker wrote:
>>>>>
>>>>>>         Or even to break into a running (recursive?) function,
>>>>>>         change
>>>>>> the function and continue. A simple function that could be used to
>>>>>> illustrate this would be
>>>>>> 
>>>>>> (declaim (notinline testit))
>>>>>
>>>>> This one makes little sense to me.
>>>>>
>>>>> It's a recursive function - how can it be inlined?
>>>>> Does this disable tail-optimization, or something? What happens,
>>>>> exactly?
>>>> 
>>>>         It's supposed to disable tail-optimization, meaning that every
>>>> call to testit has to go via the function binding for 'testit.
>>>
>>> Well, all right, but that has its own problems - namely, wasting stack
>>> space.
>> 
>>         I *know* that. This was just a simple illustration of how it
>> is possible to modify a function, and keep running. A better example
>> would be
>
> <snip>, as it isn't recursive.
>
> I'd like to know how to do it in recursive functions, while still
> eliminating the current stack frame. Is that even possible?

        By doing

        (funcall (symbol-function 'testit))

perhaps?

>>         By using catch/throw (or something a bit higher-level, perhaps)?
>> 
>
> I don't want to try it. The horrors of that code still echo in the darkest
> corners of my mind.

        Ok... I deleted the code from my reply (unless you were
talking about MY code? :-)

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Svein Ove Aas
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <P36pc.1510$RL3.33500@news2.e.nsc.no>
Raymond Wiker wrote:

> Svein Ove Aas <··············@brage.info> writes:

>> I don't want to try it. The horrors of that code still echo in the
>> darkest corners of my mind.
> 
>         Ok... I deleted the code from my reply (unless you were
> talking about MY code? :-)


Nope, it was mine. Fortunately, it snuck out and got run over by a train.
From: Brian Downing
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <iFapc.50315$iF6.4539501@attbi_s02>
In article <····················@news4.e.nsc.no>,
Svein Ove Aas  <··············@brage.info> wrote:
> >>> (declaim (notinline testit))
> >>
> >> This one makes little sense to me.
> >>
> >> It's a recursive function - how can it be inlined?
> >> Does this disable tail-optimization, or something? What happens,
> >> exactly?
> > 
> >         It's supposed to disable tail-optimization, meaning that every
> > call to testit has to go via the function binding for 'testit.
> 
> Well, all right, but that has its own problems - namely, wasting stack
> space.

Not neccessarily, depending on your implementation.

(declaim (notinline testit)) on the Python based compilers doesn't affect
tail-call optimization, but it does guarantee that calls will go through
SYMBOL-FUNCTION instead of just using a local branch.

For example:

(declaim (notinline foo))
(defun foo (n)
  (format t "foo: ~A~%" n)
  (when (= n 5) (cerror "Keep going!" 'error))
  (foo (1+ n)))

* (foo 0)
foo: 0
foo: 1
foo: 2
foo: 3
foo: 4
foo: 5

Condition ERROR was signalled.

Restarts:
  0: [CONTINUE] Keep going!
  1: [ABORT   ] Return to Top-Level.

Debug  (type H for help)

(FOO 5)
Source: 
; File: /home/bdowning/fib.lisp
(CERROR "Keep going!" 'ERROR)
0] backtrace

0: (FOO 5)
1: (INTERACTIVE-EVAL (FOO 0))
2: (COMMON-LISP::%TOP-LEVEL)
3: (COMMON-LISP::RESTART-LISP)

0] (defun foo (n)
     (format t "redefined foo: ~A~%" n)
     (when (= n 12) (cerror "Keep going!" 'error))
     (when (< n 15) (foo (1+ n))))

; Converted FOO.
FOO
0] 0
redefined foo: 6
redefined foo: 7
redefined foo: 8
redefined foo: 9
redefined foo: 10
redefined foo: 11
redefined foo: 12


Condition ERROR was signalled.

Restarts:
  0: [CONTINUE] Keep going!
  1: [ABORT   ] Return to Top-Level.

Debug  (type H for help)

(FOO 12)
Source: (CERROR "Keep going!" 'ERROR)
0] backtrace

0: (FOO 12)
1: (INTERACTIVE-EVAL (FOO 0))
2: (COMMON-LISP::%TOP-LEVEL)
3: (COMMON-LISP::RESTART-LISP)

0] 0
redefined foo: 13
redefined foo: 14
redefined foo: 15
NIL

Notice how the stack didn't build up even though we could redefine FOO in
there.

(Obviously this is implementation-specific...)

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Alexey Dejneka
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <m3ekpn10g9.fsf@comail.ru>
Hello,

Raymond Wiker wrote:

> (declaim (notinline testit))
> 
> (defun testit ()
>         (format t "foo!~%")
>         (force-output)
>         (sleep 1)
>         (testit))

Svein Ove Aas <··············@brage.info> writes:

> > (declaim (notinline testit))
> 
> This one makes little sense to me.

Naively speaking (not looking into CLHS), the DEFUN above is
equivalent to

(setf (symbol-function 'testit)
      (lambda ()
        (format t "foo!~%")
        (force-output)
        (sleep 1)
        (funcall 'testit)))

So you can see that the function is not recursive--it calls the
functional binding of the symbol TESTIT, not itself:

* (setf (symbol-function 'foo) (symbol-function 'testit))

#<FUNCTION "#'(LAMBDA NIL (FORMAT T \"foo!~%\") ...)" {9078205}>
* (setf (symbol-function 'testit) (lambda () (format t "TestIt!~%")))

#<FUNCTION "#'(LAMBDA NIL (FORMAT T \"TestIt!~%\"))" {90B4A15}>
* (foo)
foo!
TestIt!
NIL
*

Now, CLHS 3.2.2.3, point 4 tells that inside (DEFUN TESTIT) the
compiler may assume the call of TESTIT to be always the call of the
same function, unless TESTIT is declared to be NOTINLINE. One possible
use of the assumption is to implement the call with a direct control
transfer to the address of the function, without indirection through
the symbol; such call is faster than an indirect, but if you rebind
(SYMBOL-FUNCTION 'TESTIT) as above, this redefinition will not be
caught:

;;; (with TESTIT defined with DEFUN, without NOTINLINE declaration,
;;; under SBCL)
* (setf (symbol-function 'foo) (symbol-function 'testit))

#<FUNCTION TESTIT>
* (setf (symbol-function 'testit) (lambda () (format t "TestIt!~%")))

#<FUNCTION "#'(LAMBDA NIL (FORMAT T \"TestIt!~%\"))" {9158A85}>
* (foo)
foo!
foo!
foo!
foo!
...

> It's a recursive function - how can it be inlined?

With NOTINLINE it is not recursive, but if it were - with a care.

> Does this disable tail-optimization

Depends on the compiler. E.g. under SBCL, NOTINLINE does not affect
tail-call optimization.

-- 
Regards,
Alexey Dejneka

"Alas, the spheres of truth are less transparent than those of
illusion." -- L.E.J. Brouwer
From: Simon Andr�s
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <vcdvfizahng.fsf@tarski.math.bme.hu>
····@hotpop.com (Gabor Melis) writes:

> I am to present an introduction to CL to a few colleagues. The guys
> are volunteers so I expect at least mild interest :-). This need not
> necessarily be a one time presentation, it may become a course if
> interest persists.
> 
> Now I'm wondering how to do it:

A few random thoughts: 

Start at high level and tell them not to worry about the details
(incl. parantheses). They'll be ready for CAR and CDR when they're
hooked, but not before.

Avoid lists and recursion as long as you can. Use arrays, hashtables,
loops and stuff your audience is familiar with. Present Lisp not as a
radically different language but as "the same as any other but with a
lot of extra capabilities".

Tell them about macros, emphasize their code-writing capability, and
show a few examples. The example macros themselves (i.e. how they're
written) are not important, what they do is. Use the MACROEXPANDing
capability of your IDE. The point is that macros save a lot of work,
they're "programmable copy & paste"; people may like that. The examples
can be artificial (say, a macro that expands into nested loops) or
they may do things you know your audience wrestles with daily in Java,
C++ or whatever they're using.

> ? include some minimal ELisp for the immediate rewards/confusion

Don't. If you want to teach CL it'll just confuse them.

> ? emphasize the practical side

Yes. 

> ? Emacs+SLIME / demo version of ACL/Lispworks

The IDE doesn't matter as long as it is stable. So ACL with eli may be
your best bet (at least if you're on Linux). 

Just my 0.02 HUF

Andras
From: Gabor Melis
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <fb0fb805.0405140347.4dbe7d37@posting.google.com>
······@math.bme.hu (Simon Andr�s) wrote in message news:<···············@tarski.math.bme.hu>...
> A few random thoughts: 
> 
> Start at high level and tell them not to worry about the details
> (incl. parantheses). They'll be ready for CAR and CDR when they're
> hooked, but not before.

That's probably right. The optimal order of presentation depends very
much on the audience and the theoretically sound one have to be
compromised in the name of real-life considerations (i.e. not to be a
bore). And there all these very cool features and things to show, but
what is didactic and what is not is not easy to see.

> Avoid lists and recursion as long as you can. Use arrays, hashtables,
> loops and stuff your audience is familiar with. Present Lisp not as a
> radically different language but as "the same as any other but with a
> lot of extra capabilities".

Sounds good, recursion can be delayed, functional programming can be
delayed. But lists? We'll run into them very, very soon.

> Tell them about macros, emphasize their code-writing capability, and
> show a few examples. The example macros themselves (i.e. how they're
> written) are not important, what they do is. Use the MACROEXPANDing
> capability of your IDE. The point is that macros save a lot of work,
> they're "programmable copy & paste"; people may like that. The examples
> can be artificial (say, a macro that expands into nested loops) or
> they may do things you know your audience wrestles with daily in Java,
> C++ or whatever they're using.

Yes, I plan to emphasize macros very much. 'Programmable copy & paste'
is a good catch-phrase for the pragmatic who are scared by 'domain
specific languages'.

The dynamic aspects of the programming environment (compiler,
incrementality :-), debugger, redefinition) is another area worth
emphasizing. CLOS wizardry, neat tricks like memoizing.

The challenge is to package all of this into a reasonably compact,
iteratively/interactively developed example. Ideally, I will develop a
small but useful program (a web application, maybe) and make all the
necessary mistakes at the right time.

It sounds pretty hard to get right. I remember Kenny fretting over
similar issues before his ILC (?) presentation. Of course, later he
got a real confidence boost from lending out his laptop.

Gabor
From: Kenny Tilton
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <n64pc.111730$WA4.64416@twister.nyc.rr.com>
Gabor Melis wrote:
> ······@math.bme.hu (Simon Andr�s) wrote in message news:<···············@tarski.math.bme.hu>...
> 
>>A few random thoughts: 
>>
>>Start at high level and tell them not to worry about the details
>>(incl. parantheses).

I have been meaning to mention that I think it would be fun to 
demonstrate casually at some point how sexprs allow one to edit Lisp in 
coherent chunks almost effortlessly. Using AllegroCL I am forever 
double-clicking forms and copying, cutting, deleting, or paste/replacing 
them, often by control-clicking some other form. I never have to worry 
where a semantic chunk starts/ends because of the parens. After splaying 
the code around a little this way and messing up the indentation, 
control-shift-P reindents. Viola!

> Sounds good, recursion can be delayed, functional programming can be
> delayed. But lists? We'll run into them very, very soon.

..and it is a great little data structure to have at ones fingertips.

> Yes, I plan to emphasize macros very much. 'Programmable copy & paste'
> is a good catch-phrase for the pragmatic who are scared by 'domain
> specific languages'.

I like it.

> The challenge is to package all of this into a reasonably compact,
> iteratively/interactively developed example. Ideally, I will develop a
> small but useful program (a web application, maybe) and make all the
> necessary mistakes at the right time.

Yep. The best talk I have given was re-inventing Cells (Lite) before 
their eyes. I did not even have it scripted, I just did it. It started 
with CLOS cuz that's what Cells extend, then it showed a lambda function 
as a slot value, then an accessor to hide the need to call the function 
from application code, then macros for auto-generating the accessors and 
the rules cum functions. Of course I am editing and debugging along the 
way so they get to see that, and I am mentioning cool things as 
afterthoughts as I go. And in the end I have the Unbearable 
Staggeringness of Cells (the ability to extend Lisp in useful ways) and 
it's all been hidden.

  Of course Cells (or something like it) will seem goofy, so your web 
app might be the way to go. Maybe Peter will let you market his book for 
him by reviewing one of his exercises where he builds Lite versions of 
useful stuff.

kt
From: Fernando
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <20u8a01b4f3rri10apis1t9k7ifpmpdde7@4ax.com>
On 13 May 2004 06:18:25 -0700, ····@hotpop.com (Gabor Melis) wrote:

>I am to present an introduction to CL to a few colleagues. The guys
>are volunteers so I expect at least mild interest :-). This need not
>necessarily be a one time presentation, it may become a course if
>interest persists.

If they come from C++, then you should try to show how Lisp makes easy things
that are an enormous pain in the butt in C++:

a) Recompilation of only the modified part of a program.
b) Macros instead of 'template-metaprogramming' nightmares.
c) Simplified 'patterns', for example the factory.
From: Gabor Melis
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <fb0fb805.0405141139.42c3df17@posting.google.com>
Fernando <···@NOSPAMeasyjob.net> wrote in message news:<··································@4ax.com>...
> On 13 May 2004 06:18:25 -0700, ····@hotpop.com (Gabor Melis) wrote:
> 
> >I am to present an introduction to CL to a few colleagues. The guys
> >are volunteers so I expect at least mild interest :-). This need not
> >necessarily be a one time presentation, it may become a course if
> >interest persists.
> 
> If they come from C++, then you should try to show how Lisp makes easy things
> that are an enormous pain in the butt in C++:

They are doing Java, mostly.

> a) Recompilation of only the modified part of a program.
> b) Macros instead of 'template-metaprogramming' nightmares.
> c) Simplified 'patterns', for example the factory.

Speaking of patterns, maybe Peter Norvig's presentation (
http://norvig.com/design-patterns/ ) would be a good source. Take the
visitor pattern for example, "Look guys, the three pages of code here
is a Java implementation and these three methods is how you do it in
CLOS." The downside is there is not much to discuss after that :-).
From: John Thingstad
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <opr7zzcjqrpqzri1@mjolner.upc.no>
I liked simple database from chapter 3 www.gigamonekeys.com/book
Maybe this can give you some ideas.

On 13 May 2004 06:18:25 -0700, Gabor Melis <····@hotpop.com> wrote:

> I am to present an introduction to CL to a few colleagues. The guys
> are volunteers so I expect at least mild interest :-). This need not
> necessarily be a one time presentation, it may become a course if
> interest persists.
>
> Now I'm wondering how to do it:
> ? speak at the whiteboard / show off development with a projector and
> some narrative / give everyone a machine to work on
> ? limit the number of people to ~5 in any given lecture to ...
> ? give assignments
> ? include some minimal ELisp for the immediate rewards/confusion
> ? emphasize the practical side
> ? Emacs+SLIME / demo version of ACL/Lispworks
>
> The guys are suspect to losing interest quickly. Basically, I want to
> give them a good bait, knock their socks off or at least hint at cool
> things to come. I'd do that mostly in demonstration mode with a
> projector for the first lecture. This way, more people could get a
> taste of what to expect. Ideally, even if one only attends this first
> lecture he could walk away with a limited understanding of what Lisp
> is about and basic knowledge that allows to read Lisp code and avoid
> heartattack at the sight of parentheses.
>
> With the few brave souls who survive the culture shock I would switch
> to a more interactive, in depth style with a limited number of
> participants (I'd be glad to repeat lectures due to high interest) and
> give out assignments.
>
> What do you think of this approach? Have you done something similar?
>
> Gabor



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: Tayssir John Gabbour
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <866764be.0405150359.3b869886@posting.google.com>
····@hotpop.com (Gabor Melis) wrote in message news:<····························@posting.google.com>...
> The guys are suspect to losing interest quickly. Basically, I want to
> give them a good bait, knock their socks off or at least hint at cool
> things to come. 

Show off disk images? Maybe you can do something dramatic like log off
the computer and come back to it like a video game. With all the state
intact.

I also was thrilled when I came across autocaching funcitons with the
memoize command... but that was because I've had to tediously and
carefully ensure my caching didn't break things in other languages.
Dunno if it appeals to your audience.

Please tell us what worked and what didn't, I think being a good
teacher is finding how to motivate.
From: Gabor Melis
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <fb0fb805.0405200821.117f8a83@posting.google.com>
···········@yahoo.com (Tayssir John Gabbour) wrote in message news:<····························@posting.google.com>...
> Please tell us what worked and what didn't, I think being a good
> teacher is finding how to motivate.

The first lesson is done. I settled on Peter Seibel's DB example that
demonstrates higher order functions and macros quite well. I put a
quick html page on top of it using aserve. How long was it? 42
minutes, of course. But that was when I had timed it alone. Live with
the audience (20 guys), having to answer questions and explain more
than to myself it was 2 hours which is a little too long. Still, time
and air was scarce and I had to push a bit to reach macros.

What worked? The culture shock part worked remarkably well. The parens
were not mentioned - a strange thing -, but #' ' ` , and ,@ were
considered ugly which is a positive sign. I feel some think macros are
just brainfuck with no real world applications even after the html
generator example, but some say they grokked everything and it was
mildly cool.

Now, instant enlightenment is not to be expected, so all in all I
consider it a small success although the socks were still on at the
end. Next time it will have to be cooler. I have a few candidates:
- implementing a regexp engine (as suggested in private, complete with
implementation)
- an object system a'la OnLisp's mini CLOS should make for good
entertainment
- that compact little unit test framework from Peter's book

Maybe analyzing the regexp engine plus writing the unit tests and
framework for it with memoization thrown in if time permits should
also work. And since I expect much fewer guys to show up next time it
may be right time to start giving out homework.

Gabor
From: Peter Seibel
Subject: Re: how to do a lisp intro?
Date: 
Message-ID: <m3u0yar803.fsf@javamonkey.com>
····@hotpop.com (Gabor Melis) writes:

> ···········@yahoo.com (Tayssir John Gabbour) wrote in message news:<····························@posting.google.com>...
>> Please tell us what worked and what didn't, I think being a good
>> teacher is finding how to motivate.
>
> The first lesson is done. I settled on Peter Seibel's DB example
> that demonstrates higher order functions and macros quite well.

Cool! Please send along any feedback either of your own or from your
students.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp