Live data from Hacker News

Just what does “code as data” mean anyway? (2014)

adambard.com

61–70 of 178 posts

Re: Just what does “code as data” mean anyway? (2014)

#61
Code is data does not come from lisp or macros, those are simply affordances.

It comes from computer hardware architecture.

The von Neumann Architecture is named after the mathematician and early computer scientist John von Neumann. von Neumann machines have shared signals and memory for code and data. Thus, the program can be easily modified by itself since it is stored in read-write memory.

Any self-modifying program, even if it is written in Borland Delphi, expresses this code is data capability.

Re: Just what does “code as data” mean anyway? (2014)

#62
Code is data.

In Java, I could use a bytecode manipulation library to read in a class file, manipulate it by using the library's API to add, modify, delete members of the class. Then write the class back out as a file.

Code becomes data and is manipulated as date and written back out.

In Lisp 'code is data' is so much more natural because code IS the most elementary data structures of the language. No need for a library to manipulate code behind an API. The API is the language primitives. The code is the data structure you manipulate using language primitives.

Re: Just what does “code as data” mean anyway? (2014)

#63

I think there’s a much simpler example of how code is data: (hello world) That’s a list containing two symbols. So it’s data. However, if I evaluate that list, it will call the function “hello” with the argument “world”. So it’s also code. Incidentally, lists and function calls are identical in lisp, hence code is data. I think the article just complicates it by introducing macros.

    '(hello world)
is a list

    (hello world)
is a function call

Re: Just what does “code as data” mean anyway? (2014)

#64

Would it be possible to do the same thing in Haskell using partial function application, where the first argument is the name of the tag and the second argument makes the " " tags and applies string concatenation?

You could get most of the value in Haskell using higher-order functions, but note that the macro-based code generates a complete function definition from (deftag tagname). Since definitions aren't values in Haskell (code isn't data), you can't just write

  deftag "html"
but instead would have to write something like

  html = tag "html"
I'm not sure whether you could get around that limitation using Template Haskell (never tried it).

Re: Just what does “code as data” mean anyway? (2014)

#65

See what I did there? Despite the good intention, no, because you're trying to explain lisp using lisp. If I knew lisp, I wouldnt need you to explain what code-as-data means. Maybe it's time for a different strategy. As a matter of fact, I've tried to explain code-as-data using OOP just this morning: https://news.ycombinator.com/item?id=16389514

>>because you're trying to explain lisp using lisp.

There is no other way to explain it.

Simply put:

    (1 2 3 4)
Is a list

    (add-all 1 2 3 4)
Is also a list

    (add-all 1 2 (add-all 3 4))
Is also a list

In the above example the nested list is data to the main list. And there is all there is to it.

In the last example, code just went in as data to another list(code as data). Which is also code.

Re: Just what does “code as data” mean anyway? (2014)

#66

Earlier quoted context omitted.

