Live data from Hacker News

Not Lisp again (2009)

funcall.blogspot.com

231–240 of 276 posts

Re: Not Lisp again (2009)

#231

Earlier quoted context omitted.

The hesitation I'd have with Lisp(s) as an outsider, which ties in to number 3, is that the language itself is compact, elegant and extensible. It's the opposite problem to C++ (the language is too large) - the language is too small and it encourages you to build other languages inside it. So it'd be very hard to share code with others because as soon as you start building abstractions your language and worldview div…

I think that objection is likely true of scheme. Scheme is like the Assembly language of lisps. To build it up to the level of usefulness requires a lot of wheel re-inventing, and those wheels are likely to be not quite standard. Clojure and Common Lisp are larger languages and don't really suffer this problem.

That's not really the case for R6RS, and now R7RS Large.

Both of those have huge swathes of libraries and make the language quite large.

Re: Not Lisp again (2009)

#232
post #195

Earlier quoted context omitted.

>> 1 - All those parenthesis. (Still a top objection) > If you actually count parens fairly you will find that Lisp has no more than any other language Bull. For example, compare the Lisp factorial function from the article: (define (fact x) (if (zero? x) 1 (* x (fact (- x 1))))) with the corresponding F# implementation: let rec fact x = if x = 0 then 1 else x * fact (x - 1) That's 7 vs. 1 pair of parens. Also, the p…

Yeah, you know what else I'm realizing? All the different kinds of punctuation let my eyes skim over different parts of code so easily, and lisp doesn't give me that. You know how, when you're reading natural language, you don't actually read individual letters, not once you have any reading fluency? That's how I read code, too, I'm realizing. When I see the parentheses in C#, my brain just goes "oh that's a method/f…

> Looking at all the parens of even that simple lisp factorial, and I realize that I'm feeling a lot of cognitive load that would simply never go away, because the punctuation doesn't let me filter any of it out. I'd have to read everything more carefully.

Completely the opposite here.

Parens means function call or list. Lists usually denoted by a quote first.

I don't read the parens, I skim everything, reading words. And the punctuation is really simple.

For example:

    if (number? a)
      + a b
      error "Not A Number" a
I stripped most of the parens there, (like Wisp [0] does), because I don't really see them. I see function call and arguments, because there isn't anything else.

Scheme has the very least syntax out of just about any programming language I've used. It has a tiny cognitive load compared to most.

[0] http://dustycloud.org/blog/wisp-lisp-alternative/

Re: Not Lisp again (2009)

#233

The objections the author had way back in the day are no longer the objections programmers of mainstream languages have to Lisp today. Today the objections I hear are more along the lines of: 1 - All those parenthesis. (Still a top objection) 2 - Lisp doesn't look like or work like what I'm used to. 3 - Lisp doesn't have as many libraries as the most popular mainstream programming languages. 4 - There aren't nearly a…

To me the hard part about lisp is that every programmer that uses lisp tailors it so to their own taste that it can become quite hard to read the 'top level' of a lisp program without first having gone through all the lower layers. It is as if every project in lisp somehow magically develops its own DSL. That's a high hurdle for newbies to clear.

> It is as if every project in lisp somehow magically develops its own DSL. That's a high hurdle for newbies to clear.

I'm not sure it is, most Lisp code I've seen is very readable, and you don't need to understand the internal most of the time.

Like in Scheme, if the function name isn't followed by a !, then you can assume that it is functional, so you don't need to worry about anything other than input and output.

So you end up with DSLs like:

    > (read-html (string-as-port "Hello, World!"))
    = '(h1 ("Hello, World!"))
It's a DSL, it's created a non-standard list at the end, an X-Expr, but it's readable, and predictable, without me trying to work out the internals of how a string-port functions, or how read-html works beyond it reads from a port.

Re: Not Lisp again (2009)

#234
post #138

Earlier quoted context omitted.

> 1 - All those parenthesis. (Still a top objection) If you actually count parens fairly you will find that Lisp has no more than any other language, it's just that other languages use a mix of parens, square brackets and curly braces whereas Lisp only uses parens. Also, if you really don't like parens, you can get rid of a lot of them using macros. See e.g.: https://github.com/rongarret/ergolib and in particular the…

>> 1 - All those parenthesis. (Still a top objection) > If you actually count parens fairly you will find that Lisp has no more than any other language Bull. For example, compare the Lisp factorial function from the article: (define (fact x) (if (zero? x) 1 (* x (fact (- x 1))))) with the corresponding F# implementation: let rec fact x = if x = 0 then 1 else x * fact (x - 1) That's 7 vs. 1 pair of parens. Also, the p…

You can replace parens with indentation, yes. There are lisps that do this, like WISP for guile,which provides "implicit parens through indentation".

Then you get the same amount of parens as fsharp. It is even standardised as an SRFI (although not widely.implemented)

Re: Not Lisp again (2009)

#235
post #74

Earlier quoted context omitted.

It makes e.g. arithmetic expressions look rather awkward.

That's if you choose to think abiut them as arithmetic expressions and not function applications. If you work with arithmetic expressions a lot, you should probably use appropriate domain language - in fact, you can build it in Lisp itself.

