freenode/#lisp - IRC Chatlog
Search
1:36:00
nij
Should I consider using SICL over SBCL? I heard that the former is "cleaner" without understanding.
1:43:32
martinodb
hi! i have a question. I'm trying the maiden IRC framework, so this maiden-silly agent connected to an IRC channel, but it doesn't talk to me at all. The documentation says something about activating it. Doesn't it do anything out of the box? do I have to edit the code? thanks!
1:50:27
nij
"Everything should be in a repl cuz that's the coziest place to have fun.. including the repl itself!"
1:50:41
no-defun-allowed
If you are only interested in cleanliness, then your code would be subject to the ugly parts of both SBCL and SICL.
1:54:14
mister_m
I accidentally did an infinite recursion in the repl (using slime), I'd like to stop this without killing my inferior lisp process, how can I do that from within the REPL buffer? C-c C-c doesn't seem to do anything
2:07:40
mister_m
maybe I just missed the SLDB buffer that was created on C-c C-c in the REPL buffer.
3:19:48
asarch
I did a downgrade to Debian Stable and its Emacs 26.1 has been failing to get the M-x 'package-refresh-contents' to install Slime
4:00:56
White_Flame
mister_m: if your inferior-lisp gets dropped into ldb, you probably blew the heap, or the stack twice
4:03:35
dieggsy
asarch: melpa has been odd recently. I don't use it as my package repo but I search their website sometimes and it's been extremely slow
5:09:30
White_Flame
the lack of interchangeability of different communications stream styles is a general problem, across many domains
5:11:52
White_Flame
I don't know enough for it to be a definite "no", but such situations hit me too often between other stream interfaces
6:12:26
beach
pbaille: #lisp is not really for trivial questions, but such questions are tolerated, especially if traffic is low. If trivial questions become too annoying, you may get redirected to #clschool which is meant for such questions.
6:13:21
beach
pbaille: On the other hand, some newbie questions are not trivial, and the answers to them are often worth repeating here, like for instance the semantics of function calls and argument passing.
6:18:25
pyc
Does https://plaster.tymoon.eu/edit not work anymore? I tried it many times but it does not return me a link I can share. The input just disappears after posting my snippet.
6:20:23
pbaille
I was curious about code equivalence those days. Is there any known works around that. for instance determining the equivalence of those 4 expressions:
6:21:05
beach
pbaille: That would be an undecidable problem in general, so I think you are out of luck.
6:21:07
pbaille
sorry I'm discovering IRC... the four expressions posted where intended to be after my question. all my apologies.
6:21:11
no-defun-allowed
You may reduce the first three to the fourth using substitution in this case, but generally equivalence is equivalent to the halting problem.
6:21:21
pyc
no-defun-allowed: thanks! I can see your post. I wonder why it does not work for me. When I click post, it goes back to the https://plaster.tymoon.eu/edit and the input disappears. I don't get any link I can share.
6:22:04
pyc
no-defun-allowed: are you logged into https://plaster.tymoon.eu/edit ? or did you use it without logging in? I am not logged in.
6:22:19
flip214
pbaille: you could try to use macro expansion to rewrite all expressions to a minimal subset - eg. replace LET by a LAMBDA form.
6:22:56
flip214
but then you'd still need quite a few manually defined rules - eg. the order of variables in LET can be different.
6:24:12
flip214
and you might need an expression simplifier to see that (* (- a b) (+ a b)) equals (- (* a a) (* b b)) and so on.
6:24:37
flip214
so you can arbitrarily far, depending on how much time/effort you're willing to spend...
6:24:52
pbaille
but maybe bindings can be ordered using kind of an hash of the value they are bind to
6:25:07
flip214
OTOH, I can also see an alternative way -- compile the expressions, and try to prove that the machine code gives identical results.
6:25:27
Nilby
As you may know, there are many undecidable in general problems which are quite worthwile and solvable in specific.
6:25:31
flip214
Ie. like decompiling back to C or so... that would get rid of many small differences in the sources
6:25:34
moon-child
that throws away information. It is likely to be harder to prove interesting facts about machine code than about lisp code
6:26:33
flip214
moon-child: not necessarily... at least that's a well-defined set of basic instructions.
6:26:34
moon-child
those 'small differences' are things you need to be able to handle anyway. Many of them will result from compiler optimizations, the sorts of analysis underlying which you will need to replicate if you would like to automatically prove things about code
6:27:51
Nilby
pbaille: You're welcome. I think too many time people are discorged from finding useful solutions to undecidable in general problems.
6:28:57
pyc
got some clue about the pastebin issue. When I submit in the browser's network tab I see a POST being made to this URL: https://plaster.tymoon.eu/?error=You%20did%20not%20enter%20the%20captcha%20correctly.
6:31:59
pbaille
flip214: thank you for your suggestions. I've worked on those kind of things a few months ago (in clojure), I will try discuss it with you guys a bit later. thank you
6:40:06
beach
saganman: It just barely started. I need to download some screen-recording program to my new desktop computer and record my ELS talk. What about you?
7:17:02
pyc
Is this a good coding style: https://pastebin.ubuntu.com/p/Y7Y35fwjRW/ ? What I am doing here is computing everything in (let* ...) and returning what I need as a separate expression in the end. Does it look odd to experienced Lisp programmers?
7:22:06
jdz
And I think the function should accept a string, and reading file contents into a string should be done somewhere up the call chain.
7:22:17
pyc
jdz: in that case this code will fail with error. I can definitely improve the error handling. however is my style of doing all computation in (let* ...) and then returning just that one thing I need to return in the end proper coding style? Coming from other languages, it felt odd to me, so wanted the opinion of experienced programmers here.
7:23:09
beach
pyc: Again, you can probably leave out the last binding, because the name of the function should be enough to tell what the result of it would be.
7:23:17
jdz
You could make this into a generic function, with methods on specializing on STRING and PATHNAME.
7:25:11
pyc
jdz: yes, I was considering that alternative too. Certainly the whole thing can be written without let binding. so can I assume that experienced Lisp programmers avoid LET binding whenever possible? Or is it just another alternative and both alternatives (LET or no LET) are equally valid and good?
7:29:08
moon-child
in this case, though, for the purposes of efficiency I might keep track of the position of the {{{, to avoid needing to look over so much of the string for the }}}
7:30:33
pyc
moon-child: great point! in fact I do need to ensure that I search for }}} *after* {{{ and ignore any }}} before {{{. so I do need to keep track of its position.
7:31:19
jdz
pyc: I do not favor _fewer_ bindings, but introducing them unnecessarily just create more clutter and more work for brain.
7:33:03
moon-child
naming things is difficult. The wrong name is worse than no name at all; the former may mislead, where the latter is self-evident in its use
7:33:17
jdz
flip214: Sure. But that's the thing about commenting—there's no point commenting trivial code.
7:34:02
moon-child
(self-evidence may be insufficient when the thing being evinced is sufficiently complex. But.)
7:34:11
flip214
jdz: "trivial" depends on the consumer ;) and a few weeks later the author herself might be glad about one more name
7:40:33
Nilby
When coding in a forth-like language I frequently had to comment almost every line with the presumed state of the stack.
7:42:18
pyc
an off-topic question. Can forth operators act on arbitrary number of arguments. For example, Lisp can do (+ 1 2 3) where + takes any number of arguments. It is of course possible because we can delimit the call with ). Is such a thing possible in Forth?
7:44:58
pyc
Nilby: how would the operator know how many arguments the programmer wants to add for example when there are no delimiters to specify that?
7:45:09
Nilby
A common thing with varibale arguments is to have a count or a fencepost on the arglist.
7:45:32
pyc
Nilby: say, I make a Forth operator op, and I write 1 2 3 4 5 op. How would it know if I want op to consume 2 arguments or 3 arguments or 4 arguments?
7:46:00
pyc
Nilby: by fencepost, you mean, some sort of special value I keep on the stack to mark the end of list of arguments?
7:46:59
pyc
Nilby: okay, understood. so the responsibility for that falls on the programmer unlike Lisp where the paren-based syntax itself takes care of it.
7:48:52
pyc
Oh right! That gives me ideas! Write Lispy code in Forth by using ( and ) fenceposts and defining operators to work on them. :-D
7:50:00
jdz
Nilby: How are those "fenceposts"? Aren't they just numbers (ASCII codes for the characters)?
7:50:54
pyc
yes, they will just be numbers (ASCII code for the characters) although there is syntax to specify them as literal characters while the compiler still puts their ASCII codes on the stack.
7:51:28
jdz
pyc: The case when the number of arguments is lexically apparent in the code is not very interesting, is it?
7:52:08
Nilby
Interestingly if you do object oriented forth, the order seems revered to prefix, so you say: object message message ...
7:57:15
moon-child
jdz: yes, but they can still have local variables. E.G. examining the python bytecode for 'lambda x, y: x*x+y' reveals LOAD_FAST instructions referring to the parameters
8:03:04
Nilby
jdz: forth has "words" which are equivalent to lisp symbols which are looked up a dictionary. Like lisp, some symbols evalualte to themselves, like T, so can be used for fenceposts.
8:09:09
jdz
Nilby: Yes, I know that much. But you're talking about compile-time fenceposts, not runtime, right?
8:11:43
Nilby
jdz: I don't think there's as big distinction in forth. It's still just a word on the stack. I suppose in an optimizing forth compiler could optimize the fencepost out in a compiled procedure.
8:15:28
Nilby
I think you're right, in pure forth. I guess what I used wan't pure forth, so it did have tagged objects and garbage collection.
8:20:52
Nilby
The most pure forth coding I did was in a bootloader and I can't remember if it had tagged objects or not. The forth-like language I used most was https://en.wikipedia.org/wiki/NeWS
8:25:27
no-defun-allowed
Most Lisp, Python, Smalltalk, Java, etc VMs look like the SECD machine more precisely, which has an explicated environment of some sort.
9:33:38
pyc
what is wrong with this code? https://pastebin.ubuntu.com/p/NRWXCB87tk/ - From my reading of http://clhs.lisp.se/Body/m_w_out_.htm , I should be able to specify a variable name that is not defined yet. What am I doing wrong here?
9:34:33
pyc
ohh! big typo. I meant with-output-to-string but I typed with-output-to-stream. let me fix that and try again
9:35:10
loke[m]
Thus, it's first trying to call a function called STREAM before calling a function called with-output-to-stream
9:53:34
beach
phoe: http://metamodular.com/SICL/call-site-optimization-talk.mkv is my talk. It is a bit more than 20 minutes long. There is a typo on one of the slides that I have since fixed, but I am not going to re-record the talk.
10:42:19
pyc
If I have a key name as a string, e.g., "a", can I convert it to :a so that I can use it with functions like getf to look up a plist?
10:44:12
pyc
pyc: Here is an example that describes my question in detail: https://pastebin.ubuntu.com/p/2HJD8QDjFW/
10:51:29
engblom
If I pass an object to a function, is it a reference to the object or a copy of the object that is passed?
10:53:48
engblom
I mean, if I have (defun foo (obj) ...) and I call it with (foo my-obj), is a copy of my-obj passed or a reference?
10:54:26
Nilby
engblom: It's not exactly either. It's a lisp object which can be a reference or a value. E.g. 1 is a value, *readtable* is a reference.
10:55:11
daphnis
if a class's slot symbols are package-specific, how does one export a function that uses the class? i get "When attempting to set the slot's value to ... the slot .... is missing from the object .... It has a slot pac1::slt, while pac2::slt is requested.
10:55:16
pjb
engblom: (while technically numbers and characters may be passed by value when they're small enough, since they're not mutable, there's no difference).
10:55:57
pjb
daphnis: one cannot export functions from package. packages only deal with symbols. You can export a symbol from a package.
10:56:27
phoe
and that you likely should not use it, and instead should use accessor functions whose names are actually by the package in question
10:56:47
phoe
if you absolutely need to set it and bypass this, then use the fully qualified name: (setf (slot-value foo 'pac1::slt) ...)
10:57:30
pjb
daphnis: the reason why is because accessors are methods, code, they can manage the consistency of the object. Perhaps setting a slot implies modifying another sslot, or sending a messasge to another object? If you use slot-value, this cannot occur. If you use an accessor that is overriden, the class can manage it.
10:58:40
pjb
The only values that may not be references are as I mentionned numbers and characters, which are not mutable, and therefore makes no difference if they're passed as value (copied) instead of reference.
10:59:07
pjb
_death: but even in that case, most numbers and most characters may still be passed by reference, because they're big (bignums, complex, ratio, etc).
10:59:40
phoe
in C++, you can assign a refrence and have the referent modified, which is like mutating a place from inside a function in Lisp
11:00:03
_death
pjb: right, but saying lisp uses pass by reference is misleading.. the values (which may be references) are copied
11:00:29
pjb
pyc: (prog1 one-is-the-result and not the rest) (prog2 nope two-is-the-result and not the rest) (progn not this not that but the nth-is-the-result)
11:02:30
pjb
_death: granted, saying that lisp uses pass by reference may be misleading, because in C++, references are references to the variable passed, while in lisp I mean that the value bound to a variable is a reference that is passed. So sorry. lisp is pass by value, but all values are references. (apart a few possible immutable exceptions).
11:04:38
phoe
the issue is that there is C++ pass-by-value and C++ pass-by-reference, and the only good answer to "is Lisp pass by value or pass by reference?" is "neither"
11:05:28
engblom
If I change my question a bit: would passing an object to a function which then modifies the object change the original object?
11:06:51
Nilby
I know both pjb and _death know exactly what lisp object is, so it's amusing that thare can be ontological debate about it.
11:07:40
pjb
engblom: the reference to the object is copied from the argument to the parameter variable.
11:08:01
pjb
engblom: hence pass-by-value, but since the value is a reference, it's pass-by-identity.
11:09:27
phoe
since it's the nth time I've seen this discussion and it would be good to store a compressed version of it somewhere
11:10:56
pjb
phoe: or just a little drawing, of objects in a heap, with arrows from variables to them and between them.
11:11:39
phoe
pjb: lemme quickly write down a sketch of what I am thinking about and I'll post it here for review
11:18:07
_death
phoe: in C (and C++) you can also pass references by value.. if you have an int a, you can pass &a, which is a pointer (a reference).. the pointer is copied and may be dereferenced
11:19:18
Odin-
ACTION got the impression from the Lisp 1.5 manual that conceptually all Lisp objects are references.
11:20:24
_death
phoe: in C++, you can pass the int by reference.. the callee states that a reference to int should be passed, by taking an int & parameter..
11:21:22
codecaveman
I want to write an iterative recursive factorial function which does work backwards: I mean my fact(a b) = { (a=0)->b; fact(a-1, a*b) } function multiplies numbers downwards n*n-1*n-2..3*2*1 can I write one which does 1*2*3*...(n-1)*n using only two variables?
11:25:10
pjb
(defun fact (n r) (if (zerop n) r (fact (1- n) (* n r)))) (fact 10 1) #| --> 3628800 |#
11:26:02
pjb
(defun fact (n i r) (if (= i n) (* n r) (fact n (1+ i) (* i r)))) (fact 10 1 1) #| --> 3628800 |#
11:27:14
no-defun-allowed
I would think you could with a cons or a closure to put two values in one argument, but that is following the letter and not spirit of what you asked.
11:27:20
pjb
codecaveman: but you would wrap any recursive function with accumulator into a normal function: (defun ! (n) (fact n 1 1)) #| --> ! |# (! 10) #| --> 3628800 |#
11:28:25
pjb
codecaveman: (defun fact (n) (loop for i from 1 to n for r = i then (* i r) finally (return r))) (fact 10) #| --> 3628800 |#
11:28:51
pjb
The recursive function with accumulator is equivalent to this loop anyways. The compiler can generate exactly the same code for both!
11:29:04
phoe
unless you have a clever trick of sorts to encode three numbers inside two numbers, probably not
11:31:43
daphnis
i'm trying to use accessor functions instead of slot-value, but since what slot to access is to depend on arguments, i'm trying (setf (funcall . . . and that doesn't seem to work: "The function (setf funcall) is undefined . . ."
11:33:52
phoe
if the accessor looks like (foo bar baz quux), then you should be able to (setf (foo bar baz quux) new-value)
11:34:12
_death
hmmm.. but yeah, the answer should likely be that you should pass (setf foo) to funcall
11:34:33
daphnis
yeah, but i want to give the name of the accessor function as an argument to the function that sets it
11:35:36
engblom
When being in repl, is there anything I can write to see the source or description of something. For example if I want to know what arguments map is taking, can I check it from repl?
11:35:43
pjb
daphnis: (defun function-that-sets (writer object) (let ((new-value 42)) (funcall writer new-value object))) (function-that-sets (function (setf answer)) question)
11:36:38
pjb
(defclass question () ((answer :accessor answer))) (let ((q (make-instance 'question))) (function-that-sets (function (setf answer)) q) (answer q)) #| --> 42 |#
11:39:10
_death
if you're using slime, I saw this recently: https://github.com/mmontone/slime-doc-contribs
11:39:48
pjb
daphnis: with setf apply you need to put (function accessor) literally in the apply place: (let ((q (make-instance 'question)) (a (function answer))) (setf (apply a (list q)) 42)) #| ERROR: Setf of Apply is only defined for function args of form #'symbol. |#
11:40:13
pjb
(let ((q (make-instance 'question))) (setf (apply (function answer) (list q)) 42) (answer q)) #| --> 42 |#
11:41:14
pjb
engblom: you can also know what argument an operator take, just by typing (map spc in a lisp/slime buffer. Then slime will query the lisp image, and display the required arguments in the minibuffer.
11:43:24
daphnis
so i probably need to use slot-value then? and then it seems that i need to export each slot symbol in order to use the function in a new package. maybe i just put more into one package.
11:43:27
pjb
daphnis: perhaps you're doing meta protocol stuff, and using the slots directly with slot-value is the right thing in your case. It depends on what you are doing. What are you doing?
11:45:14
pjb
But again, it depends on what you're trying to do, but this seems to be a state secret.
11:45:59
engblom
Is there something that is between let and setf, so the scope is limited to the whole function rather than either having a limited scope as in let or then a global variable as in setf?
11:47:12
engblom
I am asking because I would want to write some code that would require a lot of nested let, and making the variables scope to be the whole fucntion would be handy in this case.
11:47:22
pjb
engblom: you can also define function local variables with &aux in the lambda-list, but we usually reserve this for macro expansions, since it let you add local variables without having to deal with docstrins and declarations.
11:48:29
pjb
but we prefer the (defun foo (…) (let ((x 1) (y 2) (z 3)) (list x y z))) style (foo 33) #| --> (1 2 3) |#
11:48:58
pjb
engblom: also, note how nice LET is, since it lets you bind values to the variables. So you don't need setf.
11:49:58
daphnis
i have an object representing a letter and the slots represents various features, like case, accent, name, etc. the method changes one of those features. e.g. (furnish ltr :acute) should lead to the accent slot's being set to :acute
11:50:09
engblom
no-defun-allowed: Because I would need to do (let ((some thing)) (do-something else) (let((more things)) (do-again-something-else))
11:53:46
pjb
(defun furnish (letter trait value) (ecase trait (:case (setf (casse letter) value)) (:accent (setf (accent letter) value)) (:name (setf (name letter) value))))
11:54:20
pjb
daphnis: perhaps instead of writing (furnish letter :accent 'grave) you could just write (setf (accent letter) 'grave) ?
11:55:57
pjb
daphnis: where do the trait and value come from? If that comes from a data file, it's an external source, and it should be validated. This is what ECASE does: if we get a bad trait, it signals an error. And you cannot set slots that are not in the list of cases.
11:56:45
engblom
What do you think about me using (let ((x nil) (y nil) (z nil)) (some code) (setf x something) (some code) (setf y something) ... )? That would make local variables, but not requiring a lot of nested let.
11:57:12
pjb
daphnis: now, if there was a lot of cases, or if they were "dynamic" because you'd have different classes, perhaps not know at compilation time, we could have a data structure to map trait keywords to accessors, but we would still go thru this validation and control.
11:59:14
pjb
engblom: (let* ((x (compute-x)) (y (compute-y x)) (z (compute-z x y))) (do-something x y z)) so you can have some code between the binding of the variables with let*.
11:59:57
pjb
engblom: (let* ((x (progn (something) (compute-x))) (y (progn (something) (compute-y x))) (z (progn (something) (compute-z x y)))) (do-something x y z))
12:00:22
daphnis
the traits don't come from an external source. one other thing the furnish method does is that it determines the trait based on the value (if only one trait can have that value)
12:00:23
engblom
pjb: In this case each definition of let will have a side effect: it will place a form element on a site and the reference to the element is assigned to the variable. Because of that I need to add some code between (spacers, layout, text, etc) between each assignment with let.
12:00:34
pjb
engblom: typically, when you have to initialize some complex objects, you have to use some mutation. then you can do:
12:02:26
pjb
engblom: (let ((rt (let ((rt (copy-readtable))) (set-macro-character #\a (lambda (s c) (char-upcase c)) rt) rt))) (let ((*readtable* rt)) (read-from-string "abc"))) #| --> abc ; 3 |#
12:03:11
pjb
daphnis: note that even if furnish needs to do something more, this is something you can also do by writing eg. :after or :before methods on the accessors.
12:03:40
engblom
pjb: So (let ((olt (create-select ....))) ....) would create a dropdown list on the site, and I can read the value by doiing (value olt). But to create a real layout on the site I need to add some more stuff between the form elements, so I am not able to add everything inside of a single let without some tricks.
12:04:11
pjb
daphnis: eg. (defmethod (setf accent) :before (new-accent letter) (incf *accent-count*)) (defmethod accent :after (letter) (print 'yay))
12:06:22
pjb
engblom: now the thing is that the rule of evaluations in CL are very precise. macros and special operator explicitely specify in what order, and in what scope each subexpression is evaluated, and for function calls, the arguments are evaluated from left to right. Therefore you can wrap any subexpression in a prog1/prog2/progn to add side effects before and/or after computing the subexpression.
12:07:17
pjb
And some functions are specified to return their argument on purpose so you can write stuff as : (let ((x 42) (y 33)) (print (+ (print (* (print x) 4)) (print y)))) #| 42
12:07:53
pjb
engblom: print is used like that routinely when debugging. But you can use prog1/prog2/progn and add any side effect.
12:09:45
pjb
(let ((x 42) (y 33)) (+ (* (let ((x/2 (/ x 2))) (+ (expt x/2 2) (expt x/2 1/2))) 4) y)) #| --> 1815.3303 |#
12:10:49
pjb
engblom: and vice versa. If you have an expression too complex, you can always put (defun sub (x) …) around a subexpression and replace it with (sub x)
12:11:14
pjb
(defun sub (x) (let ((x/2 (/ x 2))) (+ (expt x/2 2) (expt x/2 1/2)))) (let ((x 42) (y 33)) (+ (* (sub x) 4) y)) #| --> 1815.3303 |#
12:12:06
pjb
engblom: sexps are very easy to manipulate in the editor, and since lisp operators are very orthogonal, the code (which is actually data) is very maleable.
12:13:03
pjb
engblom: there are only expressions, and and very little syntax in macros and special operators (eg. you cannot put an expression instead of the name of a variable in a LET; but apart from those few exception, you can put any expression in place of any subexpression.
12:14:23
pjb
engblom: (if (< delta 0) (- b (sqrt (- delta))) (- b (sqrt delta))) --> (- b (sqrt (if (< delta 0) (- delta) delta))) or even --> (- b (sqrt (funcall (if (< delta 0) (function -) (function +)) delta)))
12:14:25
engblom
pjb: Thank you! Now I would only need an easy way to send stuff from vim to repl. Now testing stuff has been taking time because every time I made a change I have been (ql:quickload :my-project) in order to update repl, and I have not been able to test any function that is not external.
12:26:44
engblom
pjb: I wonder if using some vim emulation in Emacs would cause any shortcut conflicts if using Slime?
12:30:45
engblom
Is this still valid, as it is from 2016? https://fouric.github.io/posts/2016-05-20-getting-set-up-with-emacs.html
12:40:41
edgar-rft
Common Lisp is more than 25 years old and Emacs is more than 40 years old, so 2016 is like yesterday in other programming languages :-)
13:03:08
engblom
I got emacs installed. In vim I would use :set background=dark to automatically change the colors of highlightning to be readable on a dark background. Is there something similar that can quickly be done in Emacs. Right now I can not read the code with my poor eyes (when running emacs -nw).
13:08:08
_death
engblom: well, apparently color-theme is the old, deprecated, obsolete, ex-parrot way nowadays.
13:08:45
beach
engblom: I am sorry my fellow #lisp participants probably confused the hell out of you.
13:14:43
beach
It means that you don't evaluate the argument, and instead you pass a reference to a place (or an l-value).
13:15:50
jackdaniel
this is simply part of the common lisp evaluation rules, not something "natural" or obvious
13:15:59
cer-0
IIRC there are some cases when you don't apply this behaviour, take cond for example if you write incorrect code after a valid clause they won't be evaluated.
13:16:17
jackdaniel
it is related, because you present it as some natural consequence of some unspecified rule of the universe
13:16:42
jackdaniel
ACTION will back down to not confuse people hell out and leave the explanation to beach and jmercouris
13:16:52
beach
jmercouris: So, C and C++, when you call a function with an "object" will copy the object by default.
13:17:54
beach
So if you call a function with an object, the object will be copied before it is passed to the callee.
13:18:20
jmercouris
I've never been programming Lisp and thought "Man, if only I had pointers that way"
13:18:56
beach
So they have to copy in order to make sure that the number of references to an object is always 1.
13:20:32
Bike
imagine a struct that's small enough to fit in two registers. if you pass it to a function, it's passed in registers without memory being touched. if that function alters a field, it just alters a register. when the function returns, the caller registers are restored from the stack, so the struct in the caller is what it was before the call. ergo, the object is "copied"
13:21:10
Bike
C++ then adds copy constructors and move constructors and prvalues and xvalues and my god it just keeps going
13:21:23
beach
So, as Bike says, the other consequence of "copy semantics" is that a function can't modify an object that you pass to it, because it is always copied.
13:21:53
Bike
the concept of a "move constructor" is basically what beach is talking about with the number of references only being one. if you "move" an object instead of "copying" it, the old thing referring to it no longer does
13:22:09
Bike
the semantics are pretty confusing, but that's what you need to do to keep this stuff up efficiently, i guess
13:22:40
beach
Yes, it is necessarily confusing because of the lack of automatic memory management and all the consequences that follow from that decision.
13:23:26
beach
So, to me, the only sane programming model is "call-by-value" and "uniform references semantics" which is what Common Lisp uses, no matter what other people here might say.
13:24:29
beach
Granted, most modern languages do the same thing, perhaps with a few exceptional cases like Java that handles machine integers differently, or it used to.
13:25:20
beach
It is quite amazing to me the snowball effect that lack of automatic memory management creates.
13:29:55
beach
Nilby, pbj: In my opinion, it is pedagogically unhelpful to bring up the performance hack that immediate objects such as fixnums and characters use, since those objects are immutable. The semantics would still be "uniform reference semantics". At least, it is unhelpful to someone who has no clue. You can bring it up when they start asking about references to small objects like characters.