From: Martin Mallinson
Subject: Searching for that "can't be done in C code" example
Date: 
Message-ID: <38B47CA3.CB78E41B@analogsystems.com>
I note the example of the arbitrary function caching code that was
posted a little while go and I am prompted to give you another "real
world" example.

This relates to the design of CMOS logic circuits and the "tricky"
collections of gates the designers keep coming up with. For example:
full adders with only 20 devices and clever stuff like that that are not
connected in the "conventional" CMOS way. This causes a problem: a logic
simulation and verification tool must be used to confirm the correct
operation of the logic design but it has no "model" for these
unconventional designs. [You may say use the full-adder module if the
design claims to have made a 20 element full adder, but that doesn't
help because we want to check that he is correct in his design!]. The
LISP implementation of a logic simulation and verification tool solves
this problem quite nicely. Although AND gates, OR gates D-types and so
forth have a defined "macro model" (essentially a compiled hand-written
function that rapidly executes a model of the device) these specially
designed elements have no pre-defined function but the simulator is able
to build one at run time.

The LISP based simulator builds a network of event driven functions as
it parses through the electrical schematic (see for example "Structure
and Interpretation of Computer Programs" - by Sussman [I think] - for
how this is done). For example, upon finding a level of hierarchy called
"AND5" it makes reference to the compiled function AND5 in the
appropriate way as you may expect. However, upon finding one of these
"designer specials" in the hierarchy it has no predefined function to
add to the simulator. Consequently, it enters the unknown level of
hierarchy and proceeds to parse the network (in a quite simple piece of
code) that builds a list (tracing from the output nodes) of the PMOS and
NMOS devices it encounters until it reaches the supply voltages.
Whenever a series connection is found it builds (AND ...) whenever a
parallel connection is found it builds (OR ...) A PMOS device writes
(NOT <input>) an NMOS device just inputs the <input> term. Having
completed the list it wraps a #'lambda around it, calls the compiler,
and installs the resulting function in the simulator. [this is slightly
oversimplified - it handles "high impedance" and "dead short across the
supply" as well!]

The point being of course that the network parsing code and the function
code are totally separate and any benefit of an optimizing compiler is
available. Typical C implementations do one or two things (if they do
anything at all to handle this situation). C implementations can make a
function that invokes the overhead of parsing the network (or a reduced
equivalent thereof) at each call and is therefore significantly slower
than the LISP implementation, or (real example in a company I worked
for) pre process the network searching for unknown levels of hierarchy
and have the designer write the code for the new module and re-link the
entire simulator with his code module in it. (Allowing any error due to
the supposed CMOS solution not in fact implementing the designers intent
to slip in again).

Its basically a recognition that one thing a C program cant do is
compile a C program and then call a function in the program it just
compiled.

Its a good example to use in the discussions in the Pub chaps, however,
years of working with LISP have taught me not to engage in LISP vs
<language-x> wars. Pearls before swine. (no pun intended). Let's just
enjoy working in LISP and writing stuff that does cool and profitable
things in the real world.

Martin Mallinson

[As a corollary you may be interested to know that since designs must
continue no matter what (the capitalist grindstone cant be stopped!) and
C based logic simulators are commonly used; that the common industry
practice is to forbid the use of cells that have no predefined code
module! A frustrating example of the weakness of the CAD methodology
influencing industry practice. Happens a lot. Thought to be increasingly
less relevant as complexity increases. Not, in our opinion, the optimum
way of working and not the case in complex analog (linear) designs].

From: Martin Mallinson
Subject: Re: Searching for that "can't be done in C code" example
Date: 
Message-ID: <38B4C4F5.412DE5A5@analogsystems.com>
Well, I stand corrected Paul - thank you for that correction!
I understand what you are suggesting and I can see that it would work.
I apologize for my example not being a good one and note your comment about
ease of doing it.
I am quite surprised that none of the smart chaps I worked with suggested it.
(Perhaps dlopen is new....its been a long time!)

Thanks again, Martin M

Paul Foley wrote:

> On Wed, 23 Feb 2000 16:34:43 -0800, Martin Mallinson wrote:
>
> > Its basically a recognition that one thing a C program cant do is
> > compile a C program and then call a function in the program it just
> > compiled.
>
> (Not that I'd encourage anyone to use C over Lisp, but...)  Of course
> it can - just write the C code to a file, invoke the compiler on it to
> generate a shared library, and use dlopen, &c., to gain access to it.
> It's obviously easier in Lisp (not least because you have a standard
> way to compile things, no need to deal with different compiler flags,
> etc., on different platforms, or to create temporary files...)
>
> --
> Nomina stultorum in parietibus et portis semper videmus.      -- Cicero
>
> (setq reply-to
>   (concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))
From: Thomas A. Russ
Subject: Re: Searching for that "can't be done in C code" example
Date: 
Message-ID: <ymir9e2xfk2.fsf@sevak.isi.edu>
Summary:
  Challenge -- "can't be done in C"
  Response  -- invoke function in compiled, generatred file.
  Riposte   -- write file, compile to shared library, open library, call
               function.
  

OK.  We can modify the example to be one of invoking a
program-generated, compiled function in an environment where writing to
files is not allowed.  Since the C compiler is not part of the C runtime
environment, this would be difficult to do.

Of course, one could always implement one's own compiler, writing to a
particular part of memory and then casting a pointer to the memory to be
a function and invoking it.

Another example:

  Write a function that takes two arbitrary arguments (in C it would
have two "void *" pointers).  If both arguments are numbers, then add
them and return the result.  If both arguments are strings, concatenate
them and return the result.  Otherwise signal an error.



-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Sandeep Koranne
Subject: Re: Searching for that "can't be done in C code" example
Date: 
Message-ID: <yzwk8jvlzsj.fsf@natlab.research.philips.com>
Hello,
Perhaps using parse-generate-compiled-functions to represent 
unknown (read as not compiled-in function) modules is not the 
best method. Why not use symbolic techniques like BDD or 
Parker-McCluskey for functional simulation.
Extending BDDs for logic simulation with delays is also possible.
Still LISP would be better at writing it : as I myself wrote
the Parker-McCluskey symbolic simulator in LISP itself.


-- 
			"Lets Make Things Better"
ED&T Test, WAY 3.37		     		
Philips Research Laboratories			Botstraat, 7
5656 AA, Eindhoven				5654  NL, Eindhoven
The Netherlands 				The Netherlands
Phone: +31-(040)-27 45250			+31-(040)-2573492
Fax  : +31-(040)-27 44626			 
E-mail: ···············@philips.com 
From: Johan Kullstam
Subject: Re: Searching for that "can't be done in C code" example
Date: 
Message-ID: <m266veyqhd.fsf@sophia.axel.nom>
a couple of things which i have had great difficulty recently with
were these:


i wanted to make a function which would prompt, read and print what
was read at the same time.

basically i wanted to do

int prompter(
    FILE fpin,
    FILE fpout,
    char *prompt,
    char *scanfmt,
    char *printfmt,
    /* insert varargs type stuff */)
{
    fputs(prompt, fpout);
    vfscanf(fpin, scanfmt, ...);
    vprintf(fpout, printfmt, ...);
}

and call it with

    double len;

    prompter("length     : ", "%lf", "%12.4g\n", &len);

but scanf wants pointers and printf wants the things themselves.  there
was no sane way to dereference varargs.  C/C++ just plain could not do it.
note that this type of thing would be trivial in common-lisp.



another, which i was eventually able to kludge around, is this

i have a library function which takes a function of one variable.

i have a function of two variables.  i'd like to make one the
"variable" while holding the other "parameter" constant.  it happened
to be a time function with a shape parameter.  lisp can do it easily
with a lambda.

  (foo (lambda (x) (bar x y)))

in C/C++ i had to make a file, declare a variable static, make a
setter, have a 2nd function refer to that static.  it was a horrible
mess, non-nestable and just plain ugly.


i claim that the above situations are not that weird.  they only seem
strange because C programmers are so used to avoiding things which are
painful.  (your thoughts are shaped by the language you think in.)

i have a really hard time with C now that i've learned lisp.  maybe i
am a better C programmer for it, but i'm also much more frustrated.

-- 
J o h a n  K u l l s t a m
[········@ne.mediaone.net]
Don't Fear the Penguin!
From: Raffael Cavallaro
Subject: Re: Searching for that "can't be done in C code" example
Date: 
Message-ID: <raffael-231A26.01253424022000@news.ne.mediaone.net>
In article <·················@analogsystems.com>, Martin Mallinson 
<················@analogsystems.com> wrote:

>Its basically a recognition that one thing a C program cant do is
>compile a C program and then call a function in the program it just
>compiled.

It's not so much that C can't do this sort of thing (as another poster 
has pointed out) but rather, that giving C this capability, and others 
that Lisp posesses, entails recreating Lisp badly. 

Most any language can  be used to perform a given task, it's just that 
if you pick C as your language, you often have to write your own crufty, 
inefficient subset of a better language (like Lisp) to get the 
capabilities you need to perform that task.

Ralph

-- 

Raffael Cavallaro, Ph.D.
·······@mediaone.net
From: William Deakin
Subject: Re: Searching for that "can't be done in C code" example
Date: 
Message-ID: <38BA3F55.72B99A8F@pindar.com>
There may be a more fundamental point here: as these languages are (or at
least *should be*) turing equivalent [1], there is no reason why everything
that can done in CL cannot be done in C . Or vice versa. It's just that
many, many things are easier in CL.  So, I would rephrase this question as
`searching for that "very hard in C but easy in CL" example.'

Best Regards,

:) will

[1] Realising that this is red-rag-to-a-bull ;)
From: Martin Mallinson
Subject: Re: Searching for that "can't be done in C code" example
Date: 
Message-ID: <38B57D36.63657660@analogsystems.com>
It was called "Spectrum" and it was part of the "Janus" tool set developed by
the leading analog chip and system company. (Not my current company)
The tool was for internal use only. It was used to design many chips. It was
presented to Cadence on a number of occasions and ultimately the individual
who created it moved to Cadence and, to the best of my knowledge, is still
employed there.
It was a Symbolics machine tool. It suffered in the same way many fine tools
suffered when Symbolics went out of business. I recreated the tool (with some
significant input from the inventor) and used it to design an ATE test system.
When I moved to SAS I brought it with me and we use it again now for systems
designs we do here. Recently, we have decided to port a lot of the Symbolics
tools that we use to Linux and CLIM. [That's why I re-joined the news group
after many years of absence]. So maybe you will get to see the real thing. Its
a while off, we have to make money on chips and so its not exactly job one!
When we have a sufficiently functional base we are planning to make the whole
code available - jumping on the open source bandwagon.

Clemens: if you are asking with a view to making use of such a tool I would
suggest that you should look at Verilog or VHDL: many digital IC design flows
now start from that base and the ability to "craft" a new CMOS logic element
is not, in general, on the critical path.... I posted the note with a view to
showing a perhaps non-typical use of LISP and, as one or two have pointed out,
C code, with a great deal of jumping though hoops, achieve the same result. It
serves to remind me that I shouldn't precipitate a LISp vs language-x
discussion.... ah well.

Martin M.

Clemens Heitzinger wrote:

> Martin Mallinson <················@analogsystems.com> writes:
>
> > help because we want to check that he is correct in his design!]. The
> > LISP implementation of a logic simulation and verification tool solves
> > this problem quite nicely. Although AND gates, OR gates D-types and so
> > forth have a defined "macro model" (essentially a compiled hand-written
> > function that rapidly executes a model of the device) these specially
> > designed elements have no pre-defined function but the simulator is able
> > to build one at run time.
>
> What's the name of this logic simulation and verification tool, who
> sells it and who uses it?
>
> Yours,
> :Clemens
> --
> Dipl-Ing Clemens Heitzinger
> Institute for Microelectronics, Vienna University of Technology, Austria
> Homepage <http://ag.or.at:8000/~clemens>   (Lisp related material)
> Mail <···············@ag.or.at>, Phone +43-1-58801/36035
From: Joe Marshall
Subject: Re: Searching for that "can't be done in C code" example
Date: 
Message-ID: <Q9wt4.69884$vi4.140952@dfw-read.news.verio.net>
It's obvious that everything *could* be done in C
by writing a Lisp interpreter in C and doing it in the Lisp.

But barring that, here's a few things that are extremely
difficult to write in C:

condition-bind

meta-circular evaluator, especially one that is powerful
   enough that if you redefine eval, it breaks.

reader macros

compiler-macros

`advice'

unwind-protect

Not that you couldn't kludge these things, but that you'd
think *real hard* about doing without them before you'd attempt
writing them.
From: Christopher Browne
Subject: Re: Searching for that "can't be done in C code" example
Date: 
Message-ID: <slrn8bd51k.vqf.cbbrowne@knuth.brownes.org>
Centuries ago, Nostradamus foresaw a time when Joe Marshall would say:
>It's obvious that everything *could* be done in C
>by writing a Lisp interpreter in C and doing it in the Lisp.
>
>But barring that, here's a few things that are extremely
>difficult to write in C:
>
>condition-bind
>
>meta-circular evaluator, especially one that is powerful
>   enough that if you redefine eval, it breaks.
>
>reader macros
>
>compiler-macros
>
>`advice'
>
>unwind-protect
>
>Not that you couldn't kludge these things, but that you'd
>think *real hard* about doing without them before you'd attempt
>writing them.

The critical point of just about any language is to provide some
convenient notation for a set of abstractions.

The above certainly are some abstractions that Lisp provides for
"ready use."  

On the other hand, it *doesn't* provide the matrix operations that
APL does; in cases where a particular problem orients towards matrix
operations, that may establish that APL's notation is preferable.

Similarly, if constructing an "expert system" or something else involving
backtrack and search, the abstractions of Prolog provide a *convenient
notation.*

Turing completeness establishes that there's some sort of equivalence to
all reasonably powerful languages, but that is a theoretical result.
In the *real world,* you want convenient notation.

The unfortunate thing is that some of the things you name as aspects
of Lisp that are not conveniently provided by C represent abstractions
that programmers never actually learn.  Someone who only knows C almost
certainly does not know what a "condition-bind" is (I can't find it in
the HyperSpec, and frankly don't know what you're refering to by that...).
-- 
"Few people  are capable of expressing with  equanimity opinions which
differ from  the prejudices of their social  environment.  Most people
are even incapable of forming such opinions." (Albert Einstein)
········@hex.net - - <http://www.hex.net/~cbbrowne/lisp.html>
From: Pierre R. Mai
Subject: Re: Searching for that "can't be done in C code" example
Date: 
Message-ID: <87u2ix1f02.fsf@orion.dent.isdn.cs.tu-berlin.de>
········@knuth.brownes.org (Christopher Browne) writes:

> The unfortunate thing is that some of the things you name as aspects
> of Lisp that are not conveniently provided by C represent abstractions
> that programmers never actually learn.  Someone who only knows C almost

Well the same could be said of some of the matrix operation abstractions
and notations that APL has, etc.  The _really_ unfortunate thing IMHO is
that really many of the abstractions and notations that CL provides out
of the box are things that nearly every program needs:

While it makes sense to say "IF you do heavy matrix bashing, then APL
comes in very handy", saying something like "IF you do serious error
handling (or memory management, etc.), then CL will come in very handy"
seems kind of pointless, because there is no IF to consider.

And CL gives you all of the mechanisms needed to embed (the important
concepts of) APL into your programs, without rewriting a complete APL
compiler, whereas e.g. C doesn't give you that option for either CL or
APL.  So there's no escape there either.

> certainly does not know what a "condition-bind" is (I can't find it in
> the HyperSpec, and frankly don't know what you're refering to by that...).

He might be referring to handler-bind, or restart-bind, or both, or
none.

Regs, Pierre.

-- 
Pierre Mai <····@acm.org>         PGP and GPG keys at your nearest Keyserver
  "One smaller motivation which, in part, stems from altruism is Microsoft-
   bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]
From: Joe Marshall
Subject: Re: Searching for that "can't be done in C code" example
Date: 
Message-ID: <vWxt4.69925$vi4.141333@dfw-read.news.verio.net>
Pierre R. Mai <····@acm.org> wrote in message
···················@orion.dent.isdn.cs.tu-berlin.de...
>
> He might be referring to handler-bind, or restart-bind, or both, or
> none.

I meant handler-bind, but restart-bind is another example.