freenode/#lisp - IRC Chatlog
Search
0:34:41
Bike
the reason it happens is that docstrings are associated with underlying functions rather than closures, of course.
0:41:16
pillton
I am not sure I understand the difference between your example and https://plaster.tymoon.eu/view/824#824.
0:43:49
Bike
In my example the two functions almost certainly have the same underlying, eh, code object.
0:49:22
ealfonso
perhaps not a good idea, but in defstruct is it possible to spcify a default init form that uses a previously defined slot? is there a way to access "this"?
0:50:00
Bike
there isn't, but you could define a constructor that uses another parameter as a default
0:50:20
aeth
Whenever I do anything fancy with struct initialization, I tell it to make the constructor a %make-foo and I write my own make-foo constructor using %make-foo
0:51:34
devon
(format nil "~,6F" 3738064606071093/1000000) => "3738064600.000000" ; I'd prefer "3738064606.071093"
0:54:27
aeth
#'float is a bit awkward. It defaults to your default float format (in your case, and in most cases, that's single-float), but if you want to use another float format you have to provide some number of that format, in this case 1d0 (the "d0" instead of "e0" forces it to be a double)
0:57:09
aeth
Actually, apparently the default is always single-float. The difference between #'float and #'coerce is that #'float won't coerce something that is already a float.
0:59:39
Bike
you might want to consider laying out the decimal yourself. it's kind of a pain, but it beats weird rounding unintuitiveness.
1:00:34
Bike
like (multiple-value-call #'format nil "~d.~d" (floor 3738064606071093 1000000)) i mean.
1:02:59
aeth
If you do something like this you should probably write a unit test that compares it to the float version. They could differ, but if the decimal part differs by an order of magnitude or more, that's probably the leading 0s bug popping up or something similar
1:03:18
devon
Thanks, (format nil "~,6F" (coerce 3738064606000000/1000000 'double-float)) sure beats (let* ((n 3738064606071093/1000000) (s 1000000) (sn (* s n))) (multiple-value-bind (q r) (floor sn s) (format nil "~D.~6,'0D" q r)))
1:04:45
aeth
yeah, most of the time you use multiple-value-bind, you probably actually want multiple-value-call
1:15:03
pillton
Bike: Well, I think that documentation sharing thing is wrong. Imagine the surprises someone would have when using the programmatic interface to construct an environment. Secondly, an implementation may consider "compressing" code in fasls by sharing code objects.
1:20:24
devon
THX² Bike, aeth: (let ((n 3738064606071093/1000000)) (string= (format nil "~,6F" (coerce n 'double-float)) (let ((s 1000000)) (multiple-value-call #'format nil "~D.~6,'0D" (floor (* s n) s))))) => T
1:22:53
Bike
if you have a fraction already just do (format nil "~d~6,'0d" (numerator n) (denominator n))
1:25:33
aeth
devon: you wouldn't want string=, though, you'd want to find where the . is and then parse-integer and then divide the larger one by 10 until they're of the same base-10 length (but not quite beacuse you also have to take into account leading 0s) and then compare them.
1:27:30
aeth
Bike's version will prefix 0 for leading 0's to get it up to 6, but if the part after the decimal point is longer than 6, it will display them all. Afaik, the double float version will always cut it off after 6 decimal places after the decimal point. So the lengths could differ.
1:42:38
devon
Printing present-day universal times to µs, DOUBLE-FLOAT-EPSILON seems perilously close to dropping a low order bit. Perhaps it's time to define ~:F
1:52:33
devon
(format nil "~,,-6F, ~:*~,6,-6F" 1) => "1.0, 0.000001" ; is this a bug in CCL or a bug in the spec?
2:07:36
aeth
destructuring bind is most useful in macros. In fact, the lambda list of macros kind of builds it in to save a few levels of destructuring-binds.
2:08:36
aeth
a macro's lambda list might be (name (x y) &body body) and that's equivalent to it being (name parameters &body body) with a destructuring-bind in the macro of (destructuring-bind (x y) parameters ...)
2:11:20
aeth
So you're ensuring that a list matches some pattern, and binding the elements to that pattern. in (destructuring-bind (x y) (list 1 2) ...) x will be 1 and y will be 2. And (list) will be an error and (list 1 2 3) will be an error
2:12:43
aeth
The structure in destructuring-bind can be complicated like (x (y &optional z) (u (v &rest w)) &key a b c)
2:13:37
aeth
With multiple-value-bind you're just dealing with a bunch of values. so (multiple-value-bind (a b c) (values 1 2 3) (+ a b c)) => 6
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