freenode/lisp - IRC Chatlog
Search
5:57:31
Petit_Dejeuner
I was going to say "Yeah, but I heard back then you could only get smug lisp weenie answers out of functional programmers.", but I wasn't sure if I should start hamming it up in #lisp.
6:20:28
axion
Does anyone know why the version of the quicklisp bootstrapper offered on its website (https://beta.quicklisp.org/quicklisp.lisp) is different than https://github.com/quicklisp/quicklisp-bootstrap/blob/master/quicklisp.lisp ...it seems like the git repo is behind?
8:06:18
dim
beach: fyi I failed to have clim talk to XQuartz because of protocol mismatch, and didn't have time to inquire after that
8:16:25
stilda
Hello. Sorry for a newby question but can not find anything in internet. Is it acceptable thing to use a construct like (defmacro mym (args-list) (destructuring-bind (a b c) (eval args-list) ...))? The question is in using eval there. I have a defparameter that holds a list which I want to pass to the macro. Is there a better ways to do it?
8:18:48
beach
stilda: And (again, if args-list is a list of arguments), you should call it ARGUMENTS instead. The convention is to use the plural for a list (or possibly a vector) of things.
8:19:25
beach
phoe_: Maybe. More likely, it sounds like the use of a macro where a function should be used instead.
8:22:49
dim
then tou can (loop for foo in foo-list ...) and it's easier to read (I think) than (for foo in foos ...)
8:25:43
stilda
ok. more detailed description is following: I want to generate a code of function. I have (defun define-loka-code (name params) (destructuring-bind (p1 p2 p3) params `(defun ,name () ...<use p1 p2 p3 here>))). Then I have (defmacro define-loka (name params) (define-loka-code name (eval params))). Then I have (defparameter *loka-parameters* (list value1 value2 value3)). And I use it like (define-loka myfuncname *loka-parameters*)
8:27:01
beach
dim: There are several things I don't like about accepted conventions. But I think it is more important to follow those conventions so as to facilitate communication, than to use my preferred style. And this goes for code as well as for prose.
8:27:08
stilda
value1 value2 value 3 is big enough so I want to keep it in a separate list and not inline in macro call.
8:30:42
phoe_
because if it is (list value1 value2 value3), this evaluates to (value1 value2 value3), and EVAL will treat this as a function call.
8:32:22
stilda
phoe_: no I define *loka-parameters* as (defparameter *loka-parameters* (list value1 value2 value3))
8:36:34
stilda
phoe_: in scope of define-loka params will have value '*loka-parameters* so there is no problems with evaluating (value1 value2 value3)
8:41:03
phoe_
then (define-loka myfuncname *loka-parameters*) will expand to (define-loka-code myfuncname (v1 v2 v3)).
8:42:08
stilda
sorry mybe quoute should not be there. I meant that params will be symbol *loka-parameters*.
8:43:22
stilda
no, without eval or symbol-value I will get expansion (define-loka-code myfuncname *loka-parameters*). And then it complains that can not destructure a symbol.
8:46:31
stilda
then why does it not substitute *loka-parameters* value there? Am I right that eval will be called on my macro body?
8:56:33
stilda
ok, I think I was wrong saying that (define-loka-code myfuncname *loka-parameters*) is the expansion of the (define-loka myfuncname *loka-parameters*) form.
9:05:13
phoe_
(defmacro define-loka (name params) (destructuring-bind (p1 p2 p3) (symbol-value params) `(defun ,name () ,p1 ,p2 ,p3)))
9:05:44
phoe_
now (macroexpand-1 '(define-loka myfuncname *loka-parameters*)) ;=> (DEFUN MYFUNCNAME () VALUE1 VALUE2 VALUE3)
9:16:06
stilda
ok, so I have to move it to separate file and ensure it is compiled before the call to macro
9:16:57
phoe_
(eval-when (:compile-toplevel :load-toplevel :execute) (defvar *loka-parameters* '(1 2 3)))
9:29:47
stilda
phoe_: Does it not get evaluated anyway without that (eval-when ...) when I compile/load a file? And also how does this ensure the order of evaluation? At the end the order is what bothering me.
9:32:15
phoe_
but basically, it allows the Lisp image to have some variables bound during compilation time.
9:43:04
edgar-rft
stilda: Common Lisp first reads the entire file, then it tries to optimize the code, and only then it compiles the code. If you're referring in your code to something that was defined in the *same* file, then you need to wrap it in (eval-when (:compile-toplevel :load-toplevel :execute) <cour-code>), then Common Lisp evaluates <your-code> when it *reads* the file.
9:45:23
Bike
it reads one form at a time (which is why in-readtable utilities and such work). then it compiles it, or if there's a top-level eval-when, possibly evaluates it as well (or doesn't compile). and optimization is usually part of compilation.
9:46:32
Bike
stuff like defmacro is needed by the compiler, so it's evaluated. But defun and defvar aren't. So if a macroexpander function refers to a function or variable defined in the same file, there will be a problem, unless you use eval-when.
10:00:47
stilda
ok, I have to read something, to many questions. Is there a nice material to read about whole evaluation/compilation/macroexpansion process?
10:12:11
edgar-rft
stilda: the Common Lisp Specification has a whole Chapter about it, but don't expect that it will be easy to understand: <http://www.lispworks.com/documentation/lw51/CLHS/Body/03_.htm>
10:12:38
stilda
phoe_: thank you, I have to work at the moment. I will read something myself first and then ask questions if any.
10:13:32
specbot
Evaluation and Compilation: http://www.lispworks.com/reference/HyperSpec/Body/03_.htm
10:14:22
phoe_
and the page http://phoe.tymoon.eu/clus/doku.php?id=cl:special_operators:eval-when is somewhat usable right now
10:17:16
stilda
I have tried to generate code for multiplication of hypercomplex numbers. My macro takes a list of multiplication rules for imaginary units and output a code for multiplication function. So far it looks like lisp is a very good fit for this.
10:24:43
phoe_
Because, well, you have the whole language at your disposal during read-time, macroexpansion-time, compilation-time, load-time, execution-time.
10:25:14
phoe_
In most languages, only the third of these is guaranteed. In some of the more interactive languages, the fifth is also added.
10:27:55
phoe_
For read-time, there's the #. reader macro; for macroexpansion-time, there's macros; for compile-time, load-time, execution-time, there are the respective eval-when options.
10:28:28
phoe_
(If I understand it correctly. There might be some bugs in the two statements above. If I'm wrong somewhere, please correct me.)
10:44:26
dim
in some cases it's possible to deliver “results” without being asked what tooling you used to deliver, those are good opportunities to use CL
14:12:41
drmeister
ECL uses a scheme for multiprocessing where special symbols maintain a 'binding' slot that indexes into a thread local table of bindings. As you do things like (let ((*foo* 1)) (declare (special *foo*)) ...) it doesn't write the 1 into the symbol-value of *foo* but instead maintains a thread local table of bindings that needs to be expanded in every thread
14:13:06
drmeister
Are there any other schemes out there for supporting multiprocessing and special symbol binding in Common Lisp?
14:13:54
beach
It would certainly be a bad idea to write a new value to a common slot in the symbol.
14:16:15
drmeister
Ah - ECL does have a per-thread binding stack that contains pairs <symbol,value> What I described above describes where the current thread-local value of the special symbol is stored.
14:16:59
drmeister
It's just a vector of objects and as each new special symbol is bound that symbol is assigned the next index into the table.
14:18:04
drmeister
Me too (slightly). My understanding of ECL's method is that it combines both of your two options - so I wonder what your two options are.
14:18:13
beach
The table is thread-local, but the index for a particular symbol is the same in every thread, right?
14:20:09
beach
So I am guessing the binding stack contains previous values. In my option 2, it would also contain current values.
14:23:56
splittist
I wonder how much of the mechanism is, in reality, just handling a million *print-...* specials that are rarely changed.
14:24:15
drmeister
The question is - do special variable binding and lookups come up enough that a simple stack would impact performance.
14:27:35
beach
Option 2 would need a fast way of answering the question "Does this variable have a thread-specific binding in the current thread?".
14:28:23
beach
Otherwise, the entire binding stack would have to be traversed for an access to a global binding.
14:30:32
beach
How does the ECL technique determine whether there are any per-thread binding for a symbol?
14:33:06
drmeister
When it expands the per-thread table it fills the empty slots with a special no_thread_local_binding value.
14:34:06
drmeister
If you read a symbol with no_thread_local_binding - I think it copies the global value into that slot - so now you have a thread local binding that is identical to the global value.
14:36:25
beach
drmeister: Perhaps it stores a special value that is tested for when a variable is accessed. If it is EQ to that special value, it goes to the global binding?
14:38:01
beach
drmeister: Presumably, to assign to a special variable, you modify the value in the table, provided it is the thread-local binding. Otherwise, you modify the global binding.
14:53:54
attila_lendvai
drmeister: FYI, SBCL has an extension called defglobal, which makes sure the binding cannot be made thread-local
15:07:30
ogamita
if you use slot-value in your public interface, then you can define a method on slot-value.
15:08:02
ogamita
if you use an accessor in your public interface, then define a method on your reader.
15:09:21
beach
pebblexe: I am not sure I understand your question then, if it was not about the function named slot-value.
15:10:02
pebblexe
I have this in my class: (timestamp :type integer :initarg :timestamp :accessor timestamp)
15:10:16
pebblexe
ideally I could do this: (timestamp :type integer :initarg :timestamp :accessor timestamp :before 'func1 :after 'func2)
15:10:34
ogamita
So you have to use accessors and define a :before or :around method on your accessor.
15:11:05
ogamita
It would be possible with a specific metaclass that would use specific slot-definitions.
15:11:31
ogamita
pebblexe: It would be possible with a specific metaclass that would use specific slot-definitions.
15:12:16
ogamita
pebblexe: but one of the points of OO programming notably with CLOS, is also that you can split and spread stuff by other categories than just the class.
15:36:02
pebblexe
hey I am trying to load a 2gig file into ram and I am getting this error: (SB-KERNEL::HEAP-EXHAUSTED-ERROR 438632448 2541404000)
15:36:22
pebblexe
http://rosettacode.org/wiki/Read_entire_file#Common_Lisp <- that's the code I'm using to slurp
15:40:16
beach
pebblexe: The default element type for MAKE-STRING is CHARACTER, so you probably allocate 4 bytes for each character.
15:45:32
ogamita
So I'd rather (make-array big :element-type 'base-char :adjustable t :fill-pointer big) and obtain a base-string, but not a simple-base-string.
16:05:02
drmeister
I think if the thread-local-binding table has no_thread_local_binding for that symbol then it modifies the global value.
16:06:29
drmeister
That's what I came up with walking back from class - but it seems like it should work.
16:14:08
Xach
if that message comes up on sbcl, it usually indicates an incomplete or damaged installation.
16:28:36
eschulte
as I recall quicklisp supports project-local installations (effectively project local local-projects, which is hard to google), is this documented somewhere? Is qlot the tool to use?
16:30:56
bpanthi
Xach: (push #p"/usr/local/lib/sbcl/contrib/" asdf:*central-registry*) solved the problem
16:33:25
bpanthi
Xach: may be asdf or quicklisp should include that directory by default. (my asdf version is 3.1.5)
16:34:01
Xach
bpanthi: in a normal installation of sbcl, with asdf loaded, it will work without any work on the user's part.
16:34:31
Xach
bpanthi: that is, (require 'asdf) (asdf:load-system "sb-rotate-byte") will work out of the box.
16:34:45
Xach
bpanthi: if that does not work for you in some circumstance, there is something to fix.
16:37:41
bpanthi
Xach: but when i do CLEAR-CONFIGURATION-AND-RETRY in (asdf:load-system "sb-rotate-byte") restart , and try again , it works.
16:38:13
Xach
bpanthi: that suggests to me that there is an asdf config file that is messing things up
16:40:06
Xach
bpanthi: not sure...they can live in /etc, I think, and ~/.config, and perhaps other places
16:40:24
jasom
okay, where is upstream for quicklisp's esrap? What I get from quicklisp looks nothing like https://github.com/nikodemus/esrap
16:51:38
ogamita
https://gitlab.com/com-informatimago/com-informatimago/blob/master/common-lisp/cesarum/simple-test.lisp
16:51:59
ogamita
example: https://gitlab.com/com-informatimago/com-informatimago/blob/master/common-lisp/cesarum/string-test.lisp
16:56:39
scymtym
jasom: did you see the reference to https://github.com/nikodemus/esrap in the debian package or somewhere else?
17:04:56
phoe_
just don't pass it symbols, because the fleted/labeled symbols aren't globally fbound and that's where disassemble looks for the symbol-functions
17:05:26
jasom
now I'm trying to figuore out how to get the function object; I'm profiling some code and the top 3 functions are all labels/flet
17:07:13
scymtym
jasom: SB-DISASSEM:DISASSEMBLE-CODE-COMPONENT kind of shows it, but you have to map segments to back to functions
17:08:05
scymtym
with sufficient debug policy there will be semi-helpful labels that may help with that
17:09:03
jasom
phoe_: break drops you into the debugger, and from the debugger you can execute arbitrary code
17:11:46
jasom
The tooling is what keeps me coming back to lisp; I do really like macros, and editing s-expressions is much easier than less regular syntax. The condition system is pretty neat too. However the tooling is unrivaled compared to any language implementations that compile to tight machine code, and it's among the best even for highly dynamic interpreted languages.
17:13:46
jasom
mazoe: right, I can change a single function, recompile and get instruction level profiling faster than a single c++ incremental build
17:15:10
jasom
The other day I modified some performance critical code and it got 30% slower; in under 5 minutes I was able to determine it's because changing the code around an IF made a conditional move become a tst/jne and branch prediction is a thing.
17:18:41
Petit_Dejeuner
jasom: I assume SmallTalk is too in-its-own-world for you and Erlang is too functional?
17:21:41
jasom
And yes, SmallTalk has great tooling; historically there's lots of cross-pollination between ST and Lisp.
17:22:57
jasom
Oh, I should also say that there are some commercial tools that have good tooling, but the price means that they are unlikely to be used for hobby projects.
17:24:29
jasom
I'm not poor, but I'm also not going to drop $5k on development tools for software I'm giving away for free.
17:26:47
aeth
$5k is more than most reasonable development hardware expenses for one individual these days. Iirc, it's also more than setting up an LLC, trademarking something, etc. So even if you *were* selling it, $5k could be your highest expense.