POV-Ray : Newsgroups : povray.off-topic : Land of Lisp : Re: Land of Lisp Server Time
3 Sep 2024 17:11:39 EDT (-0400)
  Re: Land of Lisp  
From: nemesis
Date: 30 Oct 2010 00:00:01
Message: <web.4ccb979b2bc10e38d995c6290@news.povray.org>
in any case...

Invisible <voi### [at] devnull> wrote:
> "LAND of LISP: Secrets of the Seven Guilds."
>
> Hey, you really *don't* need drawing skills to do a web comic!

you should know that by now, XKCD fan...

> "Any humans foolish enough to resist with their primitive weapons were
> dealt with in short order."
>
> There goes Java, Python, C# and Ruby. (What, no C or C++?)

I think it's implicit... ;)

> "There's a long-forgotten place where they have weapons SO POWERFUL that
> they can defeat ANY BUG! They call it the Land of Lisp."
>
> Uhuh. So an untyped language with a single global namespace and which
> touts self-modifying code as its single most significant feature is the
> way to beat program bugs?

if by global namespace you mean no modules/libs, you're very wrong.

Lisp is not untyped either, just leaves type-handling to runtime. :)

> "Greetings, your highness!"
>
> Creatures with 12 eyes and an arm for a nose: WTF-O-Meter: 1.5

your WTF-O-Meter should go up once you realize that is how he depicts Lispers...
which BTW is not really that far from reality... :)

> "SILENCE! Back in the eighties, we showed you how to program WITHOUT
> HAVING ANY BUGS! We warned you what would happen, but you didn't listen
> to us."
>
> Uh, yeah, right. I'm pretty sure there's no programming language in
> existence that completely prevents bugs. :-P

comic license... you did notice the title can be shortened as LOL, right?

> "Each of the Seven Guilds possesses a powerful bug-killing weapon that
> is unique to Lisp!"
>
> Oh yeah?
>
> So macros, functional programming, software transactional memory,
> restartable code and "conciseness" are unique only to Lisp?

all in the same line, yes. :)

well, not quite "conciseness" as Lisp languages tend to favor words and
long-descriptive names rather than single-char operator obfuscation.  Unless
we're talking about big problems where DSL-building with macros give a clear
gain in readability can indeed bring conciseness...

> "Functional programming is a mathematical approach to programming that
> was pioneered by Lisp."
>
> I beg to differ.

you don't:  in the 50's and 60's when Lisp was born there was no Haskell,
Miranda, ML nor even lowly C:  FORTRAN or the soon to appear COBOL were your
only alternatives for high-level code... and those were definitely not
functional.  Lisp was.

> Actually, I'm not even sure why people consider Lisp to be a functional
> programming language. JavaScript is about as functional as Lisp!

It's because any language with support for creating functions on the fly,
receiving functions as arguments to other functions and returning functions as
the result of evaluation of functions is able to use the functional programming
paradigm.

> And writing code in a language which *enforces* a functional style makes
> it drastically easier to debug. :-P

yes, and writing it in a lazy evaluation language makes it damn hard to debug as
you also well know.

>    if_then True  x y = x
>    if_then False x y = y
>
> is sooo much harder to implement, eh? Newsflash: lazy evaluation
> eliminates one of the major reasons for wanting macros in the first place.

It's true that unevaluated argument-passing (call-by-name) is one of the fine
reasons for macros or, obviously, lazy evaluation.  But I'd say it's a minor
bonus when compared to its main use to generate code at compile-time and build
custom syntax for the sake of readability.

> For the other reasons, we have Template Haskell. This allows you to
> write Haskell at compile-time.

> (Lisp, AFAIK, doesn't have a
> "compile-time", so things are slightly different.)

Pretty much all Common Lisp implementations are compilers, specially noted the
commercial Allegro CL and the open-source sbcl.  In Scheme, there's gambit,
bigloo and a few other such batch-compilers.  So, yeah, macros are expanded at
compile-time and the generated expressions are all eventually transformed down
to lambdas in continuation-passing-style which are them finally compiled to
either C or native code.

But even in implementations using JITs to compile to native-code, like racket,
there's a clear separation of phases, even though no executable is formally
created.

Now, given their dynamically-typed natures, they won't usually generate as fast
code as static type compilers, but hopefully not by much:

http://shootout.alioth.debian.org/u64q/benchmark.php?test=all&lang=sbcl&lang2=ghc

OTOH, when writing code for speed, you actually pin down types for variables
with (declare ...) compiler directives in the source code.  CL allows it
intrusively, in the bodies of functions, but I prefer gambit scheme way, by
allowing such declares in the command line for the compiler. :)

In any case, it seems racket (previously PLT-Scheme) JIT kinda humiliates sbcl
old-way batch compiler without even needing to pin down types:

http://shootout.alioth.debian.org/u64/benchmark.php?test=all&lang=racket&lang2=ghc

