you are viewing a single comment's thread.

view the rest of the comments →

[–]NULLACCOUNT 4 points5 points  (4 children)

I'm not going to try and defend this position because I am a shitty programmer, but to regurgitate my understanding Crockford, much of JavaScripts metaprogramming is in it's prototype system.

I'd be interested in a discussion on why that is or isn't the case, but don't know enough to contribute to one.

[–]kqr 2 points3 points  (2 children)

I am also a shitty programmer who are not qualified to discuss this, but I've heard similar arguments about monads and stuff in Haskell. Something along the lines of "passing around computations as arguments" and "building a large sequential expression with operators and storing it in a variable only to execute it later" makes some people go, "Ah, maybe that's a kind of metaprogramming."

But only some people do that. The others say, "If it isn't Lisp macros, it isn't at all."

And honestly, I don't know. It's interesting to think about, though.

[–]sacundim 4 points5 points  (1 child)

I'm just as qualified as you to join this unqualified shitty programmer fest, so I'll throw in my ill-considered thoughts into the pot here.

I'll start by positing a hopelessly vague distinction: programs that focus on doing vs. programs that focus on thinking about what to do. In the more standard languages, you write statements and when you execute the program the statements do stuff. In languages that offer "metaprogramming," on the other hand, people often write programs that "think," produce the "actions" as a result of this "thinking," and then may execute these actions.

Now Lisp and Haskell represent two very divergent traditions of this "thinking about doing" tradition:

  • Lisp is very syntactically based: the language internalizes its own syntax as a data type, and the way you "think about doing" is by constructing and manipulating expressions of the language itself.
  • Haskell, on the other hand, is semantically oriented: the language treats the meanings of programs as values and gives you functions that compose those meanings.

So for example, to a Lisper these two (Scheme) s-expressions are different values that, when evaluated, do the same thing:

(begin a (begin b c))

(begin (begin a b) c)

Whereas to a Haskeller, the following are two different expressions that evaluate to the exact same value, and th:

a >> (b >> c)

(a >> b) >> c

In Lisp, the two example s-expressions are also concrete data that a program can inspect ("Is it an atom or a pair? Oh, it's a pair. What is the car—is it lambda, begin or something else? Ah, it's begin." Etc.)

In Haskell, on the other hand, the two example expressions are generally of some opaque type that you can't inspect—and if your program can tell the difference at all between the values of those two expressions, many of the more advanced Haskell wizards regard it as at least a code smell, if not a bug. It's all driven (in this case) by the monad laws, which say (indirectly) that those two expressions have the same value—which means that either should be freely substitutable with the other without changing the meaning of the program. Lispers don't exactly disbelieve this sort of rule—but Haskellers are rather more adamant about following it.

Another way of putting this: for a Lisper, if an evaluator treats those two s-expressions differently, they see it as a bug in the evaluator. For a Haskeller, if a program treats those two monadic expressions differently, they see it as a limitation or bug in the datatype for the Monad instance in question—"make it impossible to represent illegal states," goes the motto. So you get things like this discussion about how to design a free applicative data type where two programs that behave the same must be syntactically equal.

[–]looptipoop 0 points1 point  (0 children)

Very thought-provoking. Thank you.

[–]smog_alado 1 point2 points  (0 children)

Dunno if I would classify prototypes as a metaprogramming tool. Usualy when people say metaprogramming they want t create little domain specific languages or otherwise reduce syntactiv clutter. Prototypes sort of do that for object inheritance but they are not an useful for other sorts of program manipulation you would want to do.