freenode/#lisp - IRC Chatlog
Search
15:16:11
makomo
pjb: as i learned myself the other day, you should probably handle the case of *READ-SUPPRESS* being bound to T within your reader macros
15:23:26
pjb
Because you're mutating the variable place1, which has nothing in common with the variable x in (let ((x '())) (push2 1 x) x)
15:26:33
beach
asdf_asdf_asdf: So if you understand that C code (you didn't say either way), then you know that add2(234, x) does not alter x.
15:27:19
beach
asdf_asdf_asdf: Similarly, in Common Lisp, if you call push2 with a variable as a second argument, that variable is not altered by the call to push2.
15:28:11
pjb
Instead, use: (defun push3 (item1 place1) (cons item1 place1)) (let ((x '())) (setf x (push3 42 x)) x)
15:29:18
pjb
(setf (aref (gethash :v *h*) (round (* 10 (sin theta)))) 42) this evalautes (gethash :v *h*) and (round (* 10 (sin theta))), but not (aref (gethash :v *h*) (round (* 10 (sin theta)))).
15:30:38
beach
Aruseus: But SETF itself does not evaluate to anything. It is not in a position to be evaluated.
15:32:46
beach
Common Lisp terminology is not very "fault tolerant", so it is important to use precise terminology.
15:38:47
_death
results---the multiple values[2] returned by the storing form for the last place, or nil if there are no pairs.
16:08:09
asdf_asdf_asdf
How change global variable inside function? (defvar *x* 5) (defun aaa (a) (setf a 6)) I want: *x* => 6. How it do? Thanks.
16:09:04
beach
asdf_asdf_asdf: You ask many questions, but you don't like to answer the ones that you are asked do you?
16:09:57
pjb
asdf_asdf_asdf: but actually, have a look at: https://www.informatimago.com/articles/usenet.html#C-like-pointers-in-Lisp
16:10:51
beach
asdf_asdf_asdf: OK, so if you do int x = 5; then void set_global_binding (int a) {a = 6;}
16:12:33
beach
asdf_asdf_asdf: Like C and most other languages, Common Lisp uses "call by value", meaning that argument expressions are evaluated before the function is applied to those values.
16:20:04
beach
asdf_asdf_asdf: pjb's examples are often too sophisticated for someone at your level.
16:22:17
asdf_asdf_asdf
(defun aaa (&treat_as_original a) (setf a 100)) => AAA. (defvar *x* 0) (aaa *x*) => 100 *x* => 100.
16:25:56
beach
asdf_asdf_asdf: Common Lisp has something called "macros" that can be used exceptionally for situations like that.
16:30:02
beach
asdf_asdf_asdf: As a first-order approximation, it is generally a bad idea to have variables in the caller be modified by a function call.
16:38:16
beach
asdf_asdf_asdf: If you tell me your native language, I will check and see if there is an equivalent page.
16:42:26
beach
asdf_asdf_asdf: Why not, there are plenty of smart Polish people here that could help you in your native language.
17:09:01
pjb
asdf_asdf_asdf: you need to quote the argument, since SET works on symbols. Didn't you read clhs set?
17:09:35
pjb
(defun set-dynamic-binding (var val) (set var val)) (defvar *x* 0) (set-dynamic-binding '*x* 42) *x* #| --> 42 |#
17:10:39
pjb
asdf_asdf_asdf: so it is possible. But you should not do that! First, you should not use global variables!
17:12:05
pjb
Then since arguments are passed by value, the language doesn't help you. Mutating the symbol-value slot, which is what SET does, the modern way to write (set var val) is (setf (symbol-value var) val), is just that. It's not a general solution. See the articles linked above for a general solution using closure. Which is sophisticated, and demonstrate again that you don't want to do that!
17:12:38
pjb
There's no point in reproducing the bad things of C in CL! Use CL to write BETTER programs! Don't try to mutate your arguments.
17:12:55
pjb
Instead, if you insist on using mutation, you can mutate the objects, the _values_ of your parameters.
17:13:52
pjb
(defun my-mutating-fun (v) (incf (aref v 0))) (defvar *vals* (make-array 3 :initial-element 0)) (my-mutating-fun *vals*) *vals* #| --> #(1 0 0) |#
17:22:51
c0mrade
I've made an IRC bot that prints to a dot matrix Star printer on its serial port at ##robot, everything you type there is printed to it and it's on Live Stream on YouTube at https://youtu.be/zwRL5V0XWQY
17:32:51
jcowan
Is it normal for interactive restart handling of USE-VALUE, STORE-VALUE, etc. to evaluate the expression read from the user that specifies the new value?
17:40:35
jcowan
I am specifying (and will be writing) a TTY-style interactor as part of the Scheme restart package I am also specifying.
17:41:26
jcowan
However, the current interactor will be held in a dynamic variable so that it can be replaced completely or rebound in a dynamic scope, such as by a TUI, GUI, or browser interactor.
19:08:13
rdap
I usually tend to come here when i find myself lost with a problem, and I guess this time is no exception.
19:12:32
beach
If you want me to try to help, you had better state your problem very soon, because I am about to quit in order to go spend my (admittedly small) family.
19:12:58
phoe
and if not, take your time, and let the rest of #lisp try to help while beach is off IRC
19:14:02
rdap
Oh, no worries. It's not urgent, and either I'll figure it out after reading more, or I'll have a more clearly stated problem.
19:17:37
phoe
rdap: when do you need the test to be evaluated and when do you need to break the loop?
19:18:14
rdap
i need the test to be evaluated before the loop runs (next), and for it to break there when the condition is met
19:24:48
pjb
(defmacro if (test consequent &optional alternative) `(loop repeat 1 if ,test do (progn ,consequent) else do (progn ,alternative)))
19:28:04
pjb
phoe: this is why sicl implements loop first, and then use it to implement the rest of CL ;-)
20:48:48
_death
(defun euler-1 () "Return the sum of all natural numbers below 1000 that are multiples of 3 or 5." (loop for x below 1000 when (or (multiple-of-p x 3) (multiple-of-p x 5)) sum x))
20:58:51
caltelt
The most straightforward way: (let ((threes (loop for x.....)) (fives (loop for x ...)) ...)
21:02:52
pjb
(defun times (n) (lambda (x) (* n x))) (reduce '+ '(3 5) :key (lambda (f) (reduce '+ (mapcar (times f) (iota 1000))))) #| --> 3996000 |#
21:02:53
rdap
pjb: there really is no point, it's just something that got carried over when i was trying each piece at a time
21:03:27
pjb
or even (reduce '+ '(3 5) :key (lambda (f) (reduce '+ (iota 1000) :key (times f)))) #| --> 3996000 |#
21:04:49
pjb
*** Essadon (~Essadon@81-225-32-185-no249.tbcn.telia.com) has quit: Ping timeout: 250 seconds
21:04:57
pjb
<pjb> (defun times (n) (lambda (x) (* n x))) (reduce '+ '(3 5) :key (lambda (f) (reduce '+ (mapcar (times f) (iota 1000))))) #| --> 3996000 |#
21:05:00
pjb
<rdap> pjb: there really is no point, it's just something that got carried over when i was trying each piece at a time
21:05:04
pjb
<pjb> or even (reduce '+ '(3 5) :key (lambda (f) (reduce '+ (iota 1000) :key (times f)))) #| --> 3996000 |#
21:07:33
_death
"If there is a duplication between list-1 and list-2, only one of the duplicate instances will be in the result. If either list-1 or list-2 has duplicate entries within it, the redundant entries might or might not appear in the result."
21:08:06
pjb
Yes, so from iota this should work. (reduce '+ (union (mapcar (times 3) (iota 20)) (mapcar (times 5) (iota 20)) )) #| --> 1430 |#
21:08:20
pjb
(reduce '+ (union (mapcar (times 3) (iota 1000)) (mapcar (times 5) (iota 1000)) )) #| --> 3697500 |#
21:09:43
jcowan
There's a Scheme library that provides both behaviors (treat all elements in an input list as distinct, treat elements in a list as possibly nondistinct). It would be trivial to translate it.
21:12:04
pjb
(reduce '+ (union (mapcar (times 3) (iota (truncate 1000 3))) (mapcar (times 5) (iota (truncate 1000 5))) )) #| --> 232169 |#
21:13:12
pjb
actually, I have a iota that does: (reduce '+ (union (iota 1000 0 3) (iota 1000 0 5))) #| --> 3697500 |#
21:13:49
pjb
(reduce '+ (union (iota (truncate 1000 3) 0 3) (iota (truncate 1000 5) 0 5))) #| --> 232169 |#
21:14:45
_death
(collect-sum (choose-if (disjoin (multiple-of 3) (multiple-of 5)) (scan-range :below 1000)))
21:18:19
grewal
(- (+ (loop for x from 0 below 1000 by 3 summing x) (loop for x from 0 below 1000 by 5 summing x)) (loop for x from 0 below 1000 by 15 summing x))
21:26:53
grewal
_death: (defun add-multiples-below (p1 p2 bound) "TODO: implement values for other arguments" 233168)
21:32:28
aeth
The programmatic solution to _death's problem: (defun foo () #.(- (+ (loop for x from 0 below 1000 by 3 summing x) (loop for x from 0 below 1000 by 5 summing x)) (loop for x from 0 below 1000 by 15 summing x))) (disassemble #'foo) (foo)
21:32:59
aeth
You get a function that constantly returns 233168 with no computation, but *you* don't have to compute it and hardcode it yourself!
21:56:28
Grue`
(flet ((asum (k) (let ((n (floor 1000 k))) (* k (* n (1+ n)) 1/2)))) (+ (asum 3) (asum 5) (- (asum 15))))
1:24:17
rdap
Grue`: I know... it's just something that was left from experimenting with doing it in a piecemeal fashion. The only reason it was there was so I could catch duplicates side by side when viewing the list after append. But you're right, it wasn't needed in the final solution.
2:34:28
minion
didi, memo from Grue`: you can avoid that with (funcall 'square ,y) because then you're only calling standard functions which cannot be redefined with flet, and 'square takes the global definition of square
2:36:02
didi
I was reading a paper by Constanza et al about hygienic macros in Common Lisp. Interesting stuff.