freenode/#lisp - IRC Chatlog
Search
1:06:40
equwal
How can I change a regular character like #\f to a read macro without a dispatch character? This way I can call a read macro as if it were a function (fn...)?
1:09:56
no-defun-allowed
(defmacro brainfuck (code) `(lambda () (brainfuck-interpret ,(symbol-name code)))
1:10:21
equwal
I got it working like this: #defmacro/g! name (z) `(let ((,g!y ,z)) (list ,g!y ,g!y))
1:12:07
equwal
It does parentheses by just counting until there is an extra one on the right. I am trying to set it up such that it can be called with (defmacro/g!...) making #\d the macro-character. Unfortunately I can't do it without making it impossible to defun declare, etc.
1:13:09
Bike
putting a reader macro on d means when the reader sees a d, you take over parsing. you can't just do it halfway.
1:14:56
equwal
Well I could do that, but I was hoping to get it semantically the same as the book so I could send it to the production code repo.
1:15:45
Bike
there is no such thing as a fake function. i'm not sure where you got the idea that there was.
1:16:47
equwal
I could get it to work if, for example, I set the reader to activate a reader macro if it reads "DEFMACRO/G!"
1:18:03
Bike
as an example, if you had '(defmacro/g! ...), with your scheme funny things would happen.
1:23:19
no-defun-allowed
all i can suggest is to write a macro that takes the code as an argument, takes the SYMBOL-NAME of the symbol and uninterns it
1:40:58
no-defun-allowed
not a reader macro, just a normal macro which reads in your code as an an argument, eg (brainfuck [+.>])
1:43:11
equwal
I used the brainfuck because I though I was simplifying my question. I don't see why what I want to do should be impossible. I think I can do it if I save the original readtable and access it before reverting and the closing parenthesis.
1:44:56
no-defun-allowed
if you want to do a readtable thing, #f[code goes here] could work better for syntax i think
1:53:42
didi
I never used a read macro, but luv-slides has one that I might try some day: #L(if (oddp _) (* _ _) 0) -> (lambda (_) (if (oddp _) (* _ _) 0))
2:39:07
didi
Argh. Format's call function directive is not too hot; I've to use colons to call functions from packages, even if it's a symbol interned in the same package I'm in.
2:49:49
aeth
Any list/cons processing should directly or indirectly use destructuring-bind unless there's a built-in to handle it directly imo. Probably slows it down a bit but makes sure it is what you think it is.
2:51:09
aeth
(and if you actually don't care about the tail in a destructuring-bind it's not hard to do an ignored &rest rest)
2:52:59
aeth
In this particular case, most alternatives would probably work on NIL because (car nil) is NIL and (cdr nil) is NIL.
4:35:56
fiddlerwoaroof
elderK, equwal: LoL is a bit problematic because it doesn't restrict its macro definitions to things that are standards-compliant.
4:36:19
fiddlerwoaroof
So, in some cases, you might discover that implementations have implemented things in a way that breaks the examples.
4:37:21
fiddlerwoaroof
But, I learned the useful trick of expanding to a MACROLET in situations where one might otherwise try to write a codewalker from it.
8:20:32
beach
IF you know what you are doing, IF you have extreme performance requirements, IF you know that your implementation generates faster code for structs, IF your application is know to spend a significant amount of time accessing object slots, and IF you are willing to live with the semantics of structs, then you should use them.
8:23:48
beach
Also, slot accessors for structs are ordinary functions, and if your implementation is slower on calling a generic function, that will make structs faster as well.
8:25:07
Inline
that all sounds like inviting into structs first, try out a few oop with structs and then later on try to switch onto clos....
8:25:10
beach
Now, like I said yesterday in #clschool, I often see people using structs for better performance, but then they are totally incompetent when it comes to designing efficient data structures and algorithms. It would be much better to do it the other way around.
8:25:35
beach
Inline: Why do you say that? I would think the other way around. Premature optimization and all.
8:26:12
beach
Structs really mess up the development process, so you would want them in the end, if at all.
8:26:57
another-user
beach: i have also implemented example you gave me(optimization without breaking interface) and i was really impressed!
8:27:07
no-defun-allowed
structs are basically the C structs, they're a bunch of values stuck together
8:27:58
no-defun-allowed
a standard-instance has superclasses, subclasses, and all the OOP stuff going for it
8:28:33
beach
Inline: By the way, you can't "switch into CLOS" because CLOS is already present. STRUCTURE-OBJECT and STRUCTURE-CLASS are perfectly good classes.
8:40:19
jcowan
Henry Baker very much preferred structures to classes (maybe still does, I don't know)
8:41:46
jackdaniel
structures conceptually are much simplier, I can imagine why he preferred them in his theoretical works
8:47:03
jackdaniel
I'm certain that everyone talking about classes in Common Lisp means standard-class (and not i.e builtin-class or a metaclass of some kind)
8:47:24
jackdaniel
s/everyone/everyone in above discussion/ I can imagine someone talking about clases in general of course
8:52:42
beach
Inline: So when you say "that all sounds like inviting into structs first", either you don't buy my advice, or else it means that you initially assume that you know what you are doing, that you have extreme performance requirements, that you know that your implementation generates faster code for structs, that your application will spend a significant amount of time accessing object slots, and that you are willing to live with the
8:53:49
pjb
well, one advantage of defstruct is that it's more concise than defclass. (defstruct pt x y) and you're set.
8:54:23
jackdaniel
nb: define-class in ergolib gives you similar concise syntax for standard classes
8:58:43
pjb
The only serious problem you may have with defstruct is that the readers and writers it generates are not (necessarily) generic functions.
9:00:36
no-defun-allowed
the #1 draw for defstruct for me is that it's less typing cause of the implicit accessors, which is really stupid come to think of it
9:01:28
pjb
But classes have so many advantages. You can use change-class, you can have multiple-inheritance, you can introspect the slots with the MOP, you can add slots at run-time…
9:02:14
pjb
But structs can use vector or lists are storage, and you still have inheriting with :include >:-}
9:02:39
jackdaniel
no-defun-allowed: while it is OK to be suspicious about macros which define functions on your behalf I don't know how this is stupid - could you elaborate?
9:03:07
no-defun-allowed
that the only reason to use defstruct early in development is that it's less typing
9:05:02
jackdaniel
that's why we abstract many things with new words: you say "computer", not "an electronical circuit with a program which …"
9:05:13
pjb
Anyways, in an application, you often will write special macros to define entities of your application, that expand into a defclass and more, so you won't have to write all the verbosity of defclass yourself anyways.
9:06:23
no-defun-allowed
yes, maybe a simpler macro that expanded to defclass would be more reasonably
9:11:12
beach
I submitted this idea in #sicl, but there was no reaction: What if the :TYPE option of a slot that mentions a class could result in a slot writer method that specialized on both its parameters?
9:13:01
pjb
Furthermoree, that doesn't prevent the existance of other writers with other classes for the value, so you won't get an error. Also you'd get a missing method error, instead of a type error.
9:13:21
no-defun-allowed
so if you had a :type of FOO in BAR for the slot BAZ it'd generate the equivalent of (defmethod bar-baz ((bar bar) (baz foo)))?
9:15:19
beach
no-defun-allowed: That's the idea, yes, except it would be (defmethod (setf BAZ) ((new-value FOO) (object BAR)) ...)
9:15:52
pjb
beach: actually, the point is that I feel uneasy with it, because I'm not sure there wouldn't be case where the semantics would change. We could know if we had a formal semantic definition of the language, and check the equations…
9:16:04
no-defun-allowed
i like it, sounds good, but i think a second one would also be needed to handle type-errors presumably
9:17:52
no-defun-allowed
strangely enough, both SBCL and CLISP allow me to create an instance of a class where the slot type requirement is violated
9:17:57
pjb
I may have written such setter method by hand, so I'm not entire against the idea. Perhaps it would enter into the generalization category, so it'd be acceptable. It would allow us to write additionnal methods for other classes of value.
9:18:53
no-defun-allowed
i did (defclass a () ((b :initarg :value :type integer))) and (make-instance 'a :value :foo) and it still made the instance
9:20:22
jackdaniel
no-defun-allowed: standard doesn't say, that implementation has to enforce such type, it is just an annotation
9:23:49
jackdaniel
so in that case bahavior will be different if you supply class name as a type and if you supply another type. I wonder how much it could bite a programmer
9:24:34
beach
Good question. That's why I submitted the idea here, so that people could help me think about it.
9:26:40
jackdaniel
I don't know how much code out there depends on type-error being signalled on such setf (given standard does not mandate such error)
9:27:08
jackdaniel
but if there is such code, then handling of such conditions will break inconsistently
9:27:10
pjb
Well, the first difference would be that you'd have a method more specialized than expected. So some program could have other methods, with a more general class, a more specific class or with the same class, that would override the defclass provided method.
9:28:20
pjb
You would need to still provide the method on T, so that user supplied method with a more general class could still call-next-method. They'd be shadowed by your method for values of the correct class, but not for values of superclasses.
9:29:13
pjb
So the question is how many program include such additionnal methods on writers, and whether we accept to break them, or whether we want to continue support the possibility even if it's (almost) never used.
9:30:19
jackdaniel
pjb: I think that it is a non-brainer here: if you break conforming programs by some change it shouldn't be included. your example is a conforming use of the mechanism.
9:31:07
pjb
There's /Users/pjb/quicklisp/local-projects/com/informatimago/pgl/pgl.lisp:2031:(defmethod (setf title) ((title string) (self window))
9:31:38
jackdaniel
so even if no such code exists yet, such change would render sicl being si-not-quite-cl
9:32:15
beach
Well, I won't do it. At least not initially. I need more thoughts and more time to think about the consequences.
9:34:24
pjb
In that case, the slot has only a reader. The writer calls a function that sends message to the remote window managing process.
9:35:23
beach
Anyway, I should supply the :TYPE anyway. The purpose of my suggestion was to make satiation more reasonable. If I have an unspecialized parameter, satiation will fill the call history will all classes in the system. I wanted to avoid that. But I can use the :TYPE information just for satiation instead.
9:36:49
beach
That should be fun, i.e. rewrite satiation to take into account the :TYPE option of the slots.
9:40:50
beach
Satiation is free to do what it wants as long as the semantics are preserved. If it misses something, the only thing that happens is that the generic function will be updated when it is called with a type that satiation missed.
9:41:56
beach
The purpose is to avoid that (say) COMPUTE-DISCRIMINATING-FUNCTION is called with itself as an argument. So the call history of that function needs to include an entry for standard generic functions.
9:42:54
beach
But during bootstrapping, I need to make sure that all the accessors are satiated before I can "tie the knot".
9:46:25
jackdaniel
elderK: three steps of enlightnment: novice uses only single backquote, student uses nested backquotes, master uses only single backquote
9:47:42
elderK
I tried to write my own once-only. I failed. I know what I want to do, and what has to be done. Just not how to actually code it.
9:49:53
makomo
when the CLHS says "expanded", it's referring to the process of reading in the backquote and processing it as a reader macro, i.e. "expanding it into some implementation-defined form"
9:50:14
makomo
once you read in the nested backquote template, *then* it's time to (iteratively) evaluate it
9:51:12
makomo
so when the CLHS says "the innermost backquote should be expanded first", it's referring to the process of converting the reader macro into an implementation-defined form
9:52:39
makomo
(that particular usage of "expand" was the most troublesome thing regarding the CLHS specification of backquote (for me at least), as it's not explained explictily anywhere)
9:53:12
elderK
I was thinking like, `(stuff `(more stuff)) that it meant it would go through `(stuff EXPANDED) then FULL_EXPANSION
9:54:00
pjb
so `(stuff `(more stuff)) = '(stuff '(more stuf)) = (quote (stuff (quote (more stuff))))
9:54:27
makomo
elderK: another note -- if you ever decide to do the expansion yourself (i.e. follow the formal rules in CLHS by hand), i would suggest you do the expansion "iteratively" (in multiple passes)
9:54:46
makomo
elderK: the algorithm of course works recursively, but it's really impossible for a human to keep track of the various "stack frames"
9:55:15
makomo
so you process the expansion in passes (steps), applying the rules until you get rid of the innermost backquote template
9:55:49
pjb
Well, or not. You don't need to resolve all the backquotes. Only the one you're currently evaluating.
9:56:55
jackdaniel
whole construction, but nvm, since elderK understood it's fine, I was not an audience anyway
9:57:29
makomo
jackdaniel: i don't mind clarifying. we were referring to this line in CLHS 2.4.6 " If the backquote syntax is nested, the innermost backquoted form should be expanded first. This means that if several commas occur in a row, the leftmost one belongs to the innermost backquote. "
9:58:03
makomo
"expanded" here means "processed at read-time". it's not referring to the evaluation of the form
9:58:28
jackdaniel
I'm aware how backquote works, I've just pointed out that your explanation was confusing to me
9:59:20
elderK
Like, I get that `(...... `(....)) is expanded into some form by CL, maybe it says (quasiquote ..... `(...)) then (quasiquote .... (quasiquote ...))
10:01:00
makomo
elderK: the expansion proceeds bottom-top (innermost-to-outermost) which is important because that defines the association between a comma and a backquote -- the rightmost comma corresponds to the outermost backquote
10:01:21
makomo
elderK: the filling of the template happens at evaluation. evaluation proceeds top-bottom (outermost-to-innermost)
10:02:24
makomo
to evaluate a backquote template means to interpolate/splice in all the results of forms that have been marked with , or ,@ that *correspond to the outermost backquote*
10:05:17
pjb
So, the problem is that it's difficult to see it step by step, because since backquote is a reader macro, all the levels of backquoting are resolved and transformed in to list expressions when read.
10:07:19
makomo
i couldn't use (eval (eval (eval (eval '````,,,,c4)))) as i would lose the lexical environment (that's the behavior of EVAL) (i.e. EVAL wouldn't see the lexical bindings of the LET)
10:15:26
puchacz
no-defun-allowed: so to have O(n) flatten, I guess I need to write it myself, do I?
10:15:58
no-defun-allowed
If you can make that O(n) without changing data structures, you're a god amongst programmers.
10:16:30
makomo
no-defun-allowed: yeah of course, but it's easier to read (not to copy paste though) :-)
10:16:39
no-defun-allowed
If you can get the last cons in O(1) and don't mind destructively modifying the inputs, you can make it O(n).
10:16:49
makomo
no-defun-allowed: but it makes it clearer to see what i was trying to say (rather than the person on the other side having to untangle the one liner)
10:21:18
elderK
no-defun-allowed: The many-lines-of-code thing is for me, because I don't run IRC in Emacs.
10:21:45
elderK
Because I had to make an Emacs port, which requires libraries that refuse to cooperate.
10:22:50
elderK
One problem is that libjpeg-turbo is built using CMake, which of course, doesn't install .la files. Where as libgd is built with autotools, and expects .la for llibjpeg. Which doesn't exist. So it dies.
10:23:31
elderK
Another alternative is to replace the distribution's libgd with my own version, that uses cmake instead of autotools. But then I'm concerned what other packages it will break.
10:23:59
elderK
It's a real cluster@!#$. Especially since some projects have /two/ build systems. And they don't install the same stuff.
10:26:07
elderK
It's like, why not standardize completely around pkg-config? That could help but CMake doesn't want to. And pkg-config is useless on Windows, for the most part.
10:28:21
elderK
makomo: How do you find this answer? https://stackoverflow.com/questions/18008099/chls-innermost-backquoted-form-should-be-expanded-first-meaning
10:29:03
elderK
My urxvt setup is pretty stock - that may be why things like URIs and stuff aren't properly highlighted. At least, not across multiple terminal lines.
10:29:23
makomo
elderK: that's one of the backquote-related SO Q&As i have bookmarked :-), but only for "archiving" purposes (i.e. i didn't want to link it because i forgot what explanation was offered there)
10:29:52
makomo
elderK: i use the mouse to select the lines, copy and paste them into emacs and then trim the username/timestamp prefixes
10:34:32
makomo
elderK: that answer is okay i think, but you have to follow the poster's terminology
10:35:02
makomo
"... and that for a doubly nested backquote form, I should reinterpret the innermost backquote forms before reinterpreting the outermost backquote form."
10:41:44
makomo
see how the backquote syntax is expanded into some implementation-defined form? that's what "expansion" is referring to
10:44:05
elderK
Right, so thinking the Schemey way: ````,,,,c1 == (quasiquote (quasiquote (quasiquote (quasiquote (unquote (unquote (unquote (unquote c1)))))))) no?
10:44:11
makomo
(let ((*print-pretty nil)) <form>) won't work at the REPL as the printing of the result happens *after* <form> is evaluated (i.e. outside the LET block, somewhere within SLIME/SWANK)
10:49:05
makomo
it might seem strange, but it makes sense when you think of it as "ladders" (i've heard the term "ladder algorithm" used somewhere)
10:51:45
pjb
elderK: why don't you just read the rules in clhs? They're very clear on how to interpret backquote…
10:52:43
makomo
elderK: using the SO terminology from that answers, CLHS uses an "equivalency description" -- it describes a possible set of forms that backquote might expand into and derives the evaluation semantics from that
10:53:02
makomo
that's all fine, but it's useful to know the "replacement description" as well -- an intuitive way to think about "canceling" the various backquote/comma pairs
10:53:53
makomo
the "replacement description" is simple for simple cases, but needs to be made more complicated (or special cased somewhere) for cases like ,@,@ or ,,@, etc.
10:56:55
jackdaniel
elderK: I think that this topic requires silent contemplation with a single source of information (in this case clhs) instead of multiple ones
10:57:30
jackdaniel
it is easy to get confused, ie some people put their "intuitive" interpretation into play which may be incorrect (or may not match your mental model)
10:57:30
elderK
jackdaniel: I would ordinarily agree. But there were parts in the CLHS spec I was not sure how to... apply. Seeing that post on SO, clarifies that.
10:57:41
elderK
My goal now is to get a few nested macros, and expand them, according to CLHs rules.
10:59:44
makomo
jackdaniel: "silent contemplation" is the part i agree with, but i think you really do need multiple source of information (either to see where they went wrong, or to clarify some points)
11:00:42
jackdaniel
I think that you confuse him instead of helping (and I judge it by the fact, that I was away for more than an hour and you still talk about the same thing)
11:01:46
jackdaniel
I'm known for being unfair, sometimes it happens though that being unfair doesn't mean "wrong"
11:02:11
elderK
Maybe this really is something that's simple. Just, it's not clicking for me atm. But, I am definitely closer now.
11:02:12
jackdaniel
also being satisfied with help and getting grasp of something are two different things as well
11:05:11
jackdaniel
http://ep.yimg.com/ty/cdn/paulgraham/onlisp.pdf here you have nice explanation in english about backquote
11:10:30
makomo
elderK: 5 examples in total, don't get scared :-) http://plaster.tymoon.eu/view/1008#1008
11:11:36
jackdaniel
so called ,@,@ "idiom" is incorrect in light of clhs (it relies on some intuition shared by some)
11:12:08
jackdaniel
no you didn't, one of key arguments is that it is "natural extrapolation" from the spec
11:12:21
jackdaniel
and I was not interested in discussing it, just given you resources you may follow
11:12:26
makomo
jackdaniel: it's not an extrapolation, it's ridigly and mechanicaly following the rules
11:13:56
makomo
jackdaniel: when you get the time, take a look at the expansion i did by hand and tell me what step is wrong
11:14:37
makomo
right, but you're not providing any proof that it is undefined/incorrect as per the CLHS rules
11:14:56
jackdaniel
I have more interesting thigns to do than proving you wrong. I did point you to the references which discuss it
11:15:33
makomo
but none of the commenters there use the formal rules to prove that ,@,@ is undefined, which is why i did it by myself
11:15:34
jackdaniel
if this is not enough for you, then please consider practical argument for not spreading this incorrect information: it doesn't work on all CL implementations
11:16:03
makomo
jackdaniel: that's an implementation's problem, is it not? pjb actually reported to CCL that ,@,@ doesn't work
11:16:30
jackdaniel
no, this is a community problem that you spread a dubious syntax and you label it "idiomatic"
11:19:03
jackdaniel
makomo: let's make a wager: I prove you wrong, you solve one ECL issue I point you to, I'm not able to, I'll solve another CL foss issue you point me to
11:19:14
makomo
jackdaniel: just saying that it's incorrect and leaving isn't helpful... we should sit down and discuss it once and for all some time :-)
11:22:08
makomo
but a necessary condition for the proof is that it has to be done using the formal rules provided by the CLHS, ok?
11:43:58
elderK
makomo: You treat `'something like ''something. I.e The 'something as a "basic object." Would I be incorrect to expand that further into, `(quote something) ?
11:44:53
makomo
elderK: that would be correct and was something i tried once, but found it too verbose
11:47:00
void_pointer
elderK: reader macros are expanded when the file is read into lisp, before being evaluated, compiled, or really anything else for that matter
11:47:39
pjb
elderK: cf chapter 2. The lisp reader reads the character #\` then it looks it up in the *readtable* and find a reader macro for it. It calls the reader macro.
11:48:10
pjb
elderK: the reader-macro for ` will read the following expressions, parsing the , and ,@ and substiting the whole by a lisp form to build the equivalent list.
11:48:33
pjb
(let ((bar 42)) '`(foo ,bar)) #| --> (list* 'foo (list bar)) |# <-- This is what is read.
11:49:06
pjb
(let ((bar 42)) (read-from-string "`(foo ,bar)")) #| --> (list* 'foo (list bar)) ; 11 |#
11:49:18
jackdaniel
makomo: it mostly is, first we have to point out issues (to avoid situation, where the winner side picks an unreasonable issue)
11:50:20
makomo
jackdaniel: well, it's not like either of us is *required* to do what the other says, so it's mostly a matter of pride/honor
11:50:57
makomo
i was going to trust you to pick out something normal (it's not like i ever worked on either ECL or McCLIM, so it would be a wild ride anyway)
11:51:22
jackdaniel
so please send me your proof that ,@,@ is correct (expansion you have mentioned which follows rules) and the issue you have picked when you have it
11:54:26
jackdaniel
you need to verify, if structure layout is the same and provide two restarts if it isn't
11:55:06
jackdaniel
most effort on your side would be navigating through ecl source code which codebase you are not familiar with
11:55:56
makomo
jackdaniel: ok, my issue is (half-jokingly) https://web.archive.org/web/20130622010232/http://sourceforge.net/p/ecls/bugs/251/ :-)
11:56:51
jackdaniel
OK, but I don't promise that I'll solve it before next release, it will be pretty involving change of the reader which is written in most part in C
11:57:33
jackdaniel
I'll let you know when I get to the doulbe splice (I first need to finish current PR on McCLIM)
11:58:55
makomo
just the individual steps, i haven't documented which particular rule was used, but the steps are small enough so it should be easy to see
12:18:42
elderK
makomo: How long did it take you before you could follow this process in your head at lightspeed?
12:19:05
elderK
I've been doing the expansions by hand, on my own, then comparing against your notes.
12:22:53
makomo
Steele mentions it in cltl2 as well (and he has a very nice discussion of backquote there -- that's another resource i would suggest)