freenode/#lisp - IRC Chatlog
Search
5:44:52
beach
afiddegnum: Every language has "special forms", i.e. expressions or statements that are not function calls, and that need to be defined by the language. In a C-like language, it might be the assignment, like a[i] = 234, or a conditional, like if (x < 3) fun(x).
5:45:04
beach
In most languages, if you need a special form that doesn't already exist, then you have to wait for the new version of the standard and then for current compilers to implement the new special form. In Common Lisp, you write a macro, that transform the form you want to see (but that doesn't yet exist) into one or more existing form types.
5:45:24
beach
So, for instance, let's say you have a special application that uses Fibonacci numbers a lot. You may wish for a looping construction such as `for each Fibonacci number x do <something>'.
5:45:25
beach
In Common Lisp, you just write a macro for-each-fibonacci-number, that transforms such forms into a TAGBODY and GO that will do the looping. And, in fact, this is precisely the technique used in the built-in Common Lisp macro LOOP.
6:06:07
afiddegnum
beach: i think my problem is, after reading most docs about it, i have a fair picture of what is it like, but how to apply to my daily scenarios, decided to learn lisp because of metaprogramming, which is a feature i m in dire need.
6:06:59
afiddegnum
well i dont want repeatedly i.e build an html page over and over, templating tools, i.e have their limitations
6:07:42
beach
The way I usually do it is that I wait until I see some boilerplate code that is repeated several times and that I can't easily express as a functional abstraction.
6:08:08
afiddegnum
what i m envisoning myself doing is to build something like html->head->corewidget->left_and_right:sidebars etc...
6:09:30
afiddegnum
there are lots of repetitions in code that handle the presentation logics; UI, widgets etc...
6:09:44
beach
I don't think you should start by thinking about macros. An application typically has only a few macros defined. You will see it as your code gets bigger.
6:11:58
afiddegnum
yes, functions, classes etc... but i still want to understand where macro influcences the functions or other codes? what does it do?
6:12:35
ecraven
I mostly use simple macros for delaying evaluation in some way, lots of with-.. macros that might take a thunk argument, but to prevent that, I just wrap that in a macro
6:12:51
ecraven
I've written a few more complex macros for things like defining custom types of structures
6:13:22
beach
afiddegnum: Think of classes as data abstractions, of functions as control abstractions, and of macros as syntactic abstractions.
6:14:58
beach
afiddegnum: Perhaps it is very hard to understand the purpose of macros until you have the situation I mentioned, i.e., boilerplate code that you can't turn into functions.
6:17:50
ck_
afiddegnum: I only asked because of your question "where macro influences the functions or other ocdes". The common lisp unless is a macro. (unless a b) means the compiler sees that as if you'd written (if a nil b).
6:20:55
LdBeth
>what i m envisoning myself doing is to build something like html->head->corewidget->left_and_right:sidebars etc...
6:20:56
LdBeth
Common Lisp macro is designed for producing lisp code, and what you’re looking for is probably a meta programming system producing HTML/DOM trees
6:22:41
pjb
afiddegnum: another way to see macros, apart from the syntactic abstraction, is to consider them as design templates. Have a look at: http://groups.google.com/group/comp.lang.lisp/msg/ee09f8475bc7b2a0 http://groups.google.com/group/comp.programming/msg/9e7b8aaec1794126
6:22:50
LdBeth
While you can use any reasonable programming languages to meta program any other languages
6:24:03
ecraven
beach: what are macros that couldn't be replaced by turning things into thunks or quasiquotes (that you then analyze at runtime)? [just speaking about functionality, not efficiency]
6:24:59
pjb
ck_: (macroexpand-1 '(unless (= a b) (print a) (setf a b))) #| --> (IF (NOT (= A B)) (PROGN (PRINT A) (SETF A B))) ; T |#
6:26:31
beach
ecraven: Macros don't do anything that can't be done that way. You are describing an interpreter that can be Turing complete.
6:30:49
ck_
(unless a b) is not a program source, then? I'll make a note of that, so I don't accidentally ever type it as part of a program
6:31:27
ck_
but you're missing the entire point. A asks about macros, B answers (with an answer you don't like, granted), and you address B with a correction
6:31:58
pjb
ck_: No, it's not. It's a template. a stands for any expression, but b stands for any SEQUENCE of expression.
6:32:05
ck_
if you wanted to set the record straight for the person asking, why not tell them directly? That's what I wanted to know
6:37:45
pjb
I thought of G-force, but there are a lot of causes to Tunnel Vision. https://en.wikipedia.org/wiki/G-force
6:41:32
beach
afiddegnum: Again, it is not clear that your use case requires macros, so forget about them until you can't get rid of boilerplate code without them.
6:41:45
afiddegnum
ok, thanks for your contributions, i m still reading through, I believe Macros fit into what i wanted to do but i just want to know how and when to use it right
6:43:06
beach
afiddegnum: It is a common mistake by beginner Common Lisp programmers to attempt to use macros where functions will work.
8:12:55
marcopersson
How come (typep #(1 2) '(vector string)) return t? It seems like typep ignores the element type?
8:18:28
beach
"only those vectors are included whose actual array element type is the result of upgrading element type"
8:20:33
beach
... meaning SBCL does not have a specialized array type for strings, which is not surprising.
8:25:03
marcopersson
I think so.. So the type specifier is this case isn't so much about the contents of the vector, as it is about the representation, and since this is not a specialized vector, the element type in this case doesn't really matter because of that?
8:25:53
beach
Right, the type of an array is not directly related to its contents. It has to do with how it is represented.
8:34:02
marcopersson
Okay, so if I can only get type checking (from SBCL) of array element-types if SBCL support that specialization
8:36:32
beach
Nothing prevents you from wrapping (SETF AREF) in something that will check the type, though.
8:38:13
beach
Wrapping would be a good idea anyway, since your array most likely represents some application data type, so you would want to hide the fact that you are using an array to represent that data type.
8:44:47
marcopersson
Hmm, does it then even make sense to (declare (type)) vectors' and arrays' element types if they're not specialized? I assume then that SBCLcan't take advantage of that extra information for optimization when it's not actually guarranteed from the representation
8:45:12
beach
Like for example, if your vector represents a graph, you would want an abstraction such as ADD-VERTEX, hiding the fact that the graph is represented as a vector. It is then natural to check that a vertex was given.
8:46:36
beach
It doesn't make sense. The standard says that declaring a type is the same as wrapping all references to the variable in THE.
8:47:25
beach
So, if the type is not a specialized array, then it will check that the array has element-type T.
8:51:56
beach
Otherwise, you will end up writing a lot of declarations that you will often change later.
8:53:05
beach
That's one of the problems with statically typed languages. They force you to provide information that often does not remain true for very long.
8:53:31
marcopersson
Yeah, I shouldn't really be focusing on it at all, since this is just a prototype, and I won't be allowed to write the final product in CL anyway. I just ended up playing with types, and just got suprised by the whole (typep #(1 2) '(vector string)) thing and wanted to know more
8:54:10
beach
If you really want to do that kind of stuff, define application types with DEFTYPE and use those types. Then there is only one place to modify later on.
8:56:38
marcopersson
Good advice, thanks. And yeah I won't have any luck convincing C#/C++ programmers at my comp. to start a production CL project, so C# it is..
9:03:41
beach
Trying to convince won't work. Showing what you can do, presumable faster than your colleagues might.
9:05:43
marcopersson
Yeah, the problem then becomes "What about when you leave?", the whole finding developers/maintenance spiel
9:06:08
beach
Do your colleagues know that it is impossible to write a C++ program that is both modular and fast?
9:07:45
beach
If they did, they would notice that training people is less costly than the loss of productivity working with inferior tools.
9:13:13
marcopersson
For this project specifically writing it in C# does give the advantage that it becomes a 1st class citizen in the runtime that is the subject of the program
13:21:37
jcowan
I figure that uninterned symbols ("gensyms" for short) have three distinguishing properties: 1) they are never eq to anything else; 2) they are not read-print invariant; 3) they can be freely garbage collected even when interned symbols cannot be.
15:25:04
jcowan
dlowe: That's what I was thinking. So you can approach property 1 as a limit by using ordinary symbols long statistically-random symbol-names instead of gensyms, at the expense of property 2.