You can write a reader macro (in lisps that permit them, otherwise you've got no hope) but that's just lisp-speak for "program that parses strings". A language where you can use infix notation within the language is much nicer.

Re: Not Lisp again (2009)

#236
post #168

Earlier quoted context omitted.

Is Python a LISP? Is JavaScript a LISP? Is Java a LISP? What do you mean by LISP, by its core principles? What does a different set of core principles look like that lends itself to a different family? I threw in my vague classification above: sexps and macros. But you can have macros without sexps, and sexps without macros (lots of "toy lisp interpreters" do that), are they LISPs? Lastly one wonders why we don't go…

Is Picolisp a Lisp? Is Newlisp a Lisp? Is Emacs Lisp a Lisp? Maybe it's because I first learned programming in the 1980s in BASIC, but I'm pretty used to the idea of programming languages having dialects. Apple ][s, Commodore 64s, and Atari 800s all supposedly were programmable in BASIC, but it didn't mean you could take a program written on one and expect to run it without changes on another.

Surely that's the whole point - it's a dialect, so it has the same core but not 100% so you have to translate some of it to get to the other.

The dialects of Dutch in Belgium contain completely different words and phrases - but the core is still Dutch.

But for large parts of the speech they are recognisably similar.

So I'd say yes all the lisps you mentioned are dialects of Lisp. You can't run one directly in the other, but they are reconisably similar programming constructs.

Re: Not Lisp again (2009)

#237

Earlier quoted context omitted.

Not really in machine language or even BASIC (see below).

Your BASIC example doesn't have any local variables to close over. It just references a global. That defeats the whole point of closures. Passing or returning first-class functions aren't a problem. First-class closures (function pointer + state) are.

You can create closures in CBM BASIC V2 by referencing arrays or creating thunks as an extension. But that's beside the original point. Implementing is not a lot of work but since my mega-deriver already solves the problem (derivation) elegantly and efficiently (most likely more efficiently than the original m68k lisp program), I really don't see any reason to use closures here. Do you?

Re: Not Lisp again (2009)

#238
post #49

Earlier quoted context omitted.

Note that the simplistic approach doesn't scale well, as terms tend to "explode" in size and hence computation time. There is a whole sub field of mathematics / computer science called "algorithmic differentiation", also known as "automatic differentiation". The goal is to take an existing computer program and transform it into another computer program that calculates the derivatice just as efficiently (up to a const…

It doesn't stop at forward-mode, and reverse-mode, because finding the optimal mode relates to a complicated graph problem, which, IIRC, is NP-hard in general. Not only that, but most of the difficulty is in getting these tools to work on arbitrary codebases, making it more a software engineering problem rather than a maths problem.

> It doesn't stop at forward-mode, and reverse-mode, because finding the optimal mode relates to a complicated graph problem, which, IIRC, is NP-hard in general.

Yes, there are combined forward-reverse-mode approaches as well as "cross country" approaches. That's in part of what I menat with a "whole world to discover".

> Not only that, but most of the difficulty is in getting these tools to work on arbitrary codebases, making it more a software engineering problem rather than a maths problem

Depending on your viewpoint, it is neither SE nor math, but a PL (programming languages) issue, meaning that viewing the program e.g. as register machine (classic assembly) yields to different approaches than viewing it as lambda calculus expression (which provided great results, but it is hard to transport the results back to languages like Fortran or C++).

Re: Not Lisp again (2009)

#239
post #30

Earlier quoted context omitted.

Unreadable? Personally, I think that Lisp has the clearest possible syntax - because it basically doesn't have any. It's just straight ASTs - something that I have to visualize myself in other languages wich have more syntax sugar.

Lisp has the minimal syntax for lists: (a b c d) where other languages require separating commas, but Haskell has minimal syntax for function application: f x y z with no parenthesis needed. (Technically, this is a triple application ((f x) y) z, masked by the convention of application being a left-associative binary operator.)

> but Haskell has minimal syntax for function application: > f x y z

The question is, is it the _only_ syntax that Haskell offers and that the full language is built upon?

Re: Not Lisp again (2009)

#240
post #206

Earlier quoted context omitted.

>> 1 - All those parenthesis. (Still a top objection) > If you actually count parens fairly you will find that Lisp has no more than any other language Bull. For example, compare the Lisp factorial function from the article: (define (fact x) (if (zero? x) 1 (* x (fact (- x 1))))) with the corresponding F# implementation: let rec fact x = if x = 0 then 1 else x * fact (x - 1) That's 7 vs. 1 pair of parens. Also, the p…

F# and all ML derivatives are an aberration because they use juxtaposition to denote function calls. That eliminates a lot of parens but personally I find the result less readable. But compare to, say, C where no one complains about the parens: int fact(int n) { if (n==0) { return 1 } else { return n*fact(n-1); } } That's six pairs of parens. The only reason it's not more is because some function calls in C are disgu…

> F# and all ML derivatives are an aberration because they use juxtaposition to denote function calls. That eliminates a lot of parens but personally I find the result less readable.

It makes a lot of sense when all functions are curried. Parenthesised function calls treat all of these as different things:

    f(a, b, c, d)
    f(a, b, c)(d)
    f(a, b)(c, d)
    f(a, b)(c)(d)
    f(a)(b, c, d)
    f(a)(b, c)(d)
    f(a)(b)(c, d)
    f(a)(b)(c)(d)
If functions aren't curried, then these all mean different things. When functions are curried, all of these have the same semantics (call `f` with `a`, call the result with `b`, call that result with `c` and call that result with `d`); ML's juxtaposition syntax makes these semantically-identical expressions syntactically-identical too:

    f a b c d
Post reply on HN