Your linked comment is great but it sweeps one thing under the rug. There is a reason lisp didn't win. We put up with it (I use emacs, so I have to write it at times) but in general it's harder to reason about transformable lists of code than it is about plain old objects and their methods. Almost every problem elegantly solved in lisp has a parallel elegant solution in Ruby (using blocks, dynamic method definition,…

>There is a reason lisp didn't win. We put up with it (I use emacs, so I have to write it at times) but in general it's harder to reason about transformable lists of code than it is about plain old objects and their methods. Sounds like your experience was with Emacs Lisp, a very clunky Lisp. >Though I completely agree that inheritance gets clunky and I strongly favour composition. Check out CLOS (Common Lisp Object…

> Sounds like your experience was with Emacs Lisp, a very clunky Lisp.

The lisp that didn't win is not an acceptable lisp.

Re: Just what does “code as data” mean anyway? (2014)

#67
post #47

Earlier quoted context omitted.

I really value C syntax. I'm convinced it's much easier to navigate with the eyes than "oatmeal with fingerclips mixed in" (quoting Larry Wall). And >90% of the time the relevant syntactic unit is on its own line or ranges of lines, and that's really super easy to handle in vim. I don't think there is much to improve by building more complex abstractions on top. If you use vim as a C programmer, you should know the b…

> I don't disagree that if all you have is parens, then you want something like paredit. But for a C programmer there is no need for such a thing. If that's a good selection of tools for editing code, then why would Lisp programmers need Paredit? Most of those commands work just as well for editing Lisp. The advantages that Paredit gives over that model are semantic commands rather than character based ones, things l…

But there is no such thing as "parent lists" in C. There are much less parentheses. You don't make nested functions or data. You write simple, procedural code, and therefore you simply move lines up or down, and at most change the indentation level. (To fix indentation in vim, select a block of lines and use =. To shift left or right, use >).

Re: Just what does “code as data” mean anyway? (2014)

#68
post #41

Earlier quoted context omitted.

I agree, OO is ultimately good enough. Problem is, coding using OOP is like printing ideas on paper: you dont wanna do that because it's hard to discard ideas that's been printed on paper. You wanna use post-its instead because post-its are easy to discard. Refactoring is hard using OO and refactoring is the key difference between waterfall and good software development. Refactoring is easier, even fun, using functio…

Refactoring lisp gets harder the more complex the program gets. Approachs that are clever and reasonable for a 1000 line program can become hell in a 100,000 line program. Effectively programming languages get less powerful the longer the program becomes. Breaking up programs into more powerful little pieces is never a clean separation and you need to make real trade offs between more separation and more power.

>Refactoring lisp gets harder the more complex the program gets. Approachs that are clever and reasonable for a 1000 line program can become hell in a 100,000 line program.

Can you substantiate this claim? One of the reasons Lisp was used in the past was because it was particularly suited to complex, big projects... Like autopilot for spaceship, wind tunnel simulation, CAD/CAM systems, etc.

Lisp (as 'Common Lisp', the traditional dialect) has this concept of "packages" and "systems".

You can divide your code in "packages", each package contains separate namespaces for classes, function names, variable names, symbol names, keyword names and others. Thus each package doesn't collide with another package and names don't collide at all.

Many packages are combined into a "system" (by defining, for example, the required order for compilation, etc).

Thus you cleanly separate your code in packages and systems. The 100,000 line program becomes a combination of many shorter programs.

Of course this is nothing new, this is just standard practice for keeping big programs manageable.

>Breaking up programs into more powerful little pieces is never a clean separation

Care to explain? Well, i'll continue with my post. And we'll assume that what you say is true, so i'll list other advantages to keep complex systems at check.

Now, here is a big plus for complex systems: In such a Lisp, the system is hot-patchable. You can redefine functions while your program is running. Without stopping the program. We're talking about doing this even on a production environment, if necessary.

You can also redefine classes while your program is running. Without stopping the program.

Another big plus is the condition-restart system, which very few languages implement. Lisp has not only the notion of "catching exceptions", but also after catching the exception, provide alternate ways of recovering of this exception, including being able to resume operation at the point where the problem was found.

This is another big plus for building reliable systems -- and complex systems benefit from being composed of reliable parts.

I could go on with other big pluses as well. For example, multi-paradigm. Some parts are more readable (and thus easier to understand, maintenable) if written in the functional style. Others map better to the OOP style. Others would map better to the imperative/procedural style. Other would better be expressed as logic programming (think Prolog.)

Lisp allows you to use all these paradigms. So the code stays clear. I say this is very good for complex systems.

Re: Just what does “code as data” mean anyway? (2014)

#69

See what I did there? Despite the good intention, no, because you're trying to explain lisp using lisp. If I knew lisp, I wouldnt need you to explain what code-as-data means. Maybe it's time for a different strategy. As a matter of fact, I've tried to explain code-as-data using OOP just this morning: https://news.ycombinator.com/item?id=16389514

Your linked comment is great but it sweeps one thing under the rug. There is a reason lisp didn't win. We put up with it (I use emacs, so I have to write it at times) but in general it's harder to reason about transformable lists of code than it is about plain old objects and their methods. Almost every problem elegantly solved in lisp has a parallel elegant solution in Ruby (using blocks, dynamic method definition,…

>>in general it's harder to reason about transformable lists of code than it is about plain old objects and their methods.

Well actually no. Other languages make it easier for beginners to get started, but they just keep you there. Because its harder to do that the advanced stuff in those languages.

>>Almost every problem elegantly solved in lisp has a parallel elegant solution in Ruby (using blocks, dynamic method definition, or otherwise) and I generally find the resulting code both more maintainable as well as more readable.

Its other way around. We solve trivial library stitching problems in other language, and the we try the same in Lisp and don't see the point. But then that is also a kind of mental handicap. You can do things beyond a point because tools are making it harder for you to keep going forward. And then you use Lisp with the same philosophy and don't see the point.

Re: Just what does “code as data” mean anyway? (2014)

#70

Earlier quoted context omitted.

I agree, OO is ultimately good enough. Problem is, coding using OOP is like printing ideas on paper: you dont wanna do that because it's hard to discard ideas that's been printed on paper. You wanna use post-its instead because post-its are easy to discard. Refactoring is hard using OO and refactoring is the key difference between waterfall and good software development. Refactoring is easier, even fun, using functio…

>I agree, OO is ultimately good enough. And Common Lisp has arguably the most flexible and powerful OOP system around, CLOS. Why don't write OOP in Lisp? It is done successfully by lispers around the world.

>>Why don't write OOP in Lisp?

Because most people understand OO as some kind of namespace scheme. Basically to bunch together functionality under a name(class).

When people talk of OO, most of them, are actually talking about modularizing code.

Post reply on HN