freenode/#lisp - IRC Chatlog
Search
9:03:50
asarch
In the lines #29, 45, 51, 59, 62 where *application-frame* appears, are they closures?
9:05:26
beach
asarch: *application-frame* is a special variable that contains an instance of a standard class.
9:14:04
asarch
Why when you declare a new class: http://paste.scsys.co.uk/582762?ln=on&submit=Format+it%21
9:16:48
asarch
I mean, when it is defined, you do something like (p1 point) at line #24, first the "instance" var and then the name of the class
9:17:19
asarch
And, in the line #44 of http://paste.scsys.co.uk/582761?ln=on&submit=Format+it%21 you do the opposite, (slider value)?
9:18:19
beach
It means define a method on the generic function DRAW that is only applicable when its parameter P1 is an instance of the class POINT.
9:19:31
beach
It means: Define a function named COLORS-SLIDER-DRAGGED with two parameters. The first parameter is named SLIDER and the second parameter is named VALUE.
9:20:15
beach
The reader of the code might guess that the value of the SLIDER parameter is indeed an instance of the class SLIDER.
9:20:47
asarch
I still have a lot of C in my mind that confuses me a lot with Common Lisp way of life :-(
9:30:57
asarch
So, the only way to "declare" a function with an instance of a class as one of its parameters is with DEFMETHOD?
9:32:51
beach
There is no need for anything like that, since classes do not imply encapsulation in Common Lisp.
9:33:44
beach
asarch: Maybe in your case, it is best to try to forget what you know about C or C++ when you work with Common Lisp.
9:33:57
TMA
asarch: that does not mean that a function defined by DEFUN is unable to accept arguments of the desired type. it is just that there is no discrimination on the type of the passed argument, unless you write the discrimination yourself
9:35:14
schweers
On the topic of encapsulation: is there a way to do proper encapsulation in Lisp? Not that I even found a need for it ...
9:36:24
schweers
goood question. I guess having some value which cannot be seen or even set by "outside" code?
9:36:49
schweers
I know and it has always been enough for me. But the hiding is based on convention, the language doesn’t enforce it.
9:37:13
beach
schweers: You define those things in a separate package and you don't export their names.
9:37:18
schweers
I do, I’ve never had the need for such a thing. But many people want it. Also, I’m curious. Hence my question
9:39:51
|3b|
closures tend to hide things in a way that is hard to get to, so you could use them if you really wanted to
9:40:13
schweers
So if a C++ or Java person were to come on here and ask how to do private members in CLOS or lisp in general, you’d rather explain why it’s misguided to enforce it in the first place?
9:40:22
heisig
schweers: Proper encapsulation sounds like you have to give up root permissions on your own computer. Even then, you could still physically destroy the computer :)
9:40:23
shka__
schweers: furthermore, it would be really difficult to have C++/java style encapsulation in dynamic language like Common Lisp
9:40:55
jackdaniel
schweers: if you want to encapsulate interfaces there is an easy solution for that: you put all in a package and export only "public" things
9:41:27
jackdaniel
as of preventing from direct slot access, you may name your slots with gensym (macro is needed) and enforce proper method interface via readers/writers/accessors
9:41:35
schweers
I think my question has been answered :) To be clear: I’m with you all, I was asking this as a hypothetical
9:43:03
jackdaniel
also that, connected with backtrace capabilities: you would be able to see who calls your method and see, if it is a "friend"
9:44:30
|3b|
also hard to compare features between languages. is the #define trick, or accessing 'private' slots with pointers comparable to accessing unexported symbols, or using MOP?
9:45:30
schweers
I have a feeling that accessing unexported symbols or even using MOP is more stable. But anyway, it was a hypothetical question anyway
10:04:51
shka__
it is very much used, and it is somewhat helpfull in some projects, but it comes with downsides and make dynamic style of programming PITA
10:05:44
shka__
but i used to work in crappy C++ corpo-projects full of outsourcing programmers and there encapsulation had it's place
10:51:58
ogamita
schweers: for private members or methods, we could talk about the % naming convention. A symbol starting or ending with a % could be considered "private" and "dangerous to use, know what you're doing". But nothing prevents you to use such symbol, even if they're not exported from a package.
10:52:39
ogamita
schweers: it is assumed that the lisp programmer is smart and knows what he's doing.
10:53:34
schweers
Exactly, nothing prevents others from using this. I’m fine with this and I do this (I think I saw this convention in some code written by beach). I was just wondering if a more strict enforcement was possible. Not because I want to use it, but just as a hypothetical question because I’m curious.
10:53:43
ogamita
with packages, there's the notion of exported symbols and non-exported symbols. The later can be considered "private".
10:53:55
schweers
ogamita: doesn’t every language community assume that their members are smart and know what they are doing?
10:54:32
ogamita
schweers: the only difference is that expored symbols can be accessed direct when the package is used, or qualified with a single colon, while the non-exported must be qualified with two colons: foo:exported-sym foo::non-exported-sym.
10:55:00
ogamita
schweers: perhaps, but the difference is that most lispers do, while most Cer or C++er don't.
10:55:48
ogamita
cf. shka__'s comment: <shka__> but i used to work in crappy C++ corpo-projects full of outsourcing programmers and there encapsulation had it's place
10:59:48
schweers
Especially the java community seems to do it, but they also seem to jump though an awful lot of hoops to do so.
11:02:59
shka__
if you are encapsulating everything, if you are not starting from the tests, you are likely to write untestable code
11:04:08
schweers
You can still test the public interface. But yes, testing the more low-level stuff is difficult in such a scenario.
11:05:59
schweers
Well, java doesn’t even have C++’s broken MI. I’m still not sure which is better in that regard.
11:17:03
jackdaniel
when you acquire tao of programming you patiently wait for problems to fade away due to changed requirements, then you achieve the goal without even touching the keyboard ;-)
11:19:41
ogamita
(but then of course, it's Russian dolls: the internals are also decomposed into public API and clients, so you can test the internal APIs too).
11:20:54
ogamita
But the more internal the code, the more often it can change. The point of having API and distinguishing implementation from interface, is that you can change the implementation anytime, without breaking the rest of the program, since it only uses the public API.
11:21:19
ogamita
So if you test internal, as soon as you change it, you have to throw away the tests and write new tests for the new internals.
11:33:03
jmercouris
e.g. how can I go from (list :a "fish" :b "salmon") -> (list :a "fish" :b "carp")
11:36:27
shka__
alternative approach, sometimes usefull is to simply insert :b "carp" into front of the list
11:41:16
heisig
jmercouris: There is (let ((plist (list :a "fish" :b "salmon"))) (setf (getf plist :b) "carp") plist). But you are right, it is dirty.
11:51:42
beach
jmercouris: Since a plist is not an abstract data type, you should not expect anything better.
12:03:22
beach
What I am saying is that neither list not plist is an abstract data type, so you can't expect them to have identity-preserving abstract operations on them.
12:04:14
beach
Lisp provides excellent concrete data types, but you have to create the abstract ones yourself (mostly).
12:05:32
jmercouris
I don't get to choose the data type I'm working on without some complex transformations
12:05:33
beach
and a plist is but one possible concrete data type to build upon in order to create a dictionary ADT.
12:06:21
schweers
jmercouris: well, you could put the data into a hashtable or something similar, do your processing and create a new plist again (if needed).
12:07:26
heisig
jmercouris: The only reason to ever use plists is that their printed representation looks pretty. For anything else, use alexandria:plist-[alist,hash-table].
12:08:40
jmercouris
within the loop, my "product" is updated, but it is not updated within the products list...
12:09:29
schweers
I don’t think you can do that, as PRODUCT comes rom PRODUCTS. If you push to PRODUCT, that will not change the list PRODUCTS
12:10:03
jmercouris
so it stands to reason that modifying a PRODUCT within PRODUCTS will change PRODUCTS
12:10:41
schweers
If I’m not mistaken, PUSH creates a new cons, and sets the reference (in your case PRODUCT) to this new cell.
12:11:04
schweers
This will not change the list from which you are taking the list you are “pushing to”
12:12:19
schweers
you could collect the PRODUCT values into a new list, if you want to keep the rest of your code the same.
12:13:14
jmercouris
shrdlu68: pushing to the beginning of an alist when there is an existing entry with the same "key" means that the old key/value pair is still there
12:14:04
beach
jmercouris: What is the result of this code: (defparameter *l* '(1 2 3)) (let ((l *l*)) (push 234 l)) *l*
12:15:30
beach
jmercouris: Besides, you are not allowed to alter a list being iterated over in a LOOP.
12:20:16
beach
If TAX-PAYER inherits from PERSON then a tax payer (i.e. an instance of TAX-PAYER) is a person (i.e. and instance of PERSON).
12:20:19
schweers
beach: I’d like to thank you for your precise definitions. They may seem like nitpicking at first, but I am very glad you do this.
12:21:05
schweers
Of course it is, but not everyone knows all the details by heart (I certainly don’t).
12:21:25
jmercouris
I used to get angry at it, but I see the value in it now, at least within the context of a programming dicsussion, my significant other seems to disagree with regard to other topics...
12:21:28
shka__
shrdlu68: in this case list could be :initform '(:a "b") in defclass, and so it would be created during read time
12:23:50
beach
shka__: Which is why you hide the entire mutation behind an API so that you can make sure that the CONS cells you mutate are the ones you created yourself.
12:25:07
shka__
shrdlu68: lists are often created at the read time and also multiple lists tend to share tails
12:26:08
shka__
as beach said, if you need to mutate state you are better of making some kind of API
12:29:15
shrdlu68
I never thought about that, but I feel like this is a lesson about creating standard object...
12:51:19
jmercouris
so READ, it takes an input stream, so if you have a stream you have to make an input-stream and then pass it
12:52:08
jmercouris
sorry there was a typo above, I meant to say "so READ, it takes an input stream, so if you have a *STRING* you have to make an input stream and then pass it"
12:53:03
jmercouris
jackdaniel: ok, I read some misinformation on stack-overflow which made me not investigate, should have checked CLHS, thanks for tip!
13:00:18
jmercouris
and they come with corresponding functions/methods for manipulating those data structures
13:00:40
jmercouris
however I don't think there is a de-facto library, if there is, I am not aware of it, then again I'm not a good source, as I am not aware of a lot of things
13:08:49
larryba
is there a map function that only alters the elements, and leaves the data structure intact? so, if I pass a list, I should get list back. if I pass a string, I want string back
13:10:34
jackdaniel
doesn't he want something more like (prog1 sequence (map nil function sequence))
13:14:07
larryba
jackdaniel I don't know what that does, but based on my test with lists, shka__'s example works
13:18:25
larryba
(map (type-of input) ..) does that for strings, lists and vectors. which is good enough for me
13:19:24
jackdaniel
larryba: (map type function sequence1 sequence2 …) actually creates a new sequence which holds results of applying function to elements of enlisted sequences, it doesn't return sequence1 itself
13:20:55
margaritamike
What is the equivalent of the python request module for common lisp? http://docs.python-requests.org/en/master/
13:21:11
jackdaniel
maybe I've sipped to little coffee because it is still not clear to me what you are saying, I'll back off :-)
13:21:44
larryba
jackdaniel, if I pass it a list, it should return a list. if I pass it a vector, it should return a vector. etc. shka__'s solution does that, so all is good. :)
13:23:14
larryba
Xach, any reason to prefer that over (map (type-of thing) fun thing)? does it work with more containers?
13:25:25
jackdaniel
OK, word "identical" confused me, because function is not necessarily #'identity. 'of identical sequence type' would make it clear to me.
13:25:46
Selwyn
it is recommended as a catch all solution in 'Common Lisp Recipes' - admittedly published in 2015
13:26:16
splittist
margaritamike: what changes in the http protocol since 2017 are you concerned about?
13:27:32
Selwyn
margaritamike: in general, one can expect to use Common Lisp libraries not updated in that timeframe without concern, whereas this is not as common in, say, the Python world for various reasons
13:27:38
larryba
jackdaniel, (map (type-of input) (lambda (x) x) input) will return identical copy of input, in every regard. if compiler is smart enough, and input's type is immutable, it could even just return input
13:28:36
margaritamike
i'm cool with that, i just want to use what everyone else agrees on is considered the library to use for an http request library
13:28:40
larryba
(I guess none of the types that map supports are immutable, so that is just in theory)
13:29:02
jackdaniel
larryba: sure, that's why I've put there "because function is not necessarily #'identity", but I'll drop it, I know what you mean so there is no need to nitpick on my side ,p
13:31:19
Selwyn
i don't actually know of any others. i used the most basic functionality a couple of times without problems
13:32:01
larryba
shka__, lets say that, hypothetically, strings were immutable, map could just return input given (map 'string (lambda (x) x) input)
13:33:41
Selwyn
margaritamike: with regard to Python vs. Common Lisp, Common Lisp is defined with regard to a fixed standard since 1994 (?), whereas Python is not and changes over time.
13:34:22
Selwyn
this means that you can use Common Lisp code written portably some time ago without problems, whereas in Python there are the python2 python 3 incompatibility issues to start off with
13:35:08
marvin2
last time I checked most python programmers were still using 2.x, refusing to switch. not sure if that has changed recently
13:36:02
Selwyn
one of my biggest surprises when i started to use CL was that old code would simply run fine, i remember previously never having to rely on python code that wasn't updated in the last few months
13:36:59
jackdaniel
it is not as apparent thanks to Xach work to test at least briefly each QL release
13:38:58
Selwyn
jackdaniel: i am looking forward to try out mcclim on my new laptop when it arrives this week
14:56:51
ogamita
minion: memo for jmercouris: you can use sedit, the sexp editor. http://informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/sedit/index.html
15:00:29
ogamita
minion: memo for jmercouris: alternatively: (let ((plist (list :a "fish" :b "salmon"))) (let ((plist (list* :b "carp" plist))) (getf plist :b))) #| --> "carp" |# ; ie. functional style.
15:02:18
ogamita
beach: that said, person has two subclasses: moral-person and physical-person, so it'd be better if tax-payer was an OPTIONAL mixin… Just saying.
15:03:07
ogamita
or even, a reified association between a thug organization and a person, since a single person will often have to pay several thug organisation to avoid being molested.
15:04:36
ogamita
Some people, in particular biologists have used UML to modelize real systems (like, cell metabolism). Perhaps it'd be useful to study those models to give them as real-life examples :-)
18:28:13
pjb
So you could take the Molecule superclass, and its two direct subclasses Protein and Macromolecule.
19:03:44
asarch
Yesterder, TMA told me: "asarch: that does not mean that a function defined by DEFUN is unable to accept arguments of the desired type. it is just that there is no discrimination on the type of the passed argument, unless you write the discrimination yourself". In this context, what does "discrimination" mean?