POV-Ray : Newsgroups : povray.off-topic : Land of Lisp : Re: Land of Lisp Server Time
3 Sep 2024 23:27:26 EDT (-0400)
  Re: Land of Lisp  
From: nemesis
Date: 2 Nov 2010 13:15:00
Message: <web.4cd046952bc10e38b282d9920@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> On 02/11/2010 02:00 AM, nemesis wrote:
> > Invisible<voi### [at] devnull>  wrote:
> >> Is it possible to create variables with local rather than global scope?
> >
> > you're kidding me, right?
>
> Well, I've never seen anybody do it before, that's all.

no, you've never seen before, period.  Even previous examples I posted.  If
you'd had any curiosity on the subject, I'm sure plenty of examples abound in
places like projecteuler or language shootout.

> If you want a point, you say Point 3 7. Which, as you say, rather gives
> away the fact that it's a Point value. But how about saying "True"?
> That's of type Bool, but you didn't write that in your expression.
> Similarly, when you write
>
>    Branch (Leaf 3) (Leaf 7)
>
> you didn't say anywhere that this is of type Tree Int, did you? The
> compiler infers this automatically.

it infers from unique names relating to a type like those sprinkled everywhere
in the code.  Think about it... :)

> And don't even get me started on
> expressions which are polymorphic, and could have /several/ possible types.

expressions are polymorphic by default in dynamically-typed languages. :)

(define (foo bar) (boz (boz bar)))
(define (boz bar) (+ bar bar))

an implementation could infer foo ultimately works on numbers because boz calls
+.  But + could be redefined as

(define +
  (let ((o+ +))
    (lambda args
      (cond
        ((null? args) 0)
        ((number? (car args)) (apply o+ args))
        ((string? (car args)) (apply string-append args))))))

and thus foo works on numbers, strings and what more gets into the redefinition
of +.

or at least it could in scheme a few iterations ago.  Today implementations say
+ can't be redefined... :p

> > I'm talking ill of Hindley-Milner type system, but you should be aware that the
> > same lameness can happen in Lisps too:  here and now you will see things like
> > fl* fx+ or fl<... that is, functions to operate on specific numeric types.
> > Again, they exchange a single type declaration for type-specific operators
> > everywhere.  Makes me wonder if the Algol folks got it right...
>
> Not so in Haskell. If you want to add two numbers, you use (+). It's
> polymorphic like that.

yes, + in Lisp is polymorphic over numbers, be it float or integer.  fl+ or fx+
are performance-geared optimizations.

I still think simple declaration of a variable as of a given type would be
better than sprinkling code with operators/names that force expressions into a
given type.

> I'm actually surprised that a dynamically-typed language would do
> something like that. I thought the whole point of dynamic typing was
> that you can completely ignore types.

you can, except when you want performance.

> All I know is that every time I've used a dynamically-typed language,
> I've spent 90% of my time fixing type errors - errors which *could* have
> and *should* have been caught automatically by the machine, but I have
> ended up catching them myself, by hand. Yuck!

only you could do that in a language "without types" :p

I don't have a trouble providing arguments of the right types to functions, but
I must confess I've been flamed already by typos in the code only detected at
runtime. :p

Thankfully, the real nice thing about development with a REPL is that you can do
fine-grained iterative development:  write little expressions, test them, put
them into a function, repeat.   You write and test at the same time.  shame that
haskell's REPL is very limited and doesn't allow for full type definitions and
such.

> > I suspect its homoiconic nature has lots to do with it.  Plus, if you've never
> > edited Lisp code with hierarchical parenthetical editing you don't know what a
> > bless it is compared to any other language in existence.
>
> More like "without automatic bracket match, it's impossible to produce
> code which is even syntactically correct". It wouldn't be so bad, but it
> seems all Lisp programmers habitually indent their code incorrectly.

Lisp n00bs usually indent their code incorrectly, specially those who actually
care about the parentheses and treat them like brackets in C languages, even
going as far as matching open and close in the same indented column.  Lisp
experts have long developed a code style that makes brackets virtually invisible
by hiding them to the rightmost end.

BTW, the expressions above I typed here, but copied them to a scheme buffer to
test them.  You can do marvels by merely typing () in sequence and going in
between them next.

> I can see how having a language where everything is a list is
> technically quite a nice idea. It's simple and elegant. Unfortunately,
> the language as a whole seems to be messy and inconsistent. Too much
> backwards compatibility, too much muddled thinking. Still, I guess it
> was the first attempt...

There is quite a lot of backwards compatibility in CL, that's for sure:  it was
designed by a comittee to comply with several older lisp dialects, so they
basically just made a big union of features.  Not so much with scheme.

I'm specially annoyed at the car/cdr family of operators so dear to old Lispers.
 Those were the names of two macro-assembler instructions in the first machine
Lisp was implemented in.  They are truly lame legacy misnomers for head/tail...

I discussed a bit about them here to some strong reactions from old farts:

http://groups.google.com.br/group/comp.lang.lisp/browse_thread/thread/16135e3a09d5f6f3#

> > It's because you still don't know it well.
>
> Sure, functions are first-class. But it lacks purity.

like I said, aside from Haskell, no other language goes that far to ensure a
pure, side-effect-free mystical environment.  Including others from functional
programming land, like scheme or ML.

this is side-effect free:

(let fact ((n 25) (r 1)) (if (< n 2) r (fact (- n 1) (* n r))))

even though implementations so far don't go as far as detecting its purity to
allow for fine-grained paralellism.

(BTW, once again written in the browser)

> It also doesn't
> appear to place any emphasis at all on coding in a vaguely functional
> style - not in the language design nor the standard libraries.

if you're talking about Common Lisp you're right:  it's a very imperative
version of Lisp.  Scheme was in part developed in the 70's as a functional
rework of the original Lisp principles.

> No, a design that enforces purity has profound consequences for any
> implementation of that design. (Not to mention the entire way that the
> language is used.)

true.  But whenever I want all pure and white design I know where I can find
haskell... ;)

> And Clean doesn't count because...?

because it is even more obscure than haskell itself?

> To me, "new syntax" means that I can write something that doesn't look
> like the host language. From what little I've seen, a Lisp DSL just
> looks like Lisp.

true.  We actually consider that a benefit. ;)

> And a Haskell expression consists of some combination of exactly 6 (go
> count them) structures.

nobody codes haskell without such sugar just as nobody codes scheme like

((lambda (fact) (fact fact 5))
 (lambda (fact n) (if (< n 2) 1 (* n (fact fact (- n 1))))))

(once again written here)

> The rest is just sugar. That's peanuts compared
> to (say) the number of possible statements in Java. (For-loops,
> while-loops, if-then-else, return, switch/break...)

that's for sure is a gain of all functional programming languages:  creating
larger things from the composition of a few core functions.

> > (iterate (pf * 2) 0)
>
> Yes, that's just as succinct as (*2). Oh, wait...

it is as succint as you can get without having to alter the parser to allow for
special syntax and corner cases here and there.  Simpler design. :)


Post a reply to this message

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