freenode/#lisp - IRC Chatlog
Search
4:35:30
beach
Good. Then, if you use ERC for IRC discussions, you can use Emacs abbrevs, so that when you type "tbh" or "idk", they will be automatically expanded.
4:36:21
beach
For instance, I have abbrevs for "Common Lisp", "Common Lisp HyperSpec", "Good morning everyone!", "(first) Climacs", "Second Climacs", "first-class global environments", "(admittedly small) family", etc. etc.
4:37:13
beach
Saves A LOT of typing, and makes it less necessary to explain to others what you are trying to say.
4:41:29
beach
I once calculated how many hours per month my abbrevs for writing email saved me. It was considerable. For some reason, I am one of the few people I know who use Emacs abbrevs. Strange to me.
4:43:49
White_Flame
because you're talking about full non-abbreviated text appearing in what you communicate
4:44:19
beach
White_Flame: It's a technical term. I guess you didn't know about them either. http://www.gnu.org/software/emacs/manual/html_node/emacs/Abbrevs.html
4:45:28
beginner_supreme
Is there a document anywhere describing the swank protocol that slime uses? Can't seem to find an official doc
4:46:52
beach
I also use Emacs abbrevs to fix some of my common typos. Like, my fingers seem unable to type "the", and they type "teh" instead. So I have an abbrev that "expands", the latter into the former. Same thing for "language" and "language".
4:55:52
devon
beginner_supreme: The swank protocol is so deficient, I'd not even look unless you plan to replace it.
5:02:27
White_Flame
I'm offering money to anybody who will refactor SLIME such that the elisp portion is hosted by swank, allowing multiple connections to different deployed versions simultaneously
5:03:51
White_Flame
with the initially emacs-side code simply being a bootstrap to connect & download elisp
5:06:29
shangul
but younger people don't understand what money is. they understand what ice cream and chocolate is
5:11:42
beginner_supreme
It seems the difference is that /msg cannot be seen by anyone else, but query is visible.
5:12:45
shangul
beginner_supreme, query in my client opens a new private window and optionally sends a message
5:15:04
jackdaniel
I don't know, but unless it doesn't work for him it is a valid answer ;-) /me moves along
5:23:24
jackdaniel
on the other hand, if you are interested in your own looping construct, I'd argue that building your macro upon DO is more readable
5:24:53
shangul
I'm leave and I'm not gonna lock the screen. because I know no one here would be able to work with i3 :D
5:25:52
flip214
minion: memo for Fare: https://bbt.legi.cash/ has a typo: "Solution: Extract Everything from a Same Spec" => "*the* Same Spec"
5:26:35
beginner_supreme
Loop is a dsl for looping/iterating. Quite useful, I haven't learned all the t
8:11:05
xificurC
aeth: why only defmacro supports this destructuring? Is there a particular reason (defun foo ((x y) &rest z) ...) isn't implemented in the standard but it is for defmacro?
8:22:11
jackdaniel
xificurC: https://groups.google.com/forum/#!topic/comp.lang.lisp/J9SXofadB2c for a discussion about this
8:26:28
shrdlu68
xificurC: I suppose what I meant was "because you could always use destructuring-bind", but I really have no concrete rationale.
8:32:01
shka
shrdlu68: i don't think that destructuring in function lambda list is a good idea to be honest
8:32:29
shrdlu68
If function took destructuring lambda lists rather than ordinary lambda lists, there would be no way to pass lists to functions, would there?
8:33:03
jackdaniel
so you say it is impossible to pass lists to macros? I highly recommend reading thread linked above
8:41:22
jackdaniel
that's true that adding destructuring step to functions could hurt runtime performance
8:45:17
jackdaniel
let* at the beginning is bad indented, you put first variable in the same line as the operator
8:45:54
jackdaniel
there is no need for (n-divisors ()) , you can replace it with simply n-divisors (it defaults to ()), also if you insist, NIL is more readable than () [IMHO]
8:46:00
_death
an extensible pattern matcher would let you extract just what you need from whatever kind of object so may be a better choice, but then there are various possible solutions and it's not something that was available to everyone historically
8:46:25
jackdaniel
instead of (if test (progn …)) [it is one-branch if] use when which has implicit progn
8:47:29
jackdaniel
regarding this mod, you may also check it with (zerop (mod …)), but that's opinionated remark, nothing wrong with =
8:49:55
jackdaniel
also seeing how you do two consecutive pushes, you could replace them with (setf n-divisors (list* (/ n i) i n-divisors)), but that's also a nitpick which is opinionated
8:50:36
jackdaniel
list* creates a list with all elements, where last function argument is treated as list's tail
8:51:31
beach
jackdaniel: The advice about replacing (n-divisors ()) is not good. It should be replaced by (n-divisors '()) instead.
8:51:41
beach
shangul: The advice about replacing (n-divisors ()) is not good. It should be replaced by (n-divisors '()) instead.
8:52:08
beach
shangul: Using just n-divisors tells the person reading your code that you are going to assign to it before using it.
8:52:27
beach
shangul: Using () is not idiomatic because it is only used in code to indicate empty parameter lists.
8:52:49
beach
shangul: Similarly, using NIL means that you are initializing it to the false Boolean value or to a default value.
8:53:43
jackdaniel
'() may be considered as artificial as using eq instead of eql, so it is a matter of opinion
8:54:10
beach
shangul: () is replaced by the symbol NIL by the reader, so () and NIL mean the same to the compiler.
8:55:18
_death
shangul: ' is just a shorthand for (quote ...), so the first reads as (quote ()) and the second ().. they both evaluate to the same thing, but the first indicates to the programmer that you expect the thing to be evaluated to the empty list
8:55:36
jdz
Also, it is inconsistent if for whatever reason one wants to pre-populate the list, in which case it would have to be quoted.
8:56:19
beach
There is a very different message to the person reading the code, and that person should know as soon as possible what is going on.
8:57:20
beach
shangul: You should use the contribution slime-indentation and put the DO LOOP keyword first on the line where the (IF is. Or rather where the (WHEN will be.
8:57:47
shangul
<jackdaniel> also seeing how you do two consecutive pushes, you could replace them with (setf n-divisors (list* (/ n i) i n-divisors)), but that's also a nitpick which is opinionated
8:58:17
beach
shangul: That's a very general rule: use the most specific construct that will do the trick.
8:59:19
_death
there is a name for the pattern (zerop (mod n i)) .. so I'd use a named function for it.. say divisible-by-p
9:01:19
jackdaniel
idiomatic has no real meaning to me. for beginners one way is idiomatic, for more advanced programmers other one is. it is very nicely explained in "learn ruby the hard way"
9:03:07
makomo
what are the guidelines for naming CLOS accessors? i can't help but think that "process-context-instruction-pointer" is too verbose :^/
9:03:19
jackdaniel
loop is another interesting thing – some consider it being very lispy and others consider it being not lispy at all :)
9:03:53
makomo
beach: so if the accessor has a really short name, like "delayed", you just let it be?
9:04:00
jackdaniel
makomo: imagine it is a function having opaque argument, forget about the class thing
9:04:58
beach
makomo: Take (sheet-parent stream), for instance. It seems silly to use an accessor for a sheet on a stream. But it's valid CLIM code.
9:05:07
_death
shangul: you could also separate the algorithm from the printing of the results.. so you'd do something like (format t "Sum of divisors: ~A~%" (sum (divisors n)))
9:05:45
imjacobclark
could anybody help me understand why when encoding a list with cl-json my variable path ends up encoded as a literal string? (print (json:encode-json '#( ( ("bar" . path) (baz . #\!)))))
9:06:20
_death
shangul: in this case, it could be a bunch of PROG and SETQ since it's a very small snippet of no consequence.. but you asked for stylistic advice
9:07:09
beach
makomo: I personally dislike that, because I don't want client code to use SLOT-VALUE and I want to make that very clear.
9:07:54
beach
makomo: So I prefix the slot name with `%' which traditionally means "internal" or "dangerous".
9:08:05
scymtym
makomo: beach's suggestion works best when combined with liberal use of packages (not in the :use sense). so e.g. my-compiler.ast:successor and my-compiler.cfg:successor instead of my-compiler:ast-parent and my-compiler:cfg-parent
9:08:20
imjacobclark
shka: so given (print (json:encode-json '#( ((foo . (1 2 3)) (bar . path) (baz . #\!)) "quux" 4/17 4.25 ))) I got an output of [{"foo":[1,2,3],"bar":"path","baz":"!"},"quux",0.23529412,4.25]
9:08:34
imjacobclark
where i actually expected the string "path" to be the value of the variable path, e.g "hello world"
9:09:37
beach
makomo: That allows me to create internal protocols that can use the CLOS machinery with auxiliary methods.
9:10:26
makomo
scymtym: i see. so creating packages that provide additional context. but wouldn't that get verbose quickly as well?
9:10:45
makomo
i guess you can always USE the package if you need to cut down on the length temporarily
9:10:55
beach
makomo: It's the other way around. If you don't do it, your code will quickly become a mess of mixed symbols.
9:10:58
xificurC
shangul: you don't use n-sqr, so remove it. I would probably write (let* ((n (parse-integer (read-line t))) (divisors (for ... collect i collect (/ i n)... and then print. No need to push or setf when you are collecting into a fresh list anyway
9:12:58
beach
makomo: No, I would choose a short package local nickname and use explicit package prefix for the others.
9:13:31
scymtym
makomo: line 78 in https://techfak.de/~jmoringe/eclector-walk-and-source-tracking-simplified.html shows an example of this style
9:15:04
beach
makomo: I think they are becoming safe to use even though they are not standard. Most major implementations have them, and in the same way it seems.
9:15:34
_death
names like frob-something or something-foo indicate type envy.. sometimes it makes sense to use that style, but you should consider using just frob and foo
9:16:46
jackdaniel
on the other hand release is the thing which I celebrate with friends (: rare occasion indeed
9:16:48
makomo
beach: regarding your internal protocol comment, what exactly did you mean by "auxiliary methods"?
9:18:13
jackdaniel
so it is the same in principle (but package is ext if you want to use functions which work on packages -defpackage is extended accordingly to sbcl)
9:22:20
scymtym
jackdaniel: i see. i asked because i think Xach designed/is designing another variant of pln
9:25:22
jackdaniel
is it going to be adapted in other implementations? since it's not released yet, I'm still free to change the interface
9:29:12
imjacobclark
still baffled by "(json:encode-json '#( ((foo . (1 2 3)) (bar . path) (baz . #\!)) "quux" 4/17 4.25 ))" in cl-json - its as if it is just evaluating everything to strings and not the values
9:30:24
jackdaniel
scymtym: my question is rather: are sbcl devs willing to adopt this new interface?
9:31:18
xificurC
shangul: your n-sqr is not used anywhere. The LOOP that jdz posted is more natural then doing a let+push/setf combo
9:33:11
scymtym
jackdaniel: can't say. firstly, i can't speak for all SBCL devs. secondly, i don't know enough about Xach's proposal
9:34:17
jackdaniel
scymtym: thanks, that's understandable. thanks for the headups about Xach's work, I wasn't aware of it
9:37:22
jdz
Oh, in this case the :initial-value is not needed because + already handles the case of zero arguments.
10:00:50
xificurC
(funcall 'foo 2 3) generates the same assembly as (funcall #'foo 2 3), seeming the fdefinition of FOO is compiled in as a fixed memory location. I thought 'foo would be compiled as a runtime lookup. If one wanted runtime lookup one would need to use symbol-function?
10:31:03
xificurC
loke: where does lexical scoping come into play here? FOO is special and flet should rebind it dynamically. The way I see it right now is that BAR is calling the previously defined FOO no matter what
10:32:49
loke
However, the following works, because #' looks up the function definition in the lexical scope:
10:34:01
xificurC
loke: I always imagined I can interchange value and function lookup, i.e. (let ((foo 1)) foo) to work the same way as (flet ((foo () nil)) (funcall 'foo))
10:35:22
loke
xificurC: Note that you pass the _symbol_ foo to funcall. It's FUNCALL that looks at the symbol and decides which function to call. Funcall isn't in the same lexical scope, so there is no way it could ever see your local definition.
10:35:44
_death
although it's interesting that the funcall entry says "symbol" instead of "function name"
10:37:02
_death
(of course this contradicts my statement, and only symbols are dealt with that way..)
10:37:46
xificurC
clhs even states for noobs like me "Within the function definitions, local function names that match those being defined refer to functions or macros defined outside the flet"
11:12:52
jmercouris
I'm going through gentle introduction to symbolic computation, and I am stuck on this problem: https://imgur.com/a/rTOIRR1
11:13:19
jmercouris
I understand why the example given is wrong, but I cannot think of how to solve the second part
11:19:38
jmercouris
schweers: it doesn't say that, but it simply says "as a combination of ANDs and ORs that does not fail"
11:20:01
jmercouris
I'm going through the book, imagining that I do not know things not yet introduced
11:20:19
schweers
okay, then we may assume that both frue-part and false-part are only one form (I hope)
11:20:33
makomo
does this alternative definition of IF have to return the actual value of the true-part, or can it just return t?
11:26:00
makomo
so it seems like this alternative definition is only good at selecting the right operation
11:33:50
jmercouris
because if the first clause returns t it will jump to the second block and return "t"
11:34:38
jmercouris
also in my first message, I did not mean to say "you'll never hit the second t block", I should have said, "you'll never get the evaluation result"
11:38:56
jackdaniel
little late on the party, but: (or (or (oddp 3) 'foo) (and (oddp 3) (evenp 7))) ; if we are willing to evaluate test twice in worst case
11:40:01
jackdaniel
so either (or (or TEST FALSE) (and TEST TRUE)) or (or (or TEST FALSE :nothing) TRUE)
11:51:34
jmercouris
I can't imagine how intimidated a new CS student would feel going through this book
11:54:11
makomo
there's a certain math textbook with lots of math exercises but *NO* solutions at all
11:54:22
makomo
the rationale is that "a mathematician should get used to the unavailability of solutions"
11:54:30
jmercouris
I already took software design classes in my undergraduate, and those were oftentimes ambiguous on purpose. I think the goal is to teach lisp, not generalized software engineering
11:54:55
jmercouris
there is a valuable lesson here, I just think this is the wrong book to teach it
11:56:21
makomo
_death: also, i think that the fact that side-effects can be ignored should be mentioned upfront, even if the book didn't get to side effects yet
11:57:32
_death
makomo: if they're actually reading the book they may notice that it's not yet introduced..
11:58:39
_death
that would get in the way of understanding for people who don't know what side-effects are, which forms a big part of that book's target audience, I'd think
11:58:45
makomo
instead of the book saying something like "ah remember that example? we didn't handle the problem of multiple evaluation then" later on
12:03:18
xificurC
so I'm not sure what the exact question is. But reading the discussions it was said the return value doesn't need to be kept. The last or isn't necessary but it is symmetric to the then part
12:18:49
jackdaniel
if block/return are allowed, then it is possible to return values too, otherwise I think it is not possible without null/not
12:19:29
xificurC
shrdlu68: given that I understood code blocks are only to be run for side effects that looks correct
12:21:00
shrdlu68
Unless there's a way to create NOT using AND and OR, I don't think this has a solution.
12:59:49
makomo
beach: and what if some of these before/after methods contain error checking that is not necessary within internal functions
13:00:17
makomo
and you want to avoid that extra work, since you know you're providing correct values as the implementor
13:01:17
makomo
i suppose the accessors are part of the external protocol? how do you name these internal accessors then?
13:02:20
beach
Not all accessor names are exported. The ones that aren't belong to some internal protocol.
13:05:11
makomo
beach: so in the case when you want to avoid error checking because hypothetically it might be expensive, do you have 2 accessors? a safe one which is part of the external protocol and an unsafe one which is part of the internal protocol?
13:05:38
makomo
i suppose the difference isn't that clear though, since you might offer safe and unsafe versions as part of the external protocol?
13:06:35
beach
makomo: Two options then. Either stick two accessors for the same slot and use some auxiliary methods only on the externally visible accessor. Or make the external generic function not an accessor and have its method(s) call generic functions in the internal protocol.
13:08:02
beach
makomo: I always work under the assumption that my stuff is fast enough, even with error checking. I design good data structures and algorithms to make that happen. So far, I have not had to make anything that is part of some external protocol "unsafe".
13:08:38
beach
makomo: I usually design the external protocol first, and I decide what I want it to do.
13:12:05
beach
makomo: Yeah, I rarely have to micro-optimize, and I always compile with speed 0, debug 3, compilation-speed 0, safety 3, space 0.
13:13:10
beach
makomo: Unless, of course my research is about highly optimized code, as in this one: http://metamodular.com/reverse-order.pdf
13:18:31
kuribas
why does compiling: (defun f (x y) (declare (type fixnum x y)) (+ x (* y 2))) give me: forced to do GENERIC-+ (cost 10) ; unable to do inline fixnum arithmetic (cost 2) because: ; The second argument is a (INTEGER -9223372036854775808 ; 9223372036854775806), not a FIXNUM.
13:22:16
Xach
SBCL (and possibly other implementations) will do efficient things with machine-word modular arithmetic.
13:22:56
makomo
are there any guarantees regarding the behavior of fixnums (such as overflow, etc.)?
13:23:27
Xach
if you declare something a fixnum and it is not that size, things are allowed to break.
13:25:48
shka
makomo: thing is, all those type declarations are geared mostly toward efficiency first, and type safety secondly at best
13:26:24
shka
so until you have program that works and is already debuged, you may prefer to skip manual type declarations
13:36:44
kuribas
So I understand correctly that there is no type which have the semantics of machine integers?
13:37:29
beach
jdz: Maybe in WSCL, I will be more strict about the meaning of type declarations, especially in safe code.
13:38:19
Bike
kuribas: but integers act like integers. semantics aren't determined by type in lisp. if you want arithmetic modulo whatever, you write the modulo yourself, and your compiler can try to lower that to machine arithmetic (sbcl does so)
13:40:48
beach
kuribas: Oh, it's safe if you carefully check for it each time. Now look at how many C programs assume that x + 1 > x.
13:40:49
_death
kuribas: what lack of performance? if you have speed 3 it's a shl and an add as it's supposed to be..
13:41:02
Bike
like old video games where you heal a bunch and end up with negative four million health
13:43:27
xificurC
kuribas: wrapping might be desired in *some* cases. It's not how the world works. Or do you suddenly have 0 apples when you buy 1 more but your basket is full
13:44:03
makomo
beach: in the case of signed integers, that is actually always true and could be optimized out by the compiler :-)
13:44:03
xificurC
if you want to write assembly or C, write assembly or C. Don't expect a high level language to magically generate the tightest code possible
13:44:48
makomo
there was a bug report on GCC's issue tracker where one guy was mad when GCC started making use of that optimization
13:44:52
_death
I don't understand why people suggest switching to a different language.. sbcl is sufficient here.. and if you still want more performance, just write your assembly routines in lisp :)
13:45:32
xificurC
_death: it feels natural when one is trying to get language X's behavior in language Y
13:46:38
beach
_death: You are right of course. But it seems kuribas is pouting because Common Lisp is not unsafe by default like other languages are.
13:47:06
_death
beach: I think kuribas did just that the other day as well.. and the answers were also similar
13:47:08
xificurC
shrdlu68: why are people under the impression writing good asm by hand isn't possible anymore? Make a few web searches
13:50:05
beach
_death: Oh, this one is a pearl: "<kuribas> I am not expecting anything in common lisp to be new or surprising..."
13:51:16
beach
And this: "<kuribas> you give up a large part of safety when programming in a dynamic language", especially given that kuribas now wants arithmetic to be unsafe by default.
13:52:56
jackdaniel
I think he means a compilation-time safety wrt types of function arguments. It can't be ignored as non-existent and CL indeed doesn't provide this kind of safety
13:54:22
_death
I don't see how modular arithmetic is unsafe.. it's just something you need to implement because + and * on integers use ordinary kindergarten arithmetic
13:55:57
jackdaniel
shrdlu68: type declarations give you nothing (they may be conformingly ignored), but you may do check-type. that gives you a runtime safety (you will be dropped in a debugger whne program runs and values of incorrect type are passed to the function)
13:56:06
beach
_death: And that is what so many programs in languages that use modular arithmetic seem to do, because I don't typically see any test for that situation each time I see an addition.
13:57:34
jdz
In missiles in general I've heard -- their justification being that the missile hits the target sooner than values get close to overflow values.
13:58:14
_death
beach: right.. but here the desideratum was modular arithmetic given ordinary arithmetic, not the other way around
13:58:33
jackdaniel
I've read about a bug found on a racket (namely a memory leak which lead to OOM after some time). racket was after expensive process of QA and other verifications
13:58:54
shrdlu68
jackdaniel: But your implemention can give guarantees, right? I mean, if an implementation does not ignore type declarations.
13:59:01
jackdaniel
so they have figured out what is a maximum memory usage taking into account this memory leak while racket is running (say max 30m) and they've added enough memory to the hardware
14:00:55
jackdaniel
shrdlu68: sure, that is possible, just as it is possible to have C compiler with some undefined behavior explicitly defined. either way, my point is that it gives you runtime safety, not compilation time, so it is somewhat weaker
14:01:51
jackdaniel
I'm not saying that this kind of safety is crucial for good applications or that it improves overall quality
14:01:58
White_Flame
kuribas: if your input numbers are declared or inferred to be, say, between 0 and 1000, then the output can be inferred to be between 0 and 3000, keeping it a fixnum
14:02:06
jdz
OK, today I've learned that I've been relying on type checking behaviour that's very specific to SBCL. I guess I'll have to use SBCL exclusively from now on, because I like this behaviour.
14:03:05
jdz
Yeah, I've been keeping my code SBCL/CCL agnostic, but it is getting harder as time passes by.
14:03:57
jdz
But I definitely remember CCL giving me errors when SBCL hasn't. Don't have a record of particular instances, though.
14:05:24
jackdaniel
example are :type declarations for slots, CCL given high enough safety enforced it when you were using accessors. I think SBCL started doing that recently too
14:21:29
specbot
Splicing in Modified BNF Syntax: http://www.lispworks.com/reference/HyperSpec/Body/01_daba.htm
14:24:52
makomo
a question regarding CLOS style -- do people differentiate between using :default-initargs and :initform? the difference is subtle and i haven't seen :default-initargs used that often
14:25:25
beach
You typically use :default-initargs in a subclass to initialize slots in the superclass.
14:26:33
beach
That way, the subclass does not care how the initarg is used. It could be to initialize a slot, or it could be caught by initialize-instance.
14:27:13
makomo
i.e. i'm defining a slot within some class for the first time and i have to choose between :default-initargs and :initform
14:28:28
makomo
i've seen it discussed in the CLOS book even, but the difference was artificial and served mainly to communicate intent (but i don't know how well it does that)
14:29:31
beach
If the library is well written, it only documents initargs and accessors, not the existence or not of slots.
14:30:13
beach
So, you then use :default-initargs in your subclass, simply because it is your only option if you want to use only publicly documented features of the library.
14:31:11
makomo
aha, since you have no knowledge of the superclass' slots and cannot duplicate the definition just to change the :initform
14:32:29
beach
makomo: Your questions (and your reactions to my answers) make me think that you will make fast progress, so I don't mind answering them.
14:33:12
beach
makomo: By the way, I can't remember whether I told you, the last Common Lisp HyperSpec reference about keyword arguments makes me think that an error should be signaled for you case.
14:35:18
specbot
Keyword Arguments in Generic Functions and Methods: http://www.lispworks.com/reference/HyperSpec/Body/07_fe.htm
14:37:14
Bike
what was the setup again? (defgeneric foo (&rest r)) (defmethod foo (&key c) ...) (foo :d ...)?
14:38:04
specbot
Congruent Lambda-lists for all Methods of a Generic Function: http://www.lispworks.com/reference/HyperSpec/Body/07_fd.htm
14:38:25
makomo
and as we said, case 4 shouldn't apply in this case, since the GF doesn't have a &key in its lambda list
15:22:45
xificurC
(let ((x '(1 2 3))) (check-type x ?)) to check if x is a list of numbers with unknown length
15:25:42
pjb
xificurC: (defun list-of-number-p (x) (and (com.informatimago.common-lisp.cesarum.list:proper-list-p x) (every (function numberp) x)))
15:26:04
makomo
pjb: what does it do? i just tried to use it like (check-type (name spec) symbol), where NAME is a reader function, and i'm getting warnings since CHECK-TYPE is expanding into (setf (name spec) ...)
15:28:35
_death
makomo: yes.. check-type sets up restarts that may modify place to have a value of the proper type
15:29:13
sjl
sure, use (alexandria:proper-list-p list) instead of listp if you want to enforce proper lists
15:29:37
pjb
Sometimes you want to implement your own I/O loop validating the type of the inputs (notably if you have to do some parsing or conversions), but in simplier cases, check-type is a great operator!
15:58:15
Xach
I like cerror and try to use it when I can. I didn't really think about it for a long time.