freenode/#lisp - IRC Chatlog
Search
16:57:21
kuwze
okay I am trying to figure out thus bug. first of all, it only happens sometimes when I compile the whole project (ql:quickload "cl-oanda"). the bug/error goes away when I quit slime and restart it.
16:57:31
kuwze
here is the relevant code: https://gist.github.com/kuwze/57079a629a67d8dca229c8d795728d57
16:59:09
Shinmera
dlowe: Apparently you sent me a note about Portacle debug settings a long time ago that I never got because plexi isn't in this channel?
16:59:50
Shinmera
dlowe: The answer is that it used to use restrict-compiler-policy to force debug to 3 at one point, until I discovered that certain systems like cl-opengl perform very poorly with that.
17:05:55
kuwze
beach: I guess I was trying to practice with macros; I am not sure what I was thinking at the time
17:06:42
beach
kuwze: You can practice macros if you like, but then do it with something that requires a macro. I don't think make-book does.
17:07:49
beach
That means either of several things: 1. Your Common Lisp implementation is buggy. 2. You are doing something that the Common Lisp HyperSpec says has "undefined consequences" and your Common Lisp implementation is taking advantage of that, or 3. You are using buggy foreign code.
17:08:58
kuwze
beach, in regards to the segfault: I am not using ffi, and I am using the mature CCL, so I guess it must be 2
17:10:23
beach
kuwze: Oh, and given your level of knowledge of Common Lisp, I think Cluffer is probably too complicated at this point. But I didn't know that when I recommended it. Sorry.
17:15:53
kuwze
I'm sorry, but what's the newbite channel for common lisp? I don't want to bog down this channel
17:18:08
Devon
(fboundp '(setf car)) => NIL (fdefinition '(setf car)) and (function '(setf car)) both err undefined-function; No simple way to detect setf-able names?
17:22:13
Devon
A function named (setf f) must return its first argument as its only value in order to preserve the semantics of setf.
17:23:28
beach
I can't find it now, but I think there is a general rule that when the Common Lisp HyperSpec says it's an "accessor", then it can be implemented either as a function or as a setf expander.
17:24:48
Shinmera
It's a function name, but that doesn't mean that an accessor needs to be a function
17:25:06
Shinmera
There is a section that specifies that an implementation is allowed to implement (setf foo) as a setf-expander on foo rather than a function.
17:29:00
Devon
The symbol CAR and the list (SETF CAR) are both function names. (fboundp 'car) works, if (fboundp '(setf car)) is not required to work, what does?
17:29:18
Shinmera
For each standardized accessor function F, unless it is explicitly documented otherwise, it is implementation-dependent whether the ability to use an F form as a setf place is implemented by a setf expander or a setf function. Also, it follows from this that it is implementation-dependent whether the name (setf F) is fbound.
17:30:23
Bike
the fact that you can (setf (car ...) ...) doesn't mean there's a function called (setf car). the setf working can also be accomplished by a setf expansion (into eg rplaca and returning the value)
17:31:34
Devon
Shinmera: Thanks for finding that. The question of how to detect whether a given symbol is setf-able or not remains unanswered.
17:32:07
pjb
And even if (setf f) is bound, it's still implementation-dependent whether it's used by setf!
17:32:17
Bike
get-setf-expansion will return a default sometimes, and if it returns the default you can check whether (setf f) is bound
17:32:42
Bike
but i don't know if that's reliable, maybe an implementation could return a non-default setf expansion that still doesn't work
17:32:58
pjb
Bike: I wouldn't be so sure. I'd rather use (macroexpand-1 '(setf (f x) v)) to check whether there's a (setf f) function…
17:42:18
Devon
(second (fourth (multiple-value-list (get-setf-expansion '(#:foo #:bar))))) => #'(SETF #:FOO) in CCL but it smells unportable
17:43:41
Bike
there can also be situations like, you have a file with (defun (setf foo) ...), and also (setf (foo ...) ...) forms in the file. while compiling the file there is no setf function (and no custom setf expansion), but it'll be fine when it's loaded
17:44:16
pjb
(second (fourth (multiple-value-list (get-setf-expansion '(car x))))) #| --> #:g66321 |#
17:47:59
Devon
(defsetf file-position file-position) => FILE-POSITION ; So CCL does it and implementations have so much latitude in this, it'd be truly bizarre to forbid it.
17:49:52
Devon
11.1.2.1.2 Constraints on the COMMON-LISP Package for Conforming Programs ... undefined ... 13. Defining a setf expander for it (via defsetf or define-setf-method).
17:52:24
Bike
maybe the reason it doesn't have a setf is that it doesn't return the new value like setf is supposed to.
18:01:32
Devon
Thanks everyone, (incf (file-position s) i) will have to wait for the next *ahem* ANSI committee.
18:10:56
pjb
Devon: notice however that it should work on implementations running on POSIX systems, and assuming the stream is a binary stream or uses a 1-1 encoding.
18:16:17
pjb
Devon: also, (defun fpos (stream) (file-position stream)) (defsetf fpos (stream) (position) `(file-position ,stream ,position)) and then: (incf (fpos stream) i)
18:33:58
Devon
pjb: Needs gensym s `(let ((,s ,stream)) (unless (file-position ,s ,position) (error "Unable to set file position.")) (file-position ,s))
18:34:43
pjb
If you want to give more precise errors, ok. (incf nil) #| ERROR: The value nil is not of the expected type number. |# would do too.
18:37:01
Devon
Sans error checking still needs the gensym temp s '(let ((,s ,stream)) (file-position ,s ,position) (file-position ,s))
18:39:34
Bike
i mean, in the defsetf body stream is bound to a symbol. you don't have to worry about multiple evaluation.
20:54:24
aeth
"The function was called with fourteen arguments, but wants exactly twelve." I've created a monster.
20:55:11
aeth
And, yes, this is *with* helper struct objects, standard objects, and arrays to try to minimize that number.
22:04:53
Devon
false/true in CLHS unless ... if the test-form yields false, the forms are evaluated ... Otherwise, if the test-form yields false ...
22:10:41
Bike
there's http://www.cliki.net/Proposed%20ANSI%20Revisions%20and%20Clarifications, and it mentions that but otherwise I don't think so, no
2:53:48
Josh_2
Thanks :) Just double checking as I'm putting this into a presentation that's a large chunk of my grade
2:54:26
Bike
idealized vector access is an addition to get the memory address followed by an access of the memory address. list access is a memory access for each cons cell traversed, etc
3:09:36
dmiles
something i dont get is on the page http://www.lispworks.com/reference/HyperSpec/Body/f_mexp_.htm .. #'MACROEXPAND uses "&optional env" ... but for a macro lambdalist, one uses "&environment env" like (defmacro expand-1 (form &environment env) ... ) ?
3:13:11
Bike
if you have (defmacro expand-1 (form &environment env) ...), (expand-1 foo) is legal and (expand-1 foo bar) is not.
3:15:45
Bike
macroexpand having an &optional env is different from a macro having an &environment env. the former allows an environment to be explicitly provided by the programmer. the latter just means that the macroexpander wants to use the environment the macro form is in.
3:19:54
dmiles
.. so (defmarco expand-1 arg &optional (env env-supplied-p) &environment env) might have been used if expand-1 wanted to be like macroexpand-1 ?
3:20:39
Bike
but if i understand it correctly, no. macroexpand-1 doesn't know about the environment it's called in.
3:23:52
dmiles
but the (defmacro my-expand-1 (arg &optional penv &environment env) .. (let ((env-i-use (if penv penv env))) ... some code using env-i-use .. )
3:25:22
Bike
if you have an &environment parameter, within the body of the macroexpander it will be bound to the environment the macro form is in. Let me give you an example.
3:26:23
dmiles
(ah, i had sorta assumed the &environment env was just so the body would have a convience var named 'env for the global env :P)
3:26:48
Bike
now say we have (defmacro pexpand (form &environment env) (print (macroexpand-1 form env)) nil)
3:28:12
Bike
In contrast, say you have (defmacro dumb-pexpand (form) (print (macroexpand-1 form)) nil)
3:29:11
Bike
then (dumb-pexpand (dumb)) => 4, but (macrolet ((dumb () 5)) (dumb-pexpand (dumb)) => 4. Because it doesn't use the local environment, it just uses the global one.
3:33:26
dmiles
FLET and MACROLET are scoped in a lexical enviroment.. the way they get decared is locally.. but that would place a limit on where they can be used
3:35:19
Bike
The environment accessible with &environment contains information about these lexical scopes.
3:35:25
dmiles
why i call it a limit.. is if you use them within the scope you dont need to think about passing env arround
3:35:55
Bike
If macroexpand doesn't receive an environment parameter, it uses the global environment, which has no information about lexical bindings as produced by flet or macrolet.
3:36:12
Bike
As such, macroexpanders that need to expand other macros would behave badly if there was no &environment available.
3:36:45
dmiles
i might have to set up a testcase in the next couple houirs once i fix my current trouble
3:37:28
dmiles
what i was wondering is if other macroexpansions still use just the global enviroment even inside the lexical scope
3:39:25
Bike
Is English not your first language? I have a hard time understanding what you try to convey.
3:43:50
dmiles
(the question about if macrolet can define macros that get used inside the same lexical scope but not actualyl defined in the same scope))
3:46:12
loke
dmiles: The answer is that the unexpanded macro is returned from the first macro call. Then the compiler looks at the result of that first macro, and repeats by expanding the second macro.
3:46:59
dmiles
Bike: yes.. so i am trying to confirm that wheter or not the macrolet should be invisible to other macros that get called by other macros
3:48:27
Bike
You have (defun eval (form env) ...). The first thing that ... does is macroexpand: just (macroexpand form env). macroexpand repeatedly calls macroexpand-1, as you probably know.
3:49:15
Bike
macroexpand-1 is something like (defun macroexpand-1 (form &optional env) (if (consp form) (let ((mf (macro-function (first form) env))) (if mf (funcall *macroexpand-hook* mf form env) ...
3:50:03
Bike
In other words, it looks up the macro definition in the environment it's passed, and if it's there, calls macroexpand-hook. macroexpand-hook is basically funcall, so the macroexpander function is called with two arguments, the form to expand, and the environment.
3:50:18
Bike
If the definition of the macro had an &environment, that's the environment it gets. if not it's ignored.
3:51:01
Bike
Now, if the form passed to eval is a macrolet form, like say (macrolet ((foo ...)) ...body...), all it does is recursively evaluate body in a new environment that includes the definition of foo.
3:51:41
Bike
like (defun eval (form env) ... (if (eq (first form) 'macrolet) ... (eval (cddr form) (augment-with-macros (second form) env)) ...
3:56:53
dmiles
i would have assumed that macrolet created a "special macro" with the meaning as "special" in "special vars" that as they are being (i'll stick with special vars (forget macros for the moment) as theire bindings are availbel shadowed in the global enviironment)
3:57:31
dmiles
i was thinking that macrolet would shadow any of its uses at the same level of its env
3:57:58
dmiles
(meaning it would not be usefull tp ass env to subsequent calls.. as the shadow macro would be present)