Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Please correct me if I'm wrong, but I think the word metaprogramming (MP) is used a bit too liberal in this article. When I think of MP I think of programs-writing-programs, which might very well be a too narrow definition.

TemplateHaskell --DSLs that are transformed to (mostly rather repetitive) Haskell at compile time-- are MP in my idea, also: macros in LISP and open classes modified my the program at runtime in Ruby.

Non the less a very interesting article! Compared to C++ Haskell's syntax is soo clean!



I use the term 'metaprogramming' because that's the title of the relevant chapter in Stroustrups 'The C++ programming language'. I do think that 'C++ metaprogamming' is a bit clunky, but 'C++ template programming' sounds too limited. 'compile time programming' also sounds strange.

Wikipedia says: "Metaprogramming is the writing of computer programs with the ability to treat programs as their data." Writing C++ templates to treat Relax NG specifications and literal XML in C++ as input for schema validation would fit that definition.


I think 'C++ template programming' might be better also :/

The following syntax in Haskell causes a parse error in my brain:

    contains :: NameClass -> QName -> Bool
I really want it to be

    contains :: (NameClass, QName) -> Bool
Or even just

    contains :: NameClass, QName -> Bool
Is it just my problem to get over or do other people have it, or is there syntactic sugar coming to my rescue?


    contains :: (NameClass, QName) -> Bool
is valid Haskel, and denotes that "contains" is a function that takes a tuple and returns a bool. As a matter of style, Haskellers tend to avoid writing function like this, and prefer to write functions like

    contains :: NameClass -> (QName -> Bool)
which indicates that "contains" is a function that takes a "NameClass" and returns another function. Because this pattern is so common in Haskell, -> is defined to be right-associative, so the paranthese can be omited.


You should get over it. It's just syntax... and it's there for a reason (Makes more sense for curried functions, and it's a holdover from logic where you say that if you have a nameclass, you have an object that sense a qname to a bool, and if you have a nameclass and a qname then you have a bool.)


What? Are you saying that I can legitimately read

    contains :: NameClass -> QName -> Bool
two ways? Like,

    contains :: (NameClass, QName) -> Bool
And

    contains :: NameClass -> (QName, Bool)
? What about four types?

    contains :: Urk -> NameClass -> QName -> Bool


No, a -> b -> c always means a -> (b -> c).

a -> b -> c -> d always means a -> (b -> (c -> d)).

"->" is right-associative.


You should first understand currying. If I have a function f :: A -> B -> C -> D, every time I apply an argument, as in f a where a is of type A (b :: B, c :: C, ...), you get a new function back of type B -> C -> D. Read :: as "has type." Therefore

f :: A -> B -> C -> D

f a :: B -> C -> D

f a b :: C -> D

f a b c :: D

This is why Haskell's function call syntax seems a bit funny, and the typing syntax (->) seems funny. Every time you apply an argument you get a new object back which represents the result of applying the function. Once you've applied everything to the left of the rightmost type, you have the result.

It's a statement of implication. If I have an a and an f, the most I can have is a function which takes arguments of type B, C, and D, and so forth.


Not quite. It's equivalent to either

    contains :: (NameClass, QName) -> Bool
or

    contains :: NameClass -> (QName -> Bool)
In other words, you can treat it as a function taking two arguments, or one function taking one argument and returning another function.


It is equivalent to the second, not the first. The first is a completely distinct type -- though you can certainly write a function with that type, given the original function, by uncurrying it.


FWIW, I think the person you are responding to is using the non-Haskell requested mental syntax used by the person who asked the original question, in order so they better understand the semantics (even if at a cost of confusing them for later development in Haskell).


Yup. They're distinct types, but mentally they are the same (and the standard library has functions to convert between the two forms).


>"DSLs that are transformed to (mostly rather repetitive) Haskell at compile time-- are MP in my idea"

In it kinda the case in C++ too. C++ template system is a turing-complete machine at compiling time.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: