libera/#lisp - IRC Chatlog
Search
16:58:38
mrcom
Lotttts of links to interesting Lisp stuff, such as http://lispm.de/docs/Publications/UI/ which links to Lisp UI papers, e.g. "Allegro CL CLIM 2.2.2 User Guide".
17:00:57
mrcom
Then there's the "Links" page, which includes "IGOR - A microprogrammed LISP machine :: Overview :: OpenCores" at https://opencores.org/projects/igor [lispdm.de site points to old opencores.COM]
17:16:44
mrcom
NOTE: lispm.de home page says 'this is a tiny server' and "don't try to copy the whole site". Sometime between 2022-02-23 and 2022-02-28 he started returning an "Access Forbidden" page to the Wayback machine.
17:17:53
mrcom
So we should probably be careful about posting links on something that would get it hugged to death.
17:24:46
thymage
Where decl is defined by: https://github.com/kiselgra/c-mera/blob/master/src/c/syntax.lisp
17:25:16
thymage
I just would like to take the (decl part off of each list and then slap a single one on at the end.
17:32:43
jackdaniel
if you want to "take the decl part out", then (defvar v3 (decls ((float a) (int c))))
17:33:06
jackdaniel
mixing results of macroexpansion with concatenate won't work the way you desire them to
17:37:17
mrcom
Gotcha. Reason I asked is that it appears DECL is creating a structure which the rest of the C-Mera understands. Don't know how C-Mera expects structs or unions (not clear which is meant) to be declared.
17:38:23
mrcom
(C-Mera is a "source-to-source compiler that utilizes Lisp's marcro system for meta programming of C-like languages."
17:43:48
mrcom
thymage: I think DECL is a macro, not a function, and it is evaluating its arguments.
17:46:23
mrcom
This means it won't be simple to compute arguments to it. `(defvar v3 (concatenate ...)' doesn't compute the concatenation of v1 and v2, and then pass that to DECL.
17:48:28
mrcom
DECL sees, I believe, '(concatenate v1 v2); i.e. a list of three symbols CONCATENATE, V1, and V2.
17:49:33
mrcom
It's going to try to interpret that using it's c-like syntax; CONCATENATE would be a variable name, V1 would be a type, and V2 would be some kind of assignment or modifier.
17:51:58
mrcom
Yes. DECL is a macro; the code it generates returns some kind of internal C-Mera structure which lets the rest of the C-Mera macros know what to do.
17:54:46
jackdaniel
I see what you mean, you refer imaginary form that has never appeared on this channel, like (defvar v3 (decl (concatenate v1 v2)))
17:56:11
thymage
jackdaniel, Well, the whole reason I want to concatenate two lists is because I want to be able to make combinations of decl's
17:58:50
thymage
I was able to get it to run correctly by just putting (struct z v1 v2) instead of concatenating into v3 and doing (struct z v3)
17:58:52
mrcom
The biggest one is that DECL *only applies inside a function declaration. I don't see a way to declare a global (special) variable using c-ish syntax.
18:00:46
mrcom
You trying to globaly declare boilerpate to include in function? E.G., declare common sets of variables to include in a function?
18:05:16
thymage
So, if (struct z v1 v2) works, how can I write a macro around that in order to pass an arbitrary set of things that will get spliced in. So, after my defmacro, it would see the correct sequence if I call (declare-struct (v1 v2))
18:13:15
mrcom
So thyimage: Looks like you will need to create boilerplate which is included whereever you reference the structure.
18:24:19
mrcom
Some macro is going to need to evaluate its arguments. Let's make a general TYPEDEF macro.
18:26:01
thymage
Why are you still going on about typedef. I literally have not looked at and may not ever need typedef. I don't want to typedef.
18:26:55
mrcom
You want to globally declare a type which is then usable inside a (function foo ((MY-GLOBALLY-DEFINED-TYPE x)) ...), right?
18:27:19
thymage
I'm not working on that right now. I want to be able to compute all different kinds of structs using the macro language.
18:28:54
mrcom
Got it. Different combinations. Are you intending to use a particular combination in more than one (function...) block?
18:29:12
thymage
I am not really knowing whether it has to be in any (function. Originally, I thought that the (decl had to be taken off of each variable before their being concatenated and then put back on.
18:30:07
thymage
Mrcom I haven't thought that far ahead. Basically, after generating combinations I will then generate some C functions that use each of the different structs.
18:30:57
mrcom
You want to create a structure type-ish-thingy, and then include that thingy in various functions.
18:34:46
mrcom
Before you get that far, how do you use DECLARE-STRUCT? It appears you need to include it in each (function ...).
18:36:05
thymage
I could have the struct declarations at the C top level. So, I just think the permutation computation needs to be able to pass each possible set of arguments to the declare-struct macro
18:36:38
mrcom
In other words, does this work in C-Mera: "(struct z ((a float) (b int))) (function ((foo (struct z))) ...)"
18:40:15
thymage
And I just want to know how I define the macro correctly so I can compute v3. Please
18:44:12
thymage
I think my question references c-mera because that's what it is in terms of. But maybe it doesn't have to involve that.
18:45:09
thymage
Suppose instead that I just want to know that for a given macro, I can compute any set of arguments. (v1 v2 ... vn)
18:45:36
thymage
But, what it calls should receive that set as that set. So, you can see that (declare-struct (v1 v2)) runs just fine.
18:45:58
mrcom
What you're asking for is known as a macro that accepts a list of arguments and evaluates them.
18:49:35
thymage
This is like my second day of using lisp. I don't like the books that are out there so far.
18:50:52
mrcom
But be warned, macros are one of the more hair-pulling bits of Common Lisp, and macros that evaluate arguments even more so :)
18:55:07
thymage
So, above the macro call I have defvar v1... and so on. And I pass v1 or whatever to the macro
18:59:21
dlowe
if you're emitting code from a macro, why on earth would you use eval? Just emit the code that does what you want!
19:04:29
mrcom
(defvar v1 '(a float)) (defvar v2 '(b int)) (defmacro declare-struct (&rest args) `(struct ,@(mapcar #'eval args)))
19:05:06
pjb
This cannot work: you mare mixing things defined at run-time (the variables) and things that work at compilation-time (the macros).
19:07:54
thymage
Actually, what if I define a macro that returns another macro. And I will just incrementally build the struct until I close it...
19:08:44
mrcom
pbj: Important thing is that it will be evaluated and defined before the following... oh.
19:10:28
mrcom
As pjb pointed out, defvar isn't the right thing; it evaluates at the wrong time, after the (function ...) macros would be processed.
19:10:31
thymage
Oh that was just an example. Whether v3 is supported by defvar or not, that is fine with me, as long as I can pass it to the macro
19:11:04
pjb
and then (my-type-language (define v1 (a float)) (define v2 (b int)) (define v (structure v1 v2)))
19:11:27
pjb
If you wrap all your type expressions inside your type-language macro, you can do whatever you want.
19:16:38
mrcom
thymage: What pjb was reminding me of was the evaluation/compile cycle timing in Common Lisp.
19:16:59
thymage
mrcom, but these aren't constants?? I mean, sure it needs to work with the macro expansion, but v3 will change
19:20:32
thymage
I mean, sure it may compile or it may run. But I'm not doing anything but printing the results.
19:21:16
mrcom
One thing to consider is that each variation of the structure means you'll have a variation in the _function_, too.
19:21:35
thymage
ergh. I'm pretty sure there is a way to compute a list of arguments and splice the list contents so that list l passed to define-struct is seen as define-struct <list contents>
19:22:41
mrcom
So if you're trying something like "for x in int, uint, float, double; for y in float, double; typedef z (a x; b y); function foo (w z)..."
19:22:41
pjb
Things that need to be done at compilation time, like splicing lists of arguments must be done in macros.
19:23:22
thymage
mrcom, that's ok, I'll make the many variations of foo after I get structs all the way down
19:23:29
pjb
(defmacro my-type-language (&body expressions) … (interpret expressions) … (generate-type-expression … argument-list …))
19:24:38
pjb
As long as those regular functions are defined in the compilation environment, using either eval-when :compile-toplevel, or by putting them in separate files compiled and loaded before your compile the files defining and using the macro.
19:25:19
pjb
`(declare-struct ,@(list 'v1 'v2)) --> (declare-struct v1 v2) then why don't you just write: (declare-struct v1 v2) ???
19:26:21
mrcom
pbj: From what I can tell, it establishes a compile-time context using a FUNCTION macro (yeah, wonderful name collision).
19:26:54
mrcom
FUNCTION is like LOOP. It evaluates its argument s-expressions and spits out C code as a result.
19:28:11
mrcom
The s-expression syntax and semantics are already determined. He's trying to spoon-feed it some global type definitions.
19:38:22
mrcom
thymage: It's using something called reader macros. These happen even before compile-time, and before DEFCONSTANT computes its value.
19:48:37
mrcom
If defining an outside macro is ok, then we should be the equivalent of (function foo () -> int (decl ((y int = 0))) (return y)))
19:50:59
mrcom
Oh. Just saw that the c-mera reader is optional for prototyping, and switch back to cl-reader. That sounds like good news!
20:00:33
thymage
But for the `(,@lst) part, is there any way that I could do something without the () around the ,@? Like, I can't do `,@
20:03:37
thymage
The one you already see is a good example. The result should be identical to what it does as it is written, but no parentheses
20:05:10
thymage
I don't think I can do it with the open syntax like that because I don't know how to compute a unique list there.
20:07:00
thymage
So, if you write it like that, it stays written that way. But then you can put a computed list there.
20:11:45
thymage
Somehow, the type of the argument is different if you do (declare-struct v1 v2) vs the expansions we are considering
20:12:43
thymage
So, if you give the argument (list v1 v2) then it sees one argument that is a list, all of the arguments being in another argument
20:13:06
thymage
That's different. (declare-struct (v1 v2)) is different than (declare-struct v1 v2)
20:13:43
thymage
Right. A list is the result. But then a list is being passed to the original declare-struct
20:15:05
mrcom
(declare-struct '(v1 v2)) == (declare-struct (quote v1 v2)) => create a list of two elements, symbols named v1 and v2.
20:17:06
thymage
I'm trying to compute all of the arguments given to declare-struct. I cannot do with manually writing v1 v2 v3 as arguments to declare-struct.
20:17:17
mrcom
If you (defmacro declare-struct (x)), you're saying that declare-struct expects exactly one argument.
20:18:59
mrcom
Then to create a struct with multiple elements, you would need to (defconstant [or whatever] v3 (define-struct (list v1 v2)))
20:19:42
mrcom
If you define the macro as (defmacro define-struct (&rest args)) then you're saying that args is a list of 0 or more elements.
20:21:52
mrcom
The first definition of define-struct requires you to explicitly enclose multiple arguments in a list, and then explicitly peel them out in the macro body.
20:23:56
mrcom
The first method can have some advantages. It allows you include other types of parameters, especially keywords.
20:27:07
thymage
Crap dude, for the life of me I can't get the instance where I make a list to work.
20:30:00
mrcom
Oh... you need the &rest. Otherwise you have a single argument. (def-struct v1 v2) can't work, because that's two arguments.
20:30:30
mrcom
(If it looks like it's working then something is wrong. Maybe an old definition didn't get cleaned up.)
20:32:17
thymage
I'm getting the variable QUOTE is unbound when I do it that way. When I switch to (list 'v1 'v2) as argument, it then says the variable list is unbound.
20:34:04
mrcom
(declare-struct '(list v1 v2)) == (declare-struct (quote 'list 'v1 'v2)). The first element of the argument is the symbol quote (which does not have a variable value).
20:35:54
mrcom
(declare-struct (list 'v1 'v2)); the first element is the symbol "list", which doesn't have a variable value.
20:39:34
mrcom
(Notice no "@". "@" means "splice it into the enclosing list", and there's no outer list here.)
20:42:57
thymage
I'm getting the variable QUOTE is unbound when I do it that way. When I switch to (list 'v1 'v2) as argument, it then says the variable list is unbound.
20:43:19
thymage
Sorry I accidentally sent the above "i'm getting... messsage" when I hit up and then enter
20:45:02
mrcom
If you don't use the "&rest" before args, and explicitly pass a list, then mapcar evaluates that list item by item. The first item will be "quote" or "list" depending on exactly what you did.
20:46:56
mrcom
You want to think Lispish--except for (setxxx) functions, functions just return a value. They don't put it anywhere. That's the (setfxxx)-type functions's jobs.
20:51:54
mrcom
Think I steered you a bit wrong. This is a macro which is evaluating its arguments. So lists don't need to be quoted, and don't need to be include "list".
20:55:03
thymage
Oh wait, I don't know that I need the macroexpand anymore. I moved away from trying to do expand-args
21:03:33
mrcom
dlowe: No, we're defining s-expressions with a specific format, for feeding to a macro that evaluates its arguments ala LOOP.
21:06:04
mrcom
EVAL is needed because the end-use macro doesn't actually EVAL, so we can't just "(defmacro x (args) `(mapcar blah args)"
21:08:05
mrcom
And he wants to compose the end-use s-expression using some kind of symboled sub-expressions.
21:10:37
mfiano
Unless I'm completely misunderstanding, you don't have to use EVAL for that. I would strongly recommend against it.
21:12:55
mfiano
You can always store a thunk to be COMPILE'd, and even that is rarely ever needed over just breaking it up into functions, unless you are expanding macros at runtime.
21:15:19
mfiano
Macros are for syntactic abstractions and evaluation control. Which of these do this fall into?
21:16:23
mrcom
The library is using macros to transpile s-expressions to C code. We're way outside polite usage :)
21:16:51
thymage
So, I must defmacro my way to success. The macro gives a lot of errors and we would like to have the list be computed.
21:16:53
mfiano
That sounds like the job for a function with a light syntactical abstraction over the top
21:19:49
mrcom
What mfiano, and others, are objecting to is a good-practices and code-stink issue for Lisp.
21:20:42
mrcom
In Common Lisp you very rarely, if ever, do the equivalent of run-time syntax evaluation. That includes string interpolation.
21:22:03
mrcom
Lisp functions take input arguments, including lists and s-expressions, and return new lists.
21:24:19
mrcom
The really Lisp way to do this would be for a "to-c" function to take a tree of declarations and expression lists and write it to a stream.
21:24:51
mrcom
Instead it does it like LOOP does; creates a new syntax and embeds it in the rest of the code.
21:28:59
mrcom
We want "(defconstant v1 '(a int)) (defconstant v2 '(b float)) (defconstant v3 (declare-struct (v1 v2))"
21:31:14
thymage
I don't want to define variables as the result of declare-struct, I want to pass declare-struct an computed list
21:46:01
thymage
mrcom, The way I did it was to soft link it to the local projects. I couldn't find it in any of the ultralisp or quicklisp repos. Maybe there's another one that I don't know about.
21:53:55
thymage
RUN git clone https://github.com/kiselgra/c-mera.git ~/quicklisp/local-projects/c-mera
0:33:03
mrcom
thymage: Yeah, I'm playing with it now. (Turns out ultralisp was seeing the same load/compile error as quicklisp, it just ignored it.)
0:53:01
dlowe
remember - if you have a function that generates code, it is super easy to convert it to a macro.
0:53:49
dlowe
so often, even if you are writing a macro, it can be useful to start with a function first.
1:13:54
thymage
Ah ok. I got to where I could pass a list to define-struct but I am getting parentheses in my output
1:14:44
mrcom
This thing is just a simple re-formatter. No connections between (struct x ...) and any references to x.
1:17:41
thymage
I moved the macro use into a wrapping function call so that I could move the parentheses and backtick out of the function body
1:18:29
mrcom
That will probably make it easier for your master plan, too, where you loop over types or whatever.
1:19:14
mrcom
What I can't figure out is how to reference struct fields. (return z.x) gets translated to "RETURN Z_X;".
1:19:59
thymage
Yeah, at some points I'm like maybe it just even makes sense to use strings. I have to for some of the type names. I think I need to basically make a naming scheme.
1:20:19
mrcom
I mean, they're doing it somehow. There's test cases for struct forward definitions, and c++ output.
1:22:32
thymage
Ah ok. Hmm, well I'm not too sure. I suppose it's feasible to extend the syntax and make a PR.
1:22:57
thymage
And I was noticing that about the formatting, because it seemed like typos would make it into the output.
1:28:55
mrcom
Yeah, there's very little syntax checking. It was happy with "(decl (((struct x) z)))", which returnsed "struct x; z;".
1:33:45
bougyman
I mean, it supports syntax goodies for hundreds of languages. I assume that's written in lisp.
1:34:14
thymage
Yeah, lisp makes it really easy to extend the syntax right from the get go in the language anyway
1:49:37
mrcom
No, nothing working yet. The good news is that you can define and external macro and expand it inside (struct ...).
1:54:20
thymage
Alright... one other plan. What if, instead of trying to pass all of the arguments in at once, actually that the struct is built by iterating over the list
1:54:59
thymage
So that, at all points, you still have access to continue to add to the grammar before you interpret it.
1:56:58
mrcom
At some point you'll still need to invoke (struct ...) and (function ...) with generated stuff.
2:04:52
thymage
I know. I just mean, can't I syntactically expand something and then evaluate it afterward
2:07:42
mrcom
The two-fold problem is a) finding some way of invoking (struct...), (function...), etc. with stuff it likes. and b)
2:10:15
mrcom
I think the c-mera folks had that same problem themselves. You'll notice that calling (simple-print) and running it through cm produce two very different things.
2:16:02
mrcom
thymage: First you create a .lisp file, such as my file xx.lisp: https://plaster.tymoon.eu/view/3259#3259
2:39:43
mrcom
thymage: Its easier to wrap something around (struct) than to try to shove something into it.