freenode/lisp - IRC Chatlog
Search
5:02:35
elderK
beach: Is there a place that details the method combination types? CLHS tells me about +, and, progn, etc. But there doesn't seem to be a page that actually describes how these combinations function.
5:03:43
beach
Oh, those are trivial. The effective method is just (<operator> method1 method2 .... methodn)
5:05:44
specbot
Built-in Method Combination Types: http://www.lispworks.com/reference/HyperSpec/Body/07_ffd.htm
5:10:41
elderK
Thanks beach. I was reading that last night but got kind of confused. I'll give it a another shot.
6:36:02
fiddlerwoaroof
Anyways, depending on how much information you want elderK, Didier Verna has a recent paper on method combinations
6:37:28
beach
He defines a different mechanism, called "method combinators". But he doesn't really provide a solution to the enigmas of the AMOP and the Common Lisp HyperSpec as to how to define method combinations.
6:38:36
beach
However, I figured out how to do it in the context of SICL, and the solution provides a behavior that is consistent with both the AMOP and the Common Lisp HyperSpec, and it doesn't have the strangeness of the PCL solution.
6:39:23
beach
So, Didier and I are going to write a joint paper about it, and submit it to ELS 2019.
6:40:08
beach
I mean, what would you do with this: (defclass t () () (:metaclass built-in-class)) outside SICL?
6:40:36
fiddlerwoaroof
I was thinking more of using it to get predictable MOP behavior across implementations
6:40:55
beach
fiddlerwoaroof: Yes, they are, during bootstrapping, because I use first-class global environments to make such definitions operational.
6:41:30
beach
I don't see how you can reasonably redefine any native MOP classes in any implementation.
6:43:13
beach
The minute I do, I lose all my nice tools in a more comfortable environment than UNIX.
6:43:38
beach
So the current plan is to create a fairly complete SICL system inside a host Common Lisp implementation and debug most of the code like that first.
6:44:17
fiddlerwoaroof
So, can I do something like load SICL in a host lisp and then dump an image that runs a sicl toplevel?
6:44:50
no-defun-allowed
i know some assembler but after you run out of registers then what do you do? how do you juggle between regs and the stack/heap?
6:45:06
beach
fiddlerwoaroof: I suppose that would be possible fairly soon, but I hadn't considered that.
6:45:53
beach
no-defun-allowed: Yes, you implement a register allocator that decides where to put lexical variables at various points in time. Typically the stack frame is used as backing memory.
6:46:02
loke`
(SBCL specific answer is acceptable) If I build a standalong application by dumping it, and then it's later started the source files have moved. Is there a way for me to tell the Lisp runtime what the new source location is?
6:46:58
fiddlerwoaroof
At least, that's what I generally do: open the .asd in Emacs, C-c C-k + then (ql:quickload :my-system)
6:47:22
loke`
(the application is very large, constiging of all of Maxima as well as McCLIM, so loading the asd is not fast)
6:47:45
loke`
I'm trying to package it up into a single directory that can be launched from anywhere
6:47:50
fiddlerwoaroof
Maybe a bit, you might be able to update ASDF's notion of where the system lives some other way
6:48:58
fiddlerwoaroof
So, I just went through a bunch of work to package a smallish app as a redistributable executable
6:49:19
fiddlerwoaroof
Here's the CircleCI build setup: https://github.com/fiddlerwoaroof/daydreamer/blob/master/.circleci/config.yml
6:49:56
fiddlerwoaroof
With minor tweaks you can make CFFI statically link all the ffi dependencies into the image.
6:50:24
fiddlerwoaroof
Although if you have non-source assets, I suppose that won't work very well.... maybe logical pathnames or a configuration prompt would help in that case?
6:52:30
fiddlerwoaroof
If you use cloudformation, you should be able to download a binary of that from the github releases and run ./daydreamer -s to get a list of all your CF stacks
6:56:52
fiddlerwoaroof
loke`: this might work, https://common-lisp.net/project/asdf/asdf.html#Using-logical-pathnames-1
6:58:15
fiddlerwoaroof
That is, adjusting your system definition to use logical pathnames and then figuring out how to set it up before running the app. That might also be a huge can of worms, but this seems to be the sort of thing they were meant to solve.
7:38:53
beach
loke`: What if you just pre-loaded all files that Maxima might need (except user defined files of course)?
8:40:37
fiddlerwoaroof
Has anyone ever had the issue where the slime documentation for the current form disappears
8:59:18
jdz
fiddlerwoaroof: the autodoc thing is quite flaky for me, i sometimes type extra spaces and a backspace to get it back.
9:00:03
jackdaniel
it also doesn't work if some form is being evaluated in repl (so there is no prompt)
9:00:46
jackdaniel
(so if something runs longer than a few seconds, you may want to start it in a separate thread)
10:55:43
elderK
Guys, I'm a little confused by the "Sorting the applicable methods by precedence order" part of CLHS. It states that if two parameter specifiers are of the type like, (foo (eql something)), that they must agree.
10:56:33
elderK
But, I've seen examples in PCL where there are methods that are like, (defmethod something ((type (eql whatever) stuff...) body....0
11:03:54
elderK
Couldn't you have a method that specialize on one parameter, and then has an eql on the other?
11:04:37
shka_
like, for instance (defmethod something ((instance some-class) (operation (eql :some-operation)))
11:05:22
elderK
Okay, but if I had say, (defmethod something ((instance some-class) (operation (eql :op-a))) and (defmethod something ((instance some-class) (operation (eql :op-b))) wouldn't that violate http://clhs.lisp.se/Body/07_ffab.htm
11:08:04
beach
elderK: The APPLICABLE methods are sorted like that. For a particular list of arguments there can not be two methods that EQL specialize on the same parameter but with different objects that are simultaneously applicable.
11:09:18
beach
elderK: Notice the difference between "all methods of a generic function" and "the subset of those methods that are applicable for a particular list of arguments".
11:09:19
pjb
Basically, EQL specifiers filter out the arguments that are not eql to the specified value. This is a string filter…
11:09:30
elderK
It is /applicable/. I.e. We're selecting one method out of a ton, not a set of them. So, once we get to the (eql ...), of course they would have to agree, to be the same applicable method. Right?
11:10:13
beach
elderK: But not more than one with a particular EQL specializer on the same parameter.
11:10:47
beach
elderK: There can be other methods that specialize on classes and there can be auxiliary methods that specialize the same way as primary methods.
11:11:13
pjb
(defgeneric foo (a b) (:method ((a integer) (b (eql 24))) 1) (:method ((a integer) (b (eql 42))) 2) (:method ((a string) (b (eql 42))) 3)) (foo 2 24) #| --> 1 |# (foo 33 42) #| --> 2 |# (foo "two" 42) #| --> 3 |#
11:12:54
elderK
pjb: I appreciate your help too, and I get that's what eql does there. But, I'm still confused by the wording of CLHS entry linked.
11:14:40
elderK
I.e. The things that have an eql specifier, and don't match your call,l will be pruned at the start say. Then it'll be ordered as specified.
11:15:08
pjb
I would have had to add a (:method ((a t) (b (eql 42))) 4) so that with b = 42 and a =33, you would have 2 applicable methods (:method ((a integer) (b (eql 42))) 2) and (:method ((a t) (b (eql 42))) 4).
11:16:05
elderK
I think I get it now. I'm just not sure how to say it back, word it back, that sounds sane :P
11:16:50
elderK
Yup, exactly. so, that narrows down the "set of possible applicable methods" right away, right. Then, you order them left-to-right (unless otherwise specified), as the CLHS states.
11:17:56
shka_
there is bunch of other things like :around but the gist of it is: order using left-to-right rule
11:18:09
elderK
So, it goes LTR (unless RTL is specified), comparing the parameter specializers. If it's a class, the one that is earliest in the CPL winds up having precedence over the other. So, if I have (a some-class) and (a t), the (a some-class) method would be more specific.
11:30:22
elderK
shka_: Can you recommend any other resources that can help me learn to like, do OO the CLOS way?
11:36:36
elderK
shka_: Was the blog you linked to, yours? I hit that a few days ago and read through it :) I look forward to seeing more posts.
11:38:08
jmercouris
so basically to achieve what I want to do I have to something like (defun asdf (a &optional (b nil))) and then within the body (unless b (some calculations to set b))?
11:38:09
shka_
jmercouris: but asdf is complicated and from what i understand, it is allowed to cache
11:41:23
jmercouris
I want a funciton to act on the currently active-minibuffer (which is a function call to determine what is the active buffer), UNLESS the user specifies a different buffer to pass in
11:42:21
Xach
jmercouris: i don't know exactly what you expect, but it is a common thing in common lisp
11:43:38
elderK
The init-form of the optional will be evaluated each time the function is called, unless you provide an actual parameter fofr it.
11:43:42
jmercouris
(defun qwerty (&optional (buffer (active-buffer (window-active *interface*)))) ...)
11:44:00
jmercouris
I expect that buffer will be the result of (active-buffer (window-active *interface*)) unless otherwise specified
11:44:09
elderK
So, (active-buffer ....) will be evaluated if you provide no actual parameter for buffer.
11:44:50
Xach
I use ((:credentials *credentials*) *credentials*) in reality, that establishes a new *credentials* for the dynamic extent of the call
11:46:08
elderK
jmercouris: There, it's not a function - it's just the name. :credentials is the say, keyword name - what you'd use when calling. But in the function itself, *credentials* is the name bound to the actual value passed.
11:46:48
Xach
I do often defun functions named by keywords, but only for local utilities in the repl.
11:48:07
jmercouris
Xach: interesting, is there a reason why you use a ":"? just as an informal convention?
11:48:29
Xach
jmercouris: so i can write it the same short way no matter what the current package is.
12:01:34
elderK
Guys, in what cases is it sane to have it like, where an around method has no further methods to call? Like, it seems weird to imagine a situation where you call some GF that has no applicable primary method, but several around methods may.. work.
12:04:43
elderK
So I wonder why you'd bother checking next-method-p inside an around method, if the case where next-method-p returns false cannot ever happen for it?
12:11:32
elderK
Arounds, in MS order. Then BEFOREs, in MS order. Then the primary - potentially going to LS, if call-next-method is used. Then the AFTERs, LS to MS.
12:12:24
elderK
I would have thought the befores would have executed in LS->MS order, the afters in MS->LS.
12:13:22
pjb
elderK: https://cliki.net/CLOS https://www.amazon.com/Object-Oriented-Programming-CLOS-Perspective-Press/dp/0262661756/ref=sr_1_1?s=books&ie=UTF8&qid=1542197539&sr=1-1&keywords=CLOS https://www.amazon.com/Art-Metaobject-Protocol-Gregor-Kiczales/dp/0262610744/sr=8-1/qid=1165935734/ref=sr_1_1/102-8089847-9687308?ie=UTF8&s=books
12:13:23
pjb
https://www.amazon.com/Understanding-CLOS-Common-Lawless-1991-07-01/dp/B01K3IYJRI/ref=sr_1_3?s=books&ie=UTF8&qid=1542197559&sr=1-3
12:14:15
elderK
I can't say Ive fully understood AMOP though. I might have to read it a few more times :)
12:14:58
pjb
https://www.amazon.com/Object-Oriented-Programming-COMMON-LISP-Programmers/dp/0201175894/ref=sr_1_6?s=books&ie=UTF8&qid=1542197539&sr=1-6&keywords=CLOS
12:15:00
elderK
Aye. Just from the tinkering I've done over the past week, I get the feel that like a lot... is starting to click. It's hard to articulate.
12:15:51
heisig
The rationale is even explained (briefly) in CLHS 7.6.6.2: "The design rationale for this difference can be illustrated with an example. ..."
12:15:58
elderK
:) hopefully sometime in the near future, as I get more CL chops, I'll be able to understand it
12:19:13
pjb
elderK: you might also be interested in the MOP for C++: https://www.informatimago.com/articles/life-saver.html
12:29:29
heisig
pjb: The link to OpenC++ is dead. Maybe you want to link to the SF page instead: http://opencxx.sourceforge.net/
12:29:51
shka_
elderK: if you end up in situation when you have to use next-method-p you probabbly should reconsider your design
12:32:56
fiddlerwoaroof
elderK: the order of the methods make a lot of sense, especially when you start using them
12:34:38
fiddlerwoaroof
the before and around methods are symmetrical, so that base class can setup the context for the subclass.
12:38:39
fiddlerwoaroof
elderK: I've always found images like this useful, https://upload.wikimedia.org/wikipedia/commons/4/43/Method-combination.png
12:46:40
jmercouris
Hi everyone, trying to solve some issues with macros: https://gist.github.com/jmercouris/8ad669f06ffc6fd0580d3f2a5aa60b71
12:47:51
jmercouris
the only thing that I've come up with is that I have to change the signature of BUFFER-EXECUTE-JAVASCRIPT
12:49:57
jmercouris
I'm not sure if it is clear what I'm trying to do here: but I want to be able to create functions that invoke some parenscript on a given buffer, but also use those same functions within with-result (since parenscript/js invokation is asynchronous) if I want the value asynchronously returned by the JS function
12:51:39
jmercouris
in the example I've given in the gist, I would like to be able to say (scroll-to-top) as well as (with-result (result-value (scroll-to-top)) (print result-value))
13:01:11
mercourisj
I don't want to make a different macro, like (with-parenscript ...), I want it to be consistent throughout the codebase
13:01:11
jackdaniel
reducing this example to something minimal illustrating a problem would be a good idea (with a clear statement, what do you expect - any "desireable" expansion or you just ask someone to fix your code)?
13:02:48
mercourisj
if you were to design a continuation passing style macro, what would it look like?
13:03:15
mercourisj
e.g. (with-result ((result-value (function-with-callback))) (print result-value))
13:03:57
mercourisj
is it bad that my with-result depends on the first argument to the function-with-callback function be a callback?
13:04:36
mercourisj
jackdaniel: if you look at my gist, you'll see what with-result, is my attempt at making a macro that makes continuation passing style simpler
13:04:58
pjb
mercourisj: (defun swap-args (fun) (lambda (&rest args) (apply fun (first (last args)) (butlast args))))
13:07:02
schweers
I’m currently using defmethod, saving the result and immediately removing the newly added method again, in order to be able to add and remove it later.
13:09:18
elderK
Guys, is it safe to use with-accessors if you have a reader, but not an "accessor"? Like, no reader/writer combo, provided you never setf to a var representing a slot?
13:12:58
trittweiler
mercourisj, Are you sure this is a good way to go? In my opinion it is quite horrible. Invocations within with-result look different than their lambda list definitions. Have you considered using promises rather than cps? So read-from-minibuffer would return a promise.
13:19:12
pjb
elderK: if you have reticences, you can always use (symbol-macrolet (foo (foo x)) … foo …)
13:20:14
pjb
or define a with-readers macro. Notice that with-accessors expands to such symbol-macrolet, and your with-readers would expand exactly the same.
13:20:35
pjb
But having a with-readers macro would make it clear that you want just to read the slots.
13:21:17
pjb
ie. it's part of functional abstractions. You can define functions or macros just to give nice names to the operators, they don't need to do anything more.
13:22:09
Bicyclidine
schweers: you can make-instance 'standard-method. the mop documents online explakin the parameters somewhere.
13:23:03
Bicyclidine
http://metamodular.com/CLOS-MOP/initialization-of-generic-function-and-method-metaobjects.html here.
13:24:37
shka_
https://github.com/sirherrbatka/vector-classes/blob/c8db51eb68d3d503ec7a6691f2ef710b06d5ef36/src/protocol.lisp#L88
13:25:12
Bicyclidine
unless you want to ask about make-method-lambda, in which case i apologize in advance
13:35:02
makomo
fiddlerwoaroof: that's a nice picture visualizing the standard method combination, thanks :-)
14:21:41
elderK
You know, the X3J13 issues are actually a kind of interesting read in and of themselves.
15:26:42
francogrex
Hi, do you know if there is a way to mprotect a memory address to make it exec from lisp?
15:29:21
Xach
elderK: also the gang of five email list, which was assumed private and has some gossipy snark
15:30:17
francogrex
cffi:foreign-funcall-pointer a pointer to execute an asm code, in my 32bit the address is executable, in 64 bit it isn't
15:32:31
elderK
francogrex: Yeah, if you've created some... "machine code", you're going to need to tell the system to treat that data as executable, the pages that it lives on
15:33:25
elderK
So, I guess you'll need to use the FFI to acquire memory suitable for that "binary code", as well to make the relevant pages executable.
15:34:33
elderK
Use the FFI to give you access to functions to say, allocate foreign aligned memory.
15:34:35
francogrex
do you have a pointer, a address (no pun intended) of a webpage that explains that?
15:36:38
elderK
Studying the relevant manpages for those functions, and related ones, should do the trick.
15:38:24
francogrex
elderK: yes i actually could use the cffi to do those indeed (in an impl independent way)
15:52:21
pjb
francogrex: the how is easy: write it in C; the translate it to lisp using CFFI for the calls and data structures that cannot be translated.
16:00:14
jcowan
Better yet, write a C->CL compiler (or better, get Vacietis working). "Build a man a fire", etc.
16:12:16
Xach
wusticality: there is a lot of freedom of implementation, as long as the results are consistent
16:12:30
Xach
wusticality: there's a great book that lays out many options, it's called Lisp in Small Pieces.
16:12:35
wusticality
is only the -binding- for x captured in the closure, or is the entire lexical environment somehow
16:13:01
beach
A function can be thought of as an environment and some code. When the function is called, the caller provides the environment to the callee. The callee can then create lexical variables extending the base one.
16:13:11
wusticality
another question is if it's somehow done by the compiler / interpreter, or if it's somehow done with the respective function / macros let / lambda
16:14:10
wusticality
beach: interesting - so is the callee's environment somehow passed as an invisible argument to the callee?
16:14:20
beach
wusticality: The LAMBDA turns into some code that captures the current environment and packages it up to become the closure, i.e, the code/environment pair.
16:15:01
wusticality
beach: is that an artifact of the lambda special form, or via a macro, or what? i'm mostly just curious if it's done in lisp somehow, or if it's an artifact of the compiler
16:15:18
Xach
there's an older book called Anatomy of Lisp that may be available more cheaply, but I did not find time to read it and I don't know if it is useful on this topic.
16:16:29
beach
wusticality: I don't know why you are talking about artifacts. And why you make a difference between "the compiler" and "lisp".
16:17:01
beach
wusticality: The compiler detects that X might be captured, so X is not allocated on the stack or in a register as it otherwise would.
16:17:06
wusticality
I mean, I'm super familiar with closures, but reading Practical Common Lisp, I'm curious how it's actually implemented - that is, at the compiler / interpreter level or in lisp somehow using some macro magic
16:17:56
Xach
wusticality: Lisp in Small Pieces does a nice progression from a slow interpreter to a fast one by showing the tricks that can be brought to bear for efficiency.
16:18:20
beach
wusticality: Instead, it is allocated on the heap in some kind of structure. The compiler generates code for LAMBDA that captures that structure and the code for the function and creates a closure object.
16:19:30
beach
wusticality: When the closure object is called, the compiler has arranged for the caller to grab the environment out of the closure object, stick it in some pre-defined place, and call the code of the function.
16:20:33
wusticality
i definitely want to read more about how it's implemented, i'll check out those boks
16:21:28
beach
jcowan: If you find a bootleg, I would like to know so that I can report it to the translator (who is my wife).
16:23:55
Xach
I thought technical books were expensive until I got a tractor and priced useful attachments for it
16:26:04
pjb
https://www.amazon.fr/Lisp-Small-Pieces-Christian-Queinnec/dp/0521545668/ref=sr_1_1?ie=UTF8&qid=1542212653&sr=8-1&keywords=lisp+in+small+pieces
16:28:22
jcowan
I think more than twice before I buy any book costing more than USD 5 (approx EUR 4.5)
16:30:31
jcowan
My life expectancy does not permit me to think as many times as it would take to justify a purchase of that size. Not to mention the time it takes to learn French.
17:01:31
cage_
minion: memo for Posterdati: probably you are interested in this: https://notabug.org/cage/cazzilli ;-)