freenode/lisp - IRC Chatlog
Search
13:44:06
sm2n
is there a way to get a compile warning when defining a function with a method call with an invalid method combination?
13:45:30
sm2n
obviously this can't be an error, since you may define a valid method later, but it'd be nice to know if the method existed at the time of definition
13:48:38
beach
You probably means something else, like whether FOO has any applicable methods for the argument you are passing.
13:49:15
beach
sm2n: But that would require solving the halting problem. Consider (defun bar () (foo (ackermann 4 5)))
13:51:14
beach
You don't know what type the value returned by the function is unless you execute it, or solve the halting problem.
13:51:51
sm2n
sbcl already calculates return types to the best of its ability, I would just like it if that information was used here
13:57:29
scymtym
how would you define mutually recursive methods without getting a warning? as in (defmethod foo ((x string)) (if … (foo 1) …)) (defmethod foo ((x integer)) (if … (foo "") …))
14:00:35
scymtym
you could probably delay the warning until the end of the compilation unit, but it would be kind of hard to avoid unwarranted warnings in general
14:00:57
sm2n
if I were defining those interactively, I would consider the warning as desirable even in that case, and if you were working at the file level, the information necessary to suppress the warning should be available to the compiler
14:03:33
scymtym
for simple cases, sure. but it is really hard to know in advance which methods will be applicable when the call is executed
14:04:26
_death
with some styles, it's also quite common to compile calls to a generic function before any methods are added to it
14:30:47
biglama
Hi guys, I have a beginner question without answers on Google : how can a sort characters in a single string (Emacs lisp) ?
14:31:44
_death
you can also see calling a generic function with no applicable methods as a normal thing, since by CLOS protocol, no-applicable-method gets called.. in many cases its default method is to signal an error, and there's nothing special going on
15:30:52
warweasle
"The symbols :START-ANCHOR, :END-ANCHOR, :MODELESS-START-ANCHOR, :MODELESS-END-ANCHOR, and :MODELESS-END-ANCHOR-NO-NEWLINE are equivalent to Perl's "^", "$", "\A", "\Z", and "\z" respectively."
15:37:07
dlowe
if you want to match the beginning of the string even with multiline mode, that's what \A is for
15:49:25
warweasle
Josh_2: I'm trying to convert some filenames and directries into sql data...so I need regex power.
15:53:59
Josh_2
Okay cool, the library is very helpful for adding the trivial string manipulation you would find in other languages
16:20:14
semz
On the topic of cl-ppcre, are there ways to add parse tree aliases with parameters? While I like the sexpr method, things like (:NON-GREEDY-REPETITION 0 1 "a") often make it less readable than the string version and define-parse-tree-synonym can apparently only create static parse trees and you can't seem to make shorthands like 'ngrep -> :non-greedy-repetition.
16:23:03
semz
Of course I could just calculate them at runtime, but that'd lock me out of the neat compiler macros.
16:25:02
Bike
doesn't look like it... it doesn't seem like it would be too difficult to extend the library with a more general macro system if one wanted
17:24:23
dbotton
I noticed that I was able to change in place a constant list. SBCL through a warning which is nice. Is that techincaly a practice just fround upon or is it considered erroneous to do such a thing?
17:26:33
beach
It is not the DEFCONSTANT that matters. It has to do whether the list is literal data or not.
17:28:14
beach
DEFCONSTANT is not behaving well when the value is something other than very simple objects.
17:28:18
beach
Then you are not allowed to modify it. And that is true even if it is assigned to a variable with DEFVAR or SETQ.
17:29:03
beach
Yes, you are not allowed to do that. But that is true even if you use DEFPARAMETER rather than DEFCONSTANT.
17:31:43
beach
So if you do (defvar *l* '(a b c)) then (let ((l *l*)) (setf (car l) 234)) that is still undefined behavior.
17:33:23
beach
It has nothing to do with DEFCONSTANT or DEFPARAMETER. It has to do with whether the list is literal or not.
17:37:41
semz
it's worth mentioning that there are implementations out there which misbehave silently if you modify a literal list, such as CCL
17:37:55
semz
try this on for size: (defun test () (let* ((n 10) (x `(,n 2 3)) (y `(,n 2 3))) (list (nconc x y) x y)))
17:38:46
beach
SBCL is inconsistent as well because there is no warning on (SETF CAR), at least not in the version I am using.
17:41:18
beach
There is no such thing as "constant data". The term is "literal". When you construct a list with '(...) then the entire list is literal and you are not allowed to modify any part of it.
17:41:19
dbotton
the defconstant is saying that I am refering to a specific list - one list is itself constant, a literal the other version is built with (list) so not constant
17:42:23
dbotton
so those two messages are for the two versions 1 defconsant to literal and 2 defconstant to non-literal
17:43:12
beach
Maybe you should ask #sbcl why you observe this behavior. Either way, using DEFCONSTANT with a list is a very bad idea.
17:43:31
Bike
you know i don't actually see anything in the standard saying mutating a value bound to a constant is illegal
17:44:44
Bike
i mean, for real though, don't write programs relying on the ability to mutate constants, that's just a mess
17:47:53
_death
dbotton: defconstant is not meant for complex data.. mostly for numbers/characters/symbols.. for more complex objects you should use defvar
17:50:25
_death
and when your constant changes, as constants sometimes do, you won't have to recompile everything
17:50:26
dbotton
I guess could have a package and call it "constants" to make it harder or more obvious
17:53:09
dbotton
well the idea that one has to use myapp-const:something I like better then just a naming convention
19:51:44
dbotton_
semz, sbcl catches that with a warning that it modifies constant data even before running
20:16:05
semz
dbotton_, well my point was that you can't rely on the warnings even in mature implementations
20:28:22
Bike
if you throw (1 2 3) in your repl it's an error. what you mean is probably (constantp ''(1 2 3)) like semz said
20:30:47
Alfr
dbotton_, the first gets eaten by the reader and then constantp gets to see (quote (1 2 3)).
20:31:21
Bike
it's an error. you're passing it a form that's a call to the function "1" with arguments 2 and 3. that's invalid
20:33:13
dbotton_
ok, so it is not a literal object until the operator quote turns it in to one after and that is constant
20:35:06
Bike
Now if you evaluate, say, (eval '(+ 1 2)), you need that extra quote there because EVAL is a normal function and its arguments are evaluated before the function is called.
20:35:33
Bike
If you just write (eval (+ 1 2)), that's the same as just (eval 3), eval gets a 3 rather than a list.
20:36:02
Bike
So if you write (eval '(1 2 3)), eval receives a list of 1, 2, 3 as an argument, and that's not valid lisp code.
20:36:02
dbotton_
got is so constantp is evaluating that '(1 2 3) to (1 2 3) and ''(1 2 3) to the literal '(1 2 3)
20:36:32
Bike
constantp receives a form as its argument much like eval, so if you write (constantp '(1 2 3)), you're passing the form that's the list 1, 2, 3, which as with eval is invalid.
20:37:46
_death
CONSTANTP does not evaluate anything.. it tells you (maybe) if the form it got would always return the same object.. in fact it's a very tricky function and often misused
20:38:42
Bike
yeah, constantp analyzes forms. there's no guarantee that literal objects are distinguishable from other objects in any way at runtime anyway
20:47:31
_death
for example if you have a constant (defconstant foo 42), at compile-time (constantp 'foo) will return true, but that does not mean you can get the value of foo.. lisp may know foo is a constant, but not yet know its value until later on.. then again, on another implementation it may know the value
20:51:59
_death
sjl: I guess it's useful if you want to know whether a symbol is a constant.. for example so that you don't generate something that binds it
20:54:13
_death
sjl: in fact that's the original use case for it, I believe: http://cl-su-ai.lisp.se/msg05376.html
20:54:25
dbotton_
Still though don't know rational for having the literal forms other then optimization
21:02:00
sjl_
I still don't really understand how to use it for non-symbol things then. E.g. in SBCL (constantp (list '+ 1 2)) is true, but if I were trying to do something like... unroll a looping form if N is small, I'd need to (eval ...) that thing first, right?
21:02:56
sjl_
And SBCL will also return T for constantp of something involving e.g. a symbol-macrolet'ed thing, so you need to sb-cltl2:macroexpand-all too... and I'm just not confident at all that I'd be doing all the necessary dances
21:03:33
_death
well, bad example because it doesn't have to do with multiple copies.. in fact that would've been broken.. it's optimization in the sense that these literals can be coalesced and otherwise share structure
21:05:27
sjl_
like, this *appears* to work but I have no confidence that there's not something I haven't thought of https://gist.github.com/sjl/73e749f35763958a0158f1bdd7bb3289
21:06:10
_death
sjl: so this has the exact issue I mentioned.. the value may not be available at the time you EVAL
21:13:05
_death
then constantp could be useful too, because if it's a boundp symbol and not a constant, you don't want to unroll
21:27:16
_death
sjl: btw, I see you're still going through rosalind.. learned about it (last year) from your plan file.. it was fun
21:27:22
Nilby
Wow. Thanks _death and sjl_ for shining some light into this dark corner, and digging up the quux quote. I've really never understood constantp, so I never used it.
21:27:48
sjl_
_death: Ah nice. Yeah our book club at work is going through the Bioinformatics textbook the Rosalind authors wrote
21:28:07
sjl_
So hopefully I'll have more motivation to finish all the exercises in the book this time, ,hah.
21:29:08
sjl_
Part of me wants to sit down and write an efficient DNA/RNA seq representation in CL... but that's kind of a rabbit hole and Rosalind examples are all tiny, so I've just been using vanilla CL strings and sequence functions.
21:31:00
sjl_
I read somewhere about using (unsigned-byte 4) to represent a base, where each base has a bit
21:31:20
Bike
phoe: also it seems mildly out of wack iwth constantp, in that constantp... it looks like it tries to handle lexical constants or something?
21:31:41
sjl_
which lets you represent "this base could be any one of A, C, T" as 1101, and comparing bases with logand treats it as a wildcard
21:31:48
_death
of course some problems require special representations, but in general I just used strings
21:33:18
sjl_
Bike: essentially I'd like to make something like Julia's biosequences in CL https://github.com/BioJulia/BioSequences.jl
21:36:01
sjl_
e.g. maybe you want to optimize for short kmers, so you represent sequences of < 20ish chars as a fixnum
21:41:40
Nilby
it feels weird to push around electrons so brutally, just to have superpowers over something they do naturally. If only one could elide the quantum and atomic levels.