> And, unlike Lisp
> macros (AFAIK), Template Haskell statically guarantees that the code
> written by a template is *always* syntactically correct. (It does _not_
> guarantee that it is well-typed, just that there are no syntax errors.)

that's good for a language heavy on syntax.

> Also unlike Lisp macros, a Haskell template can inspect and alter
> anything in the current module (up to and including completely rewriting
> it).

sounds as deadly as ninja patching. :)

other than that, I'm not sure what you mean by inspect and alter anything in the
current module...

do you have any practical example other than the short but confusing already
examples at:

http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/template-haskell.html

the examples there seem to deal with a problem that doesn't exist in Lisp in the
first place:  generate code to deal with different types.

> Like Lisp macros, Haskell templates are written in vanilla Haskell.
>
> "Using restarts and the Lisp REPL, a bug can be fixed in a running program."
>
> While that /does/ sound pretty cool, it's only possible because Lisp is
> interpreted and untyped.

they compile a module and load it into the same executable image in order to run
in place of the older version.

> "They're using this incredible device called a Wii. Say cadet, why
> aren't you shooting anything?"
>
> "I'm trying to, but the controller keeps thinking that I want to HUG the
> insectiod storm-troopers!"
>
> LOLrus.

completely random Nintendo ad... :p

> "Those ships are from the DSL Guild."
>
> Uhuh. Because no other language allows you to embed a DSL right into
> your programming language. Or even, you know, embed a language with a
> syntax entirely different from that of the host language. (Haskell's
> "quasi-quoting" allows you to embed a DSL that gets read using a parser
> that you write, using any parser libraries you desire.)

yeah, but it seems so mindnumbing complex nobody uses.

BTW, you know quasi-quoting comes from Lisp, don't you?  `(let ((r ,(fact 5)))
r) will turn into (let ((r 120)) r) at compile-time... it's so friggin' easy
it's used a lot.

> "Those ships are from the CLOS Guild."
>
> I have no idea if this is good or not. Nor do Lispers, apparently.

Common Lisp Object System is one of the main prides old Lispers enjoy chatting
about.  It's the ultra-flexible polymorphic, late-binding object system that
comes with Common Lisp.

I never used it but can see it's value for OO folks.

> "What the... Oh, I forgot about those obnoxious Schemers from the
> Continuation Guild."
>
> Again, because no other programming language has continuations, right?

yes, this is actually an innacurate description of Scheme, but they got it right
that Lispers usually don't get along with schemers, even though it's all Lisp.
Scheme is also far more geared towards functional programming than CL, another
factual error there.

All programs have continuations, it's just that so few programming languages
offer them as first-class objects.

first-class continuations and the tail-call optimization used by all functional
programming languages were born or brought to light with Scheme as described in
the lambda-the-ultimate papers in the 70's:

http://library.readscheme.org/page1.html

> "Basically, continuations let you put 'time travel' into your code."
>
> Actually, you don't need continuations to do that, necessarily.

you may not need special syntax for it if you explicitly write your programs in
continuation-passing-style, in which case you get continuations for free.  Of
course, that requires tail-call optimizations otherwise your stack blows...

> "Weaknesses: Continuations are such an awesome feature that they don't
> really have a downside."
>
> O RLY?
>
> How about the ease with which you can make your program so complicated
> that it becomes totally unmaintainable?

remember continuations are essentially gotos. ;)

you're taking a comic book too seriously...

> "Those ships are form the Brevity Guild."
>
> Yeah, true. There are no other programming languages that are brief,
> right? (Scroll upwards for one tiny Haskell v Lisp example.)

some people consider python a quite apt Lisp.  Including Google's old Lisp
visionaire Peter Norvig.

> "(accum a (for n 1 1000 (unless (some [is 0 (mod n _)] (range 2 (- n
> 1))) a.n)))"
>
> That computes the prime numbers from 1 to 1000? OK, how about
>
> primes = let f (p:xs) = f $ filter (\x -> x `mod` p > 0) xs in f [2..]
>
> Yes, *clearly* only Lisp can be brief and unintelligible.
>
> (Note well that the Haskell variant generates *all* the prime numbers in
> the universe, not just the ones less than 1000.)
>

> As an aside, does Lisp have arbitrary-precision arithmetic yet? Cos that
> Haskell fragment gives you arbitrary-precision results. Using the GMP,
> no less.

arbitrary-precision arithmetic is what Lisp got since ancient times -- they call
it a full numeric tower, no overflow error.  In fact, if you want performance
out of small toy examples, you should state something like fixnum... they also
predate GMP, but some newer implementations are using it for the sake of
maintenance...

> "(take 20 (filter even? (iterate inc 0)))"
>
> Or, to put it another way,
>
>    take 20 (filter even (iterate (+1) 0))
>
> or even
>
>    take 20 $ filter even $ iterate (+1) 0

nah, inc is 1 char shorter. ;)

whew, I'll call it a draw here and reply about the Seven Guilds of Haskell
later...